
                 UNIVERSITY OF CAMBRIDGE COMPUTING SERVICE

              SPECIFICATION OF THE EXIM MAIL TRANSPORT AGENT

                                    by

                               Philip Hazel


Computer Laboratory
New Museums Site
Pembroke Street
Cambridge CB2 3QG
United Kingdom

phone:  +44 1223 334600
fax:    +44 1223 334679
email:  P.Hazel@ucs.cam.ac.uk

Edition for Exim 1.60, February 1997


                Copyright (c) University of Cambridge 1997



                           CONTENTS

1. Introduction
  1.1 Limitations
  1.2 Features
  1.3 Interface
  1.4 Terminology

2. Incorporated code

3. How Exim delivers mail
  3.1 Message reception
  3.2 Life of a message
  3.3 Delivery in detail

4. Building and installing Exim
  4.1 Unpacking
  4.2 Multiple machine architectures and operating systems
  4.3 Linux and ndbm
  4.4 Pre-building configuration
  4.5 The building process
  4.6 Overriding build-time options for Exim
  4.7 OS-specific header files
  4.8 DBM libraries
  4.9 Overriding build-time options for the monitor
  4.10 Installing commands and scripts
  4.11 Setting up the spool directory
  4.12 Testing
  4.13 Switching Exim on
  4.14 Stopping Exim on Solaris 2

5. Exim's command-line options
  5.1 Trusted and admin users
  5.2 Command line options

6. File and database lookups
  6.1 Partial matching in file lookups
  6.2 More about NIS+

7. The Exim configuration file
  7.1 Configuration file format
  7.2 Macros in the configuration file
  7.3 Common option syntax
  7.4 Integer
  7.5 Fixed point number
  7.6 Time interval
  7.7 String
  7.8 Expanded strings
  7.9 User and group names
  7.10 String lists
  7.11 Domain lists
  7.12 Partial matching in domain lists
  7.13 Address lists
  7.14 Host lists
  7.15 Net lists

8. Regular expression syntax

9. String expansions
  9.1 Expansion items
  9.2 Expansion operators
  9.3 Expansion conditions
  9.4 Expansion variables
  9.5 Expansion string examples

10. Main configuration

11. Driver specifications

12. Environment for running local transports
  12.1 Uids and gids
  12.2 Current and home directories

13. Generic transport options

14. The appendfile transport
  14.1 Operational details

15. The autoreply transport

16. The debug transport

17. The pipe transport
  17.1 Returned status and data
  17.2 How the command is run
  17.3 Environment variables
  17.4 Private options

18. The smtp transport

19. Generic director options
  19.1 Skipping directors

20. The aliasfile director
  20.1 Alias file format
  20.2 Types of alias item
  20.3 Errors in alias files
  20.4 Specifying a transport
  20.5 Aliasfile private options

21. The forwardfile director
  21.1 Forward file items
  21.2 Errors in forward files
  21.3 Filter files
  21.4 The home directory
  21.5 Forwardfile private options

22. The localuser director

23. The smartuser director

24. Generic router options
  24.1 Skipping routers

25. The domainlist router
  25.1 Routing rules
  25.2 Domainlist examples

26. The ipliteral router

27. The iplookup router

28. The lookuphost router

29. The queryprogram router

30. Retry configuration

31. Address rewriting

32. Log files
  32.1 Logging message reception
  32.2 Logging Deliveries
  32.3 Deferred deliveries
  32.4 Delivery failures
  32.5 Completion
  32.6 Log level
  32.7 Message log

33. Message processing
  33.1 The Bcc header
  33.2 The Date header
  33.3 The Delivery-date header
  33.4 The Envelope-to header
  33.5 The From header
  33.6 The Message-id header
  33.7 The Received header
  33.8 The Return-path header
  33.9 The Sender header
  33.10 The To header
  33.11 Constructed addresses
  33.12 Case of local parts
  33.13 Rewriting addresses

34. The default configuration file
  34.1 Main configuration settings
  34.2 Transport configuration settings
  34.3 Director configuration settings
  34.4 Router configuration settings
  34.5 Retry rules
  34.6 Rewriting configuration

35. Day-to-day management
  35.1 The reject log
  35.2 Log cycling
  35.3 Statistics
  35.4 What is Exim doing?
  35.5 Changing the configuration
  35.6 Watching the queue

36. Intermittently connected hosts

37. Automatic mail processing
  37.1 System-wide automatic processing
  37.2 Users' automatic processing
  37.3 Simplified vacation processing

38. Multiple user mailboxes

39. Using Exim to handle mailing lists

40. Virtual domains
  40.1 All mail to a given host
  40.2 Virtual domain not preserving envelope
  40.3 Virtual domain preserving envelope

41. Exim utilities
  41.1 Querying Exim processes
  41.2 Extracting log information
  41.3 Cycling log files
  41.4 Making DBM files
  41.5 Individual retry times
  41.6 Database maintenance
  41.7 Mail statistics

42. The Exim monitor
  42.1 Running the monitor
  42.2 The stripcharts
  42.3 Main action buttons
  42.4 The log display
  42.5 The queue display
  42.6 The queue menu

43. SMTP processing
  43.1 Outgoing SMTP over TCP/IP
  43.2 Incoming SMTP over TCP/IP
  43.3 Host and network rejection
  43.4 Sender rejection
  43.5 Control of relaying
  43.6 Unqualified addresses
  43.7 Sender verification
  43.8 Receiver verification
  43.9 System-wide message filtering
  43.10 Outgoing batched SMTP
  43.11 Incoming batched SMTP

44. Security considerations
  44.1 Root privilege
  44.2 Reading forward files
  44.3 Delivering to local files
  44.4 IP routing
  44.5 Privileged users
  44.6 Spool files

45. Format of spool files

46. Adding new drivers to Exim



                              1. INTRODUCTION


  "If I have seen further it is by standing on the shoulders of giants."
                                                             (Isaac Newton)

Exim is a mail transport agent (MTA) for Unix systems connected to the
Internet. Configuration files currently exist for the following operating
systems: AIX, BSDI, DGUX, FreeBSD, HI-OSF (Hitachi), HP-UX, IRIX, Linux,
NetBSD, OpenBSD, DEC's OSF1 (aka Digital UNIX), SCO, SCO SVR4.2 (aka UNIX-
SV), SunOS4, SunOS5, Ultrix, and Unixware. However, code is not available
for determining system load averages for AIX or Ultrix.

The terms and conditions for the use and distribution of Exim are contained
in the file NOTICE. Exim is distributed under the terms of the GNU General
Public Licence, a copy of which may be found in the file LICENCE.

Exim owes a great deal to Smail 3 and its author, Ron Karr. Without the
experience of running and working on the Smail 3 code, I could never have
contemplated starting to write a new mailer. Many of the ideas and user
interfaces are taken from Smail 3, though the actual code of Exim is
entirely new.

I am indebted to my colleague Piete Brooks for suggesting and implementing
the scheme for building Exim for multiple architectures and operating
systems, for porting Exim to several different versions of Unix, for
numerous suggestions, for pointing out where I had got things wrong, and
for extensive testing. A number of other people, both in Cambridge and
around the world, have contributed to the development and the testing of
Exim, and to porting it to various operating systems. I am grateful to them
all.

This edition of the Exim specification applies to version 1.60 of Exim.
Substantive changes from the 1.58 edition are marked by bars in the right
margin, except in the Texinfo version of the documentation, because Texinfo
doesn't support change bars. Minor corrections and rewordings are not so
marked.

As the program is still developing, there may be features in later versions
of the program that have not yet made it into this document, which is
updated only when there is a reasonable batch of changes to make. However,
all changes are noted briefly in the distributed file called doc/ChangeLog,
and specifications of new features that are not in this manual are placed
in doc/NewStuff.

There is a mailing list for users of Exim called exim-
users@lists.cam.ac.uk. Requests to be added or deleted should be sent to
exim-users-request@lists.cam.ac.uk. By courtesy of Martin Hamilton, there
is an archive of this list in plain text form at
http://www.roads.lut.ac.uk/lists/exim-users/exim-users.archive and in HTML
via Hypermail at http://www.roads.lut.ac.uk/lists/exim-users/.

The current distribution of Exim is always to be found in

  ftp://ftp.cus.cam.ac.uk/pub/software/programs/exim/exim-n.nn.tar.gz

where n.nn is the highest such version number in the directory. When there
is only a small amount of change from one version to the next, a patch file
may be provided, with a final component name of the form

  exim-patch-n.nn-m.mm.gz

The main distribution contains ASCII versions of this specification and
other documentation; other formats of the documents are available in
separate files:

ftp://ftp.cus.cam.ac.uk/pub/software/programs/exim/exim-postscript-n.nn.tar.gz
ftp://ftp.cus.cam.ac.uk/pub/software/programs/exim/exim-texinfo-n.nn.tar.gz

These tar files contain only the /doc directory, not the complete
distribution.


1.1 Limitations

 .   Exim is written in ANSI C. This should not be much of a limitation
     these days. However, to help with systems that lack a true ANSI C
     library, Exim avoids making any use of the value returned by the
     sprintf() function, which is one of the main incompatibilities. It has
     its own version of strerror() for use with SunOS4 and any other system
     that lacks this function, and a macro can be defined to turn memmove()
     into bcopy() if necessary.

 .   Exim uses file names that are longer than 14 characters.

 .   Exim is intended for use as an Internet mailer, and therefore handles
     addresses in RFC 822 domain format only. It cannot handle 'bang
     paths', though simple two-component bang paths can be converted by a
     straightforward rewriting configuration.

 .   Exim insists that every address it handles has a domain attached. For
     incoming local messages, domainless addresses are automatically quali-
     fied with a configured domain value. Configuration options specify
     from which remote systems unqualified addresses are acceptable.

 .   The only external transport currently implemented is an SMTP transport
     over a TCP/IP network (using sockets), suitable for machines on the
     Internet. However, a pipe transport is available, and there are
     facilities for writing messages to files and pipes in "batched SMTP"
     format; these can be used to send messages to some other transport
     mechanism. Batched SMTP input is also catered for.


1.2 Features

These are some of the main features of Exim:

 .   Exim follows the same general approach of decentralized control that
     Smail does. There is no central process doing overall management of
     mail delivery. However, unlike Smail, the independent delivery pro-
     cesses share data in the form of 'hints', which makes delivery more
     efficient in some cases.

 .   Exim has flexible retry algorithms, applicable to directing and
     routing addresses as well as to delivery.

 .   Exim contains header and envelope rewriting facilities.

 .   Unqualified addresses are accepted only from specified hosts or
     networks.

 .   Exim can perform multiple deliveries down the same SMTP channel after
     deliveries have been delayed.

 .   Exim can be configured to do local deliveries immediately but to leave
     remote (SMTP) deliveries until the message is picked up by a queue-
     runner process. This increases the likelihood of multiple messages
     being sent down a single SMTP connection.

 .   Remote deliveries of the same message to different hosts can option-
     ally be done in parallel.

 .   Incoming SMTP messages start delivery as soon as they are received,
     without waiting for the SMTP call to close.

 .   Regular expressions are available in a number of configuration
     parameters.

 .   Domain lists can include file lookups, making it possible to support
     very large numbers of local domains.

 .   Exim supports optional checking of incoming return path (sender) and
     receiver addresses as they are received by SMTP.

 .   SMTP calls from specific machines, optionally from specific idents,
     can be locked out, and incoming SMTP messages from specific senders
     can also be locked out.

 .   Hosts that are permitted to relay mail through a machine to another
     external domain can be controlled by IP number or IP network number.

 .   Messages on the queue can be 'frozen' and 'thawed' by the
     administrator.

 .   Exim can handle a number of independent local domains on the same
     machine; each domain can have its own alias files, etc. This facility
     is sometimes known as 'virtual domains'.

 .   Exim stats a user's home directory before looking for a .forward file,
     in order to detect the case of a missing NFS mount. Delivery is
     delayed if the directory is unavailable.

 .   Exim contains an optional built-in mail filtering facility. This can
     be configured to allow users to provide personal filter files, and it
     is also possible for a system-wide filter file to be applied to every
     message.

 .   Periodic warnings are automatically sent to messages' senders when
     delivery is delayed - the time between warnings is configurable.

 .   A queue run can be manually started to deliver just a particular
     portion of the queue, or those messages with a recipient whose address
     contains a given string.

 .   Exim can be configured to run as root all the time, except when
     performing local deliveries, which it always does in a separate
     process under an appropriate uid and gid. Alternatively, it can be
     configured to run as root only when needed; in particular, it need not
     run as root when receiving incoming messages or when sending out
     messages over SMTP. See chapter 44 for a discussion of security
     issues.

 .   I have tried to make the wording of delivery failure messages clearer
     and simpler, for the benefit of those less-experienced people who are
     now using email.

 .   The Exim Monitor is an optional extra; it displays information about
     Exim's processing in an X window, and an administrator can perform a
     number of control actions from the window interface.


1.3 Interface

Like many MTAs, Exim has adopted the Sendmail interface so that it can be a
straight replacement for /usr/lib/sendmail. All the relevant Sendmail
options are implemented, with one reservation. There are also some
additional options that are compatible with Smail 3, and some further
options that are new to Exim.

Sendmail uses the -bi option as a request to rebuild the alias file. As
Exim does not have the concept of a single alias file, it cannot mimic this
behaviour. It can be configured to run a particular script when this option
is received; otherwise the option is ignored.

The configuration interface is via a single text file which is divided into
a number of sections. The entries in this file consist of keywords and
values, in the style of Smail 3 configuration files. A default configur-
ation file which is suitable for simple installations is provided.

Control of messages on the queue can be done via certain privileged command
line options. There is also an optional monitor program called eximon,
which displays current information in an X window, and contains a menu
interface to Exim's command line administration options.


1.4 Terminology

The term "local part", which is taken from RFC 822, is used to refer to
that part of an email address that precedes the @ sign. The part that
follows the @ sign is called the "domain" or "mail domain".

The word "domain" is sometimes used to mean all but the first component of
a machine's name. It is not used in that sense here, where it normally
refers to the part of an email address following the @ sign.

"Local domains" are mail domains for which the current host is responsible;  |
in other words, it has special knowledge of what to do with messages sent    |
to such domains, and normally that means either delivering them on the       |
local host or transforming them using alias files or something similar. All  |
other domains are "remote domains", which normally cause the message to be   |
transmitted to some other host.                                              |
                                                                             |
The distinction is not always entirely clear-cut since a host can have       |
special knowledge about routing for remote domains, and messages for local   |
domains may under some circumstances be passed to other hosts.               |
                                                                             |
The terms "local delivery" and "remote delivery" are used to distinguish     |
delivery to a file or a pipe on the local machine from delivery by SMTP to   |
some remote machine. The type of delivery does not necessarily correspond    |
to the type of address. Mail for a local domain may get passed on to some    |
other host, while mail for a remote domain might get delivered locally to a  |
file or pipe for onward transmission by some other means. However, these     |
are special cases.                                                           |

The term "mailmaster" is used to refer to the person in charge of
maintaining the mail software on a given computer. Commonly this will be
the same person who fulfils the postmaster role, but this may not always be
the case.

The term "queue" is used to refer to the set of messages awaiting delivery,  |
because this term is in widespread use in the context of MTAs. However, in   |
Exim's case the reality is more like a pool than a queue, because there is   |
no ordering of waiting messages.                                             |
                                                                             |
The term "queue-runner" is used to describe a process that scans the queue   |
and attempts to deliver those messages whose retry times have come. This     |
term is used by other MTAs, and also relates to the command runq, but in     |
Exim the waiting messages are processed in an unpredictable order.           |



                            2. INCORPORATED CODE


Three pieces of external code are included in the Exim distribution.

 .   Regular expressions are supported in the main Exim program and in the
     Exim monitor using Henry Spencer's freely-distributable set of func-
     tions, copyright (c) 1986 University of Toronto. No modifications of
     substance have been made to the source, which is distributed in the
     directory called regexp, but the lines

       extern char *strchr();
       #include <string.h>

     were added to the regexp.c to get rid of warnings from modern
     compilers.

 .   RFC 1413 callbacks are supported in the main Exim program using the
     libident library made freely available by Peter Eriksson at
     ftp.lysator.liu.se. No modifications have been made to the source,
     which is distributed in the directory called src/libident.

 .   The Exim Monitor program, which is an X-Window application, includes
     modified versions of the Athena StripChart and TextPop widgets. This
     code is copyright by DEC and MIT, and their permission notice appears
     below, in accordance with the conditions expressed therein.

___________________________________________________________________________

Copyright 1987, 1988 by Digital Equipment Corporation, Maynard,
Massachusetts, and the Massachusetts Institute of Technology, Cambridge,
Massachusetts.

                            All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting documen-
tation, and that the names of Digital or MIT not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission.

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
___________________________________________________________________________



                         3. HOW EXIM DELIVERS MAIL


3.1 Message reception

When Exim receives a message, it writes two files in its spool directory.
The first contains the "envelope" information, the current status of the
message, and the headers, while the second contains the body of the
message. The envelope information consists of the address of the message's
sender and the address(es) of the recipient(s). This information is
entirely separate from any addresses contained in the headers. The status
of the message includes a list of recipients who have already received the
message. The format of the first spool file is described in chapter 45.

Every message handled by Exim is given a unique "message id" which is 16
characters long. It is divided into three parts, separated by hyphens. Each
part is a number, expressed in base 62:

     The first six characters are the time the message was received, as a
     number in seconds - the normal Unix way of representing a time of day.

     After the first hyphen, the next six characters are the id of the
     process that received the message.

     The final two characters, after the second hyphen, are used to ensure
     the id is unique, and are 00 except when a process receives more than
     one message in a single second.

The names of the two spool files consist of the message id, followed by -H
for the file containing the envelope and headers, and -D for the data file.


3.2 Life of a message

A message remains in the spool directory until it is completely delivered
to its recipients or to an error address, or until it is deleted by an
administrator or by the user who originally created it. In cases when
delivery cannot proceed - for example, when a message can neither be
delivered to its recipients nor returned to its sender, the message is
marked 'frozen' on the spool, and no more deliveries are attempted.

An administrator can thaw such messages when the problem has been correc-
ted, and can also freeze individual messages by hand if necessary. In
addition, an administrator can force a delivery error, causing an error
message to be sent.

As delivery proceeds, Exim writes timestamped information about each
address to a per-message log file; this includes any delivery error
messages. This log is solely for the benefit of the administrator, and is
normally deleted with the spool files when processing of a message is
complete. However, Exim can be configured to retain it (a dangerous option,
as the files can accumulate rapidly on a busy system). Exim also writes
delivery messages to its main log file, whose contents are described in
chapter 32.

All the information Exim itself needs to set up a delivery is kept in the    |
first spool file with the headers. When a successful delivery occurs, the    |
address is immediately written at the end of a journal file, whose name is   |
the message id followed by -J. At the end of a delivery run, if there are    |
some addresses left to be tried again later, the first spool file is         |
updated to indicate which these are, and the journal file is then deleted.   |
Updating the spool file is done by writing a new file and renaming it, to    |
minimize the possibility of data loss.                                       |
                                                                             |
Should the system or the program crash after a successful delivery but       |
before the spool file has been updated, the journal is left lying around.    |
The next time Exim attempts to deliver the message it reads the journal      |
file and updates the spool file before proceeding. This minimizes the        |
chances of double deliveries caused by crashes.                              |

The main delivery processing elements of Exim are called directors,
routers, and transports, and collectively these are known as drivers. Code
for a number of them is provided, compile-time options specify which ones
are actually included in the binary, and runtime options specify which ones
are actually used. Directors handle addresses that include one of the local
domains, routers handle remote addresses, and transports do actual
deliveries.


3.3 Delivery in detail

When a message is to be delivered, the sequence of events is roughly as
follows:

 .   If a system-wide filter file is specified, the message is passed to
     it. The filter may add recipients to the message, replace the
     recipients, discard the message, cause a new message to be generated,
     or cause the message delivery to fail. This facility is intended as a
     weapon against mail bombs and unsolicited mail.

 .   Each address is parsed and a check is made to see if it is local or
     not, by comparing the domain with the list of local domains (which can
     be wildcarded, or even read from a file).

 .   If an address is local, it is passed to each configured director in
     turn until one is able to handle it. If none can, the address is
     failed. Directors can be targeted at particular local domains, so
     several local domains can be processed entirely independently of each
     other.

 .   A director that accepts an address may set up a local or a remote
     transport for it, or it may generate one or more new addresses
     (typically from alias, forward, or filter files). New addresses are
     fed back into this process from the top, but in order to avoid loops,
     a director ignores any address which has an identically-named ancestor
     that was processed by itself.

 .   If an address is not local, it is passed to each router in turn until
     one is able to handle it. If none can, the address is failed.

 .   A router that accepts an address may set up a transport for it, or may
     pass an altered address to subsequent routers, or it may discover that
     the address is a local address after all. This typically happens when
     a partial domain name is used and (for example) the DNS lookup is
     configured to try to extend such names. In this case, the address is
     passed back to the directors.

 .   Routers normally set up remote transports for messages that are to be
     delivered to other machines. However, a router can pass a message to a
     local transport, and by this means such messages can be routed to
     other transport mechanisms via pipes or files.

 .   When all the directing and routing is done, addresses that have been
     successfully handled are passed to their assigned transports. When
     local transports are doing real local deliveries, they handle only one
     address at a time, but if a local transport is being used as a pseudo-
     remote transport (for example, to collect batched SMTP messages for
     transmission by some other means) multiple addresses can be handled.
     Remote transports can always handle more than one address at once, but
     can be configured not to do so, or to restrict multiple addresses to    |
     the same domain.

 .   Each local delivery runs in a separate process under a non-privileged
     uid, and they are run in sequence. Exim can be configured so that
     remote deliveries run under a uid that is private to Exim, instead of
     running as root. By default the remote deliveries run one at a time in
     the main Exim process, but a configuration option is available to
     allow multiple remote deliveries for a single message to be run
     simultaneously, each in its own sub-process.

 .   Before running any local transport, Exim checks its retry database to
     see if there has been a previous temporary delivery failure for the
     address. If so, it does not attempt a new delivery until the retry
     time for the address is reached. Remote transports do their own retry
     handling, since an address may be deliverable to one of a number of
     hosts, each of which may have a different retry time. If there have
     been previous failures and no host has reached its retry time, no
     delivery is attempted. See chapter 30 for details of retry strategies.

 .   If there were any errors, a message is returned to an appropriate
     address (the sender in the common case), with details of the error for
     each failing address. Exim can be configured to send copies of error
     messages to other addresses.

 .   If one or more addresses suffered a temporary failure, the message is
     left on the queue, to be tried again later. Otherwise the spool files
     and message log are deleted, though the message log can optionally be
     preserved if required.

Delivery is said to be "deferred" when the message remains on the queue for  |
a subsequent delivery attempt. Such messages get processed again by queue-   |
runner processes that are periodically started, either by an Exim daemon or  |
via cron. Temporary failures may be detected during routing and directing    |
as well as during the transport stage. Exim uses a set of configured rules   |
to determine when next to process the failing address (see chapter 30).      |
These rules also specify when Exim should give up trying to deliver to the   |
address, at which point it generates a failure report.                       |

When a message cannot be delivered to some or all of its intended
recipients, a delivery failure report is generated. All the addresses that
failed in a given delivery attempt are listed in a single failure report.
If a message has many recipients, it is possible for some addresses to fail
in one delivery attempt and others to fail subsequently, giving rise to
more than one failure report for a single message.

A failure report is normally sent to the sender of the original message, as
obtained from the message's envelope. For incoming SMTP messages, this is
the address given in the MAIL FROM command. However, when an address is
expanded via a forward or alias file, an alternative address can be
specified for delivery failures of the generated addresses. For a mailing
list expansion (see chapter 39) it is common to direct failure reports to
the manager of the list.

If a failure report (either locally generated or received from a remote
host) itself suffers a delivery failure, the message is left on the queue,
but is 'frozen', awaiting the attention of an administrator.

There are many reasons why a message may not be immediately deliverable to
a particular address. Failure to connect to a remote machine (because it,
or the connection to it, is down) is one of the most common. Local
deliveries may also be delayed if NFS files are unavailable, or if a
mailbox is on a filing system where the user is over quota. Exim can be      |
configured to impose its own quotas on local mailboxes; where system quotas  |
are set they will also apply.                                                |

A machine that is connected to the Internet can normally deliver most mail
straight away (the usual figure for Cambridge is 98%). In its default
configuration, Exim starts a delivery process whenever it receives a
message, and usually this completes the entire delivery. This is a
lightweight approach, avoiding the need for any centralized queue managing
software. There are those who argue that a central message manager would be
able to batch up messages for the same host and send them in a single SMTP
call. I do not myself believe this would occur much in general, unless
messages were significantly delayed in order to create a batch.

However, if a host is unreachable for a period of time, a number of
messages may be waiting for it by the time it recovers, and sending them in
a single SMTP connection is clearly beneficial. Whenever a delivery to a
remote host is deferred, Exim makes a note in its hints database, and
whenever a successful SMTP delivery has happened, it looks to see if any
other messages are waiting for the same host. If any are found, they are
sent over the same SMTP connection, subject to a configuration limit as to
the maximum number in any one connection.

Exim can be configured not to start a delivery process automatically when a
message is received; this can be unconditional, or depend on the number of
incoming SMTP connections or the system load (where available). In these
situations, new messages wait on the queue until a queue-runner process
picks them up.



                      4. BUILDING AND INSTALLING EXIM


4.1 Unpacking

Exim is distributed as a tar file which, when upacked, creates a directory
with the name of the current release (e.g. exim-1.60) into which the
following files are placed:

  LICENCE       the GNU General Public Licence
  Makefile      top-level make file
  NOTICE        conditions for the use of Exim
  README        list of files and directories & simple build instructions

It also creates the following subdirectories:

  OS            OS-specific files
  doc           documentation files
  exim_monitor  source files for the Exim monitor
  regexp        source files for the regular expression routines
  scripts       scripts used in the build process
  src           remaining source files
  util          independent utilities

Some utilities are contained in the src directory, and are built with the
Exim binary; those in the util directory are things like the log file
analyser, which do not depend on any compile-time configuration.


4.2 Multiple machine architectures and operating systems

The building process for Exim is arranged to make it easy to build binaries
for a number of different architectures and operating systems from the same
set of source files. Compilation does not take place in the src directory.
Instead, a "build directory" is created for each architecture and operating
system. Symbolic links to the sources are installed in this directory,
which is where the actual building takes place.

In most cases, Exim can discover the machine architecture and operating
system for itself, but the defaults can be overridden if necessary.


4.3 Linux and ndbm

Exim makes use of the fcntl() system call when locking files. In particu-
lar, it is used for Exim's databases of 'hints', which are kept as DBM
files. Some releases of Linux come with DBM functions that do their own
locking, unlike other systems, which leave all file locking to the
application. This would not be a problem, except that the obsolescent
flock() locking function is used, and Linux (quite rightly) objects to a
mixture of flock() and fcntl() locking on the same file.

Others who know more about these things and I do support the view that, as
flock() is obsolescent, Exim should not be bent to accommodate it just for
this reason. The solution to the problem is to install a different DBM
library. One that is in widespread use is the db library from Berkeley;
this can be obtained from

  ftp://ftp.cs.berkeley.edu/ucb/4bsd/db.tar.gz

By default, Exim will use the ndbm-compatible interface to this library,
but it can be configured to use the native calls by setting USE_DB in an
appropriate configuration file - see section 4.8 below.


4.4 Pre-building configuration

Before building Exim, a local configuration file that specifies options
independent of any operating system has to be created with the name
Local/Makefile. A template for this file is supplied as the file
src/EDITME, and it contains full descriptions of all the option settings
therein. Default values are supplied for all of them except for those that
specify the locations of the runtime configuration file, the directory for
holding Exim binaries, and Exim's spool directory. These must all be given,
as Exim will not build without them.

If you are going to build the Exim monitor, a similar configuration process
is required. The file exim_monitor/EDITME must be edited appropriately for
your installation and saved under the name Local/eximon.conf. If you are
happy with the default settings described in exim_monitor/EDITME, then
Local/eximon.conf can be empty, but it must exist.

This is all the configuration that is needed in straightforward cases for
known operating systems. However, the building process is set up so that it
is easy to override options that are set by default or by operating-system-
specific configuration files. See section 4.6 below for details of how to
do this.


4.5 The building process

Once Local/Makefile (and Local/eximon.conf, if required) have been created,
run "make" at the top level. It determines the architecture and operating
system types, and creates a build directory if one does not exist. For
example, on a Sun system running Solaris 2, the directory build-
SunOS5-sparc is created. Symbolic links to relevant source files are
installed in the build directory.

If this is the first time "make" has been run, it calls a script which
builds a make file inside the build directory, using the configuration
files from the Local directory. The new make file is then passed to another
instance of "make" which does the real work, building a number of utility
scripts, and then compiling and linking the binaries for the Exim monitor
(if configured), a number of utilities, and finally Exim itself. The         |
command "make makefile" can be used to rebuild the make file in the build    |
directory, should this ever be necessary.                                    |


4.6 Overriding build-time options for Exim

The main make file that is created at the beginning of the building process
consists of the concatenation of a number of files which set configuration
values, followed by a fixed set of "make" instructions. If a value is set
more than once, the last setting overrides any previous ones. This provides
a convenient way of overriding defaults. The files that are concatenated
are, in order:

  OS/Makefile-Default
  OS/Makefile-<ostype>
  Local/Makefile
  Local/Makefile-<ostype>
  Local/Makefile-<archtype>
  Local/Makefile-<ostype>-<archtype>
  OS/Makefile-Base

where <ostype> is the operating system type and <archtype> is the architec-
ture type. Local/Makefile is required to exist, and the building process
fails if it is absent. The other three Local files are optional, and are
often not needed.

The values used for <ostype> and <archtype> are obtained from scripts
called scripts/os-type and scripts/arch-type respectively. If either of the
environment variables OSTYPE or ARCHTYPE is set, their values are used,
thereby providing a means of forcing particular settings. Otherwise, the
scripts try various ad hoc methods of determining these values.

OS/Makefile-Default contains comments about the variables that are set
therein. Some (but not all) are mentioned below. If there is something that
needs changing, review the contents of this file and the contents of the
make file for your operating system (OS/Makefile-<ostype>) to see what the
default values are.

If you need to change any of the values that are set in OS/Makefile-Default
or in OS/Makefile-<ostype>, or to add any new definitions, do so by putting
the new values in an appropriate Local file. For example, to specify that
the C compiler is called cc rather than gcc when compiling in the OSF1
operating system, and that it is to be to be called with the flag -std1,
create a file called Local/Makefile-OSF1 containing the lines

  CC=cc
  CFLAGS=-std1

This makes it easy to transfer your configuration settings to new versions
of Exim simply by copying the Local directory.

Exim contains support for doing NIS lookups, but not all systems support
NIS. There is a configuration option called HAVE_NIS which defaults to the
value 'yes' in OS/Makefile-Default, but is set to 'no' for the BSDI and
FreeBSD operating systems. When it is not set to 'yes', the code for making
NIS calls is not compiled, and attempts to configure Exim to use NIS cause
configuration errors.

Exim also contains support for NIS+, and there is a configuration option
called HAVE_NISPLUS to request that it be included in the binary. This
option defaults to 'no'.

The location of the X11 libraries is something that varies a lot between
operating systems, and of course there are different versions of X11 to
cope with. The following three variables are set in OS/Makefile-Default:

  X11=/usr/X11R5
  XINCLUDE=-I$(X11)/include
  XLFLAGS=-L$(X11)/lib

These are overridden in some of the operating-system configuration files.
For example, in OS/Makefile-SunOS5 there is

  X11=/usr/openwin
  XINCLUDE=-I$(X11)/include
  XLFLAGS=-L$(X11)/lib -R$(X11)/lib

If you need to override the default setting for your operating system,
place a definition of all three of these variables into your
Local/Makefile-<ostype> file.

If you need to add any extra libraries to the link steps, these can be put
in a variable called EXTRALIBS, which appears in all the link commands, but
by default is not defined. There is also DBMLIB, which appears on the link
commands for binaries that use DBM functions (see also section 4.8 below).
Finally, there is EXTRALIBS_EXIMON, which appears only on the link step for
the Exim monitor binary, and which can be used, for example, to include
additional X11 libraries.

Another variable which is not normally defined is STDERR_FILE. This defines
a file to which debugging output is written if the -df flag is set, and is
of use when running Exim under inetd.

Yet another variable which should not normally be set is ERRNO_QUOTA. Exim
needs to know which error the operating system gives when writing to a file
fails because the user is over quota. POSIX specifies an error called
EDQUOT and this is present in the latest versions of all the systems Exim
has been ported to at the time of writing. However, it is not present in
earlier versions of SunOS5, which use ENOSPC instead. The code of Exim
defaults to using EDQUOT if it is defined, and ENOSPC otherwise. You should
set ERRNO_QUOTA only if your system uses some completely different error
code.

The make file copes with rebuilding Exim correctly if any of the configur-
ation files is edited. However, if an optional configuration file is
deleted, it is necessary to touch the associated non-optional file (i.e.
Local/Makefile or Local/eximon.conf) before rebuilding.


4.7 OS-specific header files

The OS directory contains a number files with names of the form              |
os.h-<ostype>. These are system-specific C header files that should not      |
normally need to be changed. There is a list of macro settings that are      |
recognized in the file OS/os.configuring, which should be consulted if you   |
are porting Exim to a new operating system.                                  |


4.8 DBM libraries

Licensed versions of Unix normally contain a library of DBM functions
operating via the 'ndbm' interface, and this is what Exim expects by
default. Free versions of Unix seem to vary in what they contain as
standard. In particular, I understand that Linux has no default DBM
library, and different distributors have chosen to bundle different
libraries with their packaged versions. This would not matter too much
except for the locking problem described in section 4.3 above.

Different DBM libraries have different conventions for naming the files
they use. When a program opens a file called dbmfile, there are three
possibilities:

(1)  A traditional ndbm implementation such as that supplied as part of
     Solaris 2 operates on two files called dbmfile.dir and dbmfile.pag,
     and provides functions or macros called dbm_dirfno() and dbm_pagfno()
     for obtaining the file descriptors for locking purposes.

(2)  The Berkeley db package, if called via its ndbm compatibility inter-
     face, operates on a single file called dbmfile.db, and provides a
     function or macro called dbm_dirfno() for obtaining the file descrip-
     tor. Apart from the lack of dbm_pagfno() it looks to the programmer
     exactly the same as the traditional ndbm implementation.

(3)  If the Berkeley db package is used in its native mode, it operates on
     a single file called dbmfile, and makes its file descriptor available
     as a field in the structure representing an open DBM file. The
     programmer's interface is somewhat different to the traditional ndbm
     interface.

Exim and its utilities can be compiled to use any of these interfaces. By
default it assumes an interface of type (1), though some operating-system
configuration files default to assuming (2). In order to use the Berkeley
package in native mode, it is necessary to set USE_DB in an appropriate
configuration file, and it may also be necessary to set DBMLIB. By avoiding
the translation from one interface to another, some resources may be saved.


4.9 Overriding build-time options for the monitor

A similar process is used for overriding things when building the Exim
monitor, where the files that are involved are

  OS/eximon.conf-Default
  OS/eximon.conf-<ostype>
  Local/eximon.conf
  Local/eximon.conf-<ostype>
  Local/eximon.conf-<archtype>
  Local/eximon.conf-<ostype>-<archtype>

As with Exim itself, the final three files need not exist, and in this case
the OS/eximon.conf-<ostype> file is also optional. The default values in
OS/eximon.conf-Default can be overridden dynamically by setting environment
variables of the same name, preceded by EXIMON_. For example, setting
EXIMON_LOG_DEPTH in the environment overrides the value of LOG_DEPTH at run
time.


4.10 Installing commands and scripts

The script scripts/exim_install copies binaries and utility scripts into
the directory whose name is specified by the BIN_DIRECTORY setting in
Local/Makefile. Files are copied only if they are newer than any versions
already in the binary directory, and old versions are renamed by adding the
suffix .O to their names.

The command "make install" runs the exim_install script with no arguments.
It can be run independently with arguments specifying which files are to be
copied, from within a build directory. For example,

  (cd build-SunOS5-sparc; ../scripts/exim_install exim)

copies just the main binary file. The main exim binary is required to be
owned by root and setuid. The script sets this up, and should therefore
normally be run as root. If you want to see what the script will do before
running it for real, use the -n option (for which root is not needed):

  (cd build-SunOS5-sparc; ../scripts/exim_install -n)

Exim's runtime configuration file is named by the CONFIGURE_FILE setting in
Local/Makefile. If this file does not exist, then the default configuration
file src/configure.default is copied there by the installation script. If
there already is a runtime configuration file, it is left alone.


4.11 Setting up the spool directory

When it starts up, Exim tries to create its spool directory if it does not
exist. If a specific Exim uid and gid are specified, these are used for the
owner and group of the spool directory. Sub-directories are automatically
created in the spool directory as necessary.


4.12 Testing

Having installed Exim and set up its runtime configuration file, some
simple tests can be done by using the address testing option. For example,

  exim -v -bt <local username>

should verify that it recognizes a local mailbox, and

  exim -v -bt <remote address>

a remote one. Then try getting it to deliver mail, both locally and
remotely. A problem that has shown up on some sites is the inability to do   |
local deliveries into a single shared mailbox directory that does not have   |
the 'sticky bit' set on it. By default, Exim tries to create a lock file     |
before writing to a file, and if it cannot create the file, the delivery is  |
deferred. You can get round this either by setting the 'sticky bit' on the   |
directory, or, if you don't want to do that, by configuring Exim not to use  |
lock files, but just to rely on fcntl() locking instead. See the discussion  |
of locking in chapter 14.                                                    |

One thing that cannot be tested on a system that is already running a
mailer is the receipt of incoming SMTP mail on the standard SMTP port.
However, the -oX option can be used to run an Exim daemon that listens on
some other port, or inetd can be used to do this.

Testing a new version on a system that is already running Exim can most
easily be done by building a binary with a different CONFIGURE_FILE
setting. From within the runtime configuration, all other file and direc-
tory names that Exim uses can be altered, in order to keep it entirely
clear of the production version.

For debugging purposes, code for a transport called debug is supplied, but
is not by default included in the binary. It is recommended that this never
be included as a matter of course, because it makes it possible to subvert
mail deliveries. When this code is available, the debug_transport runtime
configuration option can be set, and this suppresses normal mail delivery.
Instead, information about each delivery is written to a file named by the
debug_transport option. Further details are given in chapter 16.


4.13 Switching Exim on

Building and installing Exim does not of itself put it in general use. The
name by which the system message transfer agent is called by mail user
agents is /usr/lib/sendmail, and it is necessary to make this name point at
the exim binary in order to get them to use it. This is normally done by
renaming any existing file and making /usr/lib/sendmail a symbolic link to
the exim binary. It is then necessary to stop and restart the mailer
daemon, if one is running.


4.14 Stopping Exim on Solaris 2

The standard command for stopping the mailer daemon on Solaris 2 is

  /etc/init.d/sendmail stop

If /usr/lib/sendmail has been turned into a symbolic link, this script
fails to stop Exim because it uses the command ps -e and greps the output
for the text 'sendmail'; this is not present because the actual program
name (i.e. 'exim') is given by the ps command with these options. A fix
that works on Solaris 2.5 and above is to change the script so that the ps
command reads

  ps -e -o pid,comm

which causes the name by which the daemon was started (i.e.
/usr/lib/sendmail) to be output.



                       5. EXIM'S COMMAND-LINE OPTIONS


Exim's command line takes the standard Unix form of a sequence of options,
each starting with a hyphen character, followed by a number of arguments.
The options are compatible with the main options of Sendmail, and there are
also some additional options, some of which are compatible with Smail 3.
Certain combinations of options do not make sense, and provoke an error if
used. The form of the arguments depends on which options are set.

If Exim is called under the name mailq, it behaves as if the option -bp
were present before any other options. This is for compatibility with some
systems that contain a command of that name in one of the standard
libraries, symbolically linked to /usr/lib/sendmail.

If Exim is called under the name rsmtp it behaves as if the option -bS were
present before any other options, for compatibility with smail. The -bS
option is used for reading in a number of messages in batched SMTP format.

If Exim is called under the name rmail it behaves as if the option -i were   |
present before any other options, for compatibility with smail. The -i       |
option is used for reading a message that should not be terminated by a dot  |
on a line by itself. The name rmail is used as an interface by some UUCP     |
systems.                                                                     |
                                                                             |
If Exim is called under the name runq it behaves as if the option -q were    |
present before any other options, for compatibility with smail. The -q       |
option causes a single queue-runner process to be started.                   |


5.1 Trusted and admin users

Some Exim options are available only to "trusted users" and others are
available only to "admin users".

 .   A trusted user is root or the Exim user (if defined) or any user
     listed in the trusted_users configuration option, or any user, if the
     currently set group is one of those listed in the trusted_groups
     configuration option. Trusted users are permitted to use the -f option
     to specify the senders of messages that are passed to Exim through the
     local interface, and also to specify host names, host addresses,
     protocol names, and ident values. Thus they are able to insert
     messages into Exim's queue locally that have the characteristics of
     messages received from a remote host.

 .   An admin user is root or the Exim user (if defined) or any user that
     is a member of the Exim group (if defined). The current group does not
     have to be the Exim group. Admin users are permitted to operate on
     messages in the queue, for example, to force delivery failures. It is
     also necessary to be an admin user in order to see the full
     information provided by the Exim monitor.


5.2 Command line options

Exim's command options are as follows:

-bd    Run Exim as a daemon, awaiting incoming SMTP connections. This        |
       option can be used only by an admin user. If either of the -d or -dm  |
       options are set, the daemon does not disconnect from the controlling  |
       terminal. By default, Exim listens for incoming connections on all    |
       the host's interfaces, but it can be restricted to specific inter-    |
       faces by setting the local_interfaces option in the configuration     |
       file. The standard SMTP port is used, but this can be varied by       |
       means of the -oX option. Most commonly, the -bd option is combined
       with the -q<time> option, to cause periodic queue runs to happen as
       well.

       The process id of a daemon that is both listening and starting queue
       runners is written to a file called exim-daemon.pid in Exim's spool
       directory, unless the -oX option is used, in which case the file
       name is exim-daemon.<port-number>.pid. If a daemon is run with only
       one of -bd and -q<time>, then that option is added on to the end of
       the file name, allowing sites that run two separate daemons to
       distinguish them.

       It is possible to change the directory in which these pid files are
       written by changing the setting of PID_FILE_PATH in Local/Makefile.
       Further details are given in the comments in src/EDITME.

       The SIGHUP signal can be used to cause the daemon to re-exec itself.
       This should be done whenever Exim's configuration file is changed,
       or a new version of Exim is installed. It is not necessary to do
       this when other files (e.g. alias files) are changed.

-bf <filename>
       Run Exim in filter testing mode; the file is the filter file to be
       tested, and a test message must be supplied on the standard input.
       If there are no message-dependent tests in the filter, an empty file
       can be supplied. If the test file does not begin with the special
       line

         # Exim filter

       then it is taken to be a normal .forward file, and is tested for
       validity under that interpretation. The result of this command,
       provided no errors are detected, is a list of the actions that Exim
       would try to take if presented with the message for real. More
       details of filter testing are given in the separate document
       entitled "Exim's User interface to mail filtering".

       When testing a filter file, various parameters that would normally
       be taken from the envelope recipient address of a message can be set
       by means of additional command line options. These are:

         -bfd  <domain>            default is the qualify domain
         -bfl  <local_part>        default is the logged in user
         -bfp  <local_part_prefix> default is null
         -bfs  <local_part_suffix> default is null

       The local part should always be set to the incoming address with any
       prefix or suffix stripped, because that is how it appears when a
       message is actually being delivered.

-bi    Sendmail interprets the -bi option as a request to rebuild its alias
       file. Exim does not have the concept of a single alias file, and so
       it cannot mimic this behaviour. However, calls to /usr/lib/sendmail
       -bi tend to appear in various scripts such as NIS make files, so the
       option must be recognized.

       If -bi is encountered, the command specified by the bi_command
       configuration option is run, under the uid and gid of the caller of
       Exim. If the -oA option is used, its value is passed to the command
       as an argument. The command set by bi_command may not contain         |
       arguments. The command can use the exim_dbmbuild utility, or some     |
       other means, to rebuild alias files if this is required. If the
       bi_command option is not set, then calling Exim with -bi is a no-op.

-bm    Accept an incoming, locally-generated message on the current input,
       and deliver it to the addresses given as the command arguments
       (except when -t is also given - see below). Each argument can be a
       comma-separated list of RFC 822 addresses. This is the default
       option, and is assumed if no other conflicting option is present.
       The message may or may not be delivered immediately, depending on
       the setting of the -od option and the queue_only and queue_smtp
       configuration options.

       The format of the message must be as defined in RFC 822, except
       that, for compatibility with sendmail and smail, a line of the form

         From sender Fri Jan  5 12:55 GMT 1996

       is permitted to appear at the start of the message. The Solaris 2
       version of the "mail" command inserts such a line, though there is
       no mention of it in the sendmail man page. The sender specified in
       this line is treated as if it were given as the argument to the -f
       option.

-bp    List the contents of the mail queue on the current output. Each
       message on the queue is displayed as in the following example:        |
                                                                             |
         25m  2.9K 0t5C6f-0000c8-00 <alice@wonderland.fict.book>             |
                   red.king@looking-glass.fict.book                          |
                   <other addresses>                                         |
                                                                             |
       The first line contains the amount of time the message has been on    |
       the queue (in this case 25 minutes), the size of the message (2.9K),  |
       the unique identifier for the message, and the message sender, as
       contained in the envelope. If the message is a delivery error
       message, the sender address is empty, and appears as <>. If the
       message is frozen (attempts to deliver it are suspended) then the
       text '*** frozen ***' is displayed at the end of this line.

       The recipients of the message (taken from the envelope, not the
       headers) are displayed on subsequent lines. Those addresses to which
       the message has already been delivered are marked with the letter D.  |
       If an original address gets expanded into several addresses via an    |
       alias or forward file, the original is displayed with a 'D' when      |
       deliveries for all of its child addresses are completed.              |

-bP    If this option is given with no arguments, it causes the values of
       all Exim's main configuration options to be written to the standard
       output. The values of one or more specific options can be requested
       by giving their names as arguments, for example:

         exim -bP qualify_domain local_domains

       If configure_file is given, the name of the runtime configuration
       file is output. If log_file_path or pid_file_path are given, the
       names of the directories where log files and daemon pid files are
       written are output, respectively. If these values are unset, log
       files are written in a subdirectory of the spool directory called
       log, and pid files are written directly into the spool directory.

       If one of the words director, router, or transport is given,
       followed by the name of an appropriate driver instance, the option
       settings for that driver are output. For example:

         exim -bP transport local_delivery

       The generic driver options are output first, followed by the
       driver's private options. A list of the names of drivers of a
       particular type can be obtained by using one of the words
       director_list, router_list, or transport_list, and a complete list
       of all drivers with their option settings can be obtained by using
       directors, routers, or drivers.

-brt   This option is for testing retry rules, and it must be followed by    |
       up to three arguments. It causes Exim to look for a retry rule that   |
       matches the values and to output it on the standard output. For       |
       example:                                                              |
                                                                             |
         exim -brt bach.comp.mus                                             |
         Retry rule: *.comp.mus  F,2h,15m; FG,4d,30m;                        |
                                                                             |
       See chapter 30 for a description of Exim's retry rules. The first     |
       argument, which is required, can be a complete address in the form    |
       local_part@domain, or it can be just a domain name. The second        |
       argument is an optional second domain name; if no retry rule is       |
       found for the first argument, the second is tried. This ties in with  |
       Exim's behaviour when looking for retry rules for remote hosts - if   |
       no rule is found that matches the host, one that matches the mail     |
       domain is sought. The final argument is the name of a specific        |
       delivery error, as used in setting up retry rules, for example        |
       'quota_3d'.                                                           |
                                                                             |
-brw   This option is for testing address rewriting rules, and it must be    |
       followed by a single argument, consisting of either a local part      |
       without a domain, or a complete address with a fully-qualified        |
       domain. Exim outputs how this address would be rewritten for each     |
       possible place it might appear.                                       |

-bS    This option is used for batched SMTP input, where messages have been
       received from some external source by an alternative transport
       mechanism. It causes Exim to accept one or more messages by reading
       SMTP on the standard input, but to generate no responses. All errors
       are reported by sending mail. If the caller is trusted, then the
       senders in the MAIL FROM commands are believed; otherwise the sender
       is always the caller of Exim. Unqualified senders and receivers are
       not rejected (there seems little point) but instead just get
       qualified. Receiver verification and administrative rejection is not
       done, even if configured. HELO and EHLO act as RSET; VRFY, EXPN,
       ETRN, HELP, and DEBUG act as NOOP; QUIT quits.

-bs    This option causes Exim to accept one or more messages by reading
       SMTP commands on the standard input, and producing SMTP replies on
       the standard output. Some user agents use this interface as a way of
       passing locally-generated messages to the MTA. The option can also
       be used to run Exim from inetd, as an alternative to using a
       listening daemon, in which case the standard input is the connected
       socket. Exim distinguishes between the two cases by attempting to
       read the IP address of the peer connected to the standard input. If
       it is not a socket, the call to getpeername() fails, and Exim
       assumes it is dealing with a local message.

       If the caller of Exim is trusted, then the senders of messages are
       taken from the SMTP MAIL FROM commands. Otherwise the content of
       these commands is ignored and the sender is set up as the calling
       user.

-bt    Run in address testing mode, in which each argument is taken as an
       address to be tested. The results are written to the standard
       output. If no arguments are given, Exim runs in an interactive
       manner, prompting with > for addresses to be tested. Each address is
       handled as if it were the recipient address on a message and passed
       to the appropriate directors or routers.

-bV    Write the current version number, compilation number, and compi-
       lation date of the exim binary to the standard output.

-bv    Verify the addresses that are given as the arguments to the command,
       and write the results to the standard output. Verification differs
       from address testing (the -bt option) in that directors and routers
       that have no_verify set are skipped, and if the address is accepted
       by a director or router that has fail_verify set, verification
       fails. This is the same logic that is used when verifying addresses
       on incoming messages (see the sender_verify and receiver_verify
       options).

       If the -v (or -d) option is not set, the output consists of a single
       line for each address, stating whether it was verified or not, and
       giving a reason in the latter case. Otherwise, more details are
       given of how the address has been handled, and in the case of
       aliases or forwarding, the generated addresses are also considered.

-C <filename>
       Read the runtime configuration from the given file instead of from
       the default file specified by the CONFIGURE_FILE compile-time set-
       ting. When this option is used by an unprivileged caller, Exim gives
       up its root privilege immediately, and runs with the real and
       effective uid and gid set to those of the caller, to avoid any
       security exposure. It does not do this if the caller is root or the
       exim user. The facility is useful for ensuring that configuration
       files are syntactically correct, but cannot be used for test
       deliveries, unless the caller is privileged, or unless it's an
       exotic configuration that does not require privilege. No check is
       made on the owner or group of the file specified by this option.

-d<number>
       Sets a debug level, causing debugging information to be written to
       the standard error file. Whitespace between -d and the number is
       optional. If no number is given, 1 is assumed, and the higher the
       number, the more output is produced. A value of zero turns debugging
       output off. A value of 9 gives the maximum amount of general
       information, 10 gives in addition details of the interpretation of
       filter files, and 11 or higher also turns on the debugging option
       for DNS lookups.

-df    If this option is set and STDERR_FILE was defined when Exim was
       built, debugging information is written to the file defined by that
       variable instead of to the standard error file. This option provides
       a way of obtaining debugging information when Exim is run from
       inetd.

-dm    This option causes information about memory allocation and freeing
       operations to be written to the standard error file.

-E     This option specifies that an incoming message is a locally-
       generated delivery failure message. It is used internally by Exim
       when handling delivery failures and is not intended for external
       use. Its only effect is to stop Exim generating certain messages to
       the mailmaster, as otherwise message cascades could occur in some
       situations. As part of the same option, a message id may follow the
       characters -E. If it does, the log entry for the receipt of the new
       message contains the id, following 'R=', as a cross reference.

-ex    There are a number of sendmail options starting with -oe which seem
       to be called by various programs without the leading o in the
       option. For example, the vacation program uses -eq. Exim treats all
       options of the form -ex as synonymous with the corresponding -oex
       options.

-F <string>
       Set the sender's full name for use when a locally-generated message
       is being accepted. In the absence of this option, the user's "gecos"
       entry from the password file is used. As users are generally
       permitted to alter their "gecos" entries, no security considerations
       are involved. White space between -F and the <string> is optional.

-f <address>
       Set the address of the sender of a locally-generated message. This
       option can normally be used only by root or the Exim user or by one
       of the configured trusted users. In other cases, the sender of a
       local message is always set up as the user who ran the exim command,
       and -f is ignored, with one exception. If the special setting -f <>
       is used by an untrusted user, it does not affect the sender for the
       purposes of managing the Sender: and From: headers, but it does have
       the effect of causing any SMTP transmissions to be sent out with

         MAIL FROM: <>

       and local deliveries to contain

         Return-path: <>

       when configured to contain Return-path: headers. The filtering code
       treats such a message as an error message, and won't generate
       messages as a result of reading it.

       White space between -f and the <string> is optional. The sender of a
       locally-generated message can also be set by an initial 'From' line
       in the message - see the description of -bm above.

-h <number>
       This option is accepted for compatibility with sendmail, but at
       present has no effect. (In sendmail it overrides the 'hop count'
       obtained by counting Received headers.)

-i     This option, which has the same effect as -oi, specifies that a dot
       on a line by itself should not terminate an incoming, non-SMTP
       message. I can find no documentation for this option in Solaris 2.4
       sendmail, but the mailx command in Solaris 2.4 uses it.

-M     The arguments are interpreted as a list of message ids, and Exim
       runs a delivery attempt on each message in turn. Retry hints for any
       of the addresses are overridden - this option forces Exim to try to
       deliver even if the normal retry time has not yet been reached. If
       any of the messages is frozen, it is automatically thawed before the
       delivery attempt, provided that the caller is an admin user.

-Mar <message-id> <address> <address> ...
       The first argument must be a message id, and the remaining ones must
       be email addresses. Exim adds the addresses to the list of recipi-
       ents of the message. However, if the message is active (in the
       middle of a delivery attempt), its status is not altered. This
       option can be used only by an admin user.

-Meb <message-id>
       This runs, under /bin/sh, the command defined in the shell variable
       VISUAL or, if that is not defined, EDITOR or, if that is not
       defined, the command vi, on a copy of the spool file containing the
       body of message (eb = Edit Body). If the editor exits normally, then
       the result of editing replaces the spool file. The message is locked
       during this process, so no delivery attempts can occur. Note that
       the first line of the spool file is its own name; care should be
       taken not to disturb this. The thinking behind providing this
       feature is that an administrator who has had to mess around with the
       addresses to get a message delivered might want to add some
       (grumbly) comment at the start of the message text. This option can
       be used only by an admin user.

-Mes <message-id> <address>
       There must be exactly two arguments. The first argument must be a
       message id, and the second one an email address. Exim changes the
       sender address in the message to the given address, which must be a
       fully qualified address, or '<>'. However, if the message is active
       (in the middle of a delivery attempt), its status is not altered.
       This option can be used only by an admin user.

-Mmad <message-id>
       Exim marks the all recipient addresses in the message as already
       delivered. However, if the message is active (in the middle of a
       delivery attempt), its status is not altered. This option can be
       used only by an admin user.

-Mmd <message-id> <address> <address> ...
       The first argument must be a message id, and the remaining ones must
       be email addresses. Exim marks the given addresses as already
       delivered. However, if the message is active (in the middle of a
       delivery attempt), its status is not altered. This option can be
       used only by an admin user.

-MC <transport> <hostname> <sequence number> <message id>
       This option is not intended for use by outside callers. It is used
       internally by Exim to invoke another instance of itself to deliver a
       waiting message using an existing SMTP channel, which is passed as
       the standard input and output. Details are given in chapter 43. This
       must be the final option, and the caller must be root or the Exim
       user in order to use it.

-Mc    The arguments are interpreted as a list of message ids, and Exim
       runs a delivery attempt on each message in turn, but unlike the -M
       option, it does check for retry hints, and respects any that are
       found. This option is not very useful to external callers (except
       for testing). It is provided for internal use by Exim when it needs
       to re-invoke itself in order to regain root privilege for a delivery
       (see chapter 44).

-Mf    The arguments are interpreted as a list of message ids, and each
       message is marked 'frozen'. This prevents any delivery attempts
       taking place until the message is 'thawed', either manually or as a
       result of the auto_thaw configuration option. However, if any of the
       messages is active (in the middle of a delivery attempt), its status
       is not altered. This option can be used only by an admin user.

-Mg    The arguments are interpreted as a list of message ids, and Exim
       gives up trying to deliver those messages. A delivery error message
       is sent, containing the text 'cancelled by administrator'. However,
       if any of the messages is active, its status is not altered. This
       option can be used only by an admin user.

-Mt    The arguments are interpreted as a list of message ids, and each
       message that was 'frozen' is now 'thawed', so that delivery attempts
       can resume. However, if any of the messages is active, its status is
       not altered. This option can be used only by an admin user.

-Mrm   The arguments are interpreted as a list of message ids, and each
       message is completely removed from Exim's queue, and forgotten.
       However, if any of the messages is active, its status is not
       altered. This option can be used only by an admin user or by the
       user who originally caused the message to be placed on the queue.

-m     This is apparently a synonym for -om that is accepted by sendmail,
       so Exim treats it that way too.

-N     This is a debugging option that inhibits delivery of a message at
       the transport level. It implies at least -d1. Exim goes through many
       of the motions of delivery - it just doesn't actually transport the
       message, but instead behaves as if it had successfully done so. The
       log, for example, will contain entries as if the message had been
       delivered. Only root or the exim user are allowed to use -N with
       -bd, -q, or -M. In other words, an ordinary user can use it only
       when supplying an incoming message.

-oA <file name>
       This option is used by Sendmail in conjunction with -bi to specify
       an alternative alias file name. Exim handles -bi differently; see
       the description above.

-oB <n>This is a debugging option which limits the maximum number of SMTP
       deliveries down one channel to <n>, overriding the value set in the
       smtp transport. If <n> is omitted, the limit is set to 1 (no
       batching).

-odb   This option applies to all modes in which Exim accepts incoming
       messages, including the listening daemon. It requests 'background'
       delivery of such messages, which means that the accepting process
       automatically starts another delivery process for each message
       received. Exim does not wait for such processes to complete (it can
       take some time to perform SMTP deliveries). This is the default
       action if none of the -od options are present.

-odf   This option (compatible with smail) requests 'foreground' (syn-
       chronous) delivery when Exim has accepted a locally-generated mess-
       age. For the daemon it is exactly the same as -odb. For a single
       message received on the standard input, if the protection regime
       permits it (see chapter 44), Exim converts the reception process
       into a delivery process. In other cases, it creates a new delivery
       process, and then waits for it to complete before proceeding.

-odi   This option is synonymous with -odf. It is provided for compati-
       bility with sendmail.

-odq   This option applies to all modes in which Exim accepts incoming
       messages, including the listening daemon. It specifies that the
       accepting process should not automatically start a delivery attempt
       for each message received. Messages are placed on the queue, and
       remain there until a subsequent queue-running process encounters
       them. The queue_only configuration option has the same effect.

-odqr  This option applies to all modes in which Exim accepts incoming       |
       messages, including the listening daemon. It causes Exim to process   |
       local addresses when a message is received, but not even to try       |
       routing remote addresses. Contrast with -odqs below, which does the   |
       routing, but not the delivery. The remote addresses will be picked    |
       up by the next queue runner. The queue_remote configuration option    |
       has the same effect.                                                  |

-odqs  This option is a hybrid between -odb and -odq. A delivery process is
       started for each incoming message, the addresses are all processed,
       and local deliveries are done in the normal way. However, if any
       SMTP deliveries are required, they are not done at this time. Such
       messages remain on the queue until a subsequent queue-running
       process encounters them. Because routing was done, Exim knows which
       messages are waiting for which hosts, and so a number of messages
       for the same host will get sent in a single SMTP connection. The
       queue_smtp configuration option has the same effect.

-oem   If an error is detected while a non-SMTP message is being received
       (e.g. a malformed address), the error is reported to the sender in a
       mail message. This is the default option. After a message has been
       successfully received, any subsequent delivery errors are always
       reported in this way.

-oep   If an error is detected while a non-SMTP message is being received,
       the error is reported by writing a message to the standard error
       file (stderr).

-oeq   This option is supported for compatibility with sendmail, but has
       the same effect as -oep.

-oew   This option is supported for compatibility with sendmail, but has
       the same effect as -oem.

-oi    This option, which has the same effect as -i, specifies that a dot
       on a line by itself should not terminate an incoming, non-SMTP
       message.

-oMa <host address>
       This option sets the sender host address value, and can be used only
       by a trusted caller. The value is used in log entries and can appear
       in Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-oMr <protocol name>
       This option sets the received protocol value, and can be used only
       by a trusted caller. The value is used in log entries and can appear
       in Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-oMs <host name>
       This option sets the sender host name value, and can be used only by
       a trusted caller. The value is used in log entries and can appear in
       Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-oMt <ident string>
       This option sets the sender ident value, and can be used only by a
       trusted caller. The value is used in log entries and can appear in
       Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-om    In sendmail, this option means 'me too', indicating that the sender
       of a message should receive a copy of the message if the sender
       appears in an alias expansion. Exim always does this, so the option
       does nothing.

-or <time>
       This option sets a timeout value for incoming non-SMTP messages. If
       it is not set, Exim will wait forever for the standard input. The
       value can also be set using the accept_timeout configuration vari-
       able. The format used for specifying times is described in section
       7.6.

-ov    This option has exactly the same effect as -v.                        |

-oX <number>
       This option is relevant only when the -bd option is also given. It
       specifies an alternative TCP/IP port number for the listening
       daemon, and is useful for testing. When used, the process number of
       the daemon is written to a file whose name is exim-
       daemon.<number>.pid in Exim's spool directory.

-q     If the -q option is not followed by a time value, it requests a
       single queue run operation. This option can be used only by an admin  |
       user. Exim starts up a delivery process for each (inactive) message   |
       on the queue in turn, and waits for it to finish before starting the  |
       next one. When all the queued messages have been considered, the      |
       original process terminates. In other words, a single pass is made    |
       over the waiting mail. Use -q with a time (see below) if you want     |
       this to be repeated periodically.                                     |
                                                                             |
       Exim processes the waiting messages in an unpredictable order. It     |
       isn't very random, but it is likely to be different each time, which  |
       is all that matters. If one particular message screws up a remote     |
       MTA, other messages to the same MTA have a chance of getting through  |
       if they get tried first.                                              |
                                                                             |
       However, it is possible to cause the messages to be processed in      |
       lexical id order, which is essentially the order in which they        |
       arrived, and to start this operation at a particular point by         |
       following the -q option with a starting message id. For example:      |
                                                                             |
         exim -q 0t5C6f-0000c8-00                                            |
                                                                             |
       This causes Exim to skip any messages whose ids are lexically less    |
       than the given id. A second id can also be given to stop the queue    |
       run before the end. See also the -R option.                           |

-q <time>
       This version of the -q option (which again can be run only by an
       admin user) causes Exim to run as a daemon, starting a queue-running
       process at intervals specified by the given time value (whose format
       is described in section 7.6). This form of the -q option is commonly
       combined with the -bd option, in which case a single daemon process
       handles both functions. A common way of starting up a combined
       daemon at system boot time is to use a command such as

         /opt/exim/bin/exim -bd -q30m

       Such a daemon listens for incoming SMTP calls, and also fires up a
       queue-runner process every 30 minutes. The process id of such a
       daemon is written to a file called exim-daemon.pid in Exim's spool
       directory, unless the -oX option has been used, in which case the
       file is called exim-daemon.<port-number>.pid. The location of the
       pid file can be changed by defining PID_FILE_PATH in Local/Makefile.
       If a daemon is started without -bd then the -q option used to start
       it is added to the pid file name.

-qf    This option operates like -q, and may appear with or without a        |
       following time. The difference is that a delivery attempt is forced   |
       for each message, whereas with -q only those addresses that have      |
       passed their retry times are tried.                                   |
                                                                             |
-qfl   This option operates like -ql, and may appear with or without a       |
       following time. The difference is that a delivery attempt is forced   |
       for each message, whereas with -ql only those local addresses that    |
       have passed their retry times are tried.                              |
                                                                             |
-ql    This option operates like -q, and may appear with or without a        |
       following time. The difference is that only local addresses are       |
       considered for delivery. Note that -ql cannot detect apparently       |
       remote addresses that actually turn out to be local when their        |
       domains get fully qualified.                                          |

-R <string>
       This option is similar to -q with no time value, except that, when
       scanning the messages on the queue, Exim processes only those that
       have at least one undelivered address containing the given string,
       which is checked in a case-independent way. However, once a message
       is selected, all its addresses are processed. For the first message
       containing a matching address, Exim overrides any retry information
       and forces a delivery attempt. This makes it straightforward to
       initiate delivery for all messages to a given domain after a host
       has been down for some time. When the SMTP command ETRN is permitted  |
       (see the smtp_etrn options), its effect is to run Exim with the -R    |
       option.                                                               |

-r     This is a documented (for sendmail) obsolete alternative name for
       -f.

-t     When Exim is receiving a locally-generated, non-SMTP message on the
       current input, the -t option causes the recipients of the message to
       be obtained from the To, Cc, and Bcc headers in the message instead
       of from the command arguments. If there are any arguments, they
       specify addresses to which the message is not to be delivered. That
       is, the argument addresses are removed from the recipients list
       obtained from the headers. If a Bcc header is present, it is removed
       from the message unless there is no To or Cc header, in which case a
       Bcc header with no data is created, in accordance with RFC 822.

-v     This option has exactly the same effect as -d1; it causes Exim to be
       'verbose' and produce some output describing what it is doing on the
       standard error file. In particular, if an SMTP connection is made,
       the SMTP dialogue is shown.

-x     AIX uses -x for a private purpose ('mail from a local mail program
       has National Language Support extended characters in the body of the
       mail item'). It sets -x when calling the MTA from its mail command.
       Exim ignores this option.



                        6. 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 "single-key" style requires the specification of a file in which
     to look, and a single key to search for.

 .   The "query" style accepts a generalized query, which may contain one
     or more keys.

The following single-key lookup types are implemented:

 .   lsearch: Data are looked up by searching the given file linearly for a
     line beginning with the single key, terminated by a colon if there is
     following data. This is the traditional format of textual alias files.

 .   dbm: Calls to DBM library functions are used to extract data from the
     given DBM file by key.

 .   nis: The given file is the name of a NIS map, and data are looked up
     by calling NIS with the given key. There is a variant called nis0
     which includes a terminating binary zero character in the key. This is
     needed for Sun-style alias files.

The only query-style lookup that is currently available is nisplus, which
does a NIS+ lookup using a query that may contain any number of keys, and
which can specify the name of the field to be returned.

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 9.

(2)  Lists of domains and other items can contain lookup requests as a way
     of avoiding excessively long linear lists. See section 7.11 for a full
     description.

(3)  Some drivers can be configured 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 the cases where drivers specify file lookups, there are always two
alternative configuration options: file is specified for single-key
lookups, using an implicit key, or query is specified for query-style
lookups. In the latter case the query is an expanded string, and the
relevant key is always available as one of the normal expansion variables.


6.1 Partial matching in file 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 the keys 2001.dates.fict.book and 1984.dates.fict.book
when partial matching is requested. It also matches the key
dates.fict.book, if that key does not itself appear in the file.

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

In fact, 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.


6.2 More about NIS+

NIS+ queries consists 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 a space.
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.



                       7. THE EXIM CONFIGURATION FILE


Exim uses a single runtime configuration file which it reads when it is
starting up. The name of the file is compiled into the binary for security
reasons, and is specified by the CONFIGURE_FILE compilation option.

Some sites may wish to use the same Exim binary on different machines that
share a filing system, but to use different configuration files on each
machine. If CONFIGURE_FILE_USE_NODE is defined in Local/Makefile, then Exim
first looks for a file whose name is the configuration file name followed
by a dot and the machine's node name, as obtained from the uname()
function. If this file does not exist, the standard name is tried.

In some esoteric situations different versions of Exim may be run under
different effective uids and the CONFIGURE_FILE_USE_EUID is defined to help
with this. See the comments in src/EDITME for details.

The runtime configuration file must be owned by root or by the user that is
specified at compile time by the EXIM_USER option, and it must not be
world-writeable or group-writeable, unless its group is the one specified
at compile time by the EXIM_GROUP option.

A one-off alternative configuration file can be specified by the -C command
line option, but if this is done, Exim immediately gives up its root
privilege, unless called by root or the Exim user, so this option is useful  |
mainly for checking the syntax of configuration files before installing
them. No owner or group checks are done on a configuration file specified
by -C.

A default configuration file, which will work correctly in simple situ-
ations, is provided in the file src/configure.default. The installation
process copies this into CONFIGURE_FILE if there is no previously-existing
configuration file.

If a syntax error is detected while reading the configuration file, Exim
writes a message on the standard error, and exists with a non-zero return
code. The message is also written to the panic log.


7.1 Configuration file format

Exim's configuration file is in six parts, which must appear in the correct
order in the file, separated by a line containing just the word 'end'.
These parts contain:

 .   Main configuration settings.

 .   Configuration settings for the transport drivers.

 .   Configuration settings for the director drivers.

 .   Configuration settings for the router drivers.

 .   Retry rules, for use when a message cannot be immediately delivered.

 .   Header re-writing rules.

A convenient way to create a configuration file is to start from the
default, which is supplied in src/configure.default, and add, delete, or
change settings as required.

Blank lines in the file are ignored, and lines starting with a # character
are treated as comments and are also ignored. The retry and rewriting rules
have their own syntax which is described in chapters 30 and 31 below. The
remaining parts have some syntactic items in common, and these are
described in sections 7.3 onwards. Before that, the simple macro facility
is described.


7.2 Macros in the configuration file

If a line in the main part of the configuration (that is, before the first   |
'end' line) begins with an upper case letter, it is taken as a macro         |
definition, of the form                                                      |
                                                                             |
  <name> = <rest of line>                                                    |
                                                                             |
The name must consist of letters, digits, and underscores, and need not all  |
be in upper case, though that is recommended. The rest of the line is the    |
replacement text, and has leading and trailing white space removed. If the   |
line ends with the character \ after trailing space is removed, then the     |
next line is concatenated with it, with the \ character and any leading      |
space on the following line omitted. This continues for as long as lines     |
end in \. Thus a replacement text can never end with a \ character, but      |
this doesn't seem to me to be a serious limitation.                          |
                                                                             |
Once a macro is defined, all subsequent lines in the file are scanned for    |
the macro name; if there are several macros, the line is scanned for each    |
in turn, in the order in which they are defined. The replacement text is     |
not re-scanned for the current macro, though it will be for subsequently     |
defined macros.                                                              |
                                                                             |
For example, suppose you have lots of local domains, but they fall into      |
three different types. You could set up                                      |
                                                                             |
  LOCAL1 = domain1:\                                                         |
           domain2                                                           |
  LOCAL2 = domain3:domain4                                                   |
  LOCAL3 = dbm;/list/of/other/domains                                        |
                                                                             |
  local_domains = "LOCAL1:LOCAL2:LOCAL3"                                     |
                                                                             |
and then use the domains option on appropriate directors to handle each set  |
of domains differently. This avoids having to list each domain in more than  |
one place.                                                                   |


7.3 Common option syntax

For the main set of options and for driver options, each option setting is
on a line by itself, and starts with a name consisting of lower case
letters and underscores. Many options require a data value, and in these
cases the name must be followed by an equals sign (with optional white
space) and then the value. For example:

  exim_user = exim

Options whose type is given as boolean are on/off switches that are not
always followed by a data value. If the option name is specified on its
own, the switch is turned on; if it is preceded by 'no_' or 'not_' then the
switch is turned off. However, boolean options may alternatively be
followed by an equals sign and one of the words 'true', 'false', 'yes', or
'no'. For example:

  sender_verify
  no_smtp_verify
  queue_only = true

The types of data that may be required by non-boolean options are described
in the following sections.


7.4 Integer

If a numerical data item starts with the characters '0x', the remainder of
it is interpreted as a hexadecimal number. Otherwise, it is treated as
octal if it starts with the digit 0, and decimal if not. No negative values
are involved. If an integer value is followed by the letter K, it is
multiplied by 1024; if it is followed by the letter M, it is multiplied by
1024x1024.

When the values of option settings are output, some are always shown in
octal, and for others, values which are an exact multiple of 1024 or
1024x1024 are printed using the letters K and M. The printing style is
independent of the actual input format that was used.


7.5 Fixed point number

A fixed point number consists of a decimal integer, optionally followed by
a decimal point and up to three further digits.


7.6 Time interval

A time interval is specified as a sequence of numbers, each followed by one
of the following letters, and with no intervening white space:

  s   seconds
  m   minutes
  h   hours
  d   days
  w   weeks

For example, '3h50m' specifies 3 hours and 50 minutes. The values of time
options are output in the same format.


7.7 String

If a string data item does not start with a double-quote character, then it
is taken as consisting of the remainder of the line, starting at the first
non-whitespace character, with trailing whitespace characters removed, and
with no interpretation of the characters therein.

If a string does start with a double-quote, then it continues to a closing
double-quote, with the backslash character (\) being interpreted as an
escape character. If a backslash occurs at the end of an input line, the
string is continued on the following line, with any leading whitespace
being removed. Because Exim removes comment lines (those beginning with #)   |
at an early stage, they can appear in the middle of a multi-line string.     |

The following two settings are equivalent:

  local_domains = "wonderland.fict.book:\
                   lookingglass.fict.book"
  local_domains = wonderland.fict.book:lookingglass.fict.book

If a backslash occurs in the middle of a line, the following escapes are
recognized:

  \\               single backslash
  \n               newline
  \r               carriage return
  \t               tab
  \<octal digits>  up to 3 octal digits specify one character
  \x<hex digits>   up to 2 hexadecimal digits specify one character

If a backslash is followed by some other character, including a double-
quote character, then that character replaces the pair.


7.8 Expanded strings

Some strings in the configuration file subjected to "string expansion", by
which means various parts of the string may be changed according to the
circumstances. The input syntax for such strings is as just described; the
expansion process is described in chapter 9.


7.9 User and group names

User and group names are specified as strings, using the syntax described
above, but the strings are interpreted specially. In the main section of
the configuration file, a user or group name must either consist entirely
of digits, or be a name that can be looked up using the getpwnam() or
getgrnam() function, as appropriate.

When a user or group is specified as an option for a transport or director
driver, it may alternatively be a string that gets expanded each time the
user or group value is required. The presence of a $ character in the
string causes this action to happen. Each time the string is expanded, the
result must either be a digit string, or a name that can be looked up using
getpwnam() or getgrnam(), as appropriate.


7.10 String lists

Some configuration settings accept a colon-separated list of strings. In
these cases the entire list is treated as a single string as far as the
input syntax is concerned. The local_domains setting in section 7.7 above
is an example. There is a limit of 1023 on the number of items in a string
list. If a colon is actually needed in an item in a string list, it can be   |
entered as two colons. In other words, there can never be an empty item in   |
a string list.                                                               |


7.11 Domain lists

Domain lists are colon-separated string lists containing a number of domain
patterns that are to be matched against a domain given in a mail address.
Several different kinds of matching are provided:

 .   If a pattern consists of a single @ character, it matches the local     |
     host name, as set in the primary_hostname option. This makes it         |
     possible to use the same configuration file on several different hosts  |
     that differ only in their names.                                        |

 .   If the pattern starts with an asterisk, then the remaining characters
     of the pattern are compared with the terminating characters of the
     domain.

 .   If the pattern starts with a circumflex character, then it is treated
     as a regular expression, and matched against the domain using a
     regular expression matching function. The circumflex is treated as
     part of the regular expression. The syntax of regular expressions is
     described in chapter 8, but note that if a backslash is required in
     the regular expression, it must be given as two backslashes in the
     string if the string is in quotes.

 .   If the pattern starts with one of the strings 'dbm;' or 'lsearch;'
     then the remainder of the pattern must be an absolute file name. In
     the first case, a DBM lookup is done on the file using the domain name
     as the key; in the second case a linear search is performed for a line
     starting with the domain name, which must be followed by a colon if
     there is other data on the line (i.e. it is in the format of an alias
     file). The data from a DBM lookup or the rest of a linear search line
     is not used.

 .   If the pattern starts with one of the strings 'nis;' or 'nis0;' then
     the remainder of the pattern must be the name of a NIS map, and a NIS
     lookup is done using the domain name as the key. The difference
     between the two types of lookup is that in the case of 'nis0;' a
     terminating binary zero is included in the key. The data from the
     lookup is not used.

 .   Any of the four lookup types just mentioned may be preceded by
     'partial<n>-', where the <n> is optional, for example,

       partial-dbm;/partial/domains

     This causes partial matching logic to be invoked; a description of how
     this works is given in the next section.

 .   If the pattern starts with the string 'nisplus;' then the remainder of
     the pattern must be a NIS+ query as described in section 6.2 above.
     The query is expanded before use, and the expansion substitution $key
     can be used to insert the domain that is being tested into the query.
     The data returned by a successful NIS+ query is not used.

 .   If none of the above cases apply, a straight textual comparison is
     made between the pattern and the domain.

Here is an example which uses all six kinds of pattern:

  local_domains = "lib.unseen.edu:\
                   *.foundation.fict.book:\
                   ^[1-2][0-9][0-9][0-9]\\.fict\\.book$:\
                   dbm;/opt/data/penguin/book:\
                   nis;domains.byname:\
                   nisplus;[name=$key,status=local],domains.org_dir"

There are obvious processing trade-offs among the various matching modes.
Using an asterisk is faster than a regular expression, and listing a few
names explicitly probably is too. The use of a file or database lookup is
expensive, but may be the only option if hundreds of names are required.
The patterns are tested in order, so it makes sense to put the most
commonly matched patterns earlier in the string.


7.12 Partial matching in domain lists

When one of the single-key lookup types is preceded by 'partial-' then
matching proceeds as follows: First the subject text is looked up verbatim;
if that fails, '*.' is added to the front of the subject and another lookup
is tried. If that fails, domains are chopped off and replaced by '*.' until
there are fewer than two left. For example, if the file contains

  *.neverwhere.tvs

then domains such as market.neverwhere.tvs and downst.neverwhere.tvs match
it, as does neverwhere.tvs itself, provided there isn't a separate entry
for it in the file. A different minimum number of components can be imposed
by supplying a number after 'partial', for example, 'partial3-dbm'.


7.13 Address lists

An address list is a string list in which each item is a pattern to be
matched against a mail address. There are several alternative formats:

 .   If a pattern starts with ^ then a regular expression match is done
     against the complete address.

 .   Otherwise, if there is an @ in the pattern, then the local part of the
     subject address is compared with the local part of the pattern, which
     may start with an asterisk. If the local parts match, then the domains
     are compared in exactly the same way as entries in a domain list, so
     one can use file lookups. For example:

       sender_reject = "*@*.spamming.site:\
                        bozo@partial-lsearch;/list/of/dodgy/sites"

 .   If there is no @ in the pattern, it is matched against the domain part
     of the subject address, the local part being ignored. This match is
     also done exactly as for an entry in a domain list. If there is no
     match, and the pattern consists of a single file lookup, then the
     entire subject address is looked up in the file, with partial matching
     disabled. This means that an item such as

       sender_reject_recipients = partial-dbm;/black/list

     can reference a single file containing a mixture of complete domains,
     partial domains, and individual mail addresses.


7.14 Host lists

Host lists are in the same form as domain lists, but in addition,
individual entries may be specified as literal IP addresses, for example

  sender_reject_hosts = 111.111.111.111

Such entries may be freely mixed with other types.


7.15 Net lists

Net lists are colon-separated string lists in which each item identifies an
IP network. Each item consists of an IP (sub-)network number and a net
mask, both specified in 'dotted quad' notation, and separated by a slash.
For example:

  receiver_unqualified_nets = 131.111.14.0/255.255.255.0

An IP address is compared with the network number using the given mask.



                        8. REGULAR EXPRESSION SYNTAX


Exim uses Henry Spencer's freely distributable regular expression library.
The syntax of the regular expressions that it supports is as follows:

A regular expression is zero or more branches, separated by '|'. It matches
anything that matches one of the branches. A branch is zero or more pieces,
concatenated. It matches a match for the first, followed by a match for the
second, etc. A piece is an atom possibly followed by '*', '+', or '?'.

An atom followed by '*' matches a sequence of 0 or more matches of the
atom. An atom followed by '+' matches a sequence of 1 or more matches of
the atom. An atom followed by '?' matches a match of the atom, or the null
string.

An atom is a regular expression in parentheses (matching a match for the
regular expression), a range (see below), '.' (matching any single charac-
ter), '^' (matching the null string at the beginning of the input string),
'$' (matching the null string at the end of the input string), em a '\'
followed by a single character other than '>' or '<' (matching that
character), the sequence '\>' (matching the null string preceding a letter,
digit, or underscore that is preceded by the start of the string or a non-
letter, non-digit, non-underscore), the sequence '\<' (matching the null
string preceding a non-letter, non-digit, or non-underscore), or a single
character with no other significance (matching that character).

A range is a sequence of characters enclosed in '[]'. It normally matches
any single character from the sequence. If the sequence begins with '^', it
matches any single character not from the rest of the sequence. If two
characters in the sequence are separated by '-', this is shorthand for the
full list of ASCII characters between them (e.g. '[0-9]' matches any
decimal digit). To include a literal ']' in the sequence, make it the first
character (following a possible '^'). To include a literal '-', make it the
first or last character.



                            9. STRING EXPANSIONS


A number of configuration strings are expanded before use. Some of them are
expanded every time they are used; others are expanded only once.

Expanded strings are copied verbatim except when a dollar character is
encountered. This specifies the start of a portion of the string which is
interpreted and replaced as described below.

An uninterpreted dollar can be included in the string by putting a
backslash in front of it - if the string appears in quotes, two backslashes
are required because the quotes themselves cause some interpretation when
the string is read in. A backslash can in fact be used to prevent any
character being treated specially in an expansion.


9.1 Expansion items

The following items are recognized in expanded strings. White space may be
used between sub-items that are keywords or sub-strings enclosed in braces
inside an outer set of braces, to improve readability.

$<variable name> or ${<variable name>}

   Substitute the contents of the named variable; the latter form can be
   used to separate the name from subsequent alphameric characters. The
   names of the variables are given in section 9.4 below. If the name of a
   non-existent variable is given, the expansion fails.

$header_<header name>: or $h_<header name>:

   Substitute the contents of the named message header, for example

     $header_reply-to:

   This particular expansion is intended mainly for use in users' filter
   files. The header names follow the syntax of RFC 822, which states that
   they may contain any printing characters except space and colon.
   Consequently, curly brackets do not terminate header names. Upper and
   lower case letters are synonymous in header names. If the following
   character is white space, the terminating colon may be omitted. If the
   message does not contain the given header, the expansion item is
   replaced by an empty string. If there is more than one header with the
   same name, they are all concatenated to form the substitution string,
   with a newline character between each of them.

${<op>:<string>}

   The string is first itself expanded, and then the operation specified by
   <op> is applied to it. A list of operators is given in section 9.2
   below. The string starts with the first character after the colon, which
   may be leading white space.

${if <condition> {<string1>}{<string2>}}

   If <condition> is true, <string1> is expanded and replaces the whole
   item; otherwise <string2> is used. The second string need not be
   present; if it is not and the condition is not true, the item is
   replaced with nothing. Alternatively, the word 'fail' may be present
   instead of the second string (without any curly brackets). In this case,
   the expansion fails if the condition is not true. The available
   conditions are described in section 9.3 below.

${lookup{<key>} <search type> {<file>} {<string1>} {<string2>}}

${lookup{<search type> {<query>} {<string1>} {<string2>}}

   These items specify data lookups in files and databases, as discussed in
   chapter 6. The first form is used for single-key lookups, where
   'partial-' is permitted to precede the search type in order to do
   partial matching, while the second is used for query-style lookups.

   If the lookup succeeds, then <string1> is expanded and replaces the
   entire item. During its expansion, a variable called value is available,
   containing the data returned by the file lookup. If the lookup fails,
   <string2> is expanded and replaces the entire item. It may be omitted,
   in which case the replacement is null.

   Instead of {<string2>} the word 'fail' can appear, and in this case, if
   the lookup fails, the entire string expansion fails in a way that can be
   detected by the caller. The consequences of this depend on the
   circumstances.

   The <key>, <file>, and <query> strings are expanded before use. For
   single-key lookups the search type must be one of

     dbm       do a DBM lookup
     lsearch   do a linear search
     nis       search a NIS map
     nis0      ditto, with trailing zero on the key

   For a linear search, a line beginning with the key followed by a colon
   is searched for, and the data is the remainder of the line and any
   continuations, in the format of an alias file. For a NIS search, <file>
   is the name of the NIS map. The 'nis0' form is required for Sun alias
   files. This example looks up the postmaster alias in the conventional
   alias file:

     ${lookup {postmaster} lsearch {/etc/aliases} {$value}}

   For query-style lookups the only available search type is 'nisplus', and
   the query must be a NIS+ indexed name, optionally followed by a colon
   and the name of a field to return. For example,

     "${lookup nisplus {[name=$local_part],passwd.org_dir:gcos} \
       {$value}fail}"

   looks up the full name of the user corresponding to the local part of an
   address, failing the expansion if it is not found.

${lookup{<key:subkey>} <search type> {<file>} {<string1>} {<string2>}}

   This searches for <key> in the file as described above for single-key
   lookups; if it succeeds, it extracts from the data a subfield which is
   identified by the <subkey>. The data related to the main key must be of
   the form:

     <subkey1> = <value1>  <subkey2> = <value2> ...

   where the equals signs are optional. If any of the values contain white
   space, they must be enclosed in double quotes, and any values that are
   enclosed in double quotes are subject to escape processing as described
   in section 7.7. For example, if a line in a linearly searched file
   contains

     alice: uid=1984 gid=2001

   then expanding the string

     ${lookup{alice:uid}lsearch{<file name>}{$value}}

   yields the string '1984'. If the subkey is not found in <string1>, then
   <string2> is expanded and replaces the entire item.

${extract{<key>}{<string>}}

   The key and the string are first expanded. Then the subfield identified
   by the key is extracted from the string, exactly as just described for
   lookup items with subkeys. If the key is not found in the string, the
   item is replaced by nothing.


9.2 Expansion operators

A string can be forced into lower case by the lc operator, for example

  ${lc:$local_part}

The length operator can be used to extract the initial portion of a string.
It is followed by an underscore and the number of characters required. For
example

  ${length_50:$message_body}

The result of this operator is either the first n characters or the whole
string, whichever is the shorter. The abbreviation l can be used instead of
length.

The substr operator can be used to extract more general substrings. It is    |
followed by an underscore and the starting offset, then a second underscore  |
and the length required. For example                                         |
                                                                             |
  ${substr_3_2:$local_part}                                                  |
                                                                             |
If the starting offset is greater than the string length the result is the   |
null string; if the length plus starting offset is greater than the string   |
length, the result is the right-hand part of the string, starting from the   |
given offset. The first character in the string has offset 0. The            |
abbreviation s can be used instead of substr.                                |

The expand operator causes a string to be expanded for a second time. For
example,

  ${expand:${lookup{$domain}dbm{/some/file}{$value}}}

first looks up a string in a file while expanding the operand for expand,
and then re-expands what it has found.


9.3 Expansion conditions

The following conditions are available for testing while expanding strings:

  !<condition>

This negates the result of the condition.

  def:<variable>

This condition is true if the named expansion variable does not contain the
empty string. If the variable does not exist, the expansion fails.

  exists{<file name>}

The substring is first expanded and then interpreted as an absolute path.
The condition is true if the named file (or directory) exists. The
existence test is done by calling the stat() function.

  eq {string1}{string2}

The two substrings are first expanded. The condition is true if the two
resulting strings are identical, including the case of letters.

  match {string1}{string2}                                                   |
                                                                             |
The two substrings are first expanded. The second is then treated as a       |
regular expression and applied to the first. The condition is true if the    |
match succeeds. At the start of an "if" expansion the values of the numeric  |
expansion variables $1 etc. are remembered. Obeying a "match" condition      |
that succeeds causes them to be reset to the substrings of that condition    |
and they will have these values during the expansion of the success string.  |
At the end of the "if" expansion, the previous values are restored. After    |
testing a combination of conditions using "or", the subsequent values of     |
the numeric variables are those of the condition that succeeded.             |
                                                                             |
  or {{cond1}{cond2}...}                                                     |
                                                                             |
The sub-conditions are evaluated from left to right. The condition is true   |
if any one of the sub-conditions is true. When a true sub-condition is       |
found, the following ones are parsed but not evaluated. Thus if there are    |
several 'match' sub-conditions the values of the numeric variables are       |
taken from the first one that succeeds.                                      |
                                                                             |
  and {{cond1}{cond2}...}                                                    |
                                                                             |
The sub-conditions are evaluated from left to right. The condition is true   |
if all of the sub-conditions are true. When a false sub-condition is found,  |
the following ones are parsed but not evaluated.                             |


9.4 Expansion variables

The variables that are available for use in expansion strings are:

caller_gid: The group id under which the process that called Exim was
running.

caller_uid: The user id under which the process that called Exim was
running.

compile_date: The date on which the Exim binary was compiled.

compile_number: The building process for Exim keeps a count of the number
of times it has been compiled. This serves to distinguish different
compilations of the same version of the program.

domain: When an address is being directed, routed, or delivered on its own,
this variable contains the domain. In particular, it is set during
filtering.

For remote addresses, the domain can change as routing proceeds, as a        |
result of router actions. When a remote or local delivery is taking place,   |
if all the addresses that are being handled simultaneously contain the same  |
domain, it is placed in the domain variable. Otherwise this variable is      |
empty. Transports should be restricted to handling only one domain at once   |
if its value is required at transport time - this is the default for local   |
transports.                                                                  |
                                                                             |
When a rewrite item is being processed (see chapter 31) this variable        |
contains the domain portion of the address that is being re-written; it can  |
be used in the expansion of the replacement address, for example, to         |
rewrite domains by file lookup.                                              |

home: A home directory may be set during a local delivery, either by the
transport or by the director that handled the address. When this is the
case, the home variable contains its value and may be used in any expanded
options for the transport. The forwardfile director also makes use of the
home expansion variable. Full details are given in chapter 21. When
interpreting a user's filter file, it is normally configured so that home
contains the user's home directory. When running a filter test via the -bf
option, home is set to the value of the environment variable HOME.

host: When a local transport is run as a result of routing a remote
address, the expansion variable host is available to access the host that
the router defined. A DNS lookup may set up many hosts; in this case host
refers to the first one. It is expected that this usage will be mainly via
the domainlist router, setting up a single host for batched SMTP output,
for example.

local_part: When an address is being directed, routed, or delivered on its
own, this variable contains the local part. If a local part prefix or
suffix has been recognized, it is not included in the value. When a number   |
of addresses are being delivered in a batch by a local or remote transport,  |
local_part is not set.                                                       |
                                                                             |
When a rewrite item is being processed (see chapter 31) local_part contains  |
the local-part portion of the address that is being re-written; it can be    |
used in the expansion of the replacement address, for example, to rewrite    |
local parts by file lookup.                                                  |

local_part_prefix: When an address is being directed or delivered locally,
and a specific prefix for the local part was recognized, it is available in
this variable. Otherwise it is empty.

local_part_suffix: When an address is being directed or delivered locally,
and a specific suffix for the local part was recognized, it is available in
this variable. Otherwise it is empty.

key: When a domain list is being searched, this variable contains the value
of the key, so that it can be inserted into strings for query-style
lookups. See chapter 6 for details. In other circumstances this variable is
empty.

message_body: This variable contains the initial portion of a message's
body while it is being delivered, and is intended mainly for use in filter
files. The maximum number of characters of the body that are used is set by
the message_body_visible configuration option; the default is 500.

message_id: When a message is being received or delivered, this variable
contains the unique message id which is used by Exim to identify the
message.

message_precedence: When a message is being delivered, the value of any      |
"Precedence" header is made available in this variable. If there is no such  |
header, the value is the null string.                                        |

message_size: When a message is being received or delivered, this variable
contains its size in bytes.

original_domain: When a top-level address is being processed, this contains
the same value as domain. However, if an address generated by an alias,
forward, or filter file is being processed, this variable contains the
domain of the original address.

original_local_part: When a top-level address is being processed, this
contains the same value as local_part. However, if an address generated by
an alias, forward, or filter file is being processed, this variable
contains the local part of the original address.

pipe_addresses: This is not an expansion variable, but is mentioned here     |
because the string $pipe_addresses is handled specially in the command       |
specification for the pipe transport. It cannot be used in general           |
expansion strings, and provokes an 'unknown variable' error if encountered.  |

primary_hostname: The value set in the configuration file, or read by the
uname() function.

received_protocol: When a message is being processed, this variable con-
tains the protocol by which it was received.

recipients_count: When a message is being processed, this variable contains
the number of envelope recipients that came with the message. Duplicates
are not excluded from the count.

reply_address: When a message is being processed, this variable contains
the contents of the Reply-to: header if one exists, or otherwise the
contents of the From: header.

return_path: When a message is being delivered, this variable contains the
return path - the sender field that is sent as part of the envelope. In
many cases, this has the same value as sender_address, but if, for example,
an incoming message to a mailing list has been expanded by a director which
specifies a specific address for delivery error messages, then return_path
contains the new errors address, while sender_address contains the original
sender address that was received with the message.

route_option: A router may set up an arbitrary string to be passed to a      |
transport via this variable. Currently, only the queryprogram router has     |
the ability to do so.                                                        |

sender_address: When a message is being processed, this variable contains
the sender's address that was received in the message's envelope.

sender_address_domain: The domain portion of sender_address.

sender_address_local_part: The local part portion of sender_address.

sender_fullhost: When a message has been received from a remote host, this
variable contains the host name and IP address, as a concatenated string,
with the IP address in square brackets. In the case of incoming SMTP
messages, the host name is the data receceived in the HELO or EHLO command.

sender_host_address: When a message has been received from a remote host,
this variable contains the host's IP address.

sender_host_name: When a message has been received from a remote host, this
variable contains the host's name (from the HELO or EHLO command, in the
case of SMTP).

sender_ident: When a message has been received from a remote host, this
variable contains the identification received in response to an RFC 1413
request. When a message has been received locally, this variable contains
the login name of the user that called Exim.

spool_directory: The name of Exim's spool directory.

tod_bsdinbox: The time of day and date, in the format required for BSD-
style mailbox files, for example: Thu Oct 17 17:14:09 1995.

tod_full: A full version of the time and date, for example: Wed, 18 Oct
1995 09:51:40 +0100. The timezone is always given as a numerical offset
from GMT.

tod_log: The time and date in the format used for writing Exim's log files,
which is: 1995-10-12 15:32:29.

value: This variable contains the result of an expansion lookup operation,
as described above. If used in other circumstances, its contents are null.

version_number: The version number of Exim.


9.5 Expansion string examples

Typical settings for defining a local mailbox to the appendfile transport
are

  file = /var/spool/mail/${local_part}
  file = ${home}/inbox

The default setting for the Received header is as follows:

  received_header_text = "Received: \
       ${if def:sender_fullhost {from ${sender_fullhost} \
       ${if def:sender_ident {(${sender_ident})}}\n\t}\
       {${if def:sender_ident {from ${sender_ident} }}}}\
       by ${primary_hostname} \
       ${if def:received_protocol {with ${received_protocol}}} \
       (Exim ${version_number} #${compile_number})\n\t\
       id ${message_id}"



                           10. MAIN CONFIGURATION


The first part of the configuration file contains the main configuration
settings. Each setting occupies one line of the file, except that string
values can be continued onto multiple lines as described in section 7.7.     |
All macro definitions must be in this part of the file - they differ from    |
options settings by starting with an upper case letter. The available        |
options are as follows:

accept_8bitmime                                                              |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    This option causes Exim to send 8BITMIME in its response to an SMTP      |
    EHLO command, and to accept the BODY= parameter on MAIL FROM commands.   |
    However, Exim is not a protocol converter, and it takes no steps to do   |
    anything special with messages received by this route. Consequently,     |
    this option is turned off by default.                                    |

accept_timeout

    Type:    time
    Default: 0

    This sets the timeout for accepting a non-SMTP message, that is, the
    maximum time that Exim waits when reading a message on the standard
    input. If the value is zero, it will wait for ever. This setting is
    overridden by the -or command option.

address_file_transport

    Type:    string
    Default: "address_file"

    This sets the name of the transport driver that is to be used when the
    expansion of the local part of an address by an aliasing or forwarding
    director results in a file name.

address_pipe_transport

    Type:    string
    Default: "address_pipe"

    This sets the name of the transport driver that is to be used when the
    expansion of the local part of an address by an aliasing or forwarding
    director results in a pipe command.

address_reply_transport

    Type:    string
    Default: "address_reply"

    This sets the name of the transport driver that is to be used when the
    expansion of the local part of an address by a forwarding director
    results in the generation of an automatic reply.

always_bcc                                                                   |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    Exim adds a To header to messages whose recipients are given on the      |
    command line when there is no To, Cc, or Bcc in the message. In other    |
    cases of missing recipient headers, it just adds an empty Bcc header to  |
    make the message conform with RFC 822. Setting always_bcc causes it to   |
    add an empty Bcc in all cases. This can be helpful in conjunction with   |
    mailing list software that passes recipient addresses on the command     |
    line.                                                                    |

auto_thaw

    Type:    time
    Default: 0s

    If this option is set to a non-zero time, a new delivery is attempted
    on frozen messages if this much time has passed since the message was
    frozen.

bi_command

    Type:    string
    Default: unset

    This option supplies the name of a command that is run when Exim is      |
    called with the -bi option (see chapter 5). The string value is just     |
    the command name, it is not a complete command line. If an argument is   |
    required, it must come from the -oA command line option.                 |

collapse_source_routes

    Type:    boolean
    Default: false

    If this option is set, then source-routed mail addresses are stripped
    down to their final components.

debug_transport

    Type:    string
    Default: unset

    This option can be set only when Exim has been compiled to include the
    debug transport. It causes all deliveries to be subverted by substitut-
    ing a call to the debug transport. This appends information about the
    address, and a copy of the message, to the file whose name is specified
    by this option. No locking is used. When local deliveries are being
    subverted in this way, the file must be set up as writeable by the user
    under whose uid the delivery process will run. It is recommended that
    Exim not be compiled with the debug option as a matter of course.

delay_warning

    Type:    time
    Default: 24h

    When a message is delayed, Exim sends a warning message to the sender
    at intervals specified by this option. If it is set to a zero amount of
    time, no warnings are sent.

deliver_load_max

    Type:    fixed-point
    Default: unset

    When this option is set, no message deliveries are ever done if the
    system load average is greater than its value, except for deliveries
    forced with the -M option. If the load gets this high during a queue
    run, the run is abandoned. There are some operating systems for which
    Exim cannot determine the load average (see chapter 1); for these this
    option has no effect.

delivery_date_remove

    Type:    boolean
    Default: true

    Exim's local transports (appendfile and pipe) have an option for adding
    a Delivery-date header to a message when it is delivered - in exactly
    the same way as Return-path is handled. Delivery-date records the
    actual time of delivery. Such headers should not be present in outgoing
    messages, and this option causes them to be removed, to avoid any
    problems that might occur when a delivered message is subsequently sent
    on to some other recipient.

dns_retrans                                                                  |
                                                                             |
    Type:    time                                                            |
    Default: 0                                                               |
                                                                             |
    The options dns_retrans and dns_retry can be used to set the             |
    retransmission and retry parameters for DNS lookups. Values of zero      |
    (the defaults) leave the system default settings unchanged. The first    |
    value is the time between retries, and the second is the number of       |
    retries. It isn't totally clear exactly how these settings affect the    |
    total time a DNS lookup may take. I haven't found any documentation      |
    about timeouts on DNS lookups; these parameter values are available in   |
    the external resolver interface structure, but nowhere does it seem to   |
    describe how they are used or what you might want to set in them.        |
                                                                             |
dns_retry                                                                    |
                                                                             |
    Type:    integer                                                         |
    Default: 0                                                               |
                                                                             |
    See dns_retrans above.                                                   |

envelope_to_remove

    Type:    boolean
    Default: true

    Exim's local transports (appendfile and pipe) have an option for adding
    an Envelope-to header to a message when it is delivered - in exactly
    the same way as Return-path is handled. Envelope-to records the
    original recipient address in the envelope that caused the delivery.
    Such headers should not be present in outgoing messages, and this
    option causes them to be removed, to avoid any problems that might
    occur when a delivered message is subsequently sent on to some other
    recipient.

errors_address

    Type:    string
    Default: "postmaster"

    The mail address to which Exim will send certain error reports. As the
    default is specified without a domain, it will be sent to the domain
    specified by the qualify_recipient option. If this address is specified
    with a domain, it must be a fully qualified domain.

errors_copy

    Type:    string-list
    Default: unset

    Setting this option causes Exim to send bcc copies of delivery failure
    reports to other addresses. The value is a colon-separated list of
    items; each item consists of a pattern and an address list, separated
    by white space. If the pattern matches the recipient of the delivery
    error report, the message is copied to the addresses on the list. For
    example:

      errors_copy = "someuser@mydomain   postmaster@mydomain"

    The pattern can be a single regular expression, indicated by starting
    it with a ^ character; alternatively, either portion (local part,
    domain) can start with an asterisk, or the domain can be in any format
    that is acceptable as an item in a domain list, including a file
    lookup. A regular expression is matched against the entire (fully
    qualified) recipient; non-regular expressions must contain both a local
    part and domain, separated by @.

    The address list is a string which is expanded, and must end up as a
    comma-separated list of addresses. It is used to construct a Bcc header
    which is added to the error message. The expansion variables local_part
    and domain are set from the original recipient of the error message,
    and if there was any wildcard matching, the expansion variables $0, $1,
    etc. are set in the normal way.

errors_reply_to

    Type:    string
    Default: unset

    Exim's delivery error messages contain the header

      From: Mail Delivery System <Mailer-Daemon@${qualify_domain}>

    (where string expansion notation is used to show a variable substitu-
    tion). Experience shows that a large number of people reply to such
    messages. If the errors_reply_to option is set, a Reply-to header is
    added. The option must specify the complete header body.

exim_group

    Type:    string
    Default: compile-time configured (can be unset)

    This option sets the gid under which Exim runs when it gives up root
    privilege. It is used only when exim_user is also set. Unless it
    consists entirely of digits, the string is looked up using getgrnam(),
    and failure causes a configuration error. See chapter 44 for a
    discussion of security issues.

exim_path

    Type:    string
    Default: see below

    This option specifies the path name of the Exim binary, which is used
    when Exim needs to re-exec itself. The default is set up to point to
    the file exim in the directory configured at compile time by the
    BIN_DIRECTORY setting. It is necessary to change exim_path if Exim is
    run from some other place.

exim_user

    Type:    string
    Default: compile-time configured (can be unset)

    This option sets the uid under which Exim runs when it gives up root
    privilege. Unless it consists entirely of digits, the string is looked
    up using getpwnam(), and failure causes a configuration error. If
    exim_group is not also supplied, the gid is taken from the result of
    getpwnam() if it is used. If the resulting uid is the root uid, it has
    the effect of unsetting this option. See chapter 44 for a discussion of
    security issues. Note that the ownership of the runtime configuration
    file is checked against the compile-time setting of this parameter, not
    what is set here.

finduser_retries

    Type:    integer
    Default: 0

    On systems running NIS or other schemes in which user and group
    information is distributed from a remote system, there can be times
    when getpwnam() and related functions fail, even when given valid data,
    because things time out. Unfortunately these failures cannot be dis-
    tinguished from genuine 'not found' errors. If finduser_retries is set
    greater than zero, Exim will try that many times to find a user or a
    group, waiting for one second between tries.

forbid_domain_literals

    Type:    boolean
    Default: false

    If this option is set, the RFC 822 domain literal format is not
    permitted in addresses.

freeze_tell_mailmaster

    Type:    boolean
    Default: false

    On encountering certain errors, Exim freezes a message, which means
    that no further delivery attempts take place until an administrator
    thaws it. If this option is set, a message is sent to errors_address
    every time a message is frozen, unless the message is itself a delivery
    error message. (Without this exception there is the possibility of
    looping.) If several of the message's addresses cause freezing, only a
    single message is sent to the mail administrator. The reason(s) for
    freezing will be found in the message log.

gecos_name

    Type:    string
    Default: unset

    Some operating systems, notably HP-UX, use the 'gecos' field in the
    system password file to hold other information in addition to users'
    real names. Exim looks up this field for use when it is creating Sender
    or From headers. If either gecos_pattern or gecos_name are unset, the
    contents of the field are used unchanged, except that, if an &           |
    character is encountered, it is replaced by the user's login name with   |
    the first character forced to upper case, since this is a convention     |
    that is observed on many systems.                                        |

    When these options are set, gecos_pattern is treated as a regular
    expression that is to be applied to the field (again with & replaced by  |
    the login name), and if it matches, gecos_name is expanded and used as   |
    the user's name. Numeric variables such as $1, $2, etc. can be used in
    the expansion to pick up sub-fields that were matched by the pattern.
    In HP-UX, where the user's name terminates at the first comma, the
    following can be used:

      gecos_pattern = "([^,]*)"
      gecos_name = $1

gecos_pattern

    Type:    string
    Default: unset

    See gecos_name above.

helo_verify_nets                                                             |
                                                                             |
    Type:    net-list                                                        |
    Default: unset                                                           |
                                                                             |
    Exim does not normally verify the argument of an SMTP HELO or EHLO       |
    command, because it might involve an expensive DNS lookup, and the       |
    message may not be refused even if it is invalid. However, an SMTP       |
    server for local desktop systems (which are frequently misconfigured)    |
    can normally look up their hostnames cheaply. This improves the          |
    contents of Exim's logs by including the correct host names.             |
                                                                             |
    The helo_verify_nets option specifies IP networks for which the argu-    |
    ment of HELO or EHLO is checked by calling gethostbyaddr(). The value    |
    returned is used as the host name. Also, if no HELO or EHLO command is   |
    used, the name is looked up anyway. If a HELO or EHLO argument gets      |
    corrected, an entry is written to the main log at level 6 (not shown by  |
    default).                                                                |

ignore_errmsg_errors

    Type:    boolean
    Default: false

    If this options is set, failed addresses in error messages (i.e.
    messages whose senders are '<>') are discarded (with a log entry). The
    default action is to freeze such messages for human attention.

keep_malformed

    Type:    time
    Default: 4d

    This option specifies the length of time to keep messages whose spool
    files have been corrupted in some way. This should, of course, never
    happen. At the next attempt to deliver such a message, it gets removed.
    The incident is logged.

kill_ip_options                                                              |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    IP packets can contain options which are "source routing" data that      |
    enables one host to pretend to be another. (Don't confuse IP source      |
    routing with source-routed mail addresses, which are something entirely  |
    different.) IP source routing is an obvious security risk, and many      |
    sites lock out such packets in their routers. Also, some operating       |
    systems are able to disable IP source routing at the kernel level.       |
                                                                             |
    If Exim receives an SMTP call with IP options set, it logs the options   |
    if log_ip_options is set. Then, if refuse_ip_options is set, it drops    |
    the call; otherwise, if kill_ip_options is set, it unsets the options    |
    on the outgoing socket and attempts to continue. To read the IP          |
    options, getsockopt() is used. On some versions of SunOS 4.1 this        |
    causes system crashes. There is a patch that fixes this problem, but it  |
    can be avoided by setting all three Exim options false.                  |

local_domains

    Type:    domain-list
    Default: see below

    This specifies a list of domains which are recognized as 'local', that
    is, their final delivery (as far as the Internet is concerned) is
    handled by this MTA. If this option is not set, it defaults to the
    value of qualify_recipient.

    The name of the local host is not by default recognized as a local mail
    domain; either it must be included in local_domains, or the
    local_domains_include_host option must be set. If you want to accept
    mail addressed to your host in RFC 822 domain literal format, then
    local_host must also include the appropriate 'domains', consisting of
    IP addresses enclosed in square brackets. The
    local_domains_include_host_literals option can be set to add all IP
    addresses automatically.

    It is possible to specify no local domains by specifying no data for
    this option, for example,

      local_domains =

    If there are very many local domains, then they can be stored in a file
    and looked up whenever this string is searched. See the discussion of
    domain lists in section 7.11.

local_domains_include_host

    Type:    boolean
    Default: false

    If this option is set, the value of primary_hostname is added to the
    value of local_domains, unless it is already present. This makes it
    possible to use the same configuration file on a number of different
    hosts. This option is now obsolescent, as the same effect can be         |
    obtained by including the conventional item '@' (which matches the       |
    primary host name) in local_domains.                                     |

local_domains_include_host_literals

    Type:    boolean
    Default: false

    If this option is set and local_interfaces is unset, the IP addresses    |
    of all the interfaces on the local host, with the exception of           |
    127.0.0.1, are added to the value of local_domains, in RFC 822 domain    |
    literal format, that is, as dotted quad strings enclosed in square       |
    brackets. If local_interfaces is set, then only those addresses it       |
    contains (again excluding 127.0.0.1) are used.                           |
                                                                             |
local_interfaces                                                             |
                                                                             |
    Type:    string-list                                                     |
    Default: unset                                                           |
                                                                             |
    The string must contain a list of IP addresses in dotted-quad format.    |
    These are used for two different purposes:                               |
                                                                             |
     .   When a daemon is started to listen for incoming SMTP calls, it      |
         listens only on the interfaces identified here. An error occurs if  |
         it is unable to set up a listening socket on any interface.         |
                                                                             |
     .   Only the IP addresses listed here are taken as the local host's     |
         addresses when routing mail and checking for mail loops.            |
                                                                             |
    If local_interfaces is unset, the daemon issues a generic listen() that  |
    accepts incoming calls from any interface, and it also gets a complete   |
    list of available interfaces and treats them all as local when routing   |
    mail. On most systems the default action is what is wanted. However,     |
    some systems set up large numbers of virtual interfaces in order to      |
    provide many different virtual web servers. In these cases               |
    local_interfaces can be used to restrict SMTP traffic to one or two      |
    interfaces only.                                                         |

locally_caseless

    Type:    boolean
    Default: true

    For most Unix systems it is desirable that local parts of local mail
    addresses be treated in a case-independent manner, since most users
    expect that mail to OBailey and obailey, for example, will end up in
    the same mailbox. By default, Exim lower-cases local local parts at the
    start of processing them, but for installations that want to draw case
    distinctions, this option is provided. When turned off, local local
    parts are handled verbatim.

log_level                                                                    |
                                                                             |
    Type:    integer                                                         |
    Default: 5                                                               |
                                                                             |
    This controls the amount of data written to the main log (see chapter    |
    32). The higher the number, the more is written. At present a value of   |
    6 or higher causes all possible messages to appear.                      |
                                                                             |
log_ip_options                                                               |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    See kill_ip_options above.                                               |

log_received_recipients

    Type:    boolean
    Default: false

    When this option is set, the recipients of a message are listed on the
    main log as soon as the message is received. The list appears at the
    end of the log line that is written when a message is received,
    preceded by the word 'for'. The addresses are listed after they have
    been qualified, but before any rewriting has taken place.

log_smtp_confirmation                                                        |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    This option causes the response to the final '.' in the SMTP dialog for  |
    outgoing messages to be added to delivery log lines in the form          |
    'C="<text>"'. A number of MTAs (including Exim from release 1.60)        |
    return an identifying string in this reponse, so logging this infor-     |
    mation allows messages to be tracked more easily. This global option     |
    applies to all SMTP transports.                                          |
                                                                             |
log_subject                                                                  |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    This option causes a message's subject to be included in the arrival     |
    log line, in the form 'T="<subject text>"'. T stands for 'topic' (S is   |
    already used for 'size').                                                |

message_body_visible

    Type:    integer
    Default: 500

    This option specifies how much of a message's body is to be included in
    the message_body expansion variable.

message_filter

    Type:    string
    Default: unset

    This option specifies a filter file which is applied to all messages
    before any routing or directing is done. This is called the 'system
    message filter'. Details of this facility are given in section 43.9.

message_filter_group                                                         |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option sets the gid under which the system message filter is run.   |
    The seteuid() or setresuid() function must be available in the operat-   |
    ing system for a temporary change to be possible. If the filter          |
    generates any pipe, file, or reply addresses, the gid under which the    |
    filter is run is used when delivering to them. Unless the string         |
    consists entirely of digits, it is looked up using getgrnam(), and       |
    failure causes a configuration error. If the option is not set, and      |
    either message_filter_user is unset or consists entirely of digits, the  |
    gid is not changed when running the filter. Otherwise the group is       |
    taken from the result of getpwnam().                                     |
                                                                             |
message_filter_user                                                          |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option sets the uid under which the system message filter is run.   |
    The seteuid() or setresuid() function must be available in the operat-   |
    ing system for a temporary change to be possible. If the filter          |
    generates any pipe, file, or reply addresses, the uid under which the    |
    filter is run is used when delivering to them. If the option is not      |
    set, the uid is not changed when running the filter. Unless it consists  |
    entirely of digits, the string is looked up using getpwnam(), and        |
    failure causes a configuration error.                                    |

message_id_header_text

    Type:    string
    Default: unset

    If this variable is set, the string is expanded and used to augment the
    text of the Message-id header that Exim creates if an incoming message
    does not have one. The text of this header is required by RFC 822 to
    take the form of an address. By default, Exim uses its internal message
    id as the local part, and the primary host name as the domain. If this
    option is set, it is expanded and inserted into the header immediately
    before the @, separated from the internal message id by a dot. Any
    characters that are illegal in an address are automatically converted
    into hyphens. This means that constructions like ${tod_log} can be
    used, as the spaces and colons will become hyphens.

message_size_limit

    Type:    integer
    Default: 0

    This option limits the maximum size of message that Exim will process.
    Zero means no limit. It should be set somewhat larger than
    return_size_limit if the latter is non-zero. Incoming SMTP messages are
    failed with a 552 error if the limit is exceeded; locally-generated
    messages either get a stderr message or a delivery failure message to
    the sender, depending on the -oe setting, in the normal way. Rejection
    of an oversized message is logged on both the main and the reject logs.

never_users

    Type:    string-list
    Default: unset

    Local mail deliveries are run in processes that are setuid to the
    recipient. However, it is usually desirable to lock out root from this,
    as a safety precaution. If a message is to be delivered to any of the
    users on the never_users list, the process is run as 'nobody' instead
    (see nobody_user below). A common example is

      never_users = root:daemon:bin:exim

    This option overrides the pipe_as_creator option of the pipe transport
    driver.

nobody_group

    Type:    string
    Default: unset

    This specifies the group to use when a process is to be run as
    'nobody'. If it is unset, the value of the 'nobody' user's default
    group is used.

nobody_user

    Type:    string
    Default: unset

    This specifies the user to use when a process is to be run as 'nobody'.
    If it is unset, Exim looks up the user 'nobody' using getpwnam(). If
    this fails, Exim panics, writing a message to the panic log and exiting
    immediately.

percent_hack_domains

    Type:    domain-list
    Default: unset

    The 'percent hack' is the convention whereby a local part containing a
    percent sign is re-interpreted as a remote address, with the percent
    replaced by @. This is also known as 'source routing', though that term
    is also applied to RFC 822 addresses that begin with an @ character. If
    this option is set, Exim implements the percent facility for those
    local domains listed, but no others. The option can be set to '*' to
    allow the percent hack in all local domains.

preserve_message_logs

    Type:    boolean
    Default: false

    If this option is set, message log files are not deleted when messages
    are completed. Instead, they are moved to a subdirectory of the spool
    directory called msglog.OLD, where they remain available for statisti-
    cal or debugging purposes. This is a dangerous option to set on systems
    with any appreciable volume of mail. Use with care!

primary_hostname

    Type:    string
    Default: see below

    This specifies the name of the current host. This is used in the HELO
    command for outgoing SMTP messages, and as the default for
    qualify_domain. If it is not set, Exim calls uname() to find it. If
    this fails, Exim panics and dies. If the name returned by uname()
    contains only one component, Exim passes it to gethostbyname() in order
    to obtain the fully-qualified version.

qualify_domain

    Type:    string
    Default: see below

    This specifies the domain name that is added to any sender addresses
    that do not have a domain qualification. It also applies to recipient
    addresses if qualify_recipient is not set. Such addresses are accepted
    by default only for locally-generated messages - messages from external
    sources must always contain fully qualified addresses, unless the
    sending host matches one of the receiver_unqualified or
    sender_unqualified options. If qualify_domain is not set, it defaults
    to the primary_hostname value.

qualify_recipient

    Type:    string
    Default: see below

    This specifies the domain name that is added to any recipient addresses
    that do not have a domain qualification. Such addresses are accepted by
    default only for locally-generated messages - messages from external
    sources must always contain fully qualified addresses, unless the
    sending host matches one of the receiver_unqualified or
    sender_unqualified options (see below). If qualify_recipient is not
    set, it defaults to the qualify_domain value.

queue_only

    Type:    boolean
    Default: false

    If queue_only is set (which is equivalent to the -odq command line
    option), a delivery process is not automatically started whenever a
    message has been received. Instead, the message waits on the queue for
    the next queue run. Even if queue_only is false, incoming SMTP messages
    may not get delivered immediately if a lot of them arrive at once - see
    the queue_only_load and smtp_accept_queue options.

queue_only_load

    Type:    fixed-point
    Default: unset

    If the system load average is higher than this value, all incoming
    messages are queued, and no automatic deliveries are started. If this
    happens during local or remote SMTP input, all subsequent messages on
    the same connection are queued. Deliveries will subsequently be per-
    formed by queue running processes, unless the load is higher than
    deliver_load_max. There are some operating systems for which Exim
    cannot determine the load average (see chapter 1); for these this
    option has no effect. See also smtp_accept_queue and smtp_load_reserve.

queue_remote                                                                 |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option (equivalent to the -odqr option) is set, a delivery       |
    process is started whenever a message is received, but only local        |
    addresses are handled, and only local deliveries take place. See also    |
    queue_smtp, which is subtly different.                                   |

queue_run_max

    Type:    integer
    Default: 5

    This controls the maximum number of queue-running processes that the
    Exim daemon will run simultaneously. It does not, however, interlock
    with other processes, so additional queue-runners can be started by
    other means, or by killing and restarting the daemon.

queue_smtp

    Type:    boolean
    Default: false

    If queue_smtp is set (which is equivalent to the -odqs command line
    option), a delivery process is started whenever a message has been
    received, but only local deliveries take place. If any SMTP deliveries
    are required, the message waits on the queue for the next queue run.
    Since routing of the message has taken place, Exim knows to which
    remote hosts it must be delivered, and so when the queue run happens,
    multiple messages for the same host are delivered over a single SMTP
    connection. See also queue_remote, which is similar, but does not do
    the routing.

received_header_text

    Type:    string
    Default: see below

    This string defines the contents of the Received message header that is
    added to each message, except for the timestamp, which is automatically
    added on at the end, preceded by a semicolon. The string is expanded
    each time it is used, and the default is

      received_header_text = "Received: \
           ${if def:sender_fullhost {from ${sender_fullhost} \
           ${if def:sender_ident {(${sender_ident})}}\n\t}\
           {${if def:sender_ident {from ${sender_ident} }}}}\
           by ${primary_hostname} \
           ${if def:received_protocol {with ${received_protocol}}} \
           (Exim ${version_number} #${compile_number})\n\t\
           id ${message_id}"

    The use of conditional expansions ensures that this works for both
    locally generated messages and messages received from remote hosts,
    giving header lines such as the following:

      Received: from scrooge.carol.book [240.1.12.25] (root)
              by marley.carol.book with smtp (Exim 0.25 #9)
              id E0tS3Ga-0005C5-00; Mon, 25 Dec 1995 14:43:44 +0000
      Received: by scrooge.carol.book with local (Exim 0.25 #9)
              id E0tS3GW-0005C2-00; Mon, 25 Dec 1995 14:43:41 +0000

    Note the automatic addition of the date and time in the required
    format.

received_headers_max

    Type:    integer
    Default: 30

    When a message is to be delivered to a remote machine, the number of
    Received headers is counted, and if it is greater than this parameter,
    a mail loop is assumed to have occurred, the delivery is abandoned, and
    a delivery error message is generated.

receiver_try_verify

    Type:    boolean
    Default: false

    See receiver_verify.

receiver_unqualified_hosts

    Type:    host-list
    Default: unset

    This option lists those hosts from which Exim is prepared to accept
    unqualified receiver addresses. The addresses are made fully qualified
    by the addition of the qualify_recipient value. Typically the hosts are
    local ones, but if you want to imitate the behaviour of mailers that
    accept unqualified addresses from anywhere, specify

      receiver_unqualified_hosts = *

receiver_unqualified_nets

    Type:    net-list
    Default: unset

    This option lists those IP networks from any host on which Exim is
    prepared to accept unqualified receiver addresses. The addresses are
    made fully qualified by the addition of the qualify_domain. Typically
    local networks are specified. This is a more efficient option than
    using a wildcarded partial entry in receiver_unqualified_hosts, because
    no DNS lookup is required.

receiver_verify

    Type:    boolean
    Default: false

    When this option is set, the addresses of recipients received from a
    remote host are verified as they are received, unless the host matches   |
    an entry in either receiver_verify_except_hosts or                       |
    receiver_verify_except_nets. If an address is invalid, an incoming SMTP  |
    call gets an error response to the RCPT TO command. If an address
    cannot immediately be verified, a temporary error code is given. The
    receiver_try_verify option is less severe: it operates in the same way,
    except that an address is accepted if it cannot immediately be
    verified. Verification failures are logged.

receiver_verify_except_hosts                                                 |
                                                                             |
    Type:    host-list                                                       |
    Default: unset                                                           |
                                                                             |
    See receiver_verify above.                                               |
                                                                             |
receiver_verify_except_nets                                                  |
                                                                             |
    Type:    net-list                                                        |
    Default: unset                                                           |
                                                                             |
    See receiver_verify above.                                               |
                                                                             |
recipients_max                                                               |
                                                                             |
    Type:    integer                                                         |
    Default: 0                                                               |
                                                                             |
    If this is set greater than zero, it specifies the maximum number of     |
    recipients for any message. This applies to the original list of         |
    recipients supplied with the message. SMTP messages get a 421 response   |
    for all recipients over the limit; earlier recipients are delivered as   |
    normal. Non-SMTP messages with too many recipients are failed, and no    |
    deliveries are done.                                                     |
                                                                             |
refuse_ip_options                                                            |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    See kill_ip_options above.                                               |

relay_domains

    Type:    domain-list
    Default: unset

    See sender_host_accept_relay and related options below.

remote_max_parallel

    Type:    integer
    Default: 1

    This option controls parallel delivery to remote sites. If the value is
    less than 2, parallel delivery is disabled, and Exim does all the
    remote deliveries for a message one by one, from a single delivery
    process. Otherwise, if a message has to be delivered to more than one
    remote host, then up to remote_max_parallel deliveries are done simul-
    taneously, each in a separate process. If there are more than
    remote_max_parallel hosts to be delivered to, then the maximum number
    of processes are started, and as each one finishes, another is begun.
    The order of starting processes is the same as if sequential delivery
    were being done, and can be controlled by the remote_sort option. If
    parallel delivery takes place while running with debugging turned on,
    the debugging output from each delivery process is tagged with its
    process id.

    The overhead in doing this is a fork to set up a separate process for
    each delivery, and the associated management of the subprocess (includ-
    ing getting back the result of the delivery attempt). As well as the
    process overhead, there may be a small additional penalty paid for
    parallel delivery. If host is found to be down, this fact cannot be
    communicated to any deliveries that are running in parallel, though it
    will be passed on to any that start afterwards. This is no worse than
    if there were two separate messages being delivered simultaneously.

    The option controls only the maximum number of parallel deliveries from
    one Exim process. Since Exim has no central queue manager, there is no
    way of controlling the total number of simultaneous deliveries if the
    configuration allows a delivery attempt as soon as a message is
    received. If you want to control the total number of deliveries on the
    system, then you need to set the queue_only option, which ensures that
    all incoming messages are simply added to the queue. Then set up an
    Exim daemon to start queue runner processes at appropriate intervals
    (probably fairly often, e.g. every minute), and limit the total number
    of queue runners by setting the queue_run_max parameter. As each queue
    runner delivers only one message at a time, the maximum number of
    deliveries that can then take place at once is queue_run_max multiplied
    by remote_max_parallel.

    If it is purely remote deliveries you want to control, then use
    queue_smtp instead of queue_only. This has the added benefit of doing
    the SMTP routing before queuing, so that several messages for the same
    host will eventually get delivered down the same connection.

remote_sort

    Type:    domain-list
    Default: unset

    When there are a number of remote deliveries for a message, they are
    sorted by domain into the order given by this list. For example,

      remote_sort = "*.cam.ac.uk:*.uk"

    would attempt to deliver to all addresses in the cam.ac.uk domain
    first, then to those in the uk domain, then to any others.

retry_interval_max

    Type:    time
    Default: 24h

    Chapter 30 describes Exim's mechanisms for controlling the intervals
    between delivery attempts for messages that cannot be delivered
    straight away. This option sets an overall limit to the length of time
    between retries.

return_path_remove

    Type:    boolean
    Default: true

    RFC 822 states that the Return-path header is 'added by the final
    transport system that delivers the message to its recipient' (section
    4.3.1), which implies that this header should not be present in
    incoming messages. If this option is true, Return-path headers are
    removed from messages as they are read. Exim's local transports
    (appendfile and pipe) have options for adding Return-path headers at
    the time of local delivery.

return_size_limit

    Type:    integer
    Default: 100K

    This option sets limit in bytes on the size of messages that are
    returned to sender. If it is set to zero there is no limit. If the body
    of any message that is to be included in an error message is greater
    than the limit, it is truncated, and a comment pointing this out is
    added at the top. The actual cutoff may be greater than the value
    given, owing to the use of buffering for transferring the message in
    chunks. The idea is just to save bandwidth on those undeliverable
    15-megabyte messages. If message_size_limit is set, the value of
    return_size_limit should be somewhat smaller.

rfc1413_except_hosts

    Type:    host-list
    Default: unset

    If this option is set, RFC 1413 identification calls are not made to
    the listed hosts.

rfc1413_except_nets

    Type:    net-list
    Default: unset

    If this option is set, RFC 1413 identification calls are not made to
    any host on the listed networks.

rfc1413_query_timeout

    Type:    time
    Default: 60s

    This sets the timeout on RFC 1413 identification calls. If it is set to
    zero, no RFC 1413 calls are ever made. This is more efficient than
    setting a global pattern in one of the except options.

security

    Type:    string
    Default: see below

    When exim_user is set non-zero in the runtime configuration or an Exim
    uid is compiled into the binary, Exim gives up root privilege for some
    of the time. As there are trade-offs between increased security and
    efficiency, this option is provided to control exactly how this is
    done. The option can be set to one of the strings 'seteuid', 'setuid',
    or 'setuid+seteuid', provided that a uid for Exim is defined. Otherwise
    it must be left unset. A full description of what these values mean is
    given in chapter 44. The default for this option is unset if no special
    Exim uid is defined, otherwise it is either 'setuid+seteuid' or
    'setuid', depending on whether the seteuid() function is configured as
    being available or not.

sender_accept                                                                |
                                                                             |
    Type:    address-list                                                    |
    Default: unset                                                           |
                                                                             |
    This option requests the acceptance of incoming SMTP mail from the       |
    specified envelope senders only. It operates like sender_reject (see     |
    below).                                                                  |
                                                                             |
sender_accept_recipients                                                     |
                                                                             |
    Type:    address-list                                                    |
    Default: unset                                                           |
                                                                             |
    This operates in exactly the same way as sender_accept except that       |
    rejection is given in the form of a 550 error code to every RCPT TO      |
    command instead of rejecting MAIL FROM. This seems to be the only way    |
    of saying 'no' to some mailers.                                          |

sender_address_relay

    Type:    address-list
    Default: unset

    See sender_host_accept_relay below.

sender_host_accept

    Type:    host-list
    Default: unset

    If this option is set, incoming SMTP calls are accepted only from the
    hosts listed, possibly also qualified by an RFC 1413 identification.
    (Calls from networks listed in sender_net_accept are also accepted.)
    However, if a call arrives from a host (and identification) which is
    also listed in sender_host_reject or from a network listed in
    sender_net_reject, the call is rejected. Chapter 43 contains details of
    this facility; see also sender_accept and sender_reject.

sender_host_accept_relay

    Type:    host-list
    Default: unset

    An MTA is said to "relay" a message if it receives it from some host     |
    and delivers it directly to another host as a result of a remote         |
    address contained in it. Expanding a local address via an alias or       |
    forward file and then passing the message on is not relaying.            |

    If this option is set, a check is made on incoming recipient addresses
    in messages received from other hosts at the time of the RCPT TO
    command in the SMTP dialogue. If the domain in the address matches an
    entry in local_domains or in relay_domains, the address is always
    accepted (at least as far as this check is concerned - a subsequent
    verification check may fail it). Otherwise, the address is accepted
    only if the host matches one of the patterns in
    sender_host_accept_relay or in sender_net_accept_relay, and does not
    match any pattern in sender_host_reject_relay or
    sender_net_reject_relay, and, if sender_address_relay is set, the
    sender's address from the MAIL FROM command matches one of its
    patterns. Chapter 43 contains further details of this facility.

sender_host_reject

    Type:    host-list
    Default: unset

    If this option is set, incoming SMTP calls from the hosts listed,
    possibly also qualified by an RFC 1413 identification, are rejected.
    Chapter 43 contains details of this facility.

sender_host_reject_recipients

    Type:    host-list
    Default: unset

    If this option is set, all recipients in incoming SMTP calls from the
    hosts listed, possibly also qualified by an RFC 1413 identification,
    are rejected. Chapter 43 contains details of this facility, which
    differs from sender_host_reject only in the point in the SMTP dialogue
    at which the rejection occurs.

sender_host_reject_relay

    Type:    host-list
    Default: unset

    Recipient addresses in domains other than those in local_domains or
    relay_domains are rejected from hosts that match this list, even if
    they match a pattern in sender_host_accept_relay or
    sender_net_accept_relay. If you don't want to do any relaying at all,
    then relay_domains should be left unset, and sender_host_reject_relay
    set to *.

sender_net_accept

    Type:    net-list
    Default: unset

    If this option is set, incoming SMTP calls are accepted only from the
    IP networks specified (and from any hosts listed in
    sender_host_accept). However, if a call arrives from a host (and
    identification) which is also listed in sender_host_reject or from a
    network listed in sender_net_reject, the call is rejected. Chapter 43
    contains details of this facility; see also sender_reject.

sender_net_accept_relay

    Type:    net-list
    Default: unset

    This operates like sender_host_accept_relay, except that the check is
    done by IP network number.

sender_net_reject

    Type:    net-list
    Default: unset

    If this option is set, incoming SMTP calls from the listed networks are
    rejected. Chapter 43 contains details of this facility.

sender_net_reject_recipients

    Type:    net-list
    Default: unset

    If this option is set, all recipients on incoming SMTP calls from the
    listed networks are rejected. Chapter 43 contains details of this
    facility, which differs from sender_net_reject only in the point in the
    SMTP dialogue at which the rejection occurs.

sender_net_reject_relay

    Type:    net-list
    Default: unset

    Recipient addresses in domains other than those in local_domains or
    relay_domains are rejected from hosts on networks that match this list,
    even if they match sender_host_accept_relay or sender_net_accept_relay.
    Chapter 43 contains details of this facility.

sender_reject

    Type:    address-list
    Default: unset

    This option can be set in order to reject mail from certain senders.
    This should be used only after due consideration, but can be of use
    against spammers and mail bombers; I've provided this facility as a
    result of some real incidents. The check is done on the sender's
    address as given in the MAIL FROM command in SMTP, but not for local
    senders where the logged-in user's address is going to override anyway.

    If the sender's address is source-routed, it is the final component of
    the address that is checked. The check is not done for batch SMTP
    input. If the check fails, a 5xx return code is given to MAIL FROM.
    This doesn't always stop remote mailers from trying again. See
    sender_reject_recipients for an alternative. Typical examples of the
    use of this option might be:

      sender_reject = "spamuser@some.domain:spam.domain"
      sender_reject = partial-dbm;/etc/mail/blocked/senders

    Note that this check operates on sender address domains independently
    of the sending host; sender_reject_hosts and sender_reject_nets can be
    used to block all mail from particular hosts or nets, while
    sender_host_reject_relay, sender_net_reject_relay and
    sender_address_relay can be used to prevent unwanted relaying. See also
    sender_accept.

sender_reject_recipients

    Type:    address-list
    Default: unset

    This operates in exactly the same way as sender_reject except that the
    rejection is given in the form of a 550 error code to every RCPT TO
    command instead of rejecting MAIL FROM. This seems to be the only way
    of saying 'no' to some mailers. See also sender_accept_recipients.

sender_try_verify

    Type:    boolean
    Default: false

    See sender_verify.

sender_unqualified_hosts

    Type:    host-list
    Default: unset

    This option lists those hosts from which Exim is prepared to accept
    unqualified sender addresses. The addresses are made fully qualified by
    the addition of the qualify_domain. Typically the hosts are local ones,
    but if you want to imitate the behaviour of mailers that accept
    unqualified addresses from anywhere, specify

      sender_unqualified_hosts = *

sender_unqualified_nets

    Type:    net-list
    Default: unset

    This option lists those IP networks from any host on which Exim is
    prepared to accept unqualified sender addresses. The addresses are made
    fully qualified by the addition of the qualify_domain. Typically local
    networks are specified. This is a more efficient option than using a
    wildcarded partial entry in sender_unqualified_hosts, because no DNS
    lookup is required.

sender_verify

    Type:    boolean
    Default: false

    If this option is true, envelope sender addresses on incoming SMTP
    messages are checked to ensure that they are valid. Messages with
    invalid envelope senders are rejected with a permanent error code if
    sender_verify_reject is set (the default). Otherwise a warning is
    logged. See section 43.7 for details of the rejection, which can happen
    at three different points of the SMTP dialogue. If a sender cannot
    immediately be verified, a temporary error code is returned after        |
    reading the data (so the headers can be logged). The sender_try_verify   |
    option is less severe: it operates in exactly the same way as
    sender_verify except that if an address cannot immediately be verified,
    it is accepted instead of being temporarily rejected.

sender_verify_except_hosts

    Type:    host-list
    Default: unset

    If sender_verify is true, this option specifies a list of hosts and RFC
    1413 identifications which are exempt from sender verification. See
    chapter 43 for details.

sender_verify_except_nets

    Type:    net-list
    Default: unset

    If sender_verify is true, this option specifies a list of IP networks
    which are exempt from sender checking. See chapter 43 for details.

sender_verify_fixup

    Type:    boolean
    Default: false

    Experience shows that many messages are sent out onto the Internet with
    invalid sender addresses in the envelopes (i.e. in the MAIL FROM
    command of the SMTP dialogue), but with valid addresses in the Sender,
    From, or Reply-to header fields. If sender_verify is true and this
    option is also true, an invalid envelope sender or one that cannot       |
    immediately be verified is replaced by a valid value from the headers.   |
    See chapter 43 for details.

sender_verify_log_details

    Type:    boolean
    Default: false

    Setting this option causes additional information about sender verifi-
    cation to be written to the reject log. It is intended to help sort out
    problems concerned with sender verification, and is really more for
    debugging Exim than for regular use.

sender_verify_reject

    Type:    boolean
    Default: true

    When this is set, a message is rejected if sender verification fails.
    If it is not set, a warning message is written to the main and reject
    logs, and the message is accepted (unless some other error occurs).

smtp_accept_max

    Type:    integer
    Default: 20

    This specifies the maximum number of simultaneous incoming SMTP calls
    that Exim will accept. It applies only to the listening daemon; there
    is no control (in Exim) when incoming SMTP is being handled by inetd.
    If the value is set to zero, no limit is applied.

smtp_accept_queue

    Type:    integer
    Default: 0

    If the number of simultaneous incoming SMTP calls handled via the
    listening daemon exceeds this value, then messages received are simply
    placed on the queue, and no delivery processes are started automati-
    cally. A value of zero implies no limit, and clearly any non-zero value
    is useful only if it is less than the smtp_accept_max value (unless
    that is zero). See also queue_only, queue_only_load, queue_smtp, and
    the various -od command line options.

smtp_accept_reserve

    Type:    integer
    Default: 0

    When smtp_accept_max is set greater than zero, this option specifies a
    number of SMTP connections that are reserved for connections from the
    hosts or networks that are specified in smtp_reserve_hosts and
    smtp_reserve_nets. The value set in smtp_accept_max includes this
    reserve pool. For example, if smtp_accept_max is set to 50 and
    smtp_accept_reserve is set to 5, then once there are 45 active
    connections, new ones are accepted only from hosts listed in
    smtp_reserve_hosts or from networks listed in smtp_reserve_nets.

smtp_banner

    Type:    string
    Default: see below

    This string, which is expanded every time it is used, is output as the
    initial positive response to an SMTP connection. The default setting
    is:

      smtp_banner = "${primary_hostname} Exim ${version_number} \
        #${compile_number} ready at ${tod_full}"

    Failure to expand the string causes a panic error.

smtp_connect_backlog

    Type:    integer
    Default: 5

    This specifies a maximum number of waiting SMTP connections. Exim
    passes this value to the TCP/IP system when it sets up its listener.
    Once this number of connections are waiting for the daemon's attention,
    subsequent connection attempts are refused at the TCP/IP level. At
    least, that is what the manuals say. In Solaris 2.4 such connection
    attempts have been observed to time out. The default value of 5 is a     |
    conservative one, suitable for older and smaller systems. For large      |
    systems is it probably a good idea to increase this, possibly substan-
    tially (to 50, say). It also gives some protection against denial-of-
    service attacks by SYN flooding.

smtp_etrn_hosts                                                              |
                                                                             |
    Type:    host-list                                                       |
    Default: unset                                                           |
                                                                             |
    RFC 1985 describes a new SMTP command called ETRN which is designed to   |
    overcome the security problems of the TURN command (which has fallen     |
    into disuse). Exim recognizes ETRN if the calling host matches an entry  |
    in this option or in smtp_etrn_nets. The ETRN command is concerned with  |
    'releasing' messages that are awaiting delivery to certain hosts. As     |
    Exim does not organize its message queue by host, the only form of ETRN  |
    that is supported is the one where the text starts with the '#' prefix,  |
    where the remainder of the text is specific to the SMTP server. A valid  |
    ETRN command causes a run of Exim with the -R option to happen, with     |
    the remainder of the ETRN text as its argument. For example,             |
                                                                             |
      ETRN #brigadoon                                                        |
                                                                             |
    causes a delivery attempt on all messages with undelivered addresses     |
    containing the text 'brigadoon'. Because a separate delivery process is  |
    run to do the delivery, there is no security risk with ETRN.             |
                                                                             |
smtp_etrn_nets                                                               |
                                                                             |
    Type:    net-list                                                        |
    Default: unset                                                           |
                                                                             |
    See smtp_etrn_hosts above.                                               |

smtp_load_reserve

    Type:    fixed-point
    Default: unset

    If the system load average ever gets higher than this, incoming SMTP
    calls are accepted only from those hosts that match an entry in
    smtp_reserve_hosts or smtp_reserve_nets. There are some operating sys-
    tems for which Exim cannot determine the load average (see chapter 1);
    for these this option has no effect.

smtp_receive_timeout

    Type:    time
    Default: 5m

    This sets a timeout value for SMTP reception. If a line of input
    (either an SMTP command or a data line) is not received within this
    time, the SMTP connection is dropped and the message abandoned.

smtp_reserve_hosts

    Type:    host-list
    Default: unset

    This option lists hosts for which SMTP connections are reserved; see
    smtp_accept_reserve and smtpload_reserve above.

smtp_reserve_nets

    Type:    net-list
    Default: unset

    This option lists IP networks for which SMTP connections are reserved;
    see smtp_accept_reserve and smtpload_reserve above.

smtp_verify

    Type:    boolean
    Default: false

    If this option is true, the SMTP command VRFY is supported on incoming
    SMTP connections; otherwise it is not.

spool_directory

    Type:    string
    Default: see below

    The default value is taken from the compile-time configuration setting.
    This option makes it possible to run testing versions of Exim without
    using the standard spool.

strip_excess_angle_brackets

    Type:    boolean
    Default: false

    If this option is set, then redundant pairs of angle brackets round
    'route-addr' items in addresses are stripped. For example,
    <<xxx@a.b.c.d>> is treated as <xxx@a.b.c.d>. If this is in the envelope
    and the message is passed on to another MTA, the excess angle brackets
    are not passed on. If this option is not set, multiple pairs of angle
    brackets cause a syntax error.

strip_trailing_dot

    Type:    boolean
    Default: false

    If this option is set, a trailing dot at the end of a domain in an
    address is ignored. If this is in the envelope and the message is
    passed on to another MTA, the dot is not passed on. If this option is
    not set, a dot at the end of a domain causes a syntax error.

trusted_groups

    Type:    string-list
    Default: unset

    If this option is set, then any process that is running in one of the
    listed groups may pass a message to Exim and specify the sender's
    address using the -f command line option, without Exim's adding a
    Sender header. If neither trusted_groups nor trusted_users is set, then
    only root and the Exim user can do this.

trusted_users

    Type:    string-list
    Default: unset

    If this option is set, then any process that is running as one of the
    listed users may pass a message to Exim and specify the sender's
    address using the -f command line option, without Exim's adding a
    Sender header. If neither trusted_users nor trusted_groups is set, then
    only root and the Exim user can do this.

unknown_login

    Type:    string
    Default: unset

    This is a specialized feature for use in unusual configurations. By
    default, if the uid of the caller of Exim cannot be looked up using
    getpwuid(), Exim gives up. The unknown_login option can be used to set
    a login name to be used in this circumstance. It is expanded, so values
    like user$caller_uid can be set. When unknown_login is used, the value
    of unknown_username is used for the user's real name (gecos field),
    unless this has been set by the -F option.

unknown_username

    Type:    string
    Default: unset

    See unknown_login.



                         11. DRIVER SPECIFICATIONS


The second, third, and fourth parts of Exim's configuration file specify
which transport, director, and router drivers are to be used, respectively.
The format of the entries is the same in each case, and is as follows:

  <name:>
    <generic option>,
    ...
    <generic option>;
    <private option>,
    ...
    <private option>

The name identifies a particular instance of a driver; the same driver code
can be used more than once, with different instance names and different
option settings each time. Comment lines may appear in the middle of driver
specifications. The full list of option settings for any particular driver
instance, including all the defaults, can be extracted by making use of the
-bP command line option (see chapter 5).

The generic options are those that apply to all drivers of the same type
(i.e. all directors, or all routers, or all transports). Note that a comma
is used to terminate each option, and a semicolon is used to terminate the
list of generic options. There is always at least one generic option,
giving the name of the underlying driver. The private options are particu-
lar to each driver, and none need appear. A comma is used to separate them.

The order of driver specifications in the configuration file matters for
the directors and the routers, since an address is passed to each of them
in turn until one is able to handle it. The order of transport specifi-
cations does not matter.

The next chapter discusses the environment in which local deliveries are     |
done, and how this is affected by the configurations of the relevant         |
directors, routers, and transports.                                          |

Subsequent chapters describe the generic options for each type of driver,
and these are followed by descriptions of each of the available drivers of
each type.



                12. 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 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.                |
                                                                             |
                                                                             |
12.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. If user is set, 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, then  |
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 the one associated with the address by   |
a director, the option for calling initgroups() is taken from the director:  |
aliasfile, forwardfile, and localuser have this option.                      |
                                                                             |
When a router sends a message to a local transport (e.g. for batching) the   |
uid and gid must be set on the transport. For directed addresses, if no uid  |
is set in the transport, then one must be associated with the address by     |
the director that handled it.                                                |
                                                                             |
The aliasfile director has group and user options that can be used to        |
specify the uid and gid for local deliveries directly generated by it.       |
                                                                             |
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 local deliveres, but they can be overridden by the   |
group and user options of the director.                                      |
                                                                             |
The localuser director looks up local parts in the password file, and sets   |
the uid and gid from that file for local deliveries.                         |
                                                                             |
The smartuser director has no means of associating a uid and gid with an     |
address; consequently any local transport that it uses must specify them     |
for itself.                                                                  |
                                                                             |
                                                                             |
12.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     |
use for a home directory in this transport is if the expansion variable      |
$home is used in one of its options, in which case 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 direc-     |
tory, then Exim uses the value of the home directory, if set. Otherwise it   |
sets the current directory to '/' before running a local transport.          |
                                                                             |
The aliasfile, forwardfile, and localuser directors all 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.                                                       |
                                                                             |
The smartuser director has no means of setting up home and current           |
directory strings; consequently any local transport that it uses must        |
specify them for itself if they are required.                                |



                       13. GENERIC TRANSPORT OPTIONS


There is only one generic option for transports.

driver

    Type:    string
    Default: unset

    This specifies which of the available transport drivers is to be used.
    For example:

      driver = smtp;

    There is no default, and this option must be set for every transport.



                        14. THE APPENDFILE TRANSPORT


The appendfile transport delivers a message by appending it to a file in
the local filing system, or by creating an entirely new file in a specified
directory. It is typically used for local deliveries to users' mailboxes,
and also for copying messages to files whose names are obtained from alias,
forwarding, or filtering expansions. Appendfile can also be used as a
pseudo-remote transport for putting messages into files for remote delivery
by some means other than Exim.

As appendfile is a local transport, it is always run in a separate process,
under a non-privileged uid and gid, which are set by setuid(). In the
common local delivery case, these are the uid and gid belonging to the user
to whom the mail is being delivered. The current directory is also normally  |
set to the user's home directory. See chapter 12 for a discussion of the     |
local delivery environment.                                                  |

If the transport fails for any reason, the message remains on the input
queue so that there can be another delivery attempt later. If there is an
error while writing to the file (e.g. quota exceeded, partition filled),
Exim attempts to reset the file's length and last modification time back to
what they were before.

Before writing to the file, a number of security checks are made, and the
file is locked. A detailed description is given below, after the list of
private options, which are as follows:

allow_symlink

    Type:    boolean
    Default: false

    By default, appendfile will not deliver if the path name for the file
    is that of a symbolic link. Setting this option relaxes that con-
    straint, but there are security issues involved in the use of symbolic
    links. Be sure you know what you are doing if you set this. Details of
    exactly what this option affects are included in the discussion which
    follows this list of options.

batch                                                                        |
                                                                             |
    Type:    string                                                          |
    Default: "none"                                                          |
                                                                             |
    Normally, each address that is directed or routed to an appendfile       |
    transport is handled separately. In special cases it may be desirable    |
    to handle several addresses at once, for example, when passing a         |
    message with several addresses to a different mail regime (e.g. UUCP),   |
    though this is more often done using the pipe transport. If this option  |
    is set to the string 'domain', then all addresses with the same domain   |
    that are directed or routed to the transport are handled in a single     |
    delivery. If it is set to 'all' then multiple domains are batched. The   |
    list of addresses is included in the Envelope-to header if               |
    envelope_to_add is set (see below). The only difference between this     |
    option and bsmtp is the inclusion of SMTP command lines in the output    |
    for bsmtp.                                                               |
                                                                             |
batch_max                                                                    |
                                                                             |
    Type:    integer                                                         |
    Default: 100                                                             |
                                                                             |
    This limits the number of addresses that can be handled in a batch, and  |
    applies to both the batch and the bsmtp options.                         |

bsmtp

    Type:    string
    Default: "none"

    This option is used to set up an appendfile transport as a pseudo-
    remote transport for delivering messages into local files in batch SMTP
    format for onward transmission by some non-Exim means. The value of the
    option must be one of the strings 'none', 'one', 'domain', or 'all'.
    The first of these turns the feature off. A full description of the
    batch SMTP mechanism is given in section 43.10. When bstmp is set, the
    batch option automatically takes the same value.

check_group

    Type:    boolean
    Default: false

    The group owner of the file is checked only when this option is set.
    The default setting is unset because the default file mode is 0600,
    which means that the group is irrelevant.

create_directory

    Type:    boolean
    Default: true

    See the directory option below.

create_file

    Type:    string
    Default: "anywhere"

    This option constrains the location of files that are created by this
    transport. It must be set to one of the words 'anywhere', 'inhome', or
    'belowhome'. In the second and third cases, a home directory must have
    been set up for the address by the director that handled it. This
    option isn't useful when an explicit file name is given for normal
    mailbox deliveries; it is intended for the case when file names have
    been generated from user's .forward files, which are usually handled by
    an appendfile transport called address_file. See also file_must_exist.

current_directory                                                            |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    If this option is set, it specifies the directory to make current when   |
    running the delivery process. The string is expanded at the time the     |
    transport is run. See chapter 12 for details of the local delivery       |
    environment.                                                             |

delivery_date_add

    Type:    boolean
    Default: true

    If this option is true, a Delivery-date header is added to the message.
    This gives the actual time the delivery was made. As this is not a
    standard header, Exim has a configuration option (delivery_date_remove)
    which requests its removal from incoming messages, so that delivered
    messages can safely be resent to other recipients.

directory

    Type:    string
    Default: unset

    This option is mutually exclusive with the file option. If directory is
    set, the message is delivered into a new file in the given directory
    (whose name is expanded), instead of being appended to a single mailbox
    file. The file names created in the directory all start with the letter
    'q' for compatibility with smail. Messages are written using a tempor-
    ary name, and then renamed when complete. For example, when delivering
    messages into files using the bsmtp option (see section 43.10 for more
    details) a setting such as

      directory = /var/bsmtp/${host}

    might be used. If the create_directory option is set (the default), an
    attempt is made to create the directory if it does not exist; if it is
    created then its mode is given by the directory_mode option. If
    creation fails, or if the create_directory option is not set, then the
    delivery is just deferred. No locking is performed while writing the
    message, as each delivery creates a new file, so the various locking
    options of the transport are ignored.

directory_mode

    Type:    integer
    Default: 0700

    See the directory option above.

envelope_to_add

    Type:    boolean
    Default: true

    If this option is true, an Envelope-to header is added to the message.
    This gives the original address(es) in the incoming envelope that
    caused this delivery to happen. More than one address may be present if  |
    batch or bsmtp is set. As this is not a standard header, Exim has a      |
    configuration option (envelope_to_remove) which requests its removal
    from incoming messages, so that delivered messages can safely be resent
    to other recipients.

file

    Type:    string
    Default: unset

    This option need not be set when appendfile is being used to deliver to
    files whose names are obtained from forwarding, filtering, or aliasing
    address expansions (usually under the instance name address_file). In
    other cases, the option must be set unless the directory option is set.
    The string is expanded for each delivery, and must yield an absolute
    path. If the expansion contains a reference to the local_part variable,
    this is checked to ensure that it does not contain a '/' character - to
    prevent an unexpected change of directory. The most common settings of
    this option are variations on one of these examples:

      file = /var/spool/mail/${local_part}
      file = /home/${local_part}/inbox
      file = ${home}/inbox

    In the first example, all deliveries are done into the same directory.   |
    If Exim is configured to use lock files (see use_lockfile below) it      |
    must be able to create a file in the directory, so the 'sticky' bit      |
    must be turned on for deliveries to be possible. If you are using more   |
    than one host to deliver over NFS into the same mailboxes, you should    |
    always use lock files.                                                   |

    If there is no file name, or the expansion fails, or a local part
    contains a '/' character, a delivery error occurs.

file_must_exist

    Type:    boolean
    Default: false

    If this option is true, the file specified by the file option must
    exist, and an error occurs if it does not. Otherwise, it is created if
    it does not exist.

from_hack

    Type:    boolean
    Default: true

    If this option is true, lines in the body of the message that start
    with the string 'From ' are modified by adding the character '>' at
    their start. This is necessary for traditional BSD-format mailboxes,
    where such lines might otherwise indicate the start of a new message.

group

    Type:    string
    Default: unset

    If this option is set, it specifies the group under whose gid the
    delivery process is to be run. If it is not set, a value associated
    with a user may be used (see below); otherwise a value must have been
    associated with the address by the director which handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

lock_interval

    Type:    time
    Default: 3s

    This specifies the time to wait between attempts to lock the file. See
    below for details of locking.

lock_retries

    Type:    integer
    Default: 10

    This specifies the maximum number of attempts to lock the file. A value
    of zero is treated as 1. See below for details of locking.

lockfile_mode

    Type:    integer
    Default: 0600

    This specifies the mode of the created lock file, when a lock file is
    being used (see use_lockfile).

lockfile_timeout

    Type:    time
    Default: 30m

    When a lock file is being used (see use_lockfile), if a lock file
    already exists and is older than this value, it is assumed to have been
    left behind by accident, and Exim attempts to remove it.

mode

    Type:    integer
    Default: 0600

    If the output file is created, it is given this mode. If it already
    exists and has wider permissions, they are reduced to this mode. If it
    has narrower permissions, an error occurs. However, if the delivery is
    the result of a save command in a filter file specifing a specific
    mode, then the mode of the output file is always forced to take that
    value, and this option is ignored.

notify_comsat

    Type:    boolean
    Default: false

    If this option is true, the comsat daemon is notified after every
    successful delivery to a user mailbox. This is the daemon that notifies
    logged on users about incoming mail.

prefix

    Type:    string
    Default: see below

    The string specified here is expanded and output at the start of every
    message. The default is

      prefix = "From ${if def:return_path{$return_path}{MAILER-DAEMON}}\
        ${tod_bsdinbox}\n"

quota                                                                        |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option imposes a limit on the size of the file to which Exim is     |
    appending. The value is expanded, and must then be a numerical value     |
    (decimal point allowed), optionally followed by one of the letters K or  |
    M. The expansion happens while Exim is running as root or the Exim       |
    user, before setuid() is called for the delivery, so files that are      |
    inaccessible to the end user can be used to hold quota values that are   |
    looked up in the expansion. When delivery fails because this quota is    |
    exceeded, the handling of the error is as for system quota failures.     |
    The value specified is not accurate to the last byte, owing to           |
    separator lines and additional headers that may get added during the     |
    delivery.                                                                |

require_lockfile

    Type:    boolean
    Default: true

    When a lock file is being used (see use_lockfile) and require_lockfile
    is true, a lock file must be created before delivery can proceed. If
    the option is not true, failure to create a lock file is not treated as
    an error, though failure of the fcntl() locking function is. This
    option should always be set when delivering from more than one host
    over NFS.

retry_use_local_part                                                         |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    When a local delivery suffers a temporary failure, both the local part   |
    and the domain are normally used to form a key that is used to           |
    determine when next to try the address. This handles common cases such   |
    as exceeding a quota, where the failure applies to the specific local    |
    part. However, when local delivery is being used to collect messages     |
    for onward transmission by some other means, a temporary failure may     |
    not depend on the local part at all. Setting this option false causes    |
    Exim to use only the domain when handling retries for this transport.    |

return_path_add

    Type:    boolean
    Default: true

    If this option is true, a Return-path header is added to the message.
    Although the return path is normally available in the prefix line of
    BSD mailboxes, this is commonly not displayed by MUAs, and so the user
    does not have easy access to it.

    RFC 822 states that the Return-path header is 'added by the final
    transport system that delivers the message to its recipient' (section
    4.3.1), which implies that this header should not be present in
    incoming messages. Exim has a configuration option, return_path_remove,
    which requests removal of this header from incoming messages, so that
    delivered messages can safely be resent to other recipients.

suffix

    Type:    string
    Default: "\n"

    The string specified here is expanded and output at the end of every
    message.

use_lockfile

    Type:    boolean
    Default: true

    If this option is turned off, Exim does not attempt to create a lock
    file when appending to a file. Thus the only locking is by fcntl(). You
    should only turn use_lockfile off if you are absolutely sure that every
    MUA that is ever going to look at your users' mailboxes uses fcntl()
    rather than a lock file, and even then only when you are not delivering  |
    over NFS from more than one host. In order to append to an NFS file      |
    safely from more than one host, it is necessary to take out a lock       |
    before opening the file, and the lock file achieves this. Otherwise,     |
    even with fcntl() locking, there is a risk of file corruption. See also  |
    the require_lockfile option.

user

    Type:    string
    Default: unset

    If this option is set, it specifies the user under whose uid the
    delivery process is to be run. If it is not set, a value must have been
    associated with the address by the director that handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam(). When getpwnam() is used, either at start-up time or later,
    the group id value associated with the user is taken as the value to be
    used if the group option is not set.


14.1 Operational details

Before writing to a file, Exim proceeds as follows:

 .   If the name of the file is /dev/null, no action is taken, and a
     success return is given.

 .   If use_lockfile is set, a lock file is built in a way that will work    |
     reliably over NFS, as follows:                                          |
                                                                             |
      .   Create a 'hitching post' file whose name is that of the lock file  |
          with the current time, primary host name, and process id added,    |
          by opening for writing as a new file. If this fails with an        |
          access error, the message is frozen unless require_lockfile is     |
          false. Otherwise delivery is deferred.                             |
                                                                             |
      .   Close the hitching post file, and hard link it to the lock file    |
          name.                                                              |
                                                                             |
      .   If the call to link() succeeds, creation of the lock file has      |
          succeeded. Unlink the hitching post name.                          |
                                                                             |
      .   Otherwise, use stat() to get information about the hitching post   |
          file, and then unlink hitching post name. If the number of links   |
          is exactly two, creation of the lock file succeeded but something  |
          (e.g. an NFS server crash and restart) caused this fact not to be  |
          communicated to the link() call.                                   |
                                                                             |
      .   If creation of the lock file failed, wait for lock_interval and    |
          try again, up to lock_retries times. However, since any program    |
          that writes to a mailbox should complete its task very quickly,    |
          it is reasonable to time out old lock files that are normally the  |
          result of user agent and system crashes. If an existing lock file  |
          is older than lockfile_timeout Exim attempts to unlink it before   |
          trying again.                                                      |
                                                                             |
 .   A call is made to lstat() to discover whether the file exists, and if
     so, what its characteristics are. If lstat() fails for any reason
     other than non-existence, delivery is deferred.

 .   If the file does exist and is a symbolic link, delivery is deferred
     and the message is frozen, unless the allow_symlinks option is set, in
     which case the ownership of the link is checked, and then stat() is
     called to find out about the real file, which is then subjected to the
     checks below. The check on the top-level link ownership prevents one
     user creating a link for another's mailbox in a sticky directory,
     though allowing symbolic links in this case is definitely not a good
     idea. If there is a chain of symbolic links, the intermediate ones are
     not checked.

 .   If the file already exists but is not a regular file, or if the file's
     owner and group (if the group is being checked - see check_group
     above) are incorrect, delivery is deferred, and the message is frozen.

 .   If the file's permissions are more generous than specified, they are
     reduced. If they are insufficient, delivery is deferred, and the
     message is frozen.

 .   The file's inode number is saved, and it is then opened for appending.
     If this fails because the file has vanished, appendfile behaves as if
     it hadn't existed (see below). If the open failure is EWOULDBLOCK,
     just defer delivery; otherwise defer and freeze the message.

 .   If the file is opened successfully, check that the inode number hasn't
     changed, that it is still a regular file, and that the owner and
     permissions have not changed. If anything is wrong, defer and freeze
     the message.

 .   If the file did not exist originally, defer delivery and freeze the
     message if the file_must_exist option is set. Otherwise, check that
     the file is being created in a permitted directory if the create_file
     option is set (deferring and freezing on failure), and then open for
     writing as a new file, with the O_EXCL and O_CREAT options, except
     when dealing with a symbolic link (the allow_symlinks option must be
     set). In this case, which can happen if the link points to a non-
     existent file, the file is opened for writing using O_CREAT but not
     O_EXCL, because that prevents link following.

 .   If opening fails because the file exists, obey the tests given above
     for existing files. However, to avoid looping in a situation where the
     file is being continuously created and destroyed, the exists/not-
     exists loop is broken after 10 repetitions, and the message is then
     frozen.

 .   If opening fails with any other error, defer delivery.

Once the file is open, it is locked using fcntl(). If this fails, the file   |
is closed, Exim waits for lock_interval and then goes back and re-opens it   |
as above and tries again to lock it with fcntl(). This happens up to         |
lock_retries times, after which the delivery is deferred.                    |
                                                                             |
At the end of delivery, Exim closes the file (which releases the fcntl()     |
lock) and then deletes the lock file, if one was created.                    |



                        15. THE AUTOREPLY TRANSPORT


The autoreply transport is not a true transport in that it does not cause
the message to be transmitted. Instead, it generates another mail message,
usually as the result of mail filtering. A traditional 'vacation' message
is the standard example.

Autoreply is implemented as a local transport so that it runs under the uid
and gid of the local user and with appropriate current and home directories
(see chapter 12). The parameters of the message to be sent can be specified
in the configuration by the options described below, but in the common case
when autoreply is activated as a result of filtering, none of them are
normally set, because all the information is obtained from the filter file.

In an attempt to reduce the possibility of message cascades, messages
created by the autoreply transport always take form of delivery error
messages. That is, the envelope sender field is empty.

There is a subtle difference between directing a message to a pipe
transport that generates some text to be returned to the sender, and
directing it to an autoreply transport. This difference is noticeable only
if more than one address from the same message is so handled. In the case
of a pipe, the separate outputs from the different addresses are gathered
up and returned to the sender in a single message, while if autoreply is
used, a separate message is generated for each address passed to it.

The private options of the autoreply transport that describe the message     |
are used only when the address passed to it does not contain any reply       |
information. Thus the message is specified entirely by the director or by    |
the transport; it is never built from a mixture of options. The remaining    |
options (file_optional, group, initgroups, mode, return_message, and user)   |
apply in all cases.                                                          |

bcc

    Type:    string
    Default: unset

    Specifies the addresses that are to receive 'blind carbon copies' of
    the message when the message is specified by the transport. The string
    is expanded.

cc

    Type:    string
    Default: unset

    Specifies recipients of the message and the contents of the Cc header
    when the message is specified by the transport. The string is expanded.

file

    Type:    string
    Default: unset

    The contents of the file are sent as the body of the message when the
    message is specified by the transport. The string is expanded. If both
    file and text are set, the text string comes first.

file_expand

    Type:    boolean
    Default: false

    If this is set, the contents of the file named by the file option are
    subjected to string expansion as they are added to the message.

file_optional

    Type:    boolean
    Default: false

    If this option is true, no error is generated if the file named by the
    file option does not exist or cannot be read.

from

    Type:    string
    Default: unset

    The contents of the From header when the message is specified by the
    transport. The string is expanded.

group

    Type:    string
    Default: unset

    If this option is set, it specifies the group under whose gid the
    delivery process is to be run. If it is not set, a value associated
    with a user may be used (see below); otherwise a value must have been
    associated with the address by the director which handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

headers

    Type:    string
    Default: unset

    Specified additional RFC 822 headers that are to be added to the
    message when the message is specified by the transport. The string is
    expanded. Several can be given by using \n to separate them. There is
    no check on the format.


initgroups

    Type:    boolean
    Default: false

    If this option is true and the uid is provided by the transport, then
    the initgroups() function is called when running the transport to
    ensure that any additional groups associated with the uid are set up.
    By default no additional groups are present.

log

    Type:    string
    Default: unset

    This option names a file in which a record of every message sent is
    logged when the message is specified by the transport. The string is
    expanded.

mode

    Type:    integer
    Default: 0600

    If either the log file or the 'once' file has to be created, this mode
    is used.

once

    Type:    string
    Default: unset

    This option names a DBM database in which a record of each recipient is
    kept when the message is specified by the transport. The string is
    expanded. If a potential recipient is already in the database, no
    message is sent.

return_message

    Type:    boolean
    Default: false

    If this is set, a copy of the original message is returned with the new
    message, subject to the maximum size set in the return_size_limit
    general configuration option.

subject

    Type:    string
    Default: unset

    The contents of the Subject header when the message is specified by the
    transport. The string is expanded.

text

    Type:    string
    Default: unset

    This specifies a single string to be used as the body of the message
    when the message is specified by the transport. The string is expanded.
    If both text and file are set, the text comes first.

to

    Type:    string
    Default: unset

    Specifies recipients of the message and the contents of the To header
    when the message is specified by the transport. The string is expanded.

user

    Type:    string
    Default: unset

    If this option is set, it specifies the user under whose uid the
    delivery process is to be run. If it is not set, a value must have been
    associated with the address by the director that handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam(). When getpwnam() is used, either at start-up time or later,
    the group id value associated with the user is taken as the value to be
    used if the group option is not set.



                          16. THE DEBUG TRANSPORT


The debug transport is provided for debugging purposes only. It has no
options and is not normally referenced in a configuration file. It is
recommended that Exim normally be built without including this code.

The debug transport is used when the configuration option debug_transport
is set. It gets called instead of the real transport for all deliveries,
both local and remote, so no real mail delivery takes place. Instead, the
debug transport appends information about the message and a copy of the
message itself to the file named by the debug_transport option. No locking
is used.

The file must be writeable by Exim at the time of delivery. For intercepted
local deliveries this means it must be writeable by the relevant user,
while for intercepted remoted deliveries it must be writeable by the Exim
user, if one is defined.



                           17. THE PIPE TRANSPORT


The pipe transport is used to deliver messages via a pipe to a command
running in another process. This can happen when an address is expanded via
an alias, filter, or forward file, or when a director explicitly directs
the message to a pipe transport. The pipe transport can also be used via a
router as a pseudo-remote transport for passing messages for remote
delivery by some means other than Exim.

As pipe is a local transport, it is always run in a separate process,
normally under a non-privileged uid and gid. In the common case, these are
the uid and gid belonging to the user whose .forward file directed the
message at a pipe. However, in other cases the uid and gid may be specified
explicitly. Current and 'home' directories are also controllable. See
chapter 12 for details of the local delivery environment.


17.1 Returned status and data

If the command exits with a non-zero return code, the delivery is deemed to  |
have failed, unless either the ignore_status option is set (in which case    |
the return code is treated as zero), or the return code is EX_TEMPFAIL,      |
which is interpreted as meaning 'try again later'. Many Unix systems define  |
EX_TEMPFAIL in sysexits.h, and they all seem to use a value of 75. For       |
those systems that don't have EX_TEMPFAIL, Exim assumes that a value of 75   |
has this meaning.                                                            |
                                                                             |
The return_output option can affect the result of a pipe delivery. If it is  |
set and the command produces any output, it is considered to have failed,    |
even if it gave a zero return code or if ignore_status is set. The output    |
from the command is sent as part of the delivery failure report. However,    |
if return_fail_output is set, output is returned only when the command       |
exits with a failure return code, that is, a value other than zero or        |
EX_TEMPFAIL.                                                                 |


17.2 How the command is run

The command line is broken down into a command name and arguments by the     |
pipe transport. The restrict_to_path option can be used to restrict the      |
commands that may be run. Unquoted arguments are delimited by white space;   |
in double-quoted arguments, backslash is interpreted an escape character in  |
the usual way. This does not happen for single-quoted arguments.             |
                                                                             |
String expansion is applied to the command line except when it comes from a  |
traditional .forward file (commands from a filter file are expanded). The    |
expansion is applied to each argument in turn rather than to the whole       |
line. Thus the number of arguments cannot be changed as a result of string   |
expansion, and quotes or backslashes in inserted variables do not interact   |
with external quoting.                                                       |
                                                                             |
Special handling takes place when an argument consists precisely of the      |
text $pipe_addresses. This is not a general expansion variable; the only     |
place this string is recognized is when it appears as an argument for a      |
pipe command. It causes each address that is being handled to be inserted    |
in the argument list at that point as a separate argument. This avoids any   |
problems with spaces or shell metacharacters, and is of use when a pipe      |
transport is handling groups of addresses in a batch (see the batch option   |
below).                                                                      |

The resulting command is then run directly from the transport. It is not
run under a shell. This lessens the security risks in cases when a command
from a user's filter file is built out of data that was taken from an
incoming message. If a shell is required, it can of course be explicitly
specified as the command to be run.


17.3 Environment variables

The following environment variables are set up when the command is invoked:

  DOMAIN               the local domain of the address
  HOME                 the 'home' directory - see below
  HOST                 the host name when called from a router
  LOCAL_PART           see below
  LOGNAME              see below
  MESSAGE_ID           the message's id
  PATH                 as specified by the path option below
  QUALIFY_DOMAIN       the configured qualification domain
  SENDER               the sender of the message
  SHELL                /bin/sh
  USER                 see below

When a pipe transport is called directly from (for example) a smartuser
director, then LOCAL_PART is set to the local part of the address. When it
is called as a result of a forward or alias expansion, LOCAL_PART is set to
the local part of the address that was expanded. LOGNAME and USER are set
to the same value as LOCAL_PART for compatibility with other MTAs.

HOST is set only when a pipe transport is called from a router as a pseudo-
remote transport (e.g. for handling batched SMTP). It is set to the first
host name specified by the router (if any).

If the transport's home_directory option is set, then its value is used for
the HOME environment variable. Otherwise, certain directors may set a home
directory value, as described in chapter 12.


17.4 Private options

The private options of the pipe transport are as follows:

batch                                                                        |
                                                                             |
    Type:    string                                                          |
    Default: "none"                                                          |
                                                                             |
    Normally, each address that is directed or routed to a pipe transport    |
    is handled separately. In special cases it may be desirable to handle    |
    several addresses at once, for example, when passing a message with      |
    several addresses to a different mail regime (e.g. UUCP). If this        |
    option is set to the string 'domain', then all addresses with the same   |
    domain that are directed or routed to the transport are handled in a     |
    single delivery. If it is set to 'all' then multiple domains are         |
    batched. The list of addresses is included in the Envelope-to header if  |
    envelope_to_add is set (see below). The addresses can also be set up as  |
    separate arguments to the pipe command by means of the specially-        |
    recognized argument $pipe_addresses (see above). Otherwise, the only     |
    difference between this option and bsmtp is the inclusion of SMTP        |
    command lines in the output for bsmtp.                                   |
                                                                             |
batch_max                                                                    |
                                                                             |
    Type:    integer                                                         |
    Default: 100                                                             |
                                                                             |
    This limits the number of addresses that can be handled in a batch, and  |
    applies to both the batch and the bsmtp options.                         |

bsmtp

    Type:    string
    Default: "none"

    This option is used to set up a pipe transport as a pseudo-remote
    transport for delivering messages in batch SMTP format for onward
    transmission by some non-Exim means. The value of the option must be
    one of the strings 'none', 'one', 'domain', or 'all'. The first of
    these turns the feature off. A full description of the batch SMTP
    mechanism is given in section 43.10. When bstmp is set, the batch
    option automatically takes the same value.

command

    Type:    string
    Default: unset

    This option need not be set when pipe is being used to deliver to pipes
    obtained from address expansions (usually under the instance name
    address_pipe). In other cases, the option must be set, to provide a
    command to be run. It need not yield an absolute path (see the path
    option below). The command is split up into separate arguments by Exim,
    and each argument is separately expanded. Both single and double quotes
    are recognized. In double-quoted arguments, backslash is an escape
    character in the usual way. If a shell is required, it must be
    explicitly requested, as the command is not run under a shell by
    default.

current_directory                                                            |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    If this option is set, it specifies the directory to make current when   |
    running the delivery process. The string is expanded at the time the     |
    transport is run. If this is not set, the current directory is taken     |
    from data associated with the address. See chapter 12 for full details   |
    of the local delivery environment.                                       |

delivery_date_add

    Type:    boolean
    Default: false

    If this option is true, a Delivery-date header is added to the message.
    This gives the actual time the delivery was made. As this is not a
    standard header, Exim has a configuration option (delivery_date_remove)
    which requests its removal from incoming messages, so that delivered
    messages can safely be resent to other recipients.

directory

    Type:    string
    Default: unset

    This option was made obsolete by the introduction of the separate        |
    options current_directory and home_directory. If encountered, it is      |
    treated as synonymous with home_directory.                               |

envelope_to_add

    Type:    boolean
    Default: false

    If this option is true, an Envelope-to header is added to the message.
    This gives the original address(es) in the incoming envelope that
    caused this delivery to happen. More than one address may be present if  |
    batch or bsmtp is set. As this is not a standard header, Exim has a      |
    configuration option (envelope_to_remove) which requests its removal
    from incoming messages, so that delivered messages can safely be resent
    to other recipients.

from_hack

    Type:    boolean
    Default: false

    If this option is true, lines in the body of the message that start
    with the string 'From ' are modified by adding the character '>' at
    their start. This is necessary for traditional BSD-format mailboxes,
    where such lines might otherwise indicate the start of a new message.

group

    Type:    string
    Default: unset

    If this option is set, it specifies the group under whose gid the
    delivery process is to be run. If it is not set, a value associated
    with a user may be used (see below); otherwise a value must have been
    associated with the address by the director which handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

home_directory                                                               |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    If this option is set, its expanded value is used to set the HOME        |
    environment variable before running the command. This overrides any      |
    value that is set by the director. If no current directory is supplied   |
    by the director or the transport, the home directory value is used for   |
    that as well. See chapter 12 for details of the local delivery           |
    environment.                                                             |

ignore_status

    Type:    boolean
    Default: false

    If this option is true, the status returned by the subprocess that is
    set up to run the command is ignored, and Exim behaves as if zero had
    been returned. Otherwise, a non-zero status causes an error return from  |
    the transport unless the value is EX_TEMPFAIL, which causes the          |
    delivery to be deferred and tried again later.                           |


initgroups

    Type:    boolean
    Default: false

    If this option is true and the uid for the local delivery is specified   |
    by the user option, then the initgroups() function is called when        |
    running the transport to ensure that any additional groups associated
    with the uid are set up.

log_fail_output                                                              |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is set and the command returns any output and also ends   |
    with a return code that is neither zero nor EX_TEMPFAIL, the first line  |
    of output is written to the main log.                                    |
                                                                             |
log_output                                                                   |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is set and the command returns any output, the first      |
    line of output is written to the main log, whatever the return code.     |

max_output

    Type:    integer
    Default: 20K

    This specifies the maximum amount of output that the command may
    produce on its standard output. If the limit is exceeded, the process
    running the command is killed. This is intended as a safety measure to
    catch runaway processes. The limit is applied whether any return_output
    option is set or not. Because of buffering effects, the amount of
    output may exceed the limit by a small amount before Exim notices.

path

    Type:    string-list
    Default: "/usr/bin"

    This option specifies the string that is set up in the PATH environment
    variable of the subprocess. If the command option does not yield an
    absolute path name, the command is sought in the PATH directories, in
    the usual way.

pipe_as_creator

    Type:    boolean
    Default: false

    If user is not set and this option is true, then the delivery process
    is run under the uid that was in force when Exim was originally called
    to accept the message. If the group id is not otherwise set (via the
    group option above, or by the director that processed the address),
    then the gid that was in force when Exim was originally called to
    accept the message is used. Setting this option may be necessary in
    order to get some free-standing local delivery agents to work cor-
    rectly. Note, however, that the never_users configuration option
    overrides.

prefix

    Type:    string
    Default: see below

    The string specified here is expanded and output at the start of every
    message. The default is the same as for the appendfile transport,
    namely

      prefix = "From ${if def:return_path{$return_path}{MAILER-DAEMON}}\
        ${tod_bsdinbox}\n"

    This is required by the commonly-used /usr/ucb/vacation program.

restrict_to_path

    Type:    boolean
    Default: false

    When this option is set, the command name must contain no slashes. The
    command is searched for only in the directories listed in the path
    option. This option is intended for use in the case when a pipe command
    has been generated from user's .forward file. This is usually handled
    by an pipe transport called address_pipe.

retry_use_local_part                                                         |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    When a local delivery suffers a temporary failure, both the local part   |
    and the domain are normally used to form a key that is used to           |
    determine when next to try the address. This handles common cases such   |
    as exceeding a quota, where the failure applies to the specific local    |
    part. However, when local delivery is being used to collect messages     |
    for onward transmission by some other means, a temporary failure may     |
    not depend on the local part at all. Setting this option false causes    |
    Exim to use only the domain when handling retries for this transport.    |
                                                                             |
return_fail_output                                                           |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is true, and the command produced any standard output     |
    and ended with a return code other than zero or EX_TEMPFAIL, the output  |
    is returned in the delivery error message. However, if the message has   |
    a null sender (i.e. it is a delivery error message), output from the     |
    command is discarded.                                                    |

return_output

    Type:    boolean
    Default: false

    If this option is true, and the command produced any standard output,
    the delivery is deemed to have failed whatever the return code from the
    command, and the output is returned in the delivery error message.
    However, if the message has a null sender (i.e. it is a delivery error
    message), output from the command is discarded.

return_path_add

    Type:    boolean
    Default: false

    If this option is true, a Return-path header is added to the message.
    RFC 822 states that the Return-path header is 'added by the final
    transport system that delivers the message to its recipient' (section
    4.3.1), which implies that this header should not be present in
    incoming messages. Exim has a configuration option, return_path_remove,
    which requests removal of this header from incoming messages, so that
    delivered messages can safely be resent to other recipients.

suffix

    Type:    string
    Default: "\n"

    The string specified here is expanded and output at the end of every
    message. The default is the same as for the appendfile transport.

timeout

    Type:    time
    Default: 1h

    If the command fails to complete within this time, it is killed. This
    normally causes the delivery to fail.

umask

    Type:    integer
    Default: 022

    This specifies the umask setting for the subprocess that runs the
    command.

user

    Type:    string
    Default: unset

    If this option is set, it specifies the user under whose uid the
    delivery process is to be run. If it is not set, a value must have been
    associated with the address by the director that handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam(). When getpwnam() is used, either at start-up time or later,
    the group id value associated with the user is taken as the value to be
    used if the group option is not set.

The pipe transport can be used to pass all messages that require local
delivery to a separate local delivery agent such as procmail. When doing
this, care must be taken to ensure that the pipe is run under an
appropriate uid and gid. Typically one wants this to be a uid that is
trusted by the delivery agent to supply the correct sender of the message.
The following is an example transport and director configuration for
procmail:

  # transport
  procmail_pipe:
    driver = pipe;
    command = "/opt/local/bin/procmail -d ${local_part}",
    from_hack,
    user = exim

  # director
  procmail:
    driver = localuser,
    transport = procmail_pipe;

In this example, the pipe is run as the user exim, assuming that procmail
trusts that user.



                           18. THE SMTP TRANSPORT


The smtp transport delivers messages over TCP/IP connections using the SMTP
protocol. The list of hosts to try can either be taken from the address
that is being processed, or specified explicitly for the transport. Timeout
and retry processing (see chapter 30) is applied to each IP address
independently. The private options are as follows:

batch_max

    Type:    integer
    Default: 0

    This controls the maximum number of separate message deliveries that
    can take place over a single TCP/IP connection. If the value is zero,
    there is no limit.

    When a message has been successfully delivered over a TCP/IP connec-
    tion, Exim looks in its hints database to see if there are any other
    messages awaiting a connection to the same host. If there are, a new
    delivery process is started for one of them, and the current TCP/IP
    connection is passed on to it. The new process may in turn create yet
    another process. Each time this happens, a sequence counter is
    incremented, and if it ever gets to the (non-zero) batch_max value, no
    further messages are sent on the same TCP/IP connection.

    For testing purposes, this value can be overridden by the -oB command
    line option.

command_timeout

    Type:    time
    Default: 5m

    This sets a timeout for receiving a response to an SMTP command that
    has been sent out. It is also used when waiting for the initial banner
    line from the remote host. Its value must not be zero.

connect_timeout                                                              |
                                                                             |
    Type:    time                                                            |
    Default: 0s                                                              |
                                                                             |
    This sets a timeout for the connect() function, which sets up a TCP/IP   |
    call to a remote host. A setting of zero allows the system timeout       |
    (typically several minutes) to act. To have any effect, the value of     |
    this option must be less than the system timeout.                        |

data_timeout

    Type:    time
    Default: 5m

    This sets a timeout for the transmission of each block in the data
    portion of the message. As a result, the overall timeout for a message
    depends on the size of the message. Its value must not be zero.

delay_after_cutoff

    Type:    boolean
    Default: true

    This option controls what happens when all remote IP addresses for a
    given domain have been inaccessible for so long that they have passed
    their retry cutoff times.

    In the default state, if the next retry time has not been reached for
    any of them, the address is bounced without trying any deliveries. In
    other words, Exim delays retrying an IP address after the final cutoff
    time until a new retry time is reached, and can therefore bounce an
    address without ever trying a delivery, when machines have been down
    for a long time. Some people are unhappy at this prospect, so...

    If delay_after_cutoff is set false, Exim behaves differently. If all IP
    addresses are past their final cutoff time, then Exim tries to deliver
    to those IP addresses that have not been tried since the message
    arrived. If there are none, of if they all fail, the address is
    bounced. In other words, it does not delay when a new message arrives,
    but immediately tries those expired addresses that haven't been tried
    since the message arrived. If there is a continuous stream of messages
    for the dead hosts, unsetting delay_after_cutoff means that there will
    be many more attempts to deliver to them.

dns_qualify_single

    Type:    boolean
    Default: true

    If the hosts option is being used and names are being looked up in the
    DNS, then the option to cause the resolver to qualify single-component
    names with the local domain is set.

dns_search_parents

    Type:    boolean
    Default: true

    If the hosts option is being used and names are being looked up in the
    DNS, then the option to cause the resolver to search parent domains is
    set.

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 all the hosts
    for a particular address are failing, then Exim tries to deliver to the
    fallback hosts, in order. The resolution of the host names in this list
    is controlled by the gethostbyname(), mx_domains and non_mx_domains
    options, as for the hosts option. Fallback hosts apply both to cases
    when the host list comes with the address and when it is taken from
    hosts. This option provides a 'use a smart host only if delivery fails'
    facility.

final_timeout

    Type:    time
    Default: 10m

    This is the timeout that applies while waiting for the response to the
    final line containing just '.' that terminates a message. Its value
    must not be zero.

gethostbyname

    Type:    boolean
    Default: false

    If this option is true when the hosts and/or fallback_hosts options are
    being used, names are looked up using gethostbyname() instead of using
    the DNS. Of course, gethostbyname() may in fact use the DNS, but it
    does not do any MX processing.

hosts

    Type:    string-list
    Default: unset

    This option specifies a list of host names and/or IP addresses which
    are used if the address being processed does not have any hosts
    associated with it. The string is first expanded, before being
    interpreted as a colon-separated host list. The names are looked up
    either in the DNS or using gethostbyname(), depending on the other
    options. This option is typically used in association with a smartuser
    director that wants to direct messages to a particular host or hosts.
    The given hosts are tried in order, subject to their retry status. This
    option is ignored when the address has been routed by a router that
    supplies a host list (e.g. lookuphost).

max_rcpt                                                                     |
                                                                             |
    Type:    integer                                                         |
    Default: 100                                                             |
                                                                             |
    This option limits the number of RCPT TO commands that are sent in a     |
    single SMTP message transaction. Each set of addresses is treated        |
    independently, and so can cause parallel connections to the same host    |
    if remote_max_parallel permits this.                                     |

multi_domain

    Type:    boolean
    Default: true

    When this option is set, the smtp transport can handle a number of
    addresses containing a mixture of different domains provided they all
    resolve to the same list of hosts. Turning the option off restricts the
    transport to handling only one domain at once. This is useful if you
    want to use $domain in an expansion for the transport, because it is
    set only when there is a single domain involved in a remote delivery.

mx_domains

    Type:    domain-list
    Default: unset

    If the hosts or fallback_hosts options are being used and names are
    being looked up in the DNS, then if the host name is in this list but
    not in non_mx_domains, it is required to have an MX record.

non_mx_domains

    Type:    domain-list
    Default: unset

    See mx_domains above.

serialize_hosts                                                              |
                                                                             |
    Type:    host-list                                                       |
    Default: unset                                                           |
                                                                             |
    Because Exim operates in a distributed manner, if several messages for   |
    the same host arrive at around the same time, more than one simulta-     |
    neous connection to the remote host can occur. This is not usually a     |
    problem except when there is a slow link between the hosts. In that      |
    situation it may be helpful to restrict Exim to one connection at a      |
    time. This can be done by setting serialize_hosts or serialize_nets to   |
    match the relevant hosts.                                                |
                                                                             |
    Exim implements serialization by means of a hints database in which a    |
    record is written whenever a process connects to one of the restricted   |
    hosts, and deleted when the the connection is completed. Obviously       |
    there is scope for records to get left lying around if there is a        |
    system or program crash. To guard against this, Exim ignores any         |
    records that are more than 6 hours old.                                  |
                                                                             |
    However, if you set up any serialization, you should also arrange to     |
    delete the hints database whenever your system reboots. The names of     |
    the files all start with serialize-<transport name> and they are kept    |
    in the spool/db directory. There may be one or two files, depending on   |
    the type of DBM in use.                                                  |
                                                                             |
serialize_nets                                                               |
                                                                             |
    Type:    net-list                                                        |
    Default: unset                                                           |
                                                                             |
    See serialise_hosts above.                                               |

service

    Type:    string
    Default: "smtp"

    This option specifies the TCP/IP port that is used to send the message.
    If it begins with a digit it is taken as a port number; otherwise it is
    looked up using getservbyname().



                        19. GENERIC DIRECTOR OPTIONS


The following generic options apply to all directors.

domains

    Type:    domain-list
    Default: unset

    If this option is set, then the director is skipped unless the current
    domain matches one of the entries in the list. If both domains and
    except_domains are set, the driver is run only if the domain matches
    domains and does not match except_domains.

driver

    Type:    string
    Default: unset

    This option must always be set. It specifies the name of the director
    driver.

except_domains

    Type:    domain-list
    Default: unset

    If this option is set, then the director is skipped if the domain
    matches anything in the list. If both domains and except_domains are
    set, the director is run only if the domain matches domains and does
    not match except_domains.

except_local_parts

    Type:    string-list
    Default: unset

    If this option is set, then the director is skipped if the local part
    matches anything in the list, which is tested in the same way as a
    domain list, and may therefore contain file lookups. If both
    local_parts and except_local_parts are set, the director is run only if
    the local part matches local_parts and does not match
    except_local_parts.

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_sender                                                           |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is true and an address is accepted by this director when  |
    verifying a sender, then verification fails. This option has no effect   |
    if the verify_sender option is false.                                    |
                                                                             |
fail_verify_recipient                                                        |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is true and an address is accepted by this director when  |
    verifying a recipient, then verification fails. This option has no       |
    effect if the verify_recipient option is false.                          |

local_parts

    Type:    string-list
    Default: unset

    If this option is set, the director is run only if the local part of
    the address matches an item in the list, which is tested in the same
    way as a domain list and may therefore include file lookups. You might
    use it, for example, if you have a large number of 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:
        local_parts = postmaster,
        driver = smartuser;
        new_address = postmaster@real.dom.ain

    If both local_parts and except_local_parts are set, the director is run
    only if the local part matches local_parts and does not match
    except_local_parts.

more

    Type:    boolean
    Default: true

    If this option is false, then if the director fails to match a local
    part, no further directors are tried, and direction fails. This applies
    even in the case of address verification where the director was not run
    because the verify option was off.

prefix

    Type:    string-list
    Default: unset

    If this option is set, the director is skipped unless the local part
    starts with one of the given strings, or the prefix_optional option is
    true. 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 chapter 38.

    While the director is running, the prefix is removed from the local
    part, and is available in the expansion variable local_part_prefix. If
    the director succeeds, 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
    director like this one immediately before the director that handles
    .forward files:

      real_localuser:
        driver = localuser,
        transport = local_delivery,
        prefix = real-;

    If both prefix and suffix are set for a director, 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 director. Different separator
    characters must be used to avoid ambiguity.

prefix_optional

    Type:    boolean
    Default: false

    See prefix above.

require_files

    Type:    string-list
    Default: unset

    The value of this option is first expanded and then interpreted as a
    colon-separated list of strings. If this option is used on a localuser
    director, or on a forwardfile director that has either of the
    check_local_user or directory options set, then the expansion variable
    home may appear in the list, referring to the home directory of the
    user whose name is that of the local part of the address.

    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 director 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 provides a general mechanism for predicating the running of
    a director on the existence or non-existence of certain files or
    directories. A failure to expand the string, or the presence of a non-
    fully-qualified path within it causes a panic error.

suffix

    Type:    string-list
    Default: unset

    This option operates in the same way as prefix, except that the local
    part must end (rather than start) with the given string, the
    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.

suffix_optional

    Type:    boolean
    Default: false

    See suffix above.

transport

    Type:    string
    Default: unset

    The string must be the name of a configured transport instance. For
    some directors a transport does not make sense, and in those cases it
    is a configuration error to supply one.

unseen

    Type:    boolean
    Default: false

    Setting this option has a similar effect to the unseen command
    qualifier in filter files. It causes an address to be passed on to
    subsequent directors, even if the current director succeeds in handling
    it, and can be used to cause copies of messages to be delivered
    elsewhere.

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 director is used only when verifying an       |
    address, not when actually doing a delivery. It can be further           |
    restricted to verifying only senders or recipients by means of           |
    verify_sender and verify_recipient.                                      |
                                                                             |
verify_sender                                                                |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    If this option is false, then this director is skipped when verifying    |
    sender addresses. It is usual to set it false for instances of the       |
    smartuser director.                                                      |
                                                                             |
verify_recipient                                                             |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    If this option is false, then this director is skipped when verifying    |
    recipient addresses. It is usual to set it false for instances of the    |
    smartuser director.                                                      |

                                                                             |
19.1 Skipping directors                                                      |
                                                                             |
A number of the generic options can cause directors to be skipped for        |
particular cases. They interact with each other in the following way:        |
                                                                             |
If the domain and local part are not in agreement with domains,              |
except_domains, except_local_parts and local_parts (when set), or if         |
verify_only is set and verification is not happening, then the director is   |
skipped and the next one is tried. None of the other options is inspected.   |
                                                                             |
Otherwise, if the more option is not set, no subsequent directors are ever   |
called, in any circumstances. The current director is itself called unless   |
                                                                             |
 .   Verification is happening and its verify_sender or verify_recipient     |
     option (as appropriate) is turned off, or                               |

 .   There is a prefix or suffix mismatch, or

 .   The existence or non-existence of files listed in the require_files
     option is not as expected.

The unseen option causes directing to continue when it would otherwise       |
cease, the complementary action to no_more, which causes it to cease when    |
it would otherwise continue.                                                 |
                                                                             |
The verify, fail_verify, and verify_only options make it possible to         |
separate those local parts which correspond to a real local delivery from    |
those which are recognized, but which do something else if actually          |
encountered in a message.                                                    |
                                                                             |
For example, a smartuser director might be used to pass all unrecognized     |
local parts to a script that tries to generate a helpful error message, or   |
to a different machine that might be able to handle them. This means that    |
no local part will ever cause a delivery failure. However, if (for example)  |
verification of senders is taking place (the sender_verify main configur-    |
ation option), you probably don't want <random-local-part@your.domain> to    |
be accepted. The solution is to set no_verify or no_verify_sender on the     |
smartuser director.                                                          |
                                                                             |
On our systems in Cambridge we keep a list of users whose accounts have      |
been cancelled, and their mail is piped to a script which sends back a more  |
helpful message than 'user unknown'. Verification of such local parts        |
should fail, but just setting no_verify on the director doesn't work,        |
because the local part is then passed to a localuser director that may       |
still find it in the password file. (Initially, cancellation just resets     |
the password.) This is the sort of case for which fail_verify was invented.  |
It makes it possible to fail an explicit list of local parts.                |
                                                                             |
                                                                             |

                         20. THE ALIASFILE DIRECTOR                          |
                                                                             |

The aliasfile director expands local parts by consulting a file of aliases.  |
The expansion may safely contain the same local part, because a director is  |
automatically skipped if any ancestor of a local part has the same name and  |
was processed by that director.                                              |
                                                                             |
The alias file can be a text file that is searched linearly, or it may be a  |
DBM direct-access database, or it can be a NIS map. Alternatively, a NIS+    |
query can be used. The case of letters is not significant in searches. The   |
exim_dbmbuild utility can be used to convert a text file into a DBM          |
database; the keys are lower-cased by this process.                          |
                                                                             |
                                                                             |
20.1 Alias file format                                                       |
                                                                             |
A textual alias file to be searched linearly consists of entries that start  |
with the alias name, terminated by a colon. The remainder of the entry       |
consists of a list of addresses, file names, or pipe commands, which can be  |
continued onto several lines by starting each of the continuation lines      |
with white space. The addresses are separated by commas or newlines.         |
                                                                             |
Lines starting with a # character are comments, and are ignored, and # may   |
also appear in a white space position, in which case everything between #    |
and the end of the line is ignored.                                          |
                                                                             |
Other forms of alias file (DBM, NIS) involve lookups using the local part    |
as a key on files and databases that return a list of address, file, or      |
pipe items separated by commas or newlines.                                  |
                                                                             |
                                                                             |
20.2 Types of alias item                                                     |
                                                                             |
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 quotes.                                                   |
                                                                             |
An item is interpreted as a file name if it begins with '/' and does not     |
parse as a valid RFC 822 address that includes a domain. For example,        |
                                                                             |
  /home/world/minbari                                                        |
                                                                             |
is treated as a file name, but                                               |
                                                                             |
  /s=molari/o=babylon/@x400gate.way                                          |
                                                                             |
is treated as an address.                                                    |
                                                                             |
An item is treated as a pipe command if it begins with '|' and does not      |
parse as a valid RFC 822 address that include a domain. Both single and      |
double quotes can be used for enclosing arguments to the pipe command; no    |
interpretation of escapes is done for single quotes.                         |
                                                                             |
An item of the form                                                          |
                                                                             |
  :include:<path name>                                                       |
                                                                             |
may also appear, in which case a list of further items is taken from the     |
given file and included at that point. These items are not subject to        |
expansion when the expand option is set.                                     |

Sometimes you want to throw away mail to a particular local part. An alias
entry with no addresses causes Exim to generate an error, so this cannot be
used. However, another special item that may appear in an alias file is

  :blackhole:

which does what its name implies. The delivery for the current address is
abandoned without further ado, and no error message is generated. This is
more efficient than directing a message to /dev/null as it happens at
directing time, and also there is no need to specify a user and group to
run the transport process, which are required when /dev/null is used.


20.3 Errors in alias files

If skip_syntax_errors is set, a malformed address that causes a parsing      |
error is skipped, and an entry is written in the main log. This may be       |
useful for mailing lists that are automatically managed, but note the        |
inherent danger. Otherwise, if an 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.


20.4 Specifying a transport

If a transport is specified for this director, then the message is directed
to that transport for any local part which is found in the file, any data
in the file that is associated with the local part being ignored. Thus the
same processing can be done for any local part that is listed in the file.
For example, a file containing a list of cancelled users can be used to
direct messages addressed to them to a particular script.


20.5 Aliasfile private options


current_directory                                                            |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option associates a current directory with any address that         |
    aliasfile directs to a local transport. This can happen either because   |
    a transport is explicitly configured for the director, or because it     |
    generates a delivery to a file or a pipe. The option string is expanded  |
    and is set as the current directory during the delivery process, unless  |
    overridden by a setting on the transport. See chapter 12 for details of  |
    the local delivery environment.                                          |
                                                                             |
directory                                                                    |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option is obsolete, having been replaced by current_directory and   |
    home_directory. If used, it sets the value of home_directory.            |

errors_to

    Type:    string
    Default: unset

    Delivery errors for any addresses generated by this director are sent
    to this address, if it is set and if it verifies as valid. Otherwise
    the address associated with the incoming address (normally the sender)
    are used. A typical use might be

      errors_to = "aliasmaster"

expand                                                                       |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is set true, then the text obtained by looking up the     |
    local part is passed through the string expansion mechanism before       |
    being interpreted as a list of alias items. Addresses that are           |
    subsequently added by means of the 'include' mechanism are not           |
    expanded.                                                                |

file

    Type:    string
    Default: unset

    This option specifies the name of the alias file, and it must be set if
    search_type specifies a single-key lookup; if it does not, an error
    occurs. (For query-style lookups, query must be set instead.) See
    chapter 6 for details of different lookup styles. The string is
    expanded before use; if expansion fails, Exim panics. The resulting
    string must be an absolute path for linear search and DBM lookups. If
    the original string does not start with '/' or '$' in these cases, Exim
    gives a configuration error when it starts up; otherwise, if an
    expanded string does not begin with '/' delivery is frozen.

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.

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.

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.

group

    Type:    string
    Default: unset

    If a file or pipe delivery is generated by this director, and the
    transport does not specify a user and group, then the user and group
    given here are used when running the delivery process. If the string
    contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the director is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

home_directory                                                               |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option associates a home directory with any address that aliasfile  |
    directs to a local transport. This can happen either because a           |
    transport is explicitly configured for the director, or because it       |
    generates a delivery to a file or a pipe. The option string is expanded  |
    and is set as the home directory during the delivery process, unless     |
    overridden by a setting on the transport. See chapter 12 for details of  |
    the local delivery environment.                                          |


initgroups

    Type:    boolean
    Default: false

    If a file or pipe delivery is generated by this director, and this
    option is true, and the user option is set, then the initgroups()
    function is called when running the transport to ensure that any
    additional groups associated with the uid are set up.

modemask

    Type:    integer
    Default: 022

    This specifies mode bits which must not be set for the alias file. If
    they are set, the director fails and the message is frozen.

optional

    Type:    boolean
    Default: false

    If the file cannot be opened because it does not exist (the ENOENT
    error) and this option is set, the director simply fails to match the
    address. Otherwise any failure to open the file causes an entry to be
    written to the log and delivery to be deferred.

owners

    Type:    string-list
    Default: unset

    This specifies a list of permitted owners for the alias file. If it is
    unset, no check on the ownership is done. If the file is not owned by a
    user in the list, the director fails and the message is frozen.

owngroups

    Type:    string-list
    Default: unset

    This specifies a list of permitted groups for the alias file. If it is
    unset, no check on the file's group is done. If the file's group is not
    in the list, the director fails and the message is frozen.

query

    Type:    string
    Default: unset

    This option specifies a database query, and it must be set if
    search_type specifies a query-style lookup; if it does not, an error
    occurs. (For single-key lookups, file must be set instead.) See chapter
    6 for details of different lookup styles. The query is expanded before
    use, and would normally contain a reference to the local part. For
    example,

      query = "[alias=${local_part}],mail-aliases.org_dir:expansion"

    could be used for a NIS+ lookup.

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.                                                               |

search_type

    Type:    string
    Default: unset

    This option must be set to one of the strings 'lsearch', 'dbm', 'nis',
    'nis0', or 'nisplus', specifying the type of data lookup. When the
    setting is 'nisplus', the query option specifies the search query, and
    file must not be set. For the other search types, file is required and
    query must not be set. See chapter 6 for details of the different
    lookup styles.

skip_syntax_errors                                                           |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If skip_syntax_errors is set, a malformed address that causes a parsing  |
    error is skipped, and an entry is written in the main log. This may be   |
    useful for mailing lists that are automatically managed, but note the    |
    inherent danger.                                                         |

user

    Type:    string
    Default: unset

    When a file or pipe delivery is generated by this director, and the
    transport does not specify a user and group, then the user and group
    given here are used when running the delivery process. If the string
    contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the director is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam().



                        21. THE FORWARDFILE DIRECTOR


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 39.

The list of new addresses may safely contain the same local part as the one
currently under consideration, because a director is automatically skipped
if any ancestor has the same local part and was processed by that director.
Thus a user with login name spqr who wants to preserve a copy of mail and
also forward it somewhere else can set up a file such as

  spqr, spqr@reme.xx

without provoking a loop. A backslash before an unqualified local part is
permitted for compatibility with other mailers, but causes an error if it
appears before a qualified address. Care must be taken if there are alias
names for local users. For example if the system alias file contains

  Sam.Reman: spqr

then

  Sam.Reman, spqr@reme.xx

in spqr's forward file fails on an imcoming message addressed to Sam.Reman,
because the aliasfile director does not process Sam.Reman the second time
round.

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.


21.1 Forward file items

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 821 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 quotes.

An item is interpreted as a file name if it begins with '/' and does not
parse as a valid RFC 822 address that includes a domain. For example,

  /home/world/shadow

is treated as a file name, but

  /s=molari/o=babylon/@x400gate.way

is treated as an address.

An item is treated as a pipe command if it begins with '|' and does not
parse as a valid RFC 822 address that include a domain. Both single and
double quotes can be used for enclosing arguments to the pipe command; no
interpretation of escapes is done for single quotes.

Lines starting with a # character are comments, and are ignored, and # may
also appear in a white space position, in which case everything between #
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 different local parts, each of which
results in an expansion that generates an identical file name or pipe
command, two different deliveries occur, though of course the delivery
processes run with different values in the LOCAL_PART environment variable,
and with different uids (in the common case).

Instead of an address, file name, or pipe command, an item of the form

  :include:<path name>

may appear, in which case an 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:

 .   If the seteuid() function is being used to read the main file as a
     specific user (see seteuid below) then the included file is read as
     the same user.

 .   Otherwise Exim is running as root at this point. If check_local_user
     is set, or if an explicit directory is specified, then any included
     files must be within the home or given directory, and no symbolic
     links are permitted below the directory name.

 .   If neither check_local_user nor directory is set when seteuid() is not
     in use, then included files are not permitted.


21.2 Errors in forward files

If skip_syntax_errors is set, a malformed address that causes a parsing      |
error is skipped, and an entry is written in 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.


21.3 Filter files

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.


21.4 The home directory

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 check_local_user is set without file_directory, then the user's
     home directory is set in the home expansion variable when expanding
     the file option that specifies a forward or filter file.

 .   If file_directory is set without check_local_user, then the expanded
     value of file_directory is set in the home expansion variable when
     expanding the file option. If home appears in the string for
     file_directory, its substitution value is the empty string.

 .   If both check_local_user and file_directory are set, home in the
     string for file_directory is the user's home directory, but home in
     the file option is the expanded value of file_directory.

It is thus possible to specify

  file = ${home}/.forward

to look up .forward files without first statting the home directory to see
if it exists. This is not recommended if home directories are NFS mounted.

If the generic option require_files 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.


21.5 Forwardfile private options

A transport must not be specified for this director. A configuration error
occurs if one is given. The private options are:


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'.

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.

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 or pipe command. The option string is expanded and is set as the    |
    current directory during the delivery process, unless overridden by a    |
    setting on the transport. See chapter 12 for details of the local        |
    delivery environment.                                                    |
                                                                             |
directory                                                                    |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This is an obsolete name for the file_directory option.                  |

errors_to

    Type:    string
    Default: unset

    Delivery errors for any addresses generated by this director are sent
    to this address, if it is set and if it verifies as valid. Otherwise
    the address associated with the incoming address (normally the sender)
    are used.

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 must start with a '/' 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 inacessible, 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.                                                                |
                                                                             |
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                                                                  |
                                                                             |
      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.         |

filter

    Type:    boolean
    Default: false

    If this option is set, and the forwarding 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' User interface to mail filtering"; this is intended for use by
    end users.

    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.

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.

forbid_filter_log

    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.

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.

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.

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.

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.

group

    Type:    string
    Default: unset

    This option should be specified only in conjunction with the user
    option. If seteuid() is being used to read the file as a particular
    user, then this group is set using setegid() during that process,
    overriding any group that might have been obtained by check_local_user.

    Furthermore, if a file or pipe delivery is generated by this director,
    and the transport does not specify a user and group, then the user and
    group given in the director are used when running the delivery process.
    If the string contains no $ characters, it is resolved when Exim starts
    up. Otherwise, the string is expanded at the time the director is run,
    and must yield either a digit string or a name which can be looked up
    using getgrnam().

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, 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 12 for details of the local delivery        |
    environment. This option has no effect during the running of the         |
    forwardfile director.                                                    |


initgroups

    Type:    boolean
    Default: false

    If a file or pipe delivery is generated by this director, and this
    option is true, and user is set, then the initgroups() function is
    called when running the transport to ensure that any additional groups
    associated with the uid are set up. Also, if the forward file is read
    under a specific uid and gid, initgroups() is called after they have
    been set up.

modemask

    Type:    integer
    Default: 022

    This specifies mode bits which must not be set for the forward file. If
    they are set, the director fails and the message is frozen.

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.

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.

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.                                                               |

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 user and group options must be set. A configur-
    ation 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 to that of the local user
    before accessing the home directory and the file. This is necessary in
    two circumstances:

    (i)  When Exim is configured to change the effective uid from root to
         the Exim user (using seteuid()) while running the directors. See
         chapter 44 for details.

    (ii) When users' home directories are NFS mounted, and root access is
         not exported to the current machine, to allow for cases when the
         files are not world-readable.

    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 director-
    ies that do not export root, it is necessary for forward files to be
    world-readable.

skip_syntax_errors                                                           |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If skip_syntax_errors is set, a malformed address that causes a parsing  |
    error is skipped, and an entry is written in the main log. This may be   |
    useful for mailing lists that are automatically managed, but note the    |
    inherent danger. It should never be set for users' .forward files.       |

user

    Type:    string
    Default: unset

    If seteuid() is being used to read the file as a particular user, which
    happens when seteuid() is available in the operating system and either
    the seteuid option is set or the global security option is not set to
    'setuid', then this user is set during that process, overriding any
    user that might have been obtained by check_local_user. The user is
    also set during interpretation of a filter file; if it writes log
    entries the log file must be accessible to this user.

    In addition, when a file or pipe or auto-reply delivery is generated by
    this director, and the transport does not specify a user, then the user
    given here is used when running the delivery process. If the string
    contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the director is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam().



                         22. THE LOCALUSER DIRECTOR


The localuser director checks whether the local part of an address is the
login of a local user, by calling the getpwnam() function. If it is, and if
other conditions set by options are met, it accepts the address and sets up
a transport for it. The user's uid, gid, and home directory are set up by
default to be used while running the delivery process. The generic
transport option must always be specified.

The generic require_files option may contain references to $home when used
with this director. Thus it is possible to pick out all users with
particular files in their home directories and route their mail to a
specific transport. This could be used, for example, to check for a
.procmailrc file and then to route delivery via procmail if one is found.

current_directory                                                            |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option string is expanded and set as the current directory during   |
    the delivery process, unless overridden by a setting on the transport.   |
    See chapter 12 for details of the local delivery environment.            |

directory

    Type:    string
    Default: unset

    This is an obsolete name for the match_directory option. It was changed
    to avoid confusion with directory options in other drivers, which have
    a different kind of meaning.

home_directory                                                               |
                                                                             |
    Type:    string                                                          |
    Default: unset                                                           |
                                                                             |
    This option overrides the home directory that is obtained from the       |
    getpwnam() function. The string is expanded and set as the home          |
    directory during the delivery process, unless overridden by a setting    |
    on the transport. See chapter 12 for details of the local delivery       |
    environment.                                                             |

                                                                             |
initgroups                                                                   |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is true then the initgroups() function is called when     |
    running the transport to ensure that any additional groups associated    |
    with the uid are set up, provided the transport does not override the    |
    uid supplied by the director.                                            |


match_directory

    Type:    string
    Default: unset

    If this option is set, 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. This provides a way of partitioning the
    local users by home directory. The string is expanded before use if it
    contains any $ characters. If 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.

On central systems at Cambridge, when a user account is cancelled, it
remains in the password file for a while, with the home directory set to
/home/CANCELLED. We use the match_directory option to detect mail addressed
to such users and bounce it with an explanatory message.



                         23. THE SMARTUSER DIRECTOR


The smartuser director matches any local part, so it can be used to handle
local addresses that all other directors have failed. It is, of course,
subject to the generic director options, so specific instances can be used
for all addresses in certain domains, or all local parts with certain
prefixes or suffixes, or specific local parts.

Smartuser can generate a new address from the old one, and cause that to be
re-processed, or it can set a transport for the current address, optionally
changing the address. Common uses are to pipe the message to a script that
generates an information message to be returned to the sender, or to send
the message to another host for processing.


new_address

    Type:    string
    Default: unset

    This option specifies a new address, to replace the current one. It
    must be a qualified address (i.e. contain an '@' character). The string
    is expanded, and so settings such as

      new_address = ${local_part}@some.new.host

    can be used, or a file lookup on the local part can be done. If the
    generic transport option is not specified, this option is required, and
    the new address is processed by the directors and routers in the normal
    way. If a transport is specified, the new address just replaces the old
    one when the message is delivered.

panic_expansion_fail                                                         |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    If the expansion of new_address fails as a result of an explicit 'fail'
    item in an expansion sub-expression, the director just fails to handle
    the address. Otherwise, an expansion failure is treated as a serious
    configuration error, and causes a panic, unless this option is set
    false, in which case the same action is taken as for 'fail'.



                         24. GENERIC ROUTER OPTIONS


The following generic options apply to all the routers:

domains

    Type:    domain-list
    Default: unset

    If this option is set, then the router is skipped unless the current
    domain matches one of the entries in the list and does not match
    anything in except_domains. This can be used to reduce the use of an
    expensive router such as queryprogram by doing a preliminary
    plausibility check on the domain. Note that the current domain may
    change as routing proceeds, as routers may replace the original with
    other values.

driver

    Type:    string
    Default: unset

    This option must always be set. It specifies the name of the router
    driver.

except_domains

    Type:    domain-list
    Default: unset

    If this option is set, then the router is skipped if the domain matches
    anything in the list. If both domains and except_domains are set, the
    router is run only if the domain matches domains and does not match
    except_domains.

except_local_parts

    Type:    string-list
    Default: unset

    If this option is set, then the router is skipped if the local part
    matches anything in the list, which is tested in the same way as a
    domain list, and which may therefore contain file lookups. If both
    local_parts and except_local_parts are set, the router is run only if
    the local part matches local_parts and does not match
    except_local_parts.

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_sender                                                           |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is true and an address is accepted by this router when    |
    verifying a sender, then verification fails. This option has no effect   |
    if the verify_sender option is false.                                    |
                                                                             |
fail_verify_recipient                                                        |
                                                                             |
    Type:    boolean                                                         |
    Default: false                                                           |
                                                                             |
    If this option is true and an address is accepted by this router when    |
    verifying a recipient, then verification fails. This option has no       |
    effect if the verify_recipient option is false.                          |

local_parts

    Type:    string-list
    Default: unset

    If this option is set, the router is run only if the local part of the
    address matches an item in the list, which is tested in the same way as
    a domain list and which may therefore contain file lookups. If both
    local_parts and except_local_parts are set, the router is run only if
    the local part matches local_parts and does not match
    except_local_parts.

more

    Type:    boolean
    Default: true

    If this option is false, then if the router fails to match an address,
    no further routers are tried, and routing fails. This applies even in
    the case of address verification where the router was not run because
    the verify option was off.

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 instead
    passed on to the next router. This may be helpful for systems that are
    intermittently connected to the Internet.

require_files

    Type:    stringlist
    Default: unset

    The value of this option is first expanded and then interpreted as a
    colon-separated list of strings. 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. This provides a general
    mechanism for predicating the running of a router on the existence or
    non-existence of certain files or directories. A failure to expand the
    string, or the presence of a non-fully-qualified path within it causes
    a panic error. If the stat() function is unable to determine whether a
    file exists or not (for example, because of a missing NFS mount), then
    delivery is deferred.

self

    Type:    string
    Default: "freeze"

    This option specifies what is to happen if routing a remote address
    ends up pointing at the local host. Normally this indicates either an
    error in Exim's configuration (for example, the domain should be listed
    as local), or an error in the DNS (for example, the MX shouldn't point
    at this host). The default action is to freeze the message. The
    following alternatives are provided for use in special cases:

     .   defer
         Delivery of the message is tried again later.

     .   reroute: <domain>
         The domain is changed to the given domain, and the address is
         passed back to be reprocessed by the directors and routers. No
         rewriting of headers takes place.

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

     .   fail_soft
         The router fails, leaving the address to be passed to any
         following routers.

     .   fail_hard
         The router fails, and the address is not passed to any following
         routers. Consequently, delivery fails and an error report is
         generated.

     .   send
         The anomaly is ignored and the message is transmitted anyway. This
         setting should be used with extreme caution. 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.

    When a router just rewrites, that is, does not set up IP addresses, the
    self option is not relevant.

transport

    Type:    string
    Default: unset

    The string must be the name of a configured transport instance. Some
    routers require this option always to be set; others require it not to
    be set.

unseen

    Type:    boolean
    Default: false

    Setting this option has a similar effect to the unseen command
    qualifier in filter files. It causes an address to be passed on to
    subsequent routers, even if the current router succeeds in handling it,
    and can be used to cause copies of messages to be delivered elsewhere.

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, not when actually doing a delivery. It can be further           |
    restricted to verifying only senders or recipients by means of           |
    verify_sender and verify_recipient.                                      |
                                                                             |
verify_sender                                                                |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    If this option is false, then this router is skipped when verifying      |
    sender addresses.                                                        |
                                                                             |
verify_recipient                                                             |
                                                                             |
    Type:    boolean                                                         |
    Default: true                                                            |
                                                                             |
    If this option is false, then this router is skipped when verifying      |
    recipient addresses.                                                     |


24.1 Skipping routers

Some of the generic options can cause routers to be skipped in particular
cases. They interact with each other in the following way:

If the domain and local part are not in agreement with domains,              |
except_domains, except_local_parts and local_parts (when set), or if         |
verify_only is set but verification is not happening, then the router is     |
skipped and the next one is tried. None of the other options is inspected.   |

Otherwise, if the more option is not set, no subsequent routers are ever
called, in any circumstances. The current router is itself called unless

 .   Verification is happening and its verify_sender or verify_recipient     |
     option (as appropriate) is turned off, or                               |

 .   The existence or non-existence of files listed in the require_files
     option is not as expected.

The unseen option causes routing to continue when it would otherwise cease,
the complementary action to no_more, which causes it to cease when it would
otherwise continue.



                         25. THE DOMAINLIST ROUTER


The domainlist router compares a list of domain patterns with the domain it
is trying to route. When a match is found, the information associated with
the pattern can specify several different actions:

 .   The message can be sent to a specific host, or one of a number of
     hosts.

 .   The domain name can be replaced by a new name, which can be

     (i)  looked up in the DNS, with or without MX processing; or

     (ii) looked up using gethostbyname(); or

     (iii)passed to the next router.

The list of patterns can be specified as an option string, or looked up in
a file or database, or both; at least one of the route_list, route_file, or
route_query options must be set. A transport must be set when the routing    |
is completed by this router, that is, when the address is not passed on to   |
subsequent routers. Each routing entry can specify its own transport, with   |
the generic transport option acting as a default for those that don't.       |


modemask

    Type:    integer
    Default: 022

    This specifies mode bits which must not be set for the route file. If
    they are set, the director fails and the message is frozen.

owners

    Type:    string-list
    Default: unset

    This specifies a list of permitted owners for the route file. If it is
    unset, no check on the ownership is done. If the file is not owned by a
    user in the list, the router fails and the message is frozen.

owngroups

    Type:    string-list
    Default: unset

    This specifies a list of permitted groups for the route file. If it is
    unset, no check on the file's group is done. If the file's group is not
    in the list, the router fails and the message is frozen.

route_file

    Type:    string
    Default: unset

    If this option is set, search_type must be set to one of the single-key
    lookup types, and route_query must not be set. See chapter 6 for
    details of file and database lookups. The domain being routed is used
    as the key for the lookup, and the resulting data must be a list of
    routing rules in the form described below. The file name is expanded
    before use.

route_list

    Type:    string-list, semicolon-separated
    Default: unset

    This string is a list of routing rules, in the form defined below. Note
    that, unlike most string lists, the items are separated by semicolons.
    This is so that they may contain colon-separated host lists.

route_query

    Type:    string
    Default: unset

    If this option is set, search_type must be set to a query-style lookup
    type, and route_file must not be set. See chapter 6 for details of file
    and database lookups. The query is expanded before use, and the
    expansion variable domain contains the domain being routed. The data
    returned from the lookup must be a list of routing rules, in the form
    described below.

search_type

    Type:    string
    Default: unset

    This option is mandatory when either route_file or route_query is
    specified. It must be set to one of the strings 'lsearch', 'dbm',
    'nis', 'nis0', or 'nisplus', specifying the type of file search.

    For all but 'nisplus', the name may be preceded by 'partial-',
    indicating a simple wildcard file lookup that works as follows:

    (a)  Exim first tries to look up the domain exactly as given.

    (b)  If that fails, it adds '*.' on the front of the domain, and looks
         that up.

    (c)  If that fails, it replaces the first component of the domain with
         '*' and tries that, and continues chopping off components in this
         way until either the lookup succeeds, or there are fewer than two
         non-* components left.

    Thus, for example, if you put an entry keyed by *.austen.fict.film in
    your database, that entry will be used for

    (1)  austen.fict.film by rule (b) above, having failed on rule (a). (If
         you are worried about the resource waste implied by this, you can
         always add an entry for austen.fict.film as well.)

    (2)  emma.austen.fict.film at the first attempt in rule (c), having
         failed on rules (a) and (b).

    A domain such as jane.fict.film will fail, having tried 3 lookups:
    jane.fict.film, *.jane.fict.film, *.fict.film, but it won't waste
    effort looking up *.film because that has only one non-* component. In
    fact, the minimum number of components can be altered by including a
    number immediately before the hyphen. For example, 'partial4-dbm'
    specifies a minimum of four non-* components.


25.1 Routing rules

If both route_list and one of route_file or route_query are specified, the
string contained in route_list is searched first. It consists of a sequence
of routing rules, separated by semicolons. If a semicolon is needed in an
item, it can be entered as two semicolons. Empty items are ignored. The
format of each rule is

  <domain pattern>  <host-list>  <options>

The domain pattern is in the same format as each item in a domain list (see
section 7.11), that is, it may be wildcarded or a regular expression, or a
file or database lookup (see chapter 6 for details). The host list is a
colon-separated list of host names and/or IP addresses. The options are
described below; none need appear.

The host list is expanded before use, making it possible to have entries of
the form

  *.rhodes.tvs  $domain  byname

which routes domains that match *.rhodes.tvs by calling gethostbyname() on
the domain that matched. The numeric expansion variables are available.
These are mainly used when the first item is a regular expression in a
route_list string, but $1 is also set when partial matching is done in a
file lookup. If the string to be expanded contains spaces, it must be
enclosed in either single or double quotes.

If the string expansion of a hostlist item is forced to fail (by using the   |
'fail' item in a conditional construction), the router just fails to handle  |
the address. If expansion fails for some other reason, the message is        |
frozen as it is considered to be a configuration error.                      |
                                                                             |
When routing rules are obtained from a file or database lookup, the data     |
returned by a lookup consists of the host list and options, exactly as for   |
a string list. For example, a line from a linearly searched route file       |
might be:                                                                    |
                                                                             |
  dict.ref.book:  mail-1.ref.book:mail-2.ref.book  byname                    |
                                                                             |
If no options are specified, then the host list must contain exactly one     |
host (domain) name, as in this example:                                      |
                                                                             |
  route_list = "*.uucp  uugateway.fict.book"                                 |
                                                                             |
This causes domains that match *.uucp to replaced by uugateway.fict.book,    |
which is then passed on to subsequent routers.                               |
                                                                             |
The options are a sequence of words; a word may be the name of a configured  |
transport, or it may be one of the following:                                |
                                                                             |
 .   byname: look up the new host(s) using gethostbyname(), or use literal   |
     IP addresses if present.                                                |
                                                                             |
 .   bydns: look up the new host(s) using the DNS and doing the full MX and  |
     A record processing.                                                    |
                                                                             |
 .   bydns_a: look up a A records for the host(s) in the DNS; fail if there  |
     are none.                                                               |
                                                                             |
 .   bydns_mx: look up MX records for the host(s) in the DNS; fail if there  |
     are none.                                                               |
                                                                             |
A transport specified in a route item overrides the generic transport        |
option. If a remote transport is specified, then one of the byxxx options    |
must be present to enable the hosts to be looked up. If any of them are      |
found to be the local host, that one and all those that follow it are        |
discarded. If the first host is found to be the local host, then the         |
generic self option specifies what happens.                                  |
                                                                             |
If a local transport is specified (for example, appendfile or pipe for       |
handling batched SMTP), then there must be no more than one host name, and   |
any byxxx options are ignored. If there is a host name, it becomes           |
available for expansion as ${host} while transporting, but is not otherwise  |
used. For an example, see section 43.10.                                     |


25.2 Domainlist examples

The domainlist router can be used to handle a number of different routing
requirements, as shown in the following examples:

 .   A gateway to another mail environment can be set up using a wildcarded
     domain pattern that matches some pseudo top-level domain. For example,
     to route certain addresses to UUCP and Bitnet gateways, use an option
     like this:

       route_list = "*.uucp   uugateway.fict.book;\
                     *.bitnet bngateway.ref.book"

     Because no options or transport are specified in either case, the name
     of the gateway machine is passed to the next router for further
     routing.

 .   A machine that is itself a gateway can 'deliver' messages to pipes or
     into files in batched SMTP format for onward transportation by some
     other means. In this case, the route list entry can be as simple as a
     single domain name in a configuration like this:

       route_append:
         transport = batchsmtp_appendfile,
         driver = domainlist;
         route_list = "gated.domain"

     though often a domain pattern is used to pick up more than one domain.  |
     If there are several domains or groups of domains with different        |
     transport requirements, different transports can be listed in the       |
     routing information:                                                    |
                                                                             |
       route_append:                                                         |
         driver = domainlist;                                                |
         route_list = "gated.domain1 $domain batch_appendfile;\              |
                       gated.domain2 $domain batch_pipe"                     |
                                                                             |
 .   A "mail hub" is a machine which receives mail for a number of domains
     via MX records in the DNS and delivers it via its own private routing
     mechanism. Often the final destinations are behind a firewall, with
     the mail hub being the one machine that can connect to machines both
     inside and outside the firewall. The domainlist router can be set up
     for this purpose by using a configuration file containing entries of
     the form

       dict.ref.book:  mail-1.ref.book:mail-2.ref.book  byname

     The DNS would be set up with an MX record for dict.ref.book pointing
     to the mail hub, which then forwards its mail to one of the two
     specified machines, whose addresses are looked up by gethostbyname().

 .   The domainlist router can also be used to forward all non-local mail
     to a "smart host" by using a configuration option such as

       route_list = "*  smarthost.ref.book  bydns_a"

     which causes all messages containing remote addresses to be sent to a
     single host, whose address (in this example) is obtained from its DNS
     address record. Alternatively, a colon-separated list of smart hosts
     can be given; they are tried in order.



                          26. THE IPLITERAL ROUTER


This router succeeds if the 'domain' being routed takes the form of an RFC
822 domain literal, that is, an IP address in dotted-quad notation enclosed
in square brackets. For example, this router handles the address

  root@[111.1.1.1]

by setting up delivery to the host with that IP address. If an IP literal
turns out to refer to the local host, the generic self option determines
what happens. The RFCs require support for domain literals, though it seems
anachronistic in today's Internet. There are no private options for this
router; a transport must be set using the generic transport option.



                          27. THE IPLOOKUP ROUTER


The iplookup router was written to fulfil a specific requirement in
Cambridge. For this reason, it is not included in the binary of Exim by
default. If you want to include it, then you must set

  ROUTER_IPLOOKUP=yes

in your Local/Makefile configuration file.

The iplookup router routes an address by sending it over a TCP or UDP
connection to one or more specific hosts. The host can then return the same
or a different address - in effect rewriting the recipient address in the
message's envelope. If this process fails, the address can be passed on to
other routers, or delivery can be deferred.

Background, for those that are interested: We have an Oracle database of
all Cambridge users, and one of the bits of data it maintains for each user
is where to send mail addressed to <user>@cam.ac.uk. The MX records for
cam.ac.uk point to a central machine that has a large alias list that is
abstracted from the database. Mail from outside is switched by this system,
and originally internal mail was also done this way. However, this resulted
in a fair number of messages travelling from some of our larger systems to
the switch and back again. The Oracle machine now runs a UDP service that
can be called by the iplookup router in Exim to find out where
<user>@cam.ac.uk addresses really have to go; this saves passing through
the central switch, and in many cases saves doing any remote delivery at
all.

Since iplookup is just a re-writing router, a transport must not be
specified for it. The private options are:


hosts

    Type:    string
    Default: unset

    This option must be supplied. Its value is a colon-separated list of
    host names. The hosts are looked up using gethostbyname and are tried
    in order until one responds to the query.

optional

    Type:    boolean
    Default: false

    If optional is true, then if no response is obtained from any host, the
    address is passed on to the next router. If optional is false, delivery
    to this address is deferred.

protocol

    Type:    string
    Default: udp

    This option can be set to 'udp' or 'tcp' to specify which of the two
    protocols is to be used.

query

    Type:    string
    Default: "${local_part}@${domain} ${local_part}@${domain}"

    This defines the content of the query that is sent to the remote hosts.
    The repetition serves as a way of checking that a response is to the
    correct query in the default case (see response_pattern below).

reroute

    Type:    string
    Default: unset

    If this option is not set, the rerouted address is precisely the byte
    string returned by the remote host, up to the first white space, if
    any. If set, the string is expanded to form the rerouted address. It
    can include parts matched in the response by response_pattern by means
    of numeric variables such as $1, $2, etc. The variable $0 refers to the
    entire input string, whether or not a pattern is in use. In all cases,
    the rerouted address must end up in the form <local_part>@<domain>.

response_pattern

    Type:    string
    Default: unset

    This option can be set to a regular expression that is applied to the
    string returned from the remote host. If the pattern does not match the
    response, the router fails. If response_pattern is not set, no checking
    of the response is done, unless the query was defaulted, in which case
    there is a check that the text returned after the first white space is
    the original address. This checks that the answer that has been
    received is in response to the correct question. For example, if the
    response is just a new domain, the following could be used:

      response_pattern = "^([^@]+)$"
      reroute = "${local_part}@${1}"

service

    Type:    integer
    Default: 0

    This option must be supplied. It specifies the port number for the TCP
    or UDP call.

timeout

    Type:    time
    Default: 5s

    This specifies the amount of time to wait for a response from the
    remote machine. The same timeout is used for the connect() function for  |
    a TCP call. It does not apply to UDP.                                    |



                         28. THE LOOKUPHOST ROUTER


The lookuphost router looks up the hosts that handle mail for a given
domain either via the gethostbyname() function, or by using the DNS. A
transport must always be set (using the generic transport option) for this
router.


gethostbyname

    Type:    boolean
    Default: false

    If this is true, the gethostbyname() function is used and the options
    relating to the DNS are ignored. Otherwise, the name is looked up in
    the DNS.

mx_domains

    Type:    domain-list
    Default: unset

    This option, together with non_mx_domains, applies to domains that are
    looked up in the DNS for non-source-routed RFC 822 addresses (that is,
    addresses that do not start with @). A domain which is in mx_domains
    but is not in non_mx_domains is required to have an MX record in order
    to be recognised. For example, if all the mail hosts in fict.book are
    known to have MX records, except for those in discworld.fict.book,
    options of the form

      mx_domains = *.fict.book,
      non_mx_domains = *.discworld.fict.book

    could be used. This would cause messages addressed to a machine with
    only an A record to be bounced immediately instead sitting on the queue
    until the delivery timed out. Note, however, that for source-routed RFC
    822 addresses (ones that start with @) this restriction does not apply,
    as the first domain in such an address is a machine name. The
    collapse_source_routes main configuration option provides a way of
    locking out the use of source routes.

non_mx_domains

    Type:    domain-list
    Default: unset

    See mx_domains above.

qualify_single

    Type:    boolean
    Default: true

    If domains are being looked up in the DNS, then the resolver option
    that causes it to qualify single-component names with the local domain
    is set. For example, on a machine called dictionary.ref.book, looking
    up the domain thesaurus would cause the name thesaurus.ref.book to be
    looked up.

rewrite_headers

    Type:    boolean
    Default: true

    An abbreviated name may be expanded to its full form by both
    gethostbyname() or by DNS lookup, or as a result of the widen_domains
    option. For example, if an address is specified as dormouse@teaparty,
    the domain might get expanded to teaparty.wonderland.fict.book. If this
    option is true, then all occurrences of the abbreviated name in the
    headers of the message are rewritten with the full name. This option
    should be turned off only when it is known that no message is ever
    going to be sent outside an environment where the abbreviation makes
    sense.

    When an MX record is looked up in the DNS and matches a wildcard
    record, nameservers normally return a record containing the name that
    has been looked up, making it impossible to detect whether a wildcard
    was present or not. However, some nameservers have recently been seen
    to return the wildcard entry. If the name returned by a DNS lookup
    begins with an asterisk, it is not used for header rewriting.

search_parents

    Type:    boolean
    Default: true

    If domains are being looked up in the DNS, then the resolver option
    that causes it to search parent domains is set. This is different from
    the qualify_single option in that it applies to domains containing
    dots. For example, on a machine in the fict.book domain, when looking
    up teaparty.wonderland initially fails, the resolver automatically
    tries teaparty.wonderland.fict.book if this option is set.

self_mx

    Type:    string
    Default: "freeze"

    This is an obsolete option that has been superseded by the generic self
    option. It should no longer be used, and will be removed from some
    future version of Exim. At present, if it is set, it overrides the
    default setting of the generic self option, but does not override any
    specific self setting. Note that the options involving 'local' have
    been generalized and now use the string 'reroute' in the self option.

    This option specifies what is to happen if the lowest numbered MX
    record for a remote domain points to the local host. Normally this
    indicates either an error in Exim's configuration (the domain should be
    listed as local), or an error in the DNS (the MX shouldn't point at
    this host). The default action is to freeze the message. The following
    alternatives are provided for use in special cases:

     .   defer
         Delivery of the message is tried again later.

     .   local: <domain>
         The domain is changed to the given domain, which must be one of
         the local domains, and the address is passed back to the direc-
         tors. No rewriting of headers takes place.

     .   local: rewrite: <domain>
         The domain is changed to the given domain, which must be one of
         the local domains, and the address is passed back to the direc-
         tors. Any headers that contain the original domain are rewritten.

     .   fail_soft
         The router fails, leaving the address to be passed to any
         following routers.

     .   fail_hard
         The router fails, and the address is not passed to any following
         routers. Consequently, delivery fails and an error report is
         generated.

     .   send
         The anomaly is ignored and the message is transmitted anyway. This
         setting should be used with extreme caution. 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.

widen_domains

    Type:    string-list
    Default: unset

    If a lookup fails and this option is set, each of its strings in turn
    is added onto the end of the domain, and the lookup is tried again. For
    example, if

      widen_domains = "fict.book:ref.book"

    is set and a lookup of klingon.dictionary fails, then
    klingon.dictionary.fict.book is looked up, and if this fails, then
    klingon.dictionary.ref.book is tried. This option applies to lookups
    using gethostbyname() as well as to DNS lookups. Note that when the DNS
    is being used for lookups, the qualify_single and search_parents
    options cause some widening to be undertaken inside the DNS resolver.



                        29. THE QUERYPROGRAM ROUTER


The queryprogram router routes a domain by running an external command and
acting on its output. This is an expensive way to route, and is intended
mainly for use in lightly-loaded systems, or for performing experiments.
However, if it is possible to use the domains generic option to skip this
router for most addresses, then it could sensibly be used in special cases.
There are two private options:


command

    Type:    string
    Default: unset

    This option must be set, and must start with a '/' character. It
    specifies the command that is to be run. It is expanded before use.
    Failure to expand causes the router to fail and the message to be
    frozen.

timeout

    Type:    time
    Default: 1h

    If the command does not complete within the timeout period, its process
    is killed and the message gets frozen. A value of zero time specifies
    no timeout.

The command is run as 'nobody'. If the main configuration has not defined a
user and group for 'nobody', then it is looked up using getpwnam(). If this
fails, the router fails and the message is frozen.

The standard output of the command is connected to a pipe, which is read
when the command terminates. It should consist of a single line of output,
containing up to five fields, separated by white space. The first field is
one of the following words:

 .   OK: routing succeeded; the remaining fields specify what to do.

 .   FAIL: routing failed; pass the address to the next router.

 .   FORCEFAIL: routing failed; do not pass the address to any more
     routers.

 .   DEFER: routing could not be completed at this time; try again later.

 .   ERROR: some disastrous error occured; freeze the message.

When the first word is not OK, the remainder of the line is an error
message explaining what went wrong. For example:

  FAIL  queryprogram cannot route to unseen.discworld.fict.book

Otherwise, the line must be formatted as follows:                            |
                                                                             |
  OK <transport name> <new domain> <option> <arbitrary text>                 |
                                                                             |
The second field is the name of a transport instance, or a + character,      |
which means that the transport specified for the router using the generic    |
transport option is to be used, if set.                                      |
                                                                             |
If the third field is not empty or a + character, it is a new domain name    |
to replace the current one. If a transport is specified and the fourth       |
field is not empty or a + character, it specifies the method of looking up   |
the new name. This can be one of the words 'byname', 'bydns', 'bydns_a', or  |
'bydns_mx'. For example,                                                     |
                                                                             |
  OK  smtp  gate.star.fict.book  bydns_a                                     |
                                                                             |
causes the message to be sent using the smtp transport to the host           |
gate.star.fict.book, whose address is looked up as a DNS address record. If  |
the host turns out to be the local host, what happens is controlled by the   |
generic self option.                                                         |
                                                                             |
The fifth field, if present, is made available to the transport via the      |
expansion variable $route_option. For example, a line such as                |
                                                                             |
  OK special + + /computed/filename                                          |
                                                                             |
sends the message to the special transport, which can use $route_option in   |
its configuration to access the text '/computed/filename'.                   |
                                                                             |
The fourth and fifth fields are ignored and the new domain name (if any) is  |
passed to the next router if no transport is specified in the response line  |
(i.e. a + character is given) and the generic transport option is also       |
unset.                                                                       |



                          30. RETRY CONFIGURATION


The fifth part of the configuration file contains a list of retry rules
which control how often Exim tries to deliver messages that cannot be
delivered at the first attempt. If there are no retry rules, Exim gives up
after the first failure. The -brt command line option can be used to test    |
which retry rule will be used for a given address or domain.                 |

Retry processing applies to directing and routing as well as to delivering.
The retry rules do not distinguish between these three actions, so it is
not possible, for example, to specify different behaviour for failures to
route the domain snark.fict.book and failures to deliver to the host
snark.fict.book. I didn't think anyone would ever need this added compli-
cation, so did not implement it. Internally, however, the actual retry
times for routing, directing, and transporting are maintained
independently.

Each retry rule occupies one line and consists of three parts. The rules
are searched in order until one which matches the current domain (and
possibly local part) is found.

The first field in a retry rule is a key for the rule, which may be an       |
address (local_part@domain), a plain domain, a wild-carded domain (i.e.      |
starting with an asterisk), a domain lookup (as in a domain list), or a      |
regular expression. The first form must be used only with local domains;     |
the local part may begin with an asterisk.                                   |
                                                                             |
The string used to match the keys consists of "local_part@domain" for local  |
deliveries, and just the domain for remote ones. Regular expressions always  |
match against this entire string. Otherwise, if there is no local part in    |
the key then the local part isn't used in the matching. Thus an entry        |
such as                                                                      |
                                                                             |
  lookingglass.fict.book   *          F,24h,30m;                             |
                                                                             |
matches any address whose domain is lookingglass.fict.book, whether it is a  |
local address or a remote one.                                               |
                                                                             |
When looking for a retry rule for a remote delivery, each line in the retry  |
configuration is first tested against the remote host name, and then         |
against the address's domain name. For example, if the MX records for        |
a.b.c.d are                                                                  |
                                                                             |
  a.b.c.d  MX  5  x.y.z                                                      |
           MX  6  p.q.r                                                      |
           MX  7  m.n.o                                                      |
                                                                             |
and the retry rules are                                                      |
                                                                             |
  p.q.r    *          F,24h,30m;                                             |
  a.b.c.d  *          F,4d,45m;                                              |
                                                                             |
then failures to deliver to host p.q.r use the first rule to determine       |
retry times, but for all the other hosts for the domain a.b.c.d, the second  |
rule is used.                                                                |

The second field in a retry rule is the name of a particular error, or an
asterisk, which matches any error. The errors that can be tested for are:

     refused_MX: connection refused from a host obtained from an MX record

     refused_A: connection refused from a host not obtained from an MX
     record

     refused: any connection refusal

     timeout_connect: connection timed out

     timeout_DNS: DNS lookup timed out

     timeout: any timeout

     quota: quota exceeded in local delivery

     quota_<time>: quota exceeded in local delivery, and the mailbox has
     not been read for <time>.

The quota errors apply both to system-enforced quotas and to Exim's own      |
quota mechanism in the appendfile transport.                                 |

The third field in a retry rule is a sequence of retry parameter sets,
separated by semicolons. Each set consists of

  <letter>,<cutoff time>,<arguments>

The letter identifies the algorithm for computing a new retry time; the
cutoff time is the time beyond which this algorithm no longer applies, and
the arguments vary the algorithm's action. The cutoff time is measured from
the time that the first failure for the domain (combined with the local
part if relevant) was detected, not from the time the message was received.

The available algorithms are:

 .   F: retry at fixed intervals. There is a single time parameter
     specifying the interval.

 .   G: retry at geometrically increasing intervals. The first argument
     specifies a starting value for the interval, and the second a
     multiplier.

Here are some example retry rules suitable for use when
wonderland.fict.book is a local domain:                                      |
                                                                             |
  alice@wonderland.fict.book quota_5d  F,7d,3h                               |
  wonderland.fict.book       quota_5d                                        |
  wonderland.fict.book       *         F,1h,15m; G,2d,1h,2;                  |
  lookingglass.fict.book     *         F,24h,30m;                            |
  *                          refused_A F,2h,20m;                             |
  *                          *         F,2h,15m; G,16h,2h,1.5; F,5d,8h       |
                                                                             |
The first rule sets up special handling for mail to                          |
alice@wonderland.fict.book when there is an over-quota error and the         |
mailbox hasn't been read for at least 5 days. Retries continue every three   |
hours for 7 days. The second rule handles over-quota errors for all other    |
local parts at wonderland.fict.book; the absence of a local part has the     |
same effect as supplying '*@'. As no retry algorithms are supplied,          |
messages that fail are bounced immediately.                                  |
                                                                             |
The third rule handles all other errors at wonderland.fict.book; retries     |
happen every 15 minutes for an hour, then with geometrically increasing      |
intervals until two days have passed since a delivery first failed. The      |
fourth rule controls retries for the domain lookingglass.fict.book, whether  |
it is local or remote, and the remaining two rules handle all other          |
domains, with special action for connection refusal from hosts that were     |
not obtained from an MX record.                                              |

The final rule in a retry configuration should always have asterisks in the
first two fields so as to provide a general catch-all for any addresses
that do not have their own special handling. This example tries every 15
minutes for 2 hours, then with intervals increasing by a factor of 1.5 up
to 16 hours, then every 8 hours up to 5 days.

When computing the next retry time, the algorithm definitions are scanned
in order until one whose cutoff time has not yet passed is reached. This is
then used to compute a new retry time that is later than the current time.
In the case of fixed interval retries, this simply means adding the
interval to the current time. For geometrically increasing intervals, retry
intervals are computed from the rule's parameters until one that is greater
than the previous interval is found. The main configuration variable
retry_interval_max limits the maximum interval between retries.

A single remote domain may have a number of hosts associated with it, and
each host may have more than one IP address. Retry algorithms are selected
on the basis of the domain name, but are applied to each IP address
independently. If, for example, a host has two IP addresses and one is
broken, Exim will generate retry times for it and will not try to use it
until its next retry time comes. Thus the good IP address is likely to be
tried first most of the time.

Retry times are hints rather than promises. Exim does not make any attempt
to run deliveries exactly at the computed times. Instead, a queue-running
process starts delivery processes for delayed messages periodically, and
these attempt new deliveries only for those addresses that have passed
their next retry time.

Special processing happens when an address has been failing for so long
that the cutoff time for the last algorithm has been reached. If this is
the case for a local delivery, or for all IP addresses associated with a
remote delivery, a subsequent delivery failure causes Exim to give up on
the address, and a delivery error message is generated. In order to cater
for new messages that may use the failing address, however, a next retry
time is still computed from the final algorithm, and is used as described
below.

If the delivery is a local one, one delivery attempt is always made for any
subsequent messages. If it fails, the address fails immediately. The post-
cutoff retry time is not used.

If the delivery is remote, there are two possibilities, controlled by the
delay_after_cutoff option of the smtp transport. The option is true by
default and in that case:

     Until the post-cutoff retry time for one of the IP addresses is
     reached, any attempt to deliver to the failing address is bounced
     immediately. After that time, one new delivery attempt is made to
     those IP addresses that are past their retry times, and if that still
     fails, the address is bounced and new retry times are computed.

In other words, Exim delays retrying an IP address after the final cutoff
time until a new retry time is reached, and can therefore bounce an email
address without ever trying a delivery when machines have been down for a
long time. This ensures that few resources are wasted in repeatedly trying
to delivery to a broken destination, but if it does recover, Exim will
eventually notice.

If delay_after_cutoff is set false, Exim behaves differently. If all IP
addresses are past their final cutoff time, Exim tries to deliver to those
IP addresses that have not been tried since the message arrived. If there
are none, or if they all fail, the address is bounced. In other words, it
does not delay when a new message arrives, but tries the expired addresses
immediately, unless they have been tried since the message arrived. If
there is a continuous stream of messages for the failing domains, unsetting
delay_after_cutoff means that there will be many more attempts to deliver
to failing IP addresses than when delay_after_cutoff is true.

An additional rule is needed to cope with cases where a host is intermit-
tently available, or when a message has some attribute that prevents its
delivery when others to the same address get through. Because some messages
are successfully delivered, the 'retry clock' keeps getting restarted, and
so a message could remain on the queue for ever. To prevent this, if a
message has been on the queue for longer than the cutoff time of any
applicable retry rule, the associated email address is failed after its
next temporary delivery error. A new retry time is not computed in this
case, so that other messages for the same address are considered
immediately.

Even with this rule a large queue of messages can take a long time to clear
if some occasionally get delivered, because the intermittent failures delay
delivery attempts on the others (and the above rule acts only after a
delivery attempt). There is therefore an ultimate clean-up rule which
causes all the remaining addresses in a message to be failed, whether or
not there has just been a delivery attempt, if the message has been on the
queue for longer than the longest cutoff time for any retry rule in the
configuration file.

The data in the retry hints database can be inspected by using the
exim_dumpdb or exim_fixdb utility programs (see chapter 41). The latter
utility can also be used to change the data. The exinext utility script can
be used to find out what the next retry times are for the hosts associated
with a particular mail domain, and also for local deliveries that have been
deferred.



                           31. ADDRESS REWRITING


Some people believe that configured address rewriting is a Mortal Sin.
Others believe that life is not possible without it. Exim provides the
facility; you do not have to use it. There are two cases that are commonly
encountered:

 .   The company hitch.fict.book has a number of machines that exchange
     mail with each other behind a firewall, but only a single gateway to
     the outer world. The gateway rewrites *.hitch.fict.book as
     hitch.fict.book.

 .   A machine rewrites the local parts of outgoing messages from its own
     users so that, for example, fp42@hitch.fict.book becomes
     Ford.Prefect@hitch.fict.book.

In general, rewriting addresses from one's own system or domain has some
legitimacy. Rewriting other addresses should be done only with great care
and in special circumstances.

Exim's rewriting configuration appears as the sixth part of the runtime      |
configuration file. It can be tested by the -brw command line option. This   |
takes an address (which can be a full RFC 822 address) as its argument. The  |
output is a list of how the address would be transformed by the rewriting    |
rules for each of the different places it might appear, that is, for each    |
different header and for the envelope sender and recipient fields.           |

The rewriting configuration consists of lines of rewriting rules in the
form

  <source pattern>  <replacement>  <flags>

The rules are scanned in order and relacements from earlier rules can
themselves be replaced as a result of later rules. Long rules can be split
over several lines by terminating all but the last with a backslash
character. Leading white space on continuation lines is ignored. If the
replacement string contains spaces, which can happen for certain forms of
expansion expression, it must be enclosed in double quotes, and the normal
quoting conventions apply inside them.

$local_part and $domain can be used in the replacement string to refer the   |
the address that is being rewritten. Note that complete lookup-driven        |
rewriting can be done by a line of the form                                  |
                                                                             |
  *@*   ${lookup ...                                                         |
                                                                             |
where the lookup key is derived from $1 and $2 or $local_part and $domain.   |
                                                                             |
The source pattern can be one of the following forms. Note that it is not    |
enclosed in quotes, and there is no special processing of any characters.    |
In particular, if it is a regular expression, \ characters must not be       |
doubled.                                                                     |
                                                                             |
 .   An address containing a local part and a domain, either of which may    |
     start with an asterisk, implying independent wildcard matching, for     |
     example                                                                 |
                                                                             |
       *@orchestra-land.fict.book                                            |
                                                                             |
 .   A local part, possibly starting with an asterisk, and a lookup item     |
     (as in a domain list), for example                                      |
                                                                             |
       root@lsearch;/special/domains                                         |
                                                                             |
 .   A lookup without a local part, for example                              |
                                                                             |
       partial-dbm;/rewrite/database                                         |
                                                                             |
     This works as for an "address-list" configuration item - the domain is  |
     first looked up, possibly partially, and if that fails, the whole       |
     address is then looked up (not partially). When a partial lookup        |
     succeeds, the numerical variable $1 contains the wild part of the       |
     domain.                                                                 |
                                                                             |
 .   A regular expression. This is matched against the entire address, with  |
     the domain part lower-cased.                                            |
                                                                             |
The replacement is a string which is expanded. Within the expansion, the     |
variables $local_part and $domain refer to the address that is being         |
rewritten. If the pattern is a regular expression, the numerical variables   |
refer to the bracketed sub-expressions therein, with ${0} referring to the
entire address. For example, if the pattern

  ^(red|white).king@(wonderland|lookingglass).fict.book$

is matched against the address red.king@lookingglass.fict.book then

  ${0}   is red.king@lookingglass.fict.book
  ${1}   is red
  ${2}   is lookingglass

If the pattern is not a regular expression, the numerical variables refer
to the character strings matched by asterisks, with ${1} associated with
the first asterisk. Once again, ${0} refers to the entire address. For
example, if the pattern

  *queen@*.fict.book

is matched against the address hearts-queen@wonderland.fict.book then

  ${0}   is hearts-queen@wonderland.fict.book
  ${1}   is hearts-
  ${2}   is wonderland

Note that if the local part does not start with an asterisk, but the domain
does, then it is ${1} that contains the wild part of the domain.

The flags field may be empty, in which case the rewriting rule applies to
all headers and to both the sender and recipient fields of the envelope.
Otherwise, one or more of the following letters can be given to control
which addresses are rewritten:

  E       rewrite all envelope fields
  F       rewrite the envelope From field
  T       rewrite the envelope To field
  b       rewrite the Bcc header
  c       rewrite the Cc header
  f       rewrite the From header
  h       rewrite all headers
  r       rewrite the Reply-to header
  s       rewrite the Sender header
  t       rewrite the To header

You should be particularly careful about rewriting Sender headers, and
restrict this to special known cases in your own domains.

Rewriting happens immediately after a message has been read, which is why
it is possible to rewrite the Bcc header (though Exim removes a Bcc header
only when the -t option is used). Here is an example of the two common
rewriting paradigms:

  *@*.hitch.book.fict  $1@hitch.book.fict
  *@hitch.book.fict    ${lookup{$1}dbm{/etc/realnames}\
                       {$value}fail}@hitch.book.fict bcfrF

Note the use of 'fail' in the lookup expansion. This causes the string
expansion to fail, and in this context it has the effect of leaving the
original address unchanged. An alternative would be to supply ${1}
explicitly, which would cause the rewritten address to be the same as
before, at the cost of a small bit of processing. Not supplying either of
these is an error, since the rewritten address would then contain no local
part.

When an address in a header is rewritten, the rewriting normally applies     |
only to the working part of the address, with any comments and RFC 822       |
'phrase' left unchanged. For example, the rules above might change           |
                                                                             |
  From: Ford Prefect <fp42@restaurant.hitch.fict.book>                       |
                                                                             |
into                                                                         |
                                                                             |
  From: Ford Prefect <prefectf@hitch.fict.book>                              |
                                                                             |
Sometimes there is a need to replace the whole address item, and this can    |
be done by adding the flag letter w to a rule. If this is set on a rule      |
that causes an address in a header to be rewritten, the entire address is    |
replaced, not just the working part. The replacement must be a complete RFC  |
822 address, including the angle brackets if necessary. When the w flag is   |
set on a rule that causes an envelope address to be rewritten, all but the   |
working part of the replacement address is discarded.                        |



                               32. LOG FILES


Exim writes four different log files into a subdirectory of its spool
directory called log, unless a compile-time option called LOG_FILE_PATH is
defined to specify a different directory. See the comments in src/EDITME
for more details of this.

 .   The file called mainlog records the arrival of each message and each
     delivery in a single line in each case. The format is as compact as
     possible, in an attempt to keep down the size of log files. Two-
     character flag sequences make it easy to pick out these lines. A
     number of other events are also recorded on the main log. Some of       |
     these entries can be suppressed by changing the value of the log_level  |
     configuration option.                                                   |

 .   The file called rejectlog records information from messages that are
     rejected as a result of a configuration option, for example, because
     their return paths are invalid. In this particular case, the headers
     are written to this log, following a copy of the one-line message that
     is also written to the main log. For other rejections, just a single
     line is written to the reject log.

 .   The file called paniclog is written when Exim suffers a disaster and
     has to bomb out. This should be checked regularly to pick up any
     problems.

 .   On systems that support signal handlers that restart a system call on
     exit, Exim reacts to a USR1 signal by writing a line describing its
     current activity to a file called processlog. This makes it possible
     to find out what each exim process on a machine is currently doing.

A utility script called exicyclog which renames and compresses the main and
reject logs each time it is called is provided. The maximum number of old
logs to keep can be set. It is suggested this is run as a daily cron job. A
Perl script called eximstats which does simple analysis of main log files
is also provided. See chapter 41 for details of both these utilities.

An Exim delivery process opens the main log when it first needs to write to
it, and it keeps the file open in case subsequent entries are required -
for example, if a number of different deliveries are being done for the
same message. However, remote SMTP deliveries can take a long time, and
this means that the file may be kept open long after it is renamed if
exicyclog or something similar is being used to rename log files on a
regular basis. To ensure that a switch of log files is noticed as soon as
possible, Exim calls stat() on the main log's name before re-uses an open
file, and if the file does not exists, or its inode has changed, the old
file is closed and Exim tries to open the main log from scratch. Thus, an
old log file may remain open for quite some time, but no Exim processes
should write to it once it has been renamed.


32.1 Logging message reception

The format of the single-line entry in the main log that is written for
every message received is as in the example below, which is split over
several lines in order to fit it on the page:

1995-10-31 08:57:53 0tACW1-0005MB-00 <= kryten@dwarf.fict.book
  H=mailer.fict.book [123.123.123.123] U=exim
  P=smtp S=5678 id=<incoming message id>

The H and U fields identify the remote host and record the RFC 1413
identity of the user that sent the message, if one was received. The host
name in the H field is the name quoted by the remote host in the SMTP HELO
or EHLO command, and the number in square brackets is the IP address of the
host. Misconfigured hosts (and mail forgers) sometimes put an IP address in
the HELO or EHLO command, leading to entries in the log containing things
like

  H=10.21.32.43 [123.99.8.34]

which can be confusing. Only the address in brackets can be relied on. For
locally generated messages, the H field is omitted, and the U field
contains the login name of the caller of Exim. The P field specifies the
protocol used to receive the message, the S field is the message size, and
the id field records the existing message id, if present.

If the log_received_recipients option is on, a list of all the recipients
of a message is added to the log line, preceded by the word 'for'. The
happens after any unqualified addresses are qualified, but before any
rewriting is done. if the log_subject option is on, the subject of the       |
message is added to the log line, preceded by T= (T for 'topic', since S is  |
already used for 'size').                                                    |

A delivery error message is shown with the sender address '<>', and if it
is a locally-generated error message, this is normally followed by an item
of the form

  R=<message-id>

which is a reference to the local identification of the message that caused
the error message to be sent.


32.2 Logging Deliveries

The format of the single-line entry in the main log that is written for
every delivery is as in one of the examples below, for local or remote
deliveries, respectively. Each example has been split into two lines in
order to fit it on the page.

1995-10-31 08:59:13 0tACW1-0005MB-00 => marvin <marvin@hitch.fict.book>
  D=localuser T=local_delivery
1995-10-31 09:00:10 0tACW1-0005MB-00 => monk@holistic.fict.book
  R=lookuphost T=smtp H=holistic.fict.book [234.234.234.234]

For local deliveries, the original address is given in angle brackets after  |
the final delivery address, which might be a pipe or a file. If intermedi-   |
ate address(es) exist between the original and the final address, the last   |
of these is given in round brackets after the final address.                 |
                                                                             |
For remote deliveries, if the log_smtp_confirmation option is on, the        |
response to the final '.' in the SMTP transmission is added to the log       |
line, preceded by C=. If the final delivery address is not the same as the   |
original address (owing to changes made by routers), the original is shown   |
in angle brackets.                                                           |

The generation of a reply message by a filter file gets logged as a
'delivery' to the addressee, preceded by '>'. The D and T items record the
director and transport. For remote deliveries, the router, transport, and
host are recorded.

When more than one address is included in a single delivery (e.g. two SMTP
MAIL FROM commands in one transaction) then the second and subsequent
addresses are flagged with -> instead of =>. When two or more messages are
delivered down a single SMTP connection, an asterisk follows the IP
addresses for the second and subsequent messages.


32.3 Deferred deliveries

When a delivery is deferred, a line of the following form is logged:

1995-12-19 16:20:23 0tRiQz-0002Q5-00 == marvin@endrest.book
  T=smtp defer (146): Connection refused

In the case of remote deliveries, the error is the one that was given for
the last IP address that was tried. Details of individual SMTP failures are
also written to the log, so the above line would be preceded by something
like

1995-12-19 16:20:23 0tRiQz-0002Q5-00 Failed to connect to endrest.book
  [239.239.239.239]: Connection refused

When a deferred address is skipped because its retry time has not been       |
reached, a message is written to the log, but this can be suppressed by      |
changing the log_level option.                                               |


32.4 Delivery failures

If a delivery fails, a line of the following form is logged:

1995-12-19 16:20:23 0tRiQz-0002Q5-00 ** jim@trek99.film
  <jimtrek99.film>: unknown mail domain

This is followed (eventually) by a line giving the address to which the
delivery error has been sent.


32.5 Completion

A line of the form

  1995-10-31 09:00:11 0tACW1-0005MB-00 Completed

is written to the main log when a message is about to be removed from the
spool file at the end of its processing.

                                                                             |
32.6 Log level                                                               |
                                                                             |
The log_level configuration option controls the amount of data written to    |
the main log. The higher the number, the more is written. At present a       |
value of 6 or higher causes all possible messages to appear. Lower values    |
suppress more and more entries as follows:                                   |
                                                                             |
  5 invalid HELO and EHLO arguments (see helo_verify_nets)                   |
                                                                             |
  4 'retry time not reached [for any host]'                                  |
    'spool file locked'                                                      |
    'message frozen'                                                         |
    'error message sent to ...'                                              |
                                                                             |
  3 SMTP timeouts                                                            |
    SMTP connection refusals because too busy                                |
                                                                             |
  2 verification failures                                                    |
                                                                             |
  1 rejections because of message size                                       |
                                                                             |
  0 rejections because of policy                                             |
    re-addressing by the system filter                                       |
                                                                             |
Rejection information is still written to the reject log in all cases.       |


32.7 Message log

In addition to the four main log files, Exim writes a log file for each
message that it handles. The names of these per-message logs are the
message ids, and they are kept in the msglog subdirectory of the spool
directory. A single line is written to the message log for each delivery
attempt for each address. It records either a successful delivery, or the
reason (temporary or permanent) for failure. When a local part is expanded
by aliasing or a forwarding file, a line is written to the message log when
all its child deliveries are completed. SMTP connection failures for each
remote host are also logged here. The log is deleted when processing of the
message is complete, unless preserve_message_logs is set, but this should
be used only with great care because they can fill up your disc very
quickly.



                           33. MESSAGE PROCESSING


Exim performs various transformations on the sender and recipient addresses
of messages that it handles, and also on the messages' header lines. Some
of these are optional and configurable, while others always take place. All
of this processing, except rewriting as a result of routing, happens when a
message is received, before it is first written to the spool.

RFC 822 makes provision for headers starting with the string resent-. It     |
states that in general, the resent- fields should be treated as containing   |
a set of information that is independent of the set of original fields, and  |
that information for one set should not automatically be taken from the      |
other. If Exim finds any resent- headers in the message, it applies the      |
following transformations only to the resent- header set, leaving the        |
unqualified set alone.                                                       |

Any addresses that are unqualified are made fully qualified by adding the
qualify_domain or qualify_recipient value, as appropriate. Unqualified
addresses are accepted only from local sources or from hosts that match one
of the receiver_unqualified or sender_unqualified options, as appropriate.


33.1 The Bcc header

If Exim is called with the -t option, to take recipient addresses from a
message's headers, it removes any Bcc header that may exist (after
extracting its addresses), unless the message has no To or Cc header, in
which case a Bcc header with no addresses is left in the message, in
accordance with RFC 822. If -t is not present on the command line, any
existing Bcc header is not removed.

If Exim is called to receive a message with the recipient addresses given    |
on the command line, and there is no Bcc, To, or Cc header in the message,   |
it normally adds a To header, listing the recipients. Some mailing list      |
software is known to submit messages in this way, and in this case the       |
creation of a To header is not what is wanted. If the always_bcc option is   |
set, Exim adds an empty Bcc header instead in this circumstance.             |


33.2 The Date header

If a message has no Date header, Exim adds one, giving the current date and
time.


33.3 The Delivery-date header

Delivery-date headers are not part of the standard RFC 822 header set. Exim
can be configured to add them to the final delivery of messages. (See the
delivery_date_add option in the appendfile and pipe transports.) They
should not be present in messages in transit. If the delivery_date_remove
configuration option is set (the default), Exim removes delivery-date
headers from incoming messages.


33.4 The Envelope-to header

Envelope-to headers are not part of the standard RFC 822 header set. Exim
can be configured to add them to the final delivery of messages. (See the
envelope_to_add option in the appendfile and pipe transports.) They should
not be present in messages in transit. If the envelope_to_remove configur-
ation option is set (the default), Exim removes envelope-to headers from
incoming messages.


33.5 The From header

If an incoming message does not contain a From header, Exim adds one
containing the sender's address. This is obtained from the message's
envelope in the case of remote messages; for locally-generated messages the
calling user's login name and full name are used to construct an address,
as described in section 33.11 below. They are obtained from the password
file entry by calling getpwid() (but see the unknown_login configuration
option). The address is qualified with the value of qualify_domain.


33.6 The Message-id header

If an incoming message does not contain a Message-id header, Exim con-
structs one and adds it to the message. The id is constructed from Exim's
internal message id, preceded by the letter E to ensure it starts with a
letter, and followed by @ and the primary host name. Additional information
can be included in this header by setting the message_id_header_text
option.


33.7 The Received header

A Received header is added at the start of every message. The contents of
this header are defined by the received_header_text configuration option,
and Exim automatically adds a semicolon and a timestamp to the configured
string.


33.8 The Return-path header

Return-path headers are defined as something the MTA may insert when it
does the final delivery of messages. (See the return_path_add option in the
appendfile and pipe transports.) Therefore, they should not be present in
messages in transit. If the return_path_remove configuration option is set
(the default), Exim removes Return-path headers from incoming messages.


33.9 The Sender header

For locally-originated messages, unless originated by a trusted user using
the -f or -bs command line option, any existing Sender header is removed. A
check is then made to see if the address given in the From header is the
correct (local) sender of the message. If not, a Sender header giving the
true sender address is added to the message. No processing of the Sender
header is done for messages originating externally.


33.10 The To header

If a message has no To, Cc, or Bcc header, Exim adds an empty Bcc header,
in accordance with RFC 822, except when the message is being received        |
locally with the recipients supplied on the command line. In this case, a    |
To header listing the recipients is normally added. Some mailing list        |
software is known to submit messages in this way, and in this case the       |
creation of a To header is not what is wanted. If the always_bcc option is   |
set, Exim adds an empty Bcc header instead in this circumstance. An          |
Apparently-to header is never added.                                         |


33.11 Constructed addresses

When Exim constructs a sender address for a locally-generated message, it
uses the form

  <user name> <<login>@<qualify_domain>>

For example:

  Zaphod Beeblebrox <zaphod@end.univ>

The user name is obtained from the -F command line option if set, or
otherwise by looking up the calling user by getpwuid() and extracing the
'gecos' field from the password entry. If the 'gecos' field contains an      |
ampersand character, this is replaced by the login name with the first       |
letter uppercased, as is conventional in a number of operating systems. See  |
the gecos_name option for a way to tailor the handling of the 'gecos'
field. The unknown_username option can be used to specify user names in
cases when there is no password file entry. In all cases the user name is
made to conform to RFC 822 by quoting all or parts of it if necessary.


33.12 Case of local parts

RFC 822 states that the case of letters in the local parts of addresses
cannot be assumed not to be significant. Exim preserves the case of local
parts of remote addresses. However, when it is processing an address in one
of its local domains, the case of letters in the local part is not
significant unless the locally_caseless option is set.


33.13 Rewriting addresses

Rewriting of sender and recipient addresses, and addresses in headers, can
happen automatically, or as the result of configuration options, as
described in chapter 31.

Automatic rewriting includes qualification, as mentioned above. The other
case in which it can happen is when an incomplete non-local domain is
given. The routing process may cause this to be expanded into the full
domain name. For example, a header such as

  To: hare@teaparty

might get rewritten as

  To: hare@teaparty.wonderland.fict.book

Rewriting as a result of routing is the one kind of message processing that
does not happen at input time, as it cannot be done until the address has
been routed.

Strictly, one should not do any deliveries of a message until all its
addresses have been routed, in case any of the headers get changed as a
result of routing. However, doing this in practice would hold up many
deliveries for unreasonable amounts of time, just because one address could
not immediately be routed. Exim therefore does not delay other deliveries
when routing of one or more addresses is deferred.



                     34. THE DEFAULT CONFIGURATION FILE


The default configuration file supplied with Exim as src/configure.default
is suffient for a simple configuration.


34.1 Main configuration settings

Only one explicit option is specified in this section:

  never_users = root

This prevents Exim from ever running as root when performing a local
delivery. Instead, it runs as 'nobody'.

As the primary_hostname, qualify_domain, and local_domains options are not
specified, they will all take the name of the local host, as obtained by
the uname() function, as their value.


34.2 Transport configuration settings

Four local and one remote transport are defined. The first one is

  local_delivery:
    driver = appendfile;
    file = /var/mail/${local_part}

and is set up to deliver to local mailboxes in a traditional 'sticky bit'
directory. To deliver into files in users' home directories, a configur-
ation such as

  local_delivery:
    driver = appendfile;
    file = /home/${local_part}/inbox

should be substituted. An alternative setting for the file option is

    file = ${home}/inbox

The second local transport is

  address_pipe:
    driver = pipe;
    return_output

This transport, whose name (address_pipe) is conventional, is automatically
used by Exim when a local part that is expanded via an alias or forward
file causes delivery to a pipe. Any output from the pipe is returned to the
sender of the message. The third local transport is

  address_file:
    driver = appendfile

This transport, whose name (address_file) is conventional, is automatically
used by Exim when a local part that is expanded via an alias or forward
file causes delivery to a specified file. The final local transport is

  address_reply:
    driver = autoreply

This transport, whose name (address_reply) is conventional, is automati-
cally used by Exim when a local part that is expanded via a filter file
causes an automatic reply to a message to be generated. The only remote
transport is

  remote_smtp:
    driver = smtp;

This transport is used to do external deliveries over SMTP, with default
options.


34.3 Director configuration settings

Three directors are specified for the default configuration. Note that the
order of director definitions matters. The first director causes local
parts to be checked against the system alias file, which is searched
linearly:

  system_aliases:
    driver = aliasfile;
    file = /etc/aliases,
    search_type = lsearch

The second director comes into play if a local part does not match a system
alias:

  userforward:
    no_verify,
    driver = forwardfile;
    file = .forward,
  # filter

An attempt is made to look for a file called .forward in the home directory
of a local user. However, this director is skipped when verifying
addresses. The filter option is commented out in the default configuration.
Thus .forward files are treated in the conventional manner, but filtering
can be enabled by removing the # character. The final director is

  localuser:
    driver = localuser,
    transport = local_delivery;

This checks that a local part is the login of a local user, and if so,
directs the message to be delivered using the local_delivery transport.


34.4 Router configuration settings

Two routers are defined in the default configuration. The first is

  lookuphost:
    driver = lookuphost,
    transport = remote_smtp;

and its default settings cause it to look up the domain in the DNS, in
order to determine the host to which a message should be sent, using the
smtp transport. The second router is

  literal:
    driver = ipliteral,
    transport = remote_smtp;

This handles 'domains' that are actually RFC 822 domain literals, that is,
IP addresses enclosed in square brackets.


34.5 Retry rules

A single retry rule is given in the default configuration:

  *    *   F,2h,15m; G,16h,2h,1.5; F,4d,8h

This causes any temporarily failing address to be retried every 15 minutes
for 2 hours, then at intervals increasing by a factor of 1.5 until 16 hours
have passed, then every 8 hours up to 4 days.


34.6 Rewriting configuration

There are no explicit rewriting rules in the default configuration file.



                         35. DAY-TO-DAY MANAGEMENT


This chapter describes some of the regular tasks that need to be done to
keep Exim running smoothly.


35.1 The reject log

If checking of sender addresses on incoming mail is enabled, the headers of
rejected messages are written to the reject log. Other rejections also       |
cause entries in this log, which should be regularly checked to ensure that  |
the checking is working properly, and to pick up errors such as missing DNS
entries.


35.2 Log cycling

The exicyclog script (see chapter 41) cycles the names of log files,
compresses all but the most recent, and deletes the oldest. This should be
run at intervals dependent on the amount of mail traffic. For a system with
a reasonable amount of mail, running it daily via cron is suggested.


35.3 Statistics

The eximstats script (see chapter 41) produces statistics about messages
received and delivered, by analysing log files.


35.4 What is Exim doing?

On systems that can restart a system call after receiving a signal, Exim
responds to the SIGUSR1 signal by writing a line describing what it is
doing to its processlog file. The exiwhat script (see chapter 41) sends the
signal to all Exim processes it can find, having first emptied the log
file. It then waits a bit before displaying the results. In order to run
exiwhat successfully you have to have sufficient privilege to send the
signal to the Exim processes, so it is normally run as root.

When the number of processes handling incoming SMTP calls is limited by
setting the smtp_accept_max option, the daemon uses the SIGCHLD signal to
detect when any of its subprocesses finishes. On some operating systems
this signal sometimes gets lost when the system is very busy. However,
Exim's daemon cleans up subprocesses every time it wakes up, so even if
SIGCHLD doesn't happen, the completion of subprocesses should eventually
get noticed.


35.5 Changing the configuration

A changed configuration file is picked up immediately by any Exim processes
that are subsequently started, and by any existing process that re-execs
Exim, but it will not be noticed by any existing processes. The daemon
process can be caused to restart itself by sending it the SIGHUP signal,
which should also be sent when a new version of the Exim binary is
installed. Restarting causes its process id to change. The current process
id is written to a file whose name depends on the type of daemon being run.
By default, the file is written in Exim's spool directory, but a compile-
time configuration of PID_FILE_PATH can be used to cause it to be placed
elsewhere. When the daemon is both listening for incoming SMTP on the
standard port and periodically starting queue runner processes, the file is
called exim-daemon.pid. If it is doing only one of these things, the option
that started it (either -bd or -q<time>) is added to the file name. It is
not necessary to use SIGHUP when changing the contents of any files
referred to in the configuration (e.g. alias files) since each delivery
process reads such files independently.


35.6 Watching the queue

The queue of messages awaiting delivery can be examined by running the Exim
monitor (see chapter 42), or by obeying "exim -bp" periodically. If any
messages are frozen, their header files and message log files should be
examined to determine the cause of the problem. Once the problem is
believed to be fixed, the messages can be unfrozen by the administrator,
who can also kick off an immediate delivery attempt, and also change
recipient and sender addresses if necessary.



                     36. INTERMITTENTLY CONNECTED HOSTS


It is becoming quite common (because it is cheaper) for hosts to connect to
the Internet periodically rather than remain connected all the time. The
normal arrangement is that mail for such hosts accumulates on a system that
is permanently connected.

If such a 'holding system' is running Exim, then it should be configured
with a long retry period for the intermittent host. For example:

  cheshire.wonderland.fict.book    *   F,24h,5d

This stops a lot of failed delivery attempts from occurring, but Exim
remembers which messages it has queued up for that host. Once the
intermittent host comes online, forcing delivery of one message (either by
using the -M or -R options, or by using the ETRN SMTP command - see          |
smtp_etrn_hosts) causes all the queued up messages to be delivered, often    |
down a single SMTP connection. While the host remains connected, any new
messages get delivered immediately.



                       37. AUTOMATIC MAIL PROCESSING


This chapter describes some of the ways in which incoming mail can be
processed automatically, either on a system-wide basis, or as specified by
individual users.


37.1 System-wide automatic processing

Simple re-addressing of messages can be handled by aliasfile or forwardfile
directors. The particular case of mailing lists is covered in the following
chapter. Other kinds of automatic processing can be handled by suitable
configurations of directors and transports. As an example, here is an
extract from the configuration of a system which tries to send back helpful
information when a message is received for an unknown user. The last
director in the configuration is:

  unknownuser:
    no_verify,
    driver = smartuser,
    transport = unknownuser_pipe;

This collects all the addresses whose local parts haven't been matched by
any other director, and directs them to a special pipe transport, whose
configuration is:

  unknownuser_pipe:
    driver = pipe;
    command = /opt/exim/util/baduser.sh,
    ignore_status,
    return_output,
    user = nobody

The script is run as the user 'nobody', and it applies heuristics and a
"soundex" search to the local part, in an attempt to produce a list of
possible users for whom the message might have been intended. This is then
included in a message that is written to its standard output; Exim picks
this up and returns it to the sender as part of the delivery error message.

System-wide automatic processing on a per-address basis that depends on the
contents of messages can be implemented by means of a system mail filter
file, using a director such as the following:

  system_filter:
    no_verify,
    driver = forwardfile;
    no_check_local_user,
    filter,
    file = /etc/system-mail-filter,
    user = nobody

See the separate document entitled "Exim's User interface to mail filter-
ing" which describes the available filtering commands. Care should be taken
to ensure that none of the commands in the filter file specify a
significant delivery if the message is to go on to be delivered to its
intended recipient. The director will not then claim to have dealt with the
address, so it will be passed on to subsequent directors to be delivered in
the normal way. Note that a traditional .forward file does not have this
property, so cannot be used in this way, though you could use it to forward
all mail for a particular domain to a single recipient in a different
domain.

A filter set up as above will be run once for each local part in a message.
Sometimes there is a requirement to inspect a message once, independently
of the recipient addresses, for example, as a weapon against mail bombs and
spam. The message_filter option can be used to set up a filter file that is
run once before any routing or directing is done. In addition to the normal
message facilities, the filtering commands freeze and fail are available in
this case, causing the message to be frozen or to fail, respectively.
Alternatively, the filter may divert delivery to some other address(es) or
add addresses to the existing recipients list.


37.2 Users' automatic processing

Users can cause their mail to be processed automatically by creating
.forward files, provided that Exim's configuration contains an appropriate
forwardfile director. Traditionally, such files contain just a list of
forwarding addresses, local files, and pipe commands, but if the
forwardfile director has the filter option set, users can access Exim's
filtering facilities by beginning a .forward file with the text '# Exim
filter'. 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 name .forward is purely conventional; a forwardfile director can be
configured to use any arbitrary name. As there are some finger daemons that
display the contents of users' .forward files, some sites might like to use
a different name when mail filtering is provided.

What users may do in their .forward files can be constrained by various
options of the forwardfile director:

 .   If the filter option is not set, then only traditional .forward files
     are permitted.

 .   If the forbid_file option is set, then neither a traditional .forward
     file, nor a filter file may direct that a message be appended to a
     particular local file. An attempt to do so causes a delivery error.

 .   if the forbig_log option is set, then the use of the log command in a
     filter file is not permitted.

 .   If the forbid_pipe option is set, then neither a traditional .forward
     file, nor a filter file may direct that a message be piped to a user-
     specified command. An attempt to do so causes a delivery error.

 .   If the forbid_reply option is set, then a filter file may not direct
     that a new mail message be created. An attempt to do so causes a
     delivery error.

If piping is permitted, the pipe transport that is used (conventionally
called address_pipe) can constrain the command to be taken from a particu-
lar set of files. Pipe commands generated from traditional .forward files
are not string-expanded, but when a pipe command is generated in a filter
file, each argument is separately expanded.

If delivery to specified files is permitted, the appendfile transport that
is used (conventionally called address_file) can specify that the file must
already exist, or can restrict the whereabouts of its creation by means of
the create_file option.


37.3 Simplified vacation processing

The traditional way of running the "vacation" program is for a user to set
up a pipe command in a .forward file. This is prone to error by
inexperienced users. There are two features of Exim that can be used to
make this process simpler for users:

 .   A local part prefix such as 'vacation-' can be specified on a director
     which causes the message to be delivered directly to the "vacation"
     program, or uses Exim's autoreply transport. The contents of a user's
     .forward file are then much simpler. For example:

       spqr, vacation-spqr

 .   The require_files generic director option can be used to trigger a
     vacation delivery by checking for the existence of a certain file in
     the user's home directory. The unseen generic option should also be
     used, to ensure that the original delivery also proceeds. In this
     case, all the user has to do is to create a file called, say,
     .vacation, containing a vacation message.

Another advantage of both these methods is that they both work even when
the use of arbitrary pipes by users is locked out.



                        38. MULTIPLE USER MAILBOXES


The wild card facility of the generic prefix and suffix options for
directors allows you to configure Exim to permit users to make use of
arbitrary local part prefixes or suffixes in any way they wish. A director
such as

  userforward:
    suffix = -*,
    suffix_optional,
    driver = forwardfile;
    filter,
    file = .forward

runs a user's .forward file for all local parts of the form "username-*".
Within the filter file the user can distinguish different cases by testing
the variable local_part_suffix. For example:

  if $local_part_suffix contains -special then
    save /home/$local_part/Mail/special
  endif

If the filter file does not exist, or does not deal with such addresses,
they fall through to subsequent directors, and, assuming no subsequent use
of the suffix option is made, they presumably fail. Thus users have control
over what suffixes are valid.

Alternatively, a suffix can be used to trigger the use of a different
.forward file - which is the way a similar facility is implemented in
another MTA:

  userforward:
    suffix = -*,
    suffix_optional,
    driver = forwardfile;
    filter,
    file = .forward${local_part_suffix}

If there is no suffix, .forward is used; if the suffix is "-special", for
example, then .forward-special is used. Once again, if the appropriate file
does not deal with the address, it is passed on to subsequent directors.



                   39. USING EXIM TO HANDLE MAILING LISTS


The forwardfile director can be used to handle mailing lists where each
list is maintained in a separate file, which can therefore be managed by an
independent manager. The domains director option can be used to run these
lists in a separate domain from normal mail. For example:

  lists:
    driver = forwardfile,
    domains = lists.ref.book,
    no_more;
    file = /opt/lists/${local_part},
    no_check_local_user,
    forbid_pipe,
    forbid_file,
    errors_to = ${local_part}-request@lists.ref.book

The domain lists.ref.book must appear as one of the domains in the
local_domains configuration option. This director is used only when an
address refers to that domain. Because the no_more option is set, if the
local part of the address does not match a file in the /opt/lists
directory, causing the director to fail, no subsequent directors are tried,
and the whole delivery fails.

The no_check_local_user option stops Exim insisting that the local part is
the login id of a local user, and because no user or group is specified, no
check is made on the ownership of the file. The forbid_pipe and forbid_file
options prevent a local part from being expanded into a file name or a pipe
delivery.

The errors_to option specifies that an delivery errors caused by addresses
taken from a mailing list are to be sent to the given address rather than
the original sender of the message. However, before acting on this, Exim
verifies the error address, and ignores it if verification fails. For
example, mail sent to dicts@lists.ref.book is passed on to those addresses
contained in /opt/lists/dict with error reports directed to dicts-
request@lists.ref.book, provided that there is a file called
/opt/lists/dicts-request, presumably containing the address(es) of this
particular list's manager(s).

More complicated schemes can be set up, for example, by using the prefix or
suffix director options to handle addresses of the form owner-xxx or xxx-
request differently.

If an entry in a forward file contains a syntax error, Exim normally defers  |
delivery of the entire message. This may not be appropriate when the list    |
is being maintained automatically from address texts supplied by users. If   |
the skip_syntax_errors option is set on the forwardfile director, it just    |
skips entries that fail to parse, noting the incident on the log.            |

It is not advisable to have list files that are NFS mounted, since the
absence of the mount cannot be distinguished from a non-existent file. One
way round this is to use an aliasfile director where the alias file is
local and contains a list of the lists, and each alias expansion is simply
an 'include' item to get the list from a separate, NFS mounted file. If
no_freeze_missing_include is set for the aliasfile director, an unavailable
file then just causes delivery to be deferred.



                            40. VIRTUAL DOMAINS


There are a number of ways in which virtual domains can be handled in Exim.
As this seems to be quite a common requirement, some ways of doing this are
described here. These are not the only possibilities.


40.1 All mail to a given host

Simply sending all mail for a domain to a given host isn't really a virtual
domain; it is just a routing requirement that can be handled by a
domainlist router.

To send all mail for a domain to a particular local part at a given host,
define the domain as local, then process it with a smartuser director that
sets the new delivery address and passes the message to an smtp transport
which specifies the host. Alternatively, use a forwardfile director point-
ing to a fixed file name; the file can contain any number of addresses to
which each message is forwarded.


40.2 Virtual domain not preserving envelope

A virtual domain that does not preserve the envelope information when
delivering can be handled by an alias file defined for a local domain. If
you are handling a large number of local domains, you can define them as a
file lookup. For example:

  local_domains = "your.normal.domain:\
                   dbm;/customer/domains"

Where /customer/domains is a dbm file built from a source file that
contains just a list of domains:

  # list of virtual domains for customers
  customer1.domain
  customer2.domain

This can be turned into a dbm file by exim_dbmbuild.

You can then set up a director to handle the customer domains, arranging a
separate alias file for each domain. A single director can handle all of
them if the names follow a fixed pattern. Permissions can be arranged so
that appropriate people can edit the alias files. The domains option
ensures that this director is used only for the customer domains. The DBM
file lookup is cached, so it isn't too inefficient to do this. The no_more
setting ensures that if the lookup fails, Exim gives up on the address
without trying any subsequent directors.

  virtual:
    domains = dbm;/customer/domains,
    driver = aliasfile,
    no_more;
    file = /etc/mail/$domain,
    search_type = lsearch

A succesful aliasing operation results in a new envelope recipient address,
which is then directed or routed from scratch.


40.3 Virtual domain preserving envelope

If you want to arrange for mail for a given domain to be sent on to a host
that is dependent on the local part, without changing the envelope
recipient of the message, then the following is one way of doing it.

Set up the domains as local, and create an aliasfile director for them, as
above, but in addition, specify a transport for the director:

  virtual:
    domains = dbm;/customer/domains,
    driver = aliasfile,
    transport = virtual_smtp,
    no_more;
    file = /etc/mail/$domain,
    search_type = lsearch

Each domain has its own alias file, but the provision of a transport means
that this is used purely as a check list of local parts. The data portion
of each alias is not used.

The transport has to look up the appropriate host to which the message must
be sent:

  virtual_smtp:
    driver = smtp;
    hosts = ${lookup{$domain}dbm{/virtual/routes}{$value}fail}

The file /virtual/routes contains lines of the form

  customer1.domain:  cust1.host
  customer2.domain:  cust2.host

and the messages get delivered with RCPT TO (the envelope) containing the
original destination address (e.g. postmaster@customer1.domain). In fact,
you could use the same file for /virtual/routes and /customer/domains,
since the lookup on the latter doesn't make any use of the data - it's just
checking that the file contains the key.



                             41. EXIM UTILITIES


A number of utility scripts and programs are supplied with Exim. Most of
them are built as part of the normal building process, but the log file
analyser is entirely free-standing.


41.1 Querying Exim processes

The shell script called exiwhat first of all empties the processlog file in
Exim's log directory. It then uses the ps command to find all processes
running exim, and sends each one the SIGUSR1 signal. This causes each
process to write a single line describing its current activity to the
processlog file. The script waits a bit, then copies the file to the
standard output.

Unfortunately, the ps command varies between different versions of Unix.
Not only are different options used, but the format of the output is
different. For this reason, there are some system configuration options
that configure exactly how exiwhat works. If it doesn't seem to be working
for you, check the following compile-time options:

  EXIWHAT_PS_ARG     the argument for ps
  EXIWHAT_EGREP_ARG  the argument for egrep to select from ps output
  EXIWHAT_KILL_ARG   the argument for the kill command

This facility is available only in operating systems where a signal handler
can be set up such that an interrupted system call is resumed when the
signal handler has finished. An example of typical output from exiwhat is

  164 0.53 daemon: -q1h, listening on port 25
10483 0.54 running queue: waiting for 0tAycK-0002ij-00 (10492)
10492 0.54 delivering 0tAycK-0002ij-00 to mail.ref.book [42.42.42.42]
  (editor@ref.book)
10592 0.53 handling incoming call from [245.211.243.242]
10628 0.54 accepting a local non-SMTP message

The first number in the output line is the process number; the second is
the Exim version number. The third line has been split here, in order to
fit it on the page. Because Exim processes run under a variety of uids, it
is necessary to run exiwhat as root in order to be able to send the signal
to all Exim processes.


41.2 Extracting log information

The exigrep utility is a Perl script, provided in the util directory, that
extracts from one or more log files all entries relevant to any message
whose log entries contain at least one that matches a given pattern. The
pattern match is case-insensitive. Thus one can search for all mail for a
given user or a given host, for example. The usage is:

  exigrep [-l] <pattern> [<log file>] ...

where the -l flag means 'literal', that is, treat all characters in the
pattern as standing for themselves. Otherwise the pattern must be a Perl
regular expression. If no file names are given on the command line, the
standard input is read.


41.3 Cycling log files

The exicyclog script cycles the main and reject log files. Each time it is
run the files get 'shuffled down' by one. The mainlog file becomes
mainlog.1, the previous mainlog.1 becomes mainlog.2 and so on, up to a
limit which is set in the script, and which defaults to 10. However, if no
mainlog file exists, the script does nothing. Reject logs are handled
similarly. Files that 'drop off' the end are deleted. All files with
numbers greater than 1 are compressed, using a compression command which is
configured in the script.

It is usual to run exicyclog daily from a crontab entry of the form

  1 0 * * *  /opt/exim/bin/exicyclog

In this way, each day's log is (mostly) in a separate file. There will be
some overlap from processes that have the log open at the time of renaming.

The exicyclog script can be run as the Exim user when one is defined, as
the log files will be owned by that user in that case. Otherwise it has to
be run as root.


41.4 Making DBM files

The exim_dbmbuild program reads an input file in the format of an alias
file (see chapter 20) and writes a DBM database using the lower-cased alias
names as keys and the remainder of the information as data. Two arguments
are required: the name of the input file (which can be a single hyphen to
indicate the standard input), and the base name of the output database. For
example:

  exim_dbmbuild /etc/aliases /etc/aliases

reads the system alias file and creates a DBM database using /etc/aliases
as the base name. In systems that use the ndbm routines, the database
consists of two files called (in this case) /etc/aliases.dir and
/etc/aliases.pag, while in systems using the ndbm interface to the db
routines a single file called /etc/aliases.db is used. If the native db
interface is in use (USE_DB is set in a compile-time configuration file)
then a single file with no added prefix is used. In this case the two file
names on the command line must be different. The utility in fact creates
the database under a temporary name, and then renames the file(s).


41.5 Individual retry times

A utility called exinext (mostly a perl script) provides the ability to
fish specific information out of the retry database. Given a mail domain
(or a complete address), it looks up the hosts for that domain, and outputs
any retry information. At present, the retry information is obtained by
running exim_dumpdb (see below) and post-processing the output. For
example:

  exinext piglet@milne.fict.book
  kanga.milne.fict.book:100.100.8.1 error 146: Connection refused
    first failed: 21-Feb-1996 14:57:34
    last tried:   21-Feb-1996 14:57:34
    next try at:  21-Feb-1996 15:02:34
  roo.milne.fict.book:100.100.8.3 error 146: Connection refused
    first failed: 20-Jan-1996 13:12:08
    last tried:   21-Feb-1996 11:42:03
    next try at:  21-Feb-1996 19:42:03
    past final cutoff time

You can also give exinext a local local_part, without a domain, and it will
give any retry information for it. Exinext is not particularly efficient,
but then it isn't expected to be run very often.


41.6 Database maintenance

Three utility programs are provided for maintaining the DBM files that Exim
uses to contain its delivery hint information. Each program requires two
arguments. The first specifies the name of Exim's spool directory, and the
second is the name of the database it is to operate on. These are as
follows:

 .   retry: the database of retry information

 .   reject: the database of information about rejected messages

 .   wait-smtp: the database of information about messages waiting for SMTP
     hosts

 .   serialize-smtp: the database of information about current connections   |
     to hosts which are restricted to one connection at once                 |
                                                                             |
The entire contents of a database are written to the standard output by the
exim_dumpdb program, which has no options or arguments other than the spool
and database names. For example, to dump the retry database:

  exim_dumpdb /var/spool/exim retry

Two lines of output are produced for each entry:

    T:mail.ref.book:242.242.242.242 146 77 Connection refused
  31-Oct-1995 12:00:12  02-Nov-1995 12:21:39  02-Nov-1995 20:21:39 *

The first item on the first line is the key of the record. It starts with
one of the letters D, R, or T, depending on whether it refers to a
directing, routing, or transport retry. For a local delivery, the next part
is the local address; for a remote delivery it is the name of the remote
host, followed by its failing IP address. Then there follows an error code,
an additional error code, and a textual description of the error.

The three times on the second line are the time of first failure, the time
of the last delivery attempt, and the computed time for the next attempt.
The line ends with an asterisk if the cutoff time for the last retry rule
has been exceeded.

Each output line from exim_dumpdb for the reject database consists of a
date and time, followed by the letter T or F, followed by the address that
was rejected, followed by the name of the host that sent the bad address
(as given in the SMTP HELO command). The letter is F if only one previous
rejection of this address has been done recently, and T if a second has
occurred, causing rejection of the MAIL FROM command, and subsequently
rejection of the RCPT TO commands.

Each output line from exim_dumpdb for the wait-smtp database consists of a
host name followed by a list of ids for messages that are or were waiting
to be delivered to that host. If there are a very large number for any one
host, continuation records, with a sequence number added to the host name,
may be seen. The data in these records is often out of date, because a
message may be routed to several alternative hosts, and Exim makes no
effort to keep cross references.

Each output line from exim_dumpdb for the serialize-wmtp database consists   |
of a host name preceded by the time that Exim made a connection to that      |
host. Exim keeps track of connections only for those hosts or networks that  |
have been configured for serialization.                                      |

The exim_tidydb utility program is used to tidy up the contents of the
databases. If run with no options, it removes all records from a database
that are more than 30 days old. The cutoff date can be altered by means of
the -t option, which must be followed by a time. For example, to remove all
records older than a week from the retry database:

  exim_tidydb -t 7d /var/spool/exim retry

For the wait-smtp database, the -f option can also be used (it has no
effect for other databases). This causes a check to be made to ensure that
message ids in database records are those of messages that are still on the
queue. Other message ids are removed, and if this leaves records empty,
they are also removed.

The exim_tidydb utility outputs comments on the standard output whenever it
removes information from the database. It is suggested that it be run
periodically on all three databases, but at a quiet time of day, since it
requires a database to be locked (and therefore inaccessible to Exim) while
it does its work.

The exim_fixdb program is a utility for interactively modifying databases.
Its main use is for testing Exim, but it might also be occasionally useful
for getting round problems in a live system. It has no options, and its
interface is somewhat crude. On entry, it prompts for input with a >
character. A key of a database record can then be entered, and the data for
that record is displayed.

If 'd' is typed at the next prompt, the entire record is deleted. For the
reject, wait-smtp, and serialize-smtp databases, that is the only operation
that can be carried out. For the retry database, each field is output
preceded by a number, and data for individual fields can be changed by
typing the field number followed by new data, for example:

  > 4 951102:1000

resets the time of the next delivery attempt. Time values are given as a
sequence of digit pairs for year, month, day, hour, and minute. Colons can
be used as optional separators.


41.7 Mail statistics

A Perl script called eximstats is supplied in the util directory. This has   |
been hacked about quite a bit over time. It now gives quite a lot of         |
information by default, but there are options for suppressing various parts  |
of it. Following any options, the arguments to the script are a list of      |
files, which should be main log files.                                       |
                                                                             |
Eximstats extracts information about the number and volume of messages       |
received from or delivered to various hosts. The information is sorted both  |
by message count and by volume, and the top 50 hosts in each category are    |
listed on the standard output. For messages delivered and received locally,  |
similar statistics are produced per user.                                    |
                                                                             |
The output also includes total counts and statistics about delivery errors,  |
and histograms showing the number of messages received and deliveries made   |
in each hour of the day. A delivery with more than one address in its        |
'envelope' (e.g. an SMTP transaction with more than one RCPT TO command) is  |
counted as a single delivery by eximstats.                                   |
                                                                             |
Though normally more deliveries than receipts are reported (as messages may  |
have multiple recipients), it is possible for eximstats to report more       |
messages received than delivered, even though the spool is empty at the      |
start and end of the period in question. If an incoming message contains no  |
valid recipients, no deliveries are recorded for it. An error report is      |
handled as an entirely separate message.                                     |
                                                                             |
Eximstats always outputs a grand total summary giving the volume and number  |
of messages received and deliveries made, and the number of hosts involved   |
in each case. It also outputs the number of messages that were delayed       |
(that is, not completely delivered at the first attempt), and the number     |
that had at least one address that failed.                                   |
                                                                             |
The remainder of the output is in sections that can be independently         |
disabled or modified by various options. It consists of a summary of         |
deliveries by transport, histograms of messages received and delivered per   |
time interval (default per hour), information about the time messages spent  |
on the queue, a list of relayed messages, lists of the top 50 sending        |
hosts, local senders, destination hosts, and destination local users by      |
count and by volume, and a list of delivery errors that occurred. The        |
options are as follows:                                                      |
                                                                             |
                                                                             |
-nt    Suppress the statistics about delivery by transport.                  |
                                                                             |
-h<n>  This option controls the histograms of messages received and deliv-   |
       eries per time interval. By default the time interval is one hour.    |
       If -h0 is given, the histograms are suppressed; otherwise the value   |
       of <n> gives the number of divisions per hour, so -h2 sets an         |
       interval of 30 minutes, and the default is equivalent to -h1.         |
                                                                             |
-q0    Suppress information about times messages spend on the queue.         |
                                                                             |
-q<n1>...                                                                    |
       This option sets an alternative list of time intervals for the        |
       queueing information. The values are separated by commas and are in   |
       seconds, but can involve arithmetic multipliers, so for example you   |
       can set 3*60 to specify 3 minutes. A setting such as                  |
                                                                             |
         -q60,5*60,10*60                                                     |
                                                                             |
       causes eximstats to give counts of messages that stayed on the queue  |
       for less than one minute, less than five minutes, less than ten       |
       minutes, and over ten minutes.                                        |
                                                                             |
-nr    Suppress information about messages relayed through this host.        |
                                                                             |
-nr/pattern/                                                                 |
       Suppress information about relayed messages that match the pattern,   |
       which is matched against a string of the form                         |
                                                                             |
         H=<host> A=<address> => H=<host> A=<address>                        |
                                                                             |
       for example                                                           |
                                                                             |
         H=in.host A=from@some.where => H=out.host A=to@else.where           |
                                                                             |
       The addresses are taken from the envelope, not the headers. This      |
       option allows you to screen out hosts whom you are happy to have      |
       using your host as a relay.                                           |
                                                                             |
-t<n>  Sets the 'top' count to <n>. This controls the listings of the 'top   |
       <n>' hosts and users by count and volume. The default is 50, and      |
       setting 0 suppresses the output altogether.                           |
                                                                             |
-tnl   Omit local information from the 'top' listings.                       |
                                                                             |
-ne    Suppress the list of delivery errors.                                 |
                                                                             |


                            42. THE EXIM MONITOR


The Exim monitor is an application which displays in an X window infor-
mation about the state of Exim's queue and what Exim is doing. An admin
user can perform certain operations on messages from this GUI interface;
however all such facilities are also available from the command line.


42.1 Running the monitor

The monitor is started by running the script called eximon. This is a shell
script which sets up a number of environment parameters, and then runs the
binary called eximon.bin. The appearance of the monitor window can be
changed by editing the Local/eximon.conf file created by editing
exim_monitor/EDITME. Comments in that file describe what the various
parameters are for.

The parameters that get built into the eximon script can be overridden for
a particular invocation by setting up environment variables of the same
names, preceded by EXIMON_. For example, a command such as

  EXIMON_LOG_DEPTH=400 eximon

overrides the setting of the LOG_DEPTH parameter. X resources can be used
to change the appearance of the window in the normal way. For example, a
resource setting of the form

  Eximon*background: gray94

changes the colour of the background to light grey rather than white. The
stripcharts are drawn with both the data lines and the reference lines in
black. This means that the reference lines are not visible when on top of
the data. However, their colour can be changed by setting a resource called
'highlight' (an odd name, but that's what the Athena stripchart widget
uses). For example, if your X server is running Unix, you could set up
lighter reference lines in the stripcharts by obeying

  xrdb -merge <<End
  Eximon*highlight: gray
  End

In order to see the contents of messages on the spool, and to operate on
them, eximon must either be run as root or by an admin user, that is, a
user who is a member of the Exim group (when one is defined).

The monitor's window is divided into three parts. The first contains one or
more stripcharts and two action buttons, the second contains a 'tail' of
the main log file, and the third is a display of the queue of messages
awaiting delivery.


42.2 The stripcharts

The first stripchart is always a count of messages on the queue. The
remaining ones are defined in the configuration script by regular
expression matches on log file entries, making it possible to display, for
example, counts of messages delivered to certain hosts or using certain
transports. The supplied defaults display counts of received and delivered
messages, and of local and SMTP deliveries. The default period between
stripchart updates is one minute; this can be adjusted by a parameter in
the Local/eximon.conf file.

It is also possible to have a stripchart which shows the percentage
fullness of a particular disc partition, which is useful when local
deliveries are confined to a single partition. This relies on the avail-
ability of the statvfs function or equivalent in the operating system.
Most, but not all versions of Unix that support Exim have this.

The stripchart displays rescale themselves automatically as the value they
are displaying changes. There are always 10 horizontal lines in each chart;
the title string indicates the value of each division when it is greater
than one. For example, 'x2' means that each division represents a value
of 2.


42.3 Main action buttons

Below the stripcharts there is an action button for quitting the monitor.
Next to this is another button marked 'Size'. They are placed here so that
shrinking the window to its default minimum size leaves just the queue
count stripchart and these two buttons visible. Pressing the 'Size' button
causes the window to expand to its maximum size, unless it is already at
the maximum, in which case it is reduced to its minimum. When expanding to
the maximum, the window is moved if it will not all be visible at the
current position. When it is expanding from its minimum size, the old
position is remembered, and next time it is reduced to the minimum it is
moved back there.

The idea is that you can keep a reduced window just showing one or two
stripcharts at a convenient place on your screen, easily expand it to show
the full window when required, and just as easily put it back to what it
was. The idea is copied from what the twm window manager does for its
f.fullzoom action. The minimum size of the window can be changed by setting
the MIN_HEIGHT and MIN_WIDTH values in Local/eximon.conf.


42.4 The log display

The second section of the window is an area in which a display of the tail
of the main log is maintained. This has a scroll bar at its lefthand side
which can be used to move back to look at earlier text, and the arrow keys
also have this effect. Similarly, there is a horizontal scroll bar for
accessing long log lines. Text can be cut from this part of the window
using the mouse in the normal way. The size of this subwindow is controlled
by parameters in the configuration file Local/eximon.conf.

Searches of the text in the log window can be carried out by means of the
^R and ^S keystrokes, which default to a reverse and forwards search
respectively. The search covers only the text that is displayed in the
window. It cannot go further back up the log.

The point from which the search starts is indicated by a caret marker. This
is normally at the end of the text in the window, but can be positioned
explicitly by pointing and clicking with the left mouse button, and is
moved automatically by a successful search. If new text arrives in the
window when it is scrolled back, the caret remains where it is, but if the
window is not scrolled back, the caret is moved to the end of the new text.

Pressing ^R or ^S pops up a window into which the search text can be typed.
There are buttons for selecting forward or reverse searching, for carrying
out the search, and for cancelling. If the 'Search' button is pressed, the
search happens and the window remains so that further searches can be done.
If the 'Return' key is pressed, a single search is done and the window is
closed. If ^C is pressed the search is cancelled.

The searching facility is implemented using the facilities of the Athena     |
text widget. By default this pops up a window containing both 'search' and   |
'replace' options. In order to suppress the unwanted 'replace' portion for   |
eximon, a modified version of the TextPop widget is distributed with Exim.   |
However, the linkers in BSDI and HP-UX seem unable to handle an externally   |
provided version of TextPop when the remaining parts of the text widget      |
come from the standard libraries. The compile-time option EXIMON_TEXTPOP     |
can be unset to cut out the modified TextPop, making it possible to build    |
Eximon on these systems, at the expense of having unwanted items in the      |
search popup window.                                                         |


42.5 The queue display

The bottom section of the monitor window contains a list of all messages
that are on the queue, which includes those currently being received or
delivered, as well as those awaiting delivery. The size of this subwindow
is controlled by parameters in the configuration file Local/eximon.conf,
and the frequency at which it is updated is controlled by another parameter
in the same file - the default is 5 minutes, since queue scans can be quite
expensive. However, there is an 'Update' action button just above the
display which can be used to force an update of the queue display at any
time.

When a host is down for some time, a lot of pending mail can build up for
it, and this can make it hard to deal with other messages on the queue. To
help with this situation there is a button next to 'Update' called 'Hide'.
If pressed, a dialogue box called 'Hide addresses ending with' is put up.
If you type anything in here and press 'Return', the text is added to a
chain of such texts, and if all the undelivered addresses of a messasge
match one or other of the texts, the message is not displayed.

If any address matches none of the texts, all the addresses are displayed
as normal. The matching happens on the ends of addresses so, for example,
cam.ac.uk specifies all addresses in Cambridge, while xxx@foo.com specifies
just one specific address. When there are any hide texts in existence, a
button called 'Unhide' is displayed. If pressed, it cancels all hiding.
Also, to ensure that hidden messages don't get forgotten, a hide text is
automatically cancelled after one hour.

While the dialogue box is displayed, you can't press any buttons or do
anything else to the monitor window. For this reason, if you want to cut
text from the queue display to use in the dialogue box, you have to do the
cutting before pressing the 'Hide' button.

The queue display contains, for each unhidden queued message, the length of
time it has been on the queue, the size of the message, the message id, the  |
message sender, and the first undelivered recipient, all on one line. If it
is a delivery error message, the sender is shown as <>. If there is more
than one recipient to which the message has not yet been delivered,
subsquent ones are listed on additional lines, up to a maximum configured
number, following which an ellipsis is displayed. Recipients that have
already received the message are not shown. If a message is frozen, an
asterisk is displayed at the left-hand side.

The queue display has a vertical scroll bar, and can also be scrolled by
means of the arrow keys. Text can be cut from it using the mouse in the
normal way. The text searching facilities, as described above for the log
window, are also available, but the caret is always moved to the end of the
text when the queue display is updated.


42.6 The queue menu

If the shift key is held down and the left button is clicked when the mouse
pointer is over the text for any message, an action menu pops up, and the
first line of the queue display for the message is highlighted. This does
not affect any selected text. If you want to use some other event for
popping up the menu, you can set the MENU_EVENT parameter in
Local/eximon.conf to change the default, or set EXIMON_MENU_EVENT in the
environment before starting the monitor. The value set in this parameter is
a standard X event description. For example, to run eximon using ctrl
rather than shift you could use

  EXIMON_MENU_EVENT='Ctrl<Btn1Down>' eximon

The title of the menu is the message id, and it contains entries which act
as follows:

 .   message log: The contents of the message log for the message are
     displayed in a new text window.

 .   headers: Information from the spool file that contains the envelope
     information and headers is displayed in a new text window. See chapter
     45 for a description of the format of spool files.

 .   body: The contents of the spool file containing the body of the
     message are displayed in a new text window. There is a default limit    |
     of 20,000 bytes to the amount of data displayed. This can be changed    |
     by setting the BODY_MAX option at compile time, or the EXIMON_BODY_MAX  |
     option at runtime.                                                      |

 .   deliver message: A call to Exim is made using the -M option to request
     delivery of the message. This causes an automatic thaw if the message
     is frozen. The -v option is also set, and the output from Exim is
     displayed in a new text window. The delivery is run in a separate
     process, to avoid holding up the monitor while the delivery proceeds.

 .   freeze message: A call to Exim is made using the -Mf option to request
     that the message be frozen.

 .   thaw message: A call to Exim is made using the -Mt option to request
     that the message be thawed.

 .   give up on msg: A call to Exim is made using the -Mg option to request
     that Exim gives up trying to deliver the message. A delivery failure
     report is generated for any remaining undelivered addresses.

 .   remove message: A call to Exim is made using the -Mrm option to
     request that the message be deleted from the system without generating
     any failure reports.

 .   add recipient: A dialog box is displayed into which a recipient
     address can be typed. If the address is not qualified and the
     QUALIFY_DOMAIN parameter is set in Local/eximon.conf, the address is
     qualified with that domain. Otherwise it must be entered as a fully-
     qualified address. Pressing RETURN causes a call to Exim to be made
     using the -Mar option to request that an additional recipient be added
     to the message, unless the entry box is empty, in which case no action
     is taken.

 .   mark delivered: A dialog box is displayed into which a recipient
     address can be typed. If the address is not qualified and the
     QUALIFY_DOMAIN parameter is set in Local/eximon.conf, the address is
     qualified with that domain. Otherwise it must be entered as a fully-
     qualified address. Pressing RETURN causes a call to Exim to be made
     using the -Mmd option to mark the given recipient address as already
     delivered, unless the entry box is empty, in which case no action is
     taken.

 .   mark all delivered: A call to Exim is made using the -Mmad option to
     mark all recipient addresses as already delivered.

 .   edit sender: A dialog box is displayed initialized with the current
     sender's address. Pressing RETURN causes a call to Exim to be made
     using the -Mes option to replace the sender address, unless the entry
     box is empty, in which case no action is taken. If the address is not
     qualified and the QUALIFY_DOMAIN parameter is set in
     Local/eximon.conf, the address is qualified with that domain.
     Otherwise it must be a fully-qualified address.

 .   edit body: A new xterm process is forked in which a call to Exim is
     made using the -Meb option in order to allow the body of the message
     to be edited. Note that the first line of the body file is the name of
     the file, and this should never be changed.

In cases when a call to Exim is made, the actual command used is reflected
in a new text window by default, but this can be turned off for all except
the delivery action by setting ACTION_OUTPUT=no in Local/eximon.conf.
However, if the call results in any output from Exim (in particular, if the
command fails) a window containing the command and the output is displayed.
Otherwise, the results of the action are normally apparent from the log and
queue displays. The latter is automatically updated for actions such as
freezing and thawing, unless ACTION_QUEUE_UPDATE=no has been set in
Local/exmin.conf. In this case the 'Update' button has to be used to force
an update to the display after freezing or thawing.

In any text window that is displayed as result of a menu action, the normal
cut-and-paste facility is available, and searching can be carried out using
^R and ^S, as described above for the log tail window.



                            43. SMTP PROCESSING


Two kinds of SMTP processing are supported: SMTP over TCP/IP, and so-called
'batched SMTP'. The latter is the name for a process in which batches of
messages are stored in files, using SMTP commands as separators and to
contain the envelope information. Such batches are delivered to or received
from other systems using some transport mechanism other than Exim. For each
kind of SMTP processing there are two aspects: outgoing and incoming.


43.1 Outgoing SMTP over TCP/IP

This is implemented by the smtp transport. Exim does not at present use
ESMTP for sending mail, as it has no facilities for using the information
it might get back. At some point in the future this may change.

Responses from the remote host are supposed to be terminated by CR followed  |
by LF. However, there are known to be hosts that do not send CR characters,  |
so in order to be able to interwork with such hosts, Exim treats LF on its   |
own as a line terminator.                                                    |

If a message contains a number of different addresses, all those that
resolve to the same set of hosts, in the same order, are sent in a single
SMTP transaction, even if they are for different domains, unless there are   |
more than the setting of the max_rcpts option in the smtp transport allows,  |
in which case they are split into groups containing no more than max_rcpts   |
addresses each. The order of hosts with identical MX values is not           |
significant when checking whether addresses can be batched in this way.

Exim's retry hints are based on host name plus IP address, so if one
address of a multi-homed host is broken, it will soon be skipped most of
the time. When the smtp transport suffers a temporary failure while trying
to deliver a message, Exim updates its wait-smtp database, which contains
records indexed by host name that remember which messages are waiting for
each particular host.

When a message is successfully delivered over a TCP/IP SMTP connection,
Exim looks in the wait-smtp database to see if there are any queued
messages waiting for the host to which it is connected. If it finds one, it
creates a new process using the -MC option (which can only be used by a
process running as root or the Exim user) and passes the TCP/IP socket to
it. The new process does only those deliveries that are routed to the
connected host, and may in turn pass the socket on to a third process, and
so on. The batch_max option of the smtp transport can be used to limit the
number of messages sent down a single connection. The second and subsequent
messages delivered down an SMTP connection are identified in the main log
by the addition of an asterisk after the closing square bracket of the IP
address.


43.2 Incoming SMTP over TCP/IP

Incoming SMTP messages can be accepted in one of two ways: by running a
listening daemon, or by using inetd. In the latter case, the entry in
/etc/inetd.conf should be like this:

  smtp  stream  tcp  nowait  exim  /opt/exim/bin/exim  in.exim  -bs

Exim distinguishes between this case and the case of a user agent using the
-bs option by checking whether the standard input is a socket using the
getpeername() function.

Commands from the remote host are supposed to be terminated by CR followed   |
by LF. However, there are known to be hosts that do not send CR characters,  |
so in order to be able to interwork with such hosts, Exim treats LF on its   |
own as a line terminator.                                                    |
                                                                             |
When a message is successfully received, Exim includes the local message id  |
in its response to the final '.' that terminates the data. If the remote     |
host logs this text it can help with tracing what has happened to a          |
message.                                                                     |

The Exim daemon can limit the number of simultaneous incoming connections
it is prepared to handle (see the smtp_accept_max configuration option).
Additional connection attempts are rejected using the SMTP temporary error
code 421. On some operating systems the SIGCHLD signal that is used to
detect when a subprocess has finished can get lost at busy times. However,
the daemon looks for completed subprocesses every time it wakes up, so
provided there are other things happening (new incoming calls, starts of
queue runs), the completion of processes created to handle incoming calls
should get noticed eventually. If, however, Exim appears not to be
accepting as many incoming connections as expected, sending the daemon a
SIGCHLD signal will wake it up and cause it to check for any completed
subprocesses.

Exim can reserve some SMTP slots for specific hosts or networks, and can
also be set up to reject SMTP calls from non-reserved hosts or networks at
times of high system load - for details see the smtp_accept_reserve,
smtp_load_reserve, smtp_reserve_hosts and smtp_reserve_nets configuration
options.

If the queue_only (or -odq option) option is not set, the daemon normally
starts a delivery process for each message received. However, the number of
simultaneously running delivery processes started in this way can be
limited by the smtp_accept_queue option, and the queue_only_load option can
specify a system load average above which immediate delivery is suspended.
When either limit is reached, subsequently received messages are just put
on the input queue.

The controls just described that involve counts of incoming SMTP calls
(smtp_accept_max and smtp_accept_reserve) are not available when Exim is
started up from the inetd daemon, since each connection is handled by an
entirely separate Exim process. Control by load average is, however,
available.

Exim does not normally verify the argument of an SMTP HELO or EHLO command,  |
because it might involve an expensive DNS lookup, and the message may not    |
be refused even if it is invalid. However, an SMTP server for local desktop  |
systems (which are frequently misconfigured) can normally look up their      |
host names cheaply. This improves the contents of Exim's logs by including   |
the correct host names.                                                      |
                                                                             |
The helo_verify_nets option specifies IP networks for which the argument of  |
HELO or EHLO is checked by calling gethostbyaddr(). The value returned is    |
used as the host name. Also, if no HELO or EHLO command is used, the name    |
is looked up anyway. If a HELO or EHLO argument gets corrected, an entry is  |
written to the main log at level 6 (not shown by default).                   |

The SMTP command VRFY is accepted only when the configuration option
smtp_verify is set, and if so, it runs exactly the same code as when Exim
is called with the -bv option. The SMTP commands EXPN and DEBUG are not
supported at all. Support for EXPN could be added if there were a demand
for it.

RFC 1985 describes a new SMTP command called ETRN which is designed to       |
overcome the security problems of the TURN command (which has fallen into    |
disuse). Exim recognizes ETRN if the calling host matches an entry in        |
smtp_etrn_hosts or smtp_etrn_nets. The ETRN command is concerned with        |
'releasing' messages that are awaiting delivery to certain hosts. As Exim    |
does not organize its message queue by host, the only form of ETRN that is   |
supported is the one where the text starts with the '#' prefix, where the    |
remainder of the text is specific to the SMTP server. A valid ETRN command   |
causes a run of Exim with the -R option to happen, with the remainder of     |
the ETRN text as its argument. For example,                                  |
                                                                             |
  ETRN #brigadoon                                                            |
                                                                             |
causes a delivery attempt on all messages with undelivered addresses         |
containing the text 'brigadoon'. Because a separate delivery process is run  |
to do the delivery, there is no security risk with ETRN.                     |


43.3 Host and network rejection

It is possible to configure Exim to reject SMTP calls from certain hosts,
or from certain RFC 1413 ident values at particular hosts. This is achieved
by means of the sender_host_accept and sender_host_reject options. If the
first of these is set, Exim accepts only from a host (plus ident) that
matches; however, it rejects any call that matches sender_host_reject. Thus
sender_host_reject can be used to cut out exceptions from a wildcarded item
in sender_host_accept.

Calls are rejected as a result of these options by sending a 5xx error code
as soon as the connection is received. Since this does not relate to any
particular message, the remote host is likely to keep on trying to send
mail (possibly to an alternative MX host) until it times out. This may be
what is wanted in some circumstances (for example, you want temporarily to
hold back incoming mail). However, when trying to block spam, this is not
what is wanted. There are two other options, sender_host_reject_recipients
and sender_net_reject_recipients, which cause further tests to be applied
after the normal accept/reject tests have been passed. A call from a host
which matches them is not rejected at the start; instead, every RCPT TO
command is subsequently rejected. This should cause the remote MTA to cease
trying to deliver the message.

The format of the the accept and reject options is a colon-separated list
of entries, each of which is in one of the following formats:

  <host name>
  <IP address>
  <ident>@<host name>
  <ident>@<IP address>
  !<ident>@<host name>
  !<ident>@<IP address>

When an <ident> is preceded by an exclamation mark, it matches any other
RFC 1413 identification at the given host. Compare the following examples:

  sender_host_accept = root@hub.biog.book

accepts calls only from root on the host hub.biog.book, while

  sender_host_reject = !root@hub.biog.book

accepts calls from any host except those from hub.biog.book made by a non-
root user. The host names in these entries can be wildcarded, or can be
regular expressions. However, this flexibility is gained at the cost of
performance, particularly when a daemon listener is used.

If a complete host name is given, it is looked up in the DNS when the
daemon starts up, and subsequently the checks can be performed using only
the IP address. On the other hand, if a wildcarded name is given, the check
has to be performed by doing a reverse lookup on the IP address for each
call, in order to get the host name to match against the wildcarded string.
Therefore, it is best to avoid wild cards and regular expressions wherever
possible, apart from the case of a single * character, which matches
anything.

There are corresponding options which control connections on the basis of
IP network number. These are sender_net_accept and sender_net_reject. Each
entry consists of an IP network number and a mask, separated by a slash.
For example:

  sender_net_accept = 131.111.0.0/255.255.0.0
  sender_net_reject = 131.111.8.0/255.255.255.0

accepts calls only from the 131.111.0.0 network, unless the call is from
the 131.111.8.0 subnet. The host and net tests interact - for example, a
call from a network listed in sender_net_accept is rejected if the host
appears in sender_host_reject.


43.4 Sender rejection

Incoming messages can also be rejected on the basis of the sender address,
as given in the MAIL FROM command. A list of senders to reject is set by
the sender_reject configuration option; see its description in chapter 10
for details. There is also a sender_accept option for use in special cases.  |

Some MTAs continue to try to deliver a message even after receiving a 5xx
error code for MAIL FROM. The alternative configuration option
sender_reject_recipients is provided for use in such cases. It accepts the
MAIL FROM command but rejects all subsequent RCPT TO commands. There is      |
also a corresponding sender_accept_recipients option.                        |


43.5 Control of relaying

An MTA is said to "relay" a message if it receives it from some host and     |
delivers it directly to another host as a result of a remote address         |
contained in it. Expanding a local address via an alias or forward file and  |
then passing the message on is not relaying. It is possible to control       |
which hosts or nets are permitted to pass mail through your system and on
to another MTA. The following main configuration options control this:

  sender_host_accept_relay
  sender_net_accept_relay
  sender_host_reject_relay
  sender_net_reject_relay

In addition, sender_address_relay can specify a list of acceptable sender
addresses. If any of these options is set, a check is made on incoming
recipient addresses at the time of the RCPT TO command in the SMTP
dialogue. If the domain in the address matches an entry in local_domains or
in relay_domains, the address is accepted (at least as far as this check is
concerned - a subsequent verification check may fail it).

Otherwise, the recipient address is accepted only if the host does not
match any entries in sender_host_reject_relay or sender_net_reject_relay,
if either is set, and does match an entry in one of
sender_host_accept_relay or sender_net_accept_relay, if either is set, and
in addition, if sender_address_relay is set, the sender's address from the
MAIL FROM command matches an item therein.

In other words, relay_domains specifies those remote domains to which any
host and sender may send messages via this host, while the accept, reject
and address options control which hosts and senders may use this host as a
relay to arbitrary domains. Of course, sender addresses can easily be
forged, but the sender check does mean you can prevent some kinds of
unwanted mail from going through your host.

If the recipient address is an RFC 821 source routed address, that is, an
address of the form <@hop1,@hop2:user@domain>, it is the final domain which
is tested. By default, however, Exim will send the message to the hop1
domain, unless it is a local domain. The collapse_source_routes option can
be used to prevent this.

None of this testing applies when mail is passed to Exim locally using the
-bs or -bS options, but it does apply when -bs is used from inetd.

Exim does not attempt to fully qualify domains at RCPT TO time. If an
incoming message contains a domain which is not fully qualified, it will be
treated as a non-local, non-relay domain (unless partial domains are
included in local_domains or relay_domains, but this is not recommended).
The use of domains that are not fully qualified is non-standard, but it is
a commonly encountered usage when an MTA is being used as a smart host by
some remote UA. In this situation, it would be usual to permit the UA
system to relay to any domain, so in practice there is not normally a
problem.

If you don't want to do any relaying at all, then relay_domains should be
left unset, and sender_host_reject_relay set to *, in which case the only
acceptable recipient addresses are those that contain a local domain. This
doesn't prevent a local user from setting up forwarding to to some external
system, nor does it prevent the 'percent hack' from working; you should
ensure that percent_hack_domains is left unset if you don't want to support
it.


43.6 Unqualified addresses

By default, Exim expects every address it receives from an external host to
be fully qualified. Unqualified addresses cause negative responses to SMTP
commands. However, because SMTP is used as a means of transporting messages
from MUAs running on personal workstations, there is sometimes a require-
ment to accept unqualified addresses from specified hosts or IP networks.

Exim has two pairs of options that separately control which hosts or
networks may send unqualified sender or receiver addresses in SMTP com-
mands. The options are sender_unqualified_hosts and
sender_unqualified_nets, and receiver_unqualified_hosts and
receiver_unqualified_nets. In all cases, if an unqualified address is
accepted, it is qualified by adding the value of qualify_domain or
qualify_receiver, as appropriate.


43.7 Sender verification

When the sender_verify configuration option is set, Exim checks the senders
of incoming SMTP messages, that is, the addresses given in the SMTP MAIL
FROM commands. The check is performed by running the same verification code
as is used then Exim is called with the -bv option. The check is performed
when the MAIL FROM command is received. If the address cannot immediately
be verified (typically because of DNS timeouts), a temporary failure error
response (code 451) is given to the MAIL FROM command, unless
sender_try_verify is set, in which case the message is accepted with a
warning message.

What happens if verification fails depends on the setting of the
sender_verify_reject option. If it is set (the default) then the message is
rejected. Otherwise a warning message is logged, and processing continues.

Because remote postmasters always want to see the message headers when
there is a problem, Exim does not give an error response immediately a
sender address fails (permanently or temporarily), but instead it reads the
data for the message first. The headers of rejected messages are written to
the rejectlog file, for use in tracking down the problem or tracing mail
abusers. Up to three envelope recipients are also logged with the headers.

Unfortunately, there are a number of mailers in use that treat any SMTP
error response given after the data has been transmitted as a temporary
failure. Exim sends code 554 when it rejects a message because of a bad
sender, and RFC 821 is quite clear in stating that all codes starting with
5 are always 'permanent negative completion' replies. However, it does not
give any guidance as to what should be done on receiving such replies, and
some mailers persist in trying to send messages when they receive such a
code at the end of the data.

To get round this, Exim keeps a database in which it remembers the bad
sender address and host name when it rejects a message. If the same host
sends the same bad sender address within 24 hours, Exim rejects the message
at the MAIL FROM stage, before it reads the data for the message. This
should prevent the sender from trying to send the message again, but there
seem to be plenty of broken mailers out there that do keep on trying,
sometimes for days on end.

In an attempt to shut such MTAs up, if the same host sends the same bad
sender for a third time within 24 hours, MAIL FROM is accepted, but all
subsequent RCPT TO commands are rejected with a 550 error code. This means
'unknown user' and if a remote mailer doesn't treat that as a hard error,
it is very seriously broken.

The sender_verify_except_hosts and sender_verify_except_nets options can be
used to specify hosts and RFC 1413 idents or IP networks for which sender
verification is not applied. If a cluster of hosts all check incoming
external messages, there is no need to waste effort checking mail sent
between them. The format of the data for sender_verify_except_hosts is the
same as described for the sender_host_accept and sender_host_reject option
in the previous section. For example:

  sender_verify_except_hosts  "*.ref.book:exim@mailer.fict.book"

It is unfortunately the case that lots of messages are sent out onto the
Internet with invalid senders, mainly as a result of mis-configured mailers
and gateways. In many cases, the message itself contains a valid return
address in one of its headers. If the sender_verify_fixup option is set as
well as sender_verify, Exim does not reject a message if the sender is
invalid, provided it can find a Sender, Reply-to, or From header (whose
existence is checked in that order) and that header contains a valid
address. Instead, it replaces the sender with the valid address, and
records the fact that it has done so by adding a header of the form:

  X-BadReturnPath: <invalid address> rewritten using <name> header

The fixup happens for both permanent and temporary errors. This covers the   |
case when the bad addresses refer to some DNS zone whose nameservers are     |
unreachable. This approach is, of course, fixing the symptom and not the     |
disease.


43.8 Receiver verification

By default, Exim just checks the syntax of addresses given in the SMTP RCPT
TO command. This minimizes the time required for an SMTP message transfer,
and also makes it possible to provide special processing for unknown local
parts in local domains, by using a smartuser director to pass messages with
unknown local parts to a script or to another host.

Some installations, however, prefer to check receiver addresses as they are
received. If the receiver_verify option is set, the same code that is used
for verification by the -bv option is used to check incoming receiver
addresses, unless the remote host matches an entry in                        |
receiver_verify_except_hosts or receiver_verify_except_nets. If verifi-      |
cation fails, a permanent negative response is given to the RCPT TO          |
command. If there is a temporary failure, a temporary error is given,        |
unless receiver_try_verify is set, in which case the address is accepted.    |


43.9 System-wide message filtering

Exim can arrange to pass all messages through a filter before any routing
or directing is done. This is intended as a weapon in the war against mail
bombers and spammers. The message_filter option names the filter file,
while message_filter_user and message_filter_group specify the uid and gid
to be used while processing it. If they are not set, then the exim uid is
used if available and if seteuid() is available; otherwise root is used.

The filter file can contain any of the normal filtering commands, as
described in the separate document "Exim's User interface to mail filtering
". There are in addition two extra commands which are available in system-
wide filter files:

  freeze   the message is frozen unless it was previously manually thawed
           (see below)
  fail     all recipients are failed

These are not available to ordinary users and are faulted in normal use and
in testing via -bf.

If the filter sets up any deliveries, an extra header line is added to them
with the name X-Envelope-To. This contains up to 100 of the original
message's envelope recipients. If the filter specifies any significant
deliveries, then the message's own recipients list is ignored; otherwise it
is added to any recipients set up by the filter.

The freeze command is ignored if the message has been manually unfrozen and
not manually frozen since. This means that freezing can be used as a way of
checking out suspicious messages. If a message is found to be all right,
manually unfreezing it allows it to be delivered.

Take great care with the fail option when basing the decision to fail on
the contents of the message, because this option causes a normal delivery
error message to be generated, and it will of course include the contents
of the original message and will therefore trigger the fail option again
(causing a mail loop) unless steps are taken to prevent this. Testing the
error_message condition is one way to prevent this. You could use, for
example

  if
    $message_body contains "this is spam"
      and not error_message
  then fail endif

though of course that might still let through unwanted messages. The
alternative is clever checking of the body and/or headers to detect error
messages caused by the filter.


43.10 Outgoing batched SMTP

Both the appendfile and pipe transports can be used for handling batched
SMTP. Each has an option called bsmtp which, if set to anything other than
'none' causes the message to be output in SMTP format. The message is
written to the file or pipe preceded by the SMTP commands MAIL FROM and
RCPT TO, and followed by a line containing a single dot. Lines in the
message starting with a dot get an extra dot added. If the prefix or suffix
options are set, their contents are included inside the SMTP commands;
normally they would be specified as empty, to override the defaults. No
return-path or delivery-date header is ever added.

The value of the bsmtp option determines how multiple addresses in a single
message may be batched, if other conditions permit. If the value of bsmtp
is 'one', then there is no batching, and a copy of the message is output
for each address. If the value is 'domain' then a single copy (with
multiple RCPT TO commands) is output for all addresses that have the same
domain. If the value is 'all' then only a single copy of the message is
written. The batching is further constrained by other parameters:

 .   If any of the transport's expandable strings contain a reference to
     local_part, then no batching takes place.

 .   If any of the transport's expandable strings contains a reference to
     domain, then only domain batching is done.

 .   Addresses are not batched if they have different error addresses or
     different associated hosts.

 .   The transport must set the uid and gid for delivery. If at some future
     time routers are allowed to set the uid/gid, then batching can only
     occur for addresses that have the same uid/gid set up.

Here is an example of a transport and router for batched SMTP:

  # transport
  smtp_appendfile:
    driver = appendfile;
    directory = /var/bsmtp/${host},
    bsmtp = all,
    prefix =,
    suffix =,
    user = exim

  # router
  route_append:
    transport = smtp_appendfile,
    driver = domainlist;
    route_list = "some.domain batch.host"

This causes messages addressed to some.domain to be written in batched SMTP
format to /var/bsmtp/batch.host, with only a single copy of each message.
Note that prefix and suffix must be explicitly changed from their defaults.


43.11 Incoming batched SMTP

The -bS command line option causes Exim to accept one or more messages by
reading SMTP on the standard input, but to generate no responses. All
errors are reported by sending mail. If the caller is trusted, then the
senders in the MAIL FROM commands are believed; otherwise the sender is
always the caller of Exim. Unqualified senders and receivers are not
rejected (there seems little point) but instead just get qualified.
Receiver verification and administrative rejection is not done, even if
configured. HELO and EHLO act as RSET; VRFY, EXPN, ETRN, HELP, and DEBUG
act as NOOP; QUIT quits.



                        44. SECURITY CONSIDERATIONS


This chapter discusses a number of issues concerned with security, some of
which are also covered in other parts of this manual.


44.1 Root privilege

The Exim binary has to start off running as root, and is therefore a setuid
program. Root privilege is required for two things:

 .   To set up a socket connected to the standard SMTP port (25) when
     initialising the listening daemon.

 .   To be able to change uid and gid in order to read forward files and
     perform local deliveries as the receiving user or as specified in the
     configuration.

It is not necessary to be root to do any of the other things Exim does,
such as receiving messages and delivering them externally over SMTP, and it
is obviously more secure if Exim does not run as root except when
necessary.

If no user is specified for Exim in either the compile-time or runtime
configuration files, then it runs as root all the time, except when
performing local deliveries. When an alternative user is specified, it
gives up root privilege when it can. Exactly how and when it does this
depends on whether the operating system supports the seteuid() or the
setresuid() function.

To avoid unnecessary complication, the discussion below talks about users,
and functions for setting the uid. It should be understood that in all
cases there is a corresponding group and gid, and that this is also changed
whenever the uid is changed. The description is written in terms of
seteuid(), since this is more common than setresuid(). However, it is
possible to specify at compile time that an operating system has
setresuid() and not seteuid().

On systems without seteuid(), Exim uses setuid() to give up root privilege
at certain times, at the expense of having to re-invoke itself (using exec)
in order to regain privilege. When seteuid() is available, there is a
configuration choice as to which method is used for temporarily giving up
the privilege. Using setuid() is more secure, but uses more resources.

Exim always uses setuid() to become a non-root user when running a local
delivery process. This applies whether or not an Exim user is defined. The
following discussion applies only when an Exim user is defined; if it is
not, Exim runs as root except when doing local deliveries.

Exim always uses setuid() to change to the Exim user before doing remote
deliveries. These are the last things a delivery process does, so it does
not need to regain root privilege again.

For other operations, the security configuration option controls whether
Exim uses setuid() or seteuid(). It can be set to one of three strings:

 .   seteuid: Exim uses seteuid() to give up root temporarily when it does
     not need it, and to regain the privilege subsequently. This enables it
     to run with a non-root effective uid most of the time, at very little
     cost.

 .   setuid: Exim uses setuid() to give up root when it is receiving a
     locally generated message, and after it has set up a listening socket
     when running as a daemon. This means that, in order to deliver a
     message that it has received, it has to re-invoke a fresh copy of
     itself to regain root privilege. During delivery, it retains root
     except when actually transporting the message. In particular, it runs
     the directors and routers as root. Setuid() is generally reckoned to
     be more secure than seteuid() but running this way uses more
     resources.

 .   setuid+seteuid: Exim uses setuid() as described immediately above, but
     in addition, it uses seteuid() to give up root privilege temporarily
     when it needs to regain it subsequently without losing a lot of state
     information, for example, while running the directors and routers.

On systems that do not support the seteuid() function, the only possible
value for the security option is 'setuid', and this is the default on such
systems if an Exim user is defined. Otherwise the default is
'setuid+seteuid' - the most secure setting.


44.2 Reading forward files

When forward files are read from users' home directories and those home
directories are NFS mounted without root privilege, even a program running
as root cannot read a forward file that does not have world read access.

If the seteuid() function is being used as described in the previous
section, so that Exim is not root when running the directors, then the
forwardfile director automatically uses seteuid() to become the local user
when attempting to read a file in a user's home directory. If seteuid() is
not being used generally, but is available in the operating system, the
forwardfile director can be configured to make use of it when reading files
in home directories.

The forwardfile director does not necessarily have to read from users' home
directories as obtained from getpwnam(). It can be given a directory
explicitly, and a specific associated user and group. The above remarks are
applicable in this case also.

On systems that do not have seteuid(), the only way to support forward
files on NFS file systems that do not export root is to insist that the
files be world readable.

Forward files are permitted to contain :include: items unless forbidden by
setting forbid_include in the director. If seteuid() is being used to read
the forward file, then any included files are read as the same user.
Otherwise Exim is running as root, and it insists that any included files
are within the same directory as the forward file, and that there are no
symbolic links below the directory. If no directory is specified (either
explicitly or by looking up a local user's home directory) then included
files are not permitted when seteuid() is not in use.

When the filtering option is enabled for forward files, users can construct
pipe commands that contain data from the incoming message by quoting
variables such as $sender_address. To prevent the contents of inserted data
from interfering with a command, the string expansion is done after the
command line is split up into separate arguments, and the command is run
directly instead of passing the command line to a shell.


44.3 Delivering to local files

Full details of the checks applied by appendfile before it writes to a file
are given in chapter 14.

                                                                             |
44.4 IP routing                                                              |
                                                                             |
Many operating systems suppress IP source-routed packets in the kernel, but  |
some cannot be made to do this. Exim is configured by default to log         |
incoming source-routed TCP calls, and then to drop the call. These actions   |
can be independently turned off. Alternatively, the IP options can be        |
deleted instead of dropping the call.                                        |


44.5 Privileged users

Exim recognises two sets of users with special privileges. Trusted users
are able to submit new messages to Exim locally, but supply their own
sender addresses and information about a sending host. For other users
submitting local messages, Exim sets up the sender address from the uid,
and doesn't permit a remote host to be specified.

However, an untrusted user is permitted to use the -f command line option
in the special form -f <> to indicate that a delivery failure for the
message should not cause an error report. This affects the message's
envelope, but it does not affect the Sender header.

Trusted users are used to run processes that receive mail messages from
some other mail domain and pass them on to Exim for delivery either
locally, or over the Internet. Exim trusts a caller that is running as
root, as the Exim user (if defined), as any user listed in the
trusted_users configuration option, or under any group listed in the
trusted_group option.

Admin users are permitted to do things to the messages on Exim's queue.
They can freeze or thaw messages, cause them to be returned to their
senders, remove them entirely, or modify them in various ways. In addition,
admin users can run the Exim monitor and see all the information it is
capable of providing, which includes the contents of files on the spool.

Exim recognises an admin user if the calling process is running as root or
as the Exim user (if defined) or if any of the groups associated with the
calling process is the Exim group (if defined). It is not necessary
actually to be running under the Exim group. However, if admin users who
are not root or exim are to access the contents of files on the spool via
the Exim monitor (which runs unprivileged), Exim must be built to allow
group read access to its spool files.


44.6 Spool files

If a uid and gid are defined for Exim, then the spool directory and
everything it contains will be owned by exim and have its group set to
exim. The mode for spool files is defined in the Local/Makefile configur-
ation file, and defaults to 0600. This should normally be changed to 0640
if a uid and gid are defined for Exim, to allow access to spool files via
the Exim monitor by other members of the exim group.


                         45. FORMAT OF SPOOL FILES


A message on Exim's spool consists of two files, whose names are the
message id followed by -D and -H, respectively. The data portion of the
message is kept in the -D file on its own. The message's 'envelope',
status, and headers are all kept in the -H file, whose format is described
in this chapter. Each of these two files contains the final component of
its own name as its first line. This is insurance against disc crashes
where the directory is lost but the files themselves are recoverable.

Files whose names end with -J may also be seen in the spool directory.       |
These are journal files, used to record addresses to which the message has   |
been delivered during the course of a delivery run. At the end of the run,   |
the -H file is updated, and the -J file is deleted.                          |

The second line of the header file contains the login id of the process
that called Exim to create the file, followed by the numerical uid and gid.
For a locally generated message, this is normally the user who sent the
message. For an external message, the user is either root or Exim.

The third line of the file contains the address of the message's sender as
transmitted on the 'envelope', contained in angle brackets. In the case of
incoming SMTP mail, this is the address given in the MAIL FROM command. For
locally generated mail, the sender address is created by Exim from the
login of the current user and the configured qualify_domain, except when
Exim is called by a trusted user that supplied a sender address via the -f
option. The sender address is null if the message is a delivery failure
report.

The fourth line contains two numbers. The first is the time that the
message was received, in the form supplied by the Unix time() function - a
number of seconds since the start of the epoch. The second number is a
count of the number of messages warning of delayed delivery that have been
sent to the sender.

There follow a number of optional lines, each of which starts with a hyphen
when present. These can appear in any order:

 .   -frozen <time>: The message is frozen, and the freezing happened at
     <time>. No deliveries will be attempted while the message remains
     frozen, but the auto_thaw configuration option can specify a time
     delay after which a delivery will be attempted.

 .   -local: The message is from a local sender.

 .   -localerror: The message is a locally-generated delivery error report.

 .   -manual_thaw: The message was frozen but has been thawed manually,
     that is, by an explicit Exim command rather than via the auto-thaw
     process.

 .   -resent: The message contains Resent- headers, so the alternative set
     of header names is to be used (see RFC 822).

 .   -user_null_sender: The message was received from an unprivileged user
     with the -f option specifying '<>' as the sender.

Following the options are those addresses to which the message is not to be
delivered. This set of addresses is initialized from the command line when
the -t option is used; otherwise it starts out empty. Whenever a successful
delivery is made, the address is added to this set. The addresses are kept
internally as a balanced binary tree, and it is a representation of that
tree which is written to the spool file. If an address is expanded via an
alias or forward file, the original address is added to the tree when
deliveries to all its child addresses are completed.

If the tree is empty, there is a single line in the spool file containing
just the text XX. Otherwise, each line consists of two letters, which are
either Y or N, followed by an address. The address is the value for the
node of the tree, and the letters indicate whether the node has a left
branch and/or a right branch attached to it, respectively. If branches
exist, they immediately follow. Here is an example of a three-node tree:

  YY darcy@austen.fict.book
  NN alice@wonderland.fict.book
  NN editor@thesaurus.ref.book

After the non-recipients tree, there is a list of the message's recipients.
This is a simple list, preceded by a count. It includes all the original
recipients of the message, including those to whom the message has already
been delivered. For example,

  4
  editor@thesaurus.ref.book
  darcy@austen.fict.book
  rdo@foundation
  alice@wonderland.fict.book

A blank line separates the envelope and status information from the headers
which follow. A header may occupy several lines of the file, and to save
effort when reading it in, each header is preceded by a number and an
identifying character. The number is the number of characters in the
header, including any embedded newlines and the terminating newline. The
character is one of the following:

  <blank>  header in which Exim has no special interest
   B       Bcc header
   C       Cc header
   F       From header
   P       Received header - P for 'postmark'
   R       Reply-to header
   S       Sender header
   T       To header
   *       replaced or deleted header

Deleted or replaced (rewritten) headers remain in the spool file for
debugging purposes. They are not transmitted when the message is delivered.
When Resent- headers are present, it is those headers that have the
appropriate flags. Here is a typical set of headers:

  111P Received: by hobbit.fict.book with local (Exim 0.17 #8)
          id E0tHplY-0000mG-00; Tue, 21 Nov 1995 10:17:32 +0000
  049  Message-Id: <E0tHplY-0000mG-00@hobbit.fict.book>
  038* X-rewrote-sender: bb@hobbit.fict.book
  042* From: Bilbo Baggins <bb@hobbit.fict.book>
  049F From: Bilbo Baggins <B.Baggins@hobbit.fict.book>
  099* To: alice@wonderland.fict.book, rdo@foundation,
   darcy@austen.fict.book, editor@thesaurus.ref.book
  109T To: alice@wonderland.fict.book, rdo@foundation.fict.book,
   darcy@austen.fict.book, editor@thesaurus.ref.book
  038  Date: Tue, 21 Nov 1995 10:17:32 +0000

The asterisked headers indicate that the envelope sender, From header, and
To header have been rewritten, the last one because routing expanded the
unqualified domain foundation.



                       46. ADDING NEW DRIVERS TO EXIM


The following actions have to be taken in order to add a new director,
router, or transport to Exim:

 .   Choose a name for the driver that does not conflict with any existing
     name; I will use 'newdriver' in what follows.

 .   Add to src/EDITME the line

       <type>_NEWDRIVER=yes

     where <type> is DIRECTOR or ROUTER or TRANSPORT, depending on the type
     of driver. If the driver is not to be included in the binary by
     default, comment this line out. It may also be worth adding comments
     about the driver.

 .   Add to src/config.h.defaults the line

       #define <type>_NEWDRIVER

 .   Edit src/drtables.c, adding conditional code to pull in the driver's
     header and create a table entry as is done for all the other drivers.

 .   Edit Makefile in the appropriate subdirectory (directors, routers, or
     transports); add a line for the new driver and add it to the
     definition of OBJ.

 .   Create newdriver.h and newdriver.c in the appropriate subdirectory of
     src.

 .   Edit scripts/MakeLinks and add commands to link the .h and .c files as
     for other drivers.

Then all you need to do is write the code! A good way to start is to make a
proforma by copying an existing driver of the same type, globally changing
all occurrences of the name, and cutting out most of the code.

