-. $Cambridge: exim/doc/doc-src/spec.src,v 1.3 2005/01/14 16:18:57 tom Exp $
+. $Cambridge: exim/doc/doc-src/spec.src,v 1.9 2008/01/16 09:51:00 tom Exp $
.
.set version "4.50"
.set previousversion "4.40"
-.set versionmonth "January"
+.set versionmonth "February"
.set versionyear "2005"
.set ACL "ACL"
.blank
.endm
-.macro startconf
+.macro startconf ""
+.set confsection "~~1"
.newline
.push
.if ~~sys.fancy
.else
.index \~~1\ option
.fi
+.if "~~confsection" == ""
+.set inssect ""
+.else
+.set inssect "$rm{Use:} $it{~~confsection}###"
+.fi
.tempindent 0
-\**~~1**\ $c $rm{Type:} $it{~~2} $e $rm{Default:} $it{~~3}
+\**~~1**\ $c ~~inssect$rm{Type:} $it{~~2} $e $rm{Default:} $it{~~3}
.blank
.endm
.index LF character $it{see linefeed}
.index maximum $it{see limit}
.index NUL $it{see binary zero}
+.index passwd file $it{see \(/etc/passwd)\}
.index process id $it{see pid}
.index RBL $it{see DNS list}
.index redirection $it{see address redirection}
\(ACKNOWLEDGMENTS)\, in which I have started recording the names of
contributors.
+
.section Exim documentation
.index documentation
+.em
This edition of the Exim specification applies to version ~~version of Exim.
Substantive changes from the ~~previousversion edition are marked by bars in
the right-hand margin in the PostScript, PDF, and plain text versions of the
document, and by green text in the HTML version, as shown by this paragraph.
Changes are not marked in the Texinfo version, because Texinfo doesn't support
change bars. Minor corrections and rewordings are not marked.
+.nem
This document is very much a reference manual; it is not a tutorial. The reader
is expected to have some familiarity with the SMTP mail transfer protocol and
.index change log
As the program develops, there may be features in newer versions that have not
yet made it into this document, which is updated only when the most significant
-digit of the fractional part of the version number changes. However,
-specifications of new features that are not yet in this manual are placed in
-the file \(doc/NewStuff)\ in the Exim distribution. All changes to the program
-(whether new features, bug fixes, or other kinds of change) are noted briefly
-in the file called \(doc/ChangeLog)\.
+digit of the fractional part of the version number changes. Specifications of
+new features that are not yet in this manual are placed in the file
+\(doc/NewStuff)\ in the Exim distribution.
+
+.em
+Some features may be classified as `experimental'. These may change
+incompatibly while they are developing, or even be withdrawn. For this reason,
+they are not documented in this manual. Information about experimental features
+can be found in the file \(doc/experimental.txt)\.
+.nem
+
+All changes to the program (whether new features, bug fixes, or other kinds of
+change) are noted briefly in the file called \(doc/ChangeLog)\.
.index \(doc/spec.txt)\
This specification itself is available as an ASCII file in \(doc/spec.txt)\ so
\(OptionLists.txt)\ $t $rm{list of all options in alphabetical order}
\(dbm.discuss.txt)\ $t $rm{discussion about DBM libraries}
\(exim.8)\ $t $rm{a man page of Exim's command line options}
+.newline
+.em
+\(experimental.txt)\ $t $rm{documentation of experimental features}
+.nem
+.newline
\(filter.txt)\ $t $rm{specification of the filter language}
\(pcrepattern.txt)\ $t $rm{specification of PCRE regular expressions}
\(pcretest.txt)\ $t $rm{specification of the PCRE testing program}
~~SECTavail below tells you how to get hold of these.
-.section FTP and web sites, and mailing list
+.section FTP and web sites
.index web site
.index FTP site
-The primary distribution site for Exim is an FTP site, whose contents are
-described in \*Where to find the Exim distribution*\ below. In addition,
-there is a web site at \?http://www.exim.org?\ by courtesy of Energis Squared,
-formerly Planet Online Ltd, who are situated in the UK. The site is mirrored in
-a number of other countries; links to the mirrors are listed on the home page.
-The web site contains the Exim distribution, and you can also find the
-documentation and the
+.em
+The primary distribution site for Exim is currently the University of
+Cambridge's FTP site, whose contents are described in \*Where to find the Exim
+distribution*\ below. In addition, there is a
+.if ~~html
+[(A HREF="http://www.exim.org/")]
+.fi
+web site
+.if ~~html
+[(/A)]
+.fi
+and an
+.if ~~html
+[(A HREF="ftp://ftp.exim.org/")]
+.fi
+FTP site
+.if ~~html
+[(/A)]
+.fi
+at \exim.org\. These are now also hosted at the University of Cambridge.
+The \exim.org\ site was previously hosted for a number of years by Energis
+Squared, formerly Planet Online Ltd, whose support I gratefully acknowledge.
+
+As well as Exim distribution tar files, the Exim web site contains a number of
+differently formatted versions of the documentation, including the
.index FAQ
.if ~~html
[(A HREF="FAQ.html")]
.if ~~html
[(/A)]
.fi
-online there, as well as other relevant material.
+in both text and HTML formats. The HTML version comes with a keyword-in-context
+index. A recent addition to the online information is the
+.index wiki
+.if ~~html
+[(A HREF="http://www.exim.org/eximwiki/")]
+Exim wiki.
+[(/A)]
+.else
+Exim wiki (\?http://www.exim.org/eximwiki/?\).
+.fi
+We hope that this will make it easier for Exim users to contribute examples,
+tips, and know-how for the benefit of others.
+.nem
+.section Mailing lists
.index mailing lists||for Exim users
-Energis Squared also provide resources for the following mailing lists:
+.em
+The following are the three main Exim mailing lists:
.display rm
.tabs 28
$it{exim-users@@exim.org} $t general discussion list
+$it{exim-dev@@exim.org} $t discussion of bugs, enhancements, etc.
$it{exim-announce@@exim.org} $t moderated, low volume announcements list
.endd
+.nem
You can subscribe to these lists, change your existing subscriptions, and view
or search the archives via the
.if ~~html
to post a message to the $it{exim-users} mailing list and have it discussed.
+.em
.section Where to find the Exim distribution
.rset SECTavail "~~chapter.~~section"
.index FTP site
.fi
\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim?\
.endd
-Within that directory there are subdirectories called \(exim3)\ (for previous
-Exim 3 distributions), \(exim4)\ (for the latest Exim 4 distributions), and
-\(Testing)\ for occasional testing versions. Those mirror sites that I know
-about are listed in the file
+This is mirrored by
.display rm
.if ! ~~sys.fancy
.indent 0
.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Mirrors?\
+\?ftp://ftp.exim.org/pub/exim?\
.endd
-In the \(exim4)\ subdirectory, the current release can always be found in
-files called
+The file references that follow are relative to the \(exim)\ directories at
+these sites.
+
+There are now quite a number of independent mirror sites around the world.
+Those that I know about are listed in the file called \(Mirrors)\.
+
+Within the \(exim)\ directory there are subdirectories called \(exim3)\ (for
+previous Exim 3 distributions), \(exim4)\ (for the latest Exim 4
+distributions), and \(Testing)\ for testing versions. In the \(exim4)\
+subdirectory, the current release can always be found in files called
.display rm
\(exim-$it{n.nn}.tar.gz)\
\(exim-$it{n.nn}.tar.bz2)\
.index distribution||signing details
.index distribution||public key
.index public key for signed distribution
-The distributions are signed with Philip Hazel's GPG key.
-The corresponding public key is available from a number of keyservers, and
-there is also a copy in the file:
-.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Public-Key?\
-.endd
-The signatures for the tar bundles are in:
+The distributions are currently signed with Philip Hazel's GPG key. The
+corresponding public key is available from a number of keyservers, and there is
+also a copy in the file \(Public-Key)\. The signatures for the tar bundles are
+in:
.display rm
\(exim-$it{n.nn}.tar.gz.sig)\
\(exim-$it{n.nn}.tar.bz2.sig)\
.endd
-
-When there is only a small amount of change from one release to the next, a
-patch file may be provided, with a final component name of the form
-.display rm
-\(exim-patch-$it{n.nn}-$it{m.mm}.gz)\
-.endd
-For each released version, the log of changes is made separately available in
-the directory
-.display rm
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/ChangeLogs?\
-.endd
-so that it is possible to find out what has changed without having to download
-the entire distribution.
+For each released version, the log of changes is made separately available in a
+separate file in the directory \(ChangeLogs)\ so that it is possible to
+find out what has changed without having to download the entire distribution.
.index documentation||available formats
The main distribution contains ASCII versions of this specification and other
distribution, and are also available in \(.bz2)\ as well as \(.gz)\ forms.
.index FAQ
-The FAQ is available for downloading in two different formats from
+The FAQ is available for downloading in two different formats in these files:
.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/FAQ.txt.gz?\
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/FAQ.html.tar.gz?\
+\(exim4/FAQ.txt.gz)\
+\(exim4/FAQ.html.tar.gz)\
.endd
The first of these is a single ASCII file that can be searched with a text
editor. The second is a directory of HTML files, normally accessed by starting
.section Wish list
.index wish list
A wish list is maintained, containing ideas for new features that have been
-submitted. From time to time the file is exported to the ftp site:
-.display rm
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/WishList?\
-.endd
-Items are removed from the list if they get implemented.
+submitted. From time to time the file is exported to the ftp site into the file
+\(exim4/WishList)\. Items are removed from the list if they get implemented.
.section Contributed material
.index contributed material
-At the ftp site, there is a directory called
-.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/Contrib/?\
-.endd
-which contains miscellaneous files contributed to the Exim community by Exim
-users. There is also a collection of contributed configuration examples in
-.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.gz?\
-.endd
-These samples are referenced from the FAQ.
-
+At the ftp site, there is a directory called \(Contrib)\ that contains
+miscellaneous files contributed to the Exim community by Exim users. There is
+also a collection of contributed configuration examples in
+\(exim4/config.samples.tar.gz)\. These samples are referenced from the FAQ.
+.nem
.section Limitations
.index limitations of Exim
(that is, off Exim's queue) and subsequently passed on to the dial-in hosts by
other means.
.nextp
-Although Exim does have some facilities for scanning incoming messages, these
+.em
+Although Exim does have basic facilities for scanning incoming messages, these
are not comprehensive enough to do full virus or spam scanning. Such operations
-are best carried out using additional specialized software packages.
+are best carried out using additional specialized software packages. If you
+compile Exim with the content-scanning extension, straightforward interfaces to
+a number of common scanners are provided.
+.nem
.endp
.index bounce message||definition of
When a message cannot be delivered, it is normally returned to the sender in a
-delivery failure message. The term \*bounce*\ is commonly used for this action,
-and the error reports are often called \*bounce messages*\. This is a
-convenient shorthand for `delivery failure error report'. Such messages have an
-empty sender address in the message's \*envelope*\ (see below) to ensure that
-they cannot themselves give rise to further bounce messages.
+delivery failure message or a `non-delivery report' (NDR). The term \*bounce*\
+is commonly used for this action, and the error reports are often called
+\*bounce messages*\. This is a convenient shorthand for `delivery failure error
+report'. Such messages have an empty sender address in the message's
+\*envelope*\ (see below) to ensure that they cannot themselves give rise to
+further bounce messages.
The term \*default*\ appears frequently in this manual. It is used to qualify a
value which is used in the absence of any setting in the configuration. It may
A number of pieces of external code are included in the Exim distribution.
.numberpars $.
Regular expressions are supported in the main Exim program and in the Exim
-monitor using the freely-distributable PCRE library, copyright (c) 2003
-University of Cambridge. The source is distributed in the directory
-\(src/pcre)\. However, this is a cut-down version of PCRE. If you want to use
-the PCRE library in other programs, you should obtain and install the full
-version from \?ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre?\.
+monitor using the freely-distributable PCRE library, copyright (c) University
+of Cambridge. The source is distributed in the directory \(src/pcre)\. However,
+this is a cut-down version of PCRE. If you want to use the PCRE library in
+other programs, you should obtain and install the full version from
+\?ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre?\.
.space 1ld
.nextp
.index cdb||acknowledgement
Support for the cdb (Constant DataBase) lookup method is provided by code
-contributed by Nigel Metheringham of Planet Online Ltd. which contains the
-following statements:
+contributed by Nigel Metheringham of (at the time he contributed it) Planet
+Online Ltd. which contains the following statements:
.rule
.push
.if ~~sgcal
.newline
.pop
.rule
+.space 1ld
+.nextp
+.em
+Many people have contributed code fragments, some large, some small, that were
+not covered by any specific licence requirements. It is assumed that the
+contributors are happy to see their code incoporated into Exim under the GPL.
+.nem
.endp
.numberpars $.
.index ~~ACL||introduction
Exim 4 (unlike previous versions of Exim) implements policy controls on
-incoming SMTP mail by means of \*Access Control Lists*\ (ACLs). Each list is a
+incoming mail by means of \*Access Control Lists*\ (ACLs). Each list is a
series of statements that may either grant or deny access. ACLs can be used at
-several places in the SMTP dialogue while receiving a message. However, the
-most common places are after each \\RCPT\\ command, and at the very end of the
-message. The sysadmin can specify conditions for accepting or rejecting
-individual recipients or the entire message, respectively, at these two points
-(see chapter ~~CHAPACL). Denial of access results in an SMTP error code.
+several places in the SMTP dialogue while receiving a message from a remote
+host. However, the most common places are after each \\RCPT\\ command, and at
+the very end of the message. The sysadmin can specify conditions for accepting
+or rejecting individual recipients or the entire message, respectively, at
+these two points (see chapter ~~CHAPACL). Denial of access results in an SMTP
+error code.
.nextp
An ACL is also available for locally generated, non-SMTP messages. In this
case, the only available actions are to accept or deny the entire message.
.nextp
+.em
+When Exim is compiled with the content-scanning extension, facilities are
+provided in the ACL mechanism for passing the message to external virus and/or
+spam scanning software. The result of such a scan is passed back to the ACL,
+which can then use it to decide what to do with the message.
+.nem
+.nextp
When a message has been received, either from a remote host or from the local
host, but before the final acknowledgement has been sent, a locally supplied C
function called \*local@_scan()*\ can be run to inspect the message and decide
whether to accept it or not (see chapter ~~CHAPlocalscan). If the message is
accepted, the list of recipients can be modified by the function.
.nextp
+.em
+Using the \*local@_scan()*\ mechanism is another way of calling external
+scanner software. The \SA-Exim\ add-on package works this way. It does not
+require Exim to be compiled with the content-scanning extension.
+.nem
+.nextp
After a message has been accepted, a further checking mechanism is available in
the form of the $it{system filter} (see chapter ~~CHAPsystemfilter). This runs
at the start of every delivery process.
detected early in Exim's execution (such as a malformed configuration file) can
be logged.
+.index content scanning||specifying at build time
+.em
+Exim's interfaces for calling virus and spam scanning sofware directly from
+access control lists are not compiled by default. If you want to include these
+facilities, you need to set
+.display asis
+WITH_CONTENT_SCAN=yes
+.endd
+in your \(Local/Makefile)\. For details of the facilities themselves, see
+chapter ~~CHAPexiscan.
+.nem
+
.index \(Local/eximon.conf)\
.index \(exim@_monitor/EDITME)\
If you are going to build the Exim monitor, a similar configuration process is
Exim can be built to support encrypted SMTP connections, using the \\STARTTLS\\
command as per RFC 2487. It can also support legacy clients that expect to
start a TLS session immediately on connection to a non-standard port (see the
-\-tls-on-connect-\ command line option).
+\tls@_on@_connect@_ports\ runtime option and the \-tls-on-connect-\ command
+line option).
If you want to build Exim with TLS support, you must first install either the
OpenSSL or GnuTLS library. There is no cryptographic code in Exim itself for
where the IPv6 support is not fully integrated into the normal include and
library files.
-IPv6 is still changing rapidly. Two different types of DNS record for handling
-IPv6 addresses have been defined. AAAA records are already in use, and are
-currently seen as the `mainstream', but another record type called A6 is being
-argued about. Its status is currently `experimental'. Exim has support for A6
-records, but this is included only if you set \\SUPPORT@_A6=YES\\ in
-\(Local/Makefile)\.
-
+.em
+Two different types of DNS record for handling IPv6 addresses have been
+defined. AAAA records (analagous to A records for IPv4) are in use, and are
+currently seen as the mainstream. Another record type called A6 was proposed
+as better than AAAA because it had more flexibility. However, it was felt to
+be over-complex, and its status was reduced to `experimental'. It is not known
+if anyone is actually using A6 records. Exim has support for A6 records, but
+this is included only if you set \\SUPPORT@_A6=YES\\ in \(Local/Makefile)\. The
+support has not been tested for some time.
+.nem
.section The building process
.index build directory
Run Exim in expansion testing mode. Exim discards its root privilege, to
prevent ordinary users from using this mode to read otherwise inaccessible
files. If no arguments are given, Exim runs interactively, prompting for lines
-of data. Long expressions can be split over several lines by using backslash
-continuations.
-As in Exim's run time configuration, whitespace at the start of continuation
-lines is ignored.
+of data.
+.em
+If Exim was built with \\USE@_READLINE\\=yes in \(Local/Makefile)\, it tries
+to load the \libreadline\ library dynamically whenever the \-be-\ option is
+used without command line arguments. If successful, it uses the \*readline()*\
+function, which provides extensive line-editing facilities, for reading the
+test data. A line history is supported.
+.nem
-Each argument or data line is passed through the string expansion mechanism,
-and the result is output. Variable values from the configuration file (for
-example, \$qualify@_domain$\) are available, but no message-specific values
-(such as \$domain$\) are set, because no message is being processed.
+Long expansion expressions can be split over several lines by using backslash
+continuations. As in Exim's run time configuration, whitespace at the start of
+continuation lines is ignored. Each argument or data line is passed through the
+string expansion mechanism, and the result is output. Variable values from the
+configuration file (for example, \$qualify@_domain$\) are available, but no
+message-specific values (such as \$domain$\) are set, because no message is
+being processed.
.option bF #<<filename>>
.index system filter||testing
.index forward file||testing
.index testing||forward file
.index Sieve filter||testing
-This option runs 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 a
-system filter file is being tested, \-bF-\ should be used instead of \-bf-\. If
-the test file does not begin with
-one of the special lines
+This option runs Exim in user 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.
+.em
+If you want to test a system filter file, use \-bF-\ instead of \-bf-\. You can
+use both \-bF-\ and \-bf-\ on the same command, in order to
+test a system filter and a user filter in the same run. For example:
+.display asis
+exim -bF /system/filter -bf /user/filter </test/message
+.endd
+This is helpful when the system filter adds header lines or sets filter
+variables that are used by the user filter.
+.nem
+
+If the test filter file does not begin with one of the special lines
.display asis
# Exim filter
# Sieve filter
When testing a filter file, the envelope sender can be set by the \-f-\ option,
or by a `From ' line at the start of the test message. Various parameters that
would normally be taken from the envelope recipient address of the message can
-be set by means of additional command line options. These are:
-.display rm
-.if ~~sys.fancy
-.tabset 12em 16em
-.else
-.tabset 15em 20em
-.fi
-. The odd alignment here gets it lined up in the man page.
-\-bfd-\ $t <<domain>> $t $rm{default is the qualify domain}
-\-bfl-\ $t <<local@_part>> $t $rm{default is the logged in user}
-\-bfp-\ $t <<local@_part@_prefix>> $t $rm{default is null}
-\-bfs-\ $t <<local@_part@_suffix>> $t $rm{default is null}
-.endd
-The local part should always be set to the incoming address with any prefix or
+be set by means of additional command line options (see the next four options).
+
+.em
+.option bfd #<<domain>>
+This sets the domain of the recipient address when a filter file is being
+tested by means of the \-bf-\ option. The default is the value of
+\$qualify@_domain$\.
+
+.option bfl #<<local part>>
+This sets the local part of the recipient address when a filter file is being
+tested by means of the \-bf-\ option. The default is the username of the
+process that calls Exim. A local part should be specified with any prefix or
suffix stripped, because that is how it appears to the filter when a message is
actually being delivered.
+.option bfp #<<prefix>>
+This sets the prefix of the local part of the recipient address when a filter
+file is being tested by means of the \-bf-\ option. The default is an empty
+prefix.
+
+.option bfp #<<suffix>>
+This sets the suffix of the local part of the recipient address when a filter
+file is being tested by means of the \-bf-\ option. The default is an empty
+suffix.
+.em
+
+
.option bh #<<IP address>>
.index testing||incoming SMTP
.index SMTP||testing incoming
exim -bh 10.9.8.7.1234
exim -bh fe80::a00:20ff:fe86:a061.5678
.endd
+.em
+When an IPv6 address is given, it is converted into canonical form. In the case
+of the second example above, the value of \$sender@_host@_address$\ after
+conversion to the canonical form is \"fe80:0000:0000:0a00:20ff:fe86:a061.5678"\.
+.nem
+
Comments as to what is going on are written to the standard error file. These
include lines beginning with `LOG' for anything that would have been logged.
This facility is provided for testing configuration options for incoming
.index address||testing
This option runs Exim in address testing mode, in which each argument is taken
as an address to be tested for deliverability. The results are written to the
-standard output.
-If a test fails, and the caller is not an admin user, no details of the
-failure are output, because these might contain sensitive information such as
-usernames and passwords for database lookups.
+standard output. If a test fails, and the caller is not an admin user, no
+details of the failure are output, because these might contain sensitive
+information such as usernames and passwords for database lookups.
If no arguments are given, Exim runs in an interactive manner, prompting with a
-right angle bracket for addresses to be tested. Each address is handled as if
-it were the recipient address of a message (compare the \-bv-\ option). It is
-passed to the routers and the result is written to the standard output.
-However, any router that has \no@_address@_test\ set is bypassed. This can
-make \-bt-\ easier to use for genuine routing tests if your first router passes
-everything to a scanner program.
+right angle bracket for addresses to be tested.
+.em
+Unlike the \-be-\ test option, you cannot arrange for Exim to use the
+\*readline()*\ function, because it is running as \*root*\ and there are
+security issues.
+.nem
+
+Each address is handled as if it were the recipient address of a message
+(compare the \-bv-\ option). It is passed to the routers and the result is
+written to the standard output. However, any router that has
+\no@_address@_test\ set is bypassed. This can make \-bt-\ easier to use for
+genuine routing tests if your first router passes everything to a scanner
+program.
.index return code||for \-bt-\
The return code is 2 if any address failed outright; it is 1 if no address
specific lookup types), the drivers that are included in the binary, and the
name of the run time configuration file that is in use.
+.em
+As part of its operation, \-bV-\ causes Exim to read and syntax check its
+configuration file. However, this is a static check only. It cannot check
+values that are to be expanded. For example, although a misspelt ACL verb is
+detected, an error in the verb's arguments is not. You cannot rely on \-bV-\
+alone to discover (for example) all the typos in the configuration; some
+realistic testing is needed. The \-bh-\ and \-N-\ options provide more dynamic
+testing facilities.
+.nem
+
+
.option bv
.index verifying||address, using \-bv-\
.index address||verification
usernames and passwords for database lookups.
If no arguments are given, Exim runs in an interactive manner, prompting with a
-right angle bracket for addresses to be verified. Verification differs from
-address testing (the \-bt-\ option) in that routers that have \no@_verify\ set
-are skipped, and if the address is accepted by a router that has \fail@_verify\
-set, verification fails. The address is verified as a recipient if \-bv-\ is
-used; to test verification for a sender address, \-bvs-\ should be used.
+right angle bracket for addresses to be verified.
+.em
+Unlike the \-be-\ test option, you cannot arrange for Exim to use the
+\*readline()*\ function, because it is running as \*exim*\ and there are
+security issues.
+.nem
+
+Verification differs from address testing (the \-bt-\ option) in that routers
+that have \no@_verify\ set are skipped, and if the address is accepted by a
+router that has \fail@_verify\ set, verification fails. The address is verified
+as a recipient if \-bv-\ is used; to test verification for a sender address,
+\-bvs-\ should be used.
If the \-v-\ 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
file that exists is used. Failure to open an existing file stops Exim from
proceeding any further along the list, and an error is generated.
-When this option is used by a caller other than root or the Exim user,
-and the list is different from the compiled-in list, Exim gives up
-its root privilege immediately, and runs with the real and effective uid and
-gid set to those of the caller.
-However, if \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in \(Local/Makefile)\, root
-privilege is retained for \-C-\ only if the caller of Exim is root.
-This option is not set by default.
+When this option is used by a caller other than root or the Exim user, and the
+list is different from the compiled-in list, Exim gives up its root privilege
+immediately, and runs with the real and effective uid and gid set to those of
+the caller. However, if \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in
+\(Local/Makefile)\, root privilege is retained for \-C-\ only if the caller of
+Exim is root.
+.em
+That is, the Exim user is no longer privileged in this regard. This build-time
+option is not set by default in the Exim source distribution tarbundle.
+However, if you are using a `packaged' version of Exim (source or binary), the
+packagers might have enabled it.
+.nem
Setting \\ALT@_CONFIG@_ROOT@_ONLY\\ locks out the possibility of testing a
configuration using \-C-\ right through message reception and delivery, even if
If the \debug@_print\ option is set in any driver, it produces output whenever
any debugging is selected, or if \-v-\ is used.
+.em
+.option dd <<debug options>>
+This option behaves exactly like \-d-\ except when used on a command that
+starts a daemon process. In that case, debugging is turned off for the
+subprocesses that the daemon creates. Thus, it is useful for monitoring the
+behaviour of the daemon without creating as much output as full debugging does.
+.nem
+
.option dropcr
This is an obsolete option that is now a no-op. It used to affect the way Exim
handled CR and LF characters in incoming messages. What happens now is
This option sets the address of the envelope sender of a locally-generated
message (also known as the return path). The option can normally be used only
by a trusted user, but \untrusted@_set@_sender\ can be set to allow untrusted
-users to use it. In the absence of \-f-\, or if the caller is not allowed to
-use it, the sender of a local message is set to the caller's login name at the
-default qualify domain.
+users to use it.
+.em
+Processes running as root or the Exim user are always trusted. Other
+trusted users are defined by the \trusted@_users\ or \trusted@_groups\ options.
+
+In the absence of \-f-\, or if the caller is not trusted, the sender of a local
+message is set to the caller's login name at the default qualify domain.
There is one exception to the restriction on the use of \-f-\: an empty sender
-can be specified by any user, to create a message that can never provoke a
-bounce. An empty sender can be specified either as an empty string, or as a
-pair of angle brackets with nothing between them, as in these examples of shell
-commands:
+can be specified by any user, trusted or not,
+.nem
+to create a message that can never provoke a bounce. An empty sender can be
+specified either as an empty string, or as a pair of angle brackets with
+nothing between them, as in these examples of shell commands:
.display asis
exim -f '<>' user@domain
exim -f "" user@domain
.index delivery||in the background
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 delivery
-process for each message received, but does not wait for the delivery process
-to complete. This is the default action if none of the \-od-\ options are
-present.
+messages, which means that the accepting process automatically starts a
+delivery process for each message received, but does not wait for the delivery
+processes to finish.
+.em
+When all the messages have been received, the reception process exits, leaving
+the delivery processes to finish in their own time. The standard output and
+error streams are closed at the start of each delivery process.
+.nem
+This is the default action if none of the \-od-\ options are present.
If one of the queueing options in the configuration file
(\queue@_only\ or \queue@_only@_file\, for example) is in effect, \-odb-\
a locally-generated message. (For the daemon it is exactly the same as
\-odb-\.) A delivery process is automatically started to deliver the
message, and Exim waits for it to complete before proceeding.
+.em
+The original Exim reception process does not finish until the delivery
+process for the final message has ended. The standard error stream is left open
+during deliveries.
+.nem
However, like \-odb-\, this option has no effect if \queue@_only@_override\ is
false and one of the queueing options in the configuration file is in effect.
+.em
+If there is a temporary delivery error during foreground delivery, the message
+is left on the queue for later delivery, and the original reception process
+exists. See chapter ~~CHAPnonqueueing for a way of setting up a restricted
+configuration that never queues messages.
+.nem
+
.option odi
This option is synonymous with \-odf-\. It is provided for compatibility with
Sendmail.
.option oMr #<<protocol name>>
.index protocol||incoming, specifying for local message
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMr-\
-option sets the received protocol value
-in \$received@_protocol$\.
-However, this applies only when \-bs-\ is not used. For interactive SMTP input,
-the protocol is determined by whether \\EHLO\\ or \\HELO\\ is used, and is
-always either `local-esmtp' or `local-smtp'. For \-bS-\ (batch SMTP) however,
-the protocol can be set by \-oMr-\.
+option sets the received protocol value that is stored in
+\$received@_protocol$\. However, this applies only when \-bs-\ is not used. For
+interactive SMTP input (\-bs-\), the protocol is always
+.em
+`local-' followed by one of the standard SMTP protocol names (see the
+description of \$received@_protocol$\ in section ~~SECTexpvar).
+.nem
+For \-bS-\ (batch SMTP) however, the protocol can be set by \-oMr-\.
.option oMs #<<host name>>
.index sender||host name, specifying for local message
.option tls-on-connect
.index TLS||use without STARTTLS
.index TLS||automatic start
-This option is available when Exim is compiled with TLS support. It makes it
-possible to support legacy clients that do not support the \\STARTTLS\\
-command, but instead expect to start up a TLS session as soon as a connection
-to the server is established. These clients use a special port (usually called
-the `ssmtp' port) instead of the normal SMTP port 25. The \-tls-on-connect-\
-option can be used to run Exim in this way from \*inetd*\, and it can also be
-used to run a special daemon that operates in this manner (use \-oX-\ to
-specify the port). However, although it is possible to run one daemon that
-listens on several ports, it is not possible to have some of them operate one
-way and some the other. With only a few clients that need the legacy support, a
-convenient approach is to use a daemon for normal SMTP (with or without
-\\STARTTLS\\) and \*inetd*\ with \-tls-on-connect-\ for the legacy clients.
+This option is available when Exim is compiled with TLS support.
+.em
+It forces all incoming SMTP connections to behave as if the incoming port is
+listed in the \tls@_on@_connect@_ports\ option. See section ~~SECTsupobssmt and
+chapter ~~CHAPTLS for further details.
+.nem
.option U
.index Sendmail compatibility||\-U-\ option ignored
.index run time configuration
.index configuration file||general description
.index \\CONFIGURE@_FILE\\
+.index configuration file||errors in
+.index error||in configuration file
+.index return code||for bad configuration
Exim uses a single run time configuration file that is read whenever an Exim
binary is executed. Note that in normal operation, this happens frequently,
because Exim is designed to operate in a distributed manner, without central
control.
+.em
+If a syntax error is detected while reading the configuration file, Exim
+writes a message on the standard error, and exits with a non-zero return code.
+The message is also written to the panic log. \**Note**\: only simple syntax
+errors can be detected at this time. The values of any expanded options are
+not checked until the expansion happens, even when the expansion does not
+actually alter the string.
+.nem
+
+
The name of the configuration file is compiled into the binary for security
reasons, and is specified by the \\CONFIGURE@_FILE\\ compilation option. In
most configurations, this specifies a single file. However, it is permitted to
.index \\EXIM@_USER\\
.index \\EXIM@_GROUP\\
+.index \\CONFIGURE@_OWNER\\
+.index \\CONFIGURE@_GROUP\\
.index configuration file||ownership
.index ownership||configuration file
-The run time configuration file must be owned by root or by the user that
-is specified at compile time by the \\EXIM@_USER\\ option,
-or by the user that is specified at compile time by the \\CONFIGURE@_OWNER\\
-option (if set).
-The configuration file must not be world-writeable or group-writeable, unless
-its group is the one specified at compile time by the \\EXIM@_GROUP\\ option.
+The run time configuration file must be owned by root or by the user that is
+specified at compile time by the \\EXIM@_USER\\ option, or by the user that is
+specified at compile time by the \\CONFIGURE@_OWNER\\ option (if set). The
+configuration file must not be world-writeable or group-writeable, unless its
+group is the one specified at compile time by the \\EXIM@_GROUP\\ option
+.em
+or by the \\CONFIGURE@_GROUP\\ option.
+.nem
\**Warning**\: In a conventional configuration, where the Exim binary is setuid
to root, anybody who is able to edit the run time configuration file has an
of the Exim group, but do not trust them with root, make sure that the run time
configuration is not group writeable.
-
A default configuration file, which will work correctly in simple situations,
-is provided in the file \(src/configure.default)\.
-If \\CONFIGURE@_FILE\\ defines just one file name, the installation process
-copies the default configuration to a new file of that name if it did not
-previously exist. If \\CONFIGURE@_FILE\\ is a list, no default is automatically
-installed. Chapter ~~CHAPdefconfil is a `walk-through' discussion of the
-default configuration.
-
-.index configuration file||errors in
-.index error||in configuration file
-.index return code||for bad configuration
-If a syntax error is detected while reading the configuration file, Exim
-writes a message on the standard error, and exits with a non-zero return code.
-The message is also written to the panic log.
+is provided in the file \(src/configure.default)\. If \\CONFIGURE@_FILE\\
+defines just one file name, the installation process copies the default
+configuration to a new file of that name if it did not previously exist. If
+\\CONFIGURE@_FILE\\ is a list, no default is automatically installed. Chapter
+~~CHAPdefconfil is a `walk-through' discussion of the default configuration.
.section Using a different configuration file
in \(Local/Makefile)\ before building Exim. Full details of the
\*local@_scan()*\ facility are given in chapter ~~CHAPlocalscan.
.endp
+.index configuration file||leading whitespace in
+.index configuration file||trailing whitespace in
+.index whitespace||in configuration file
+.em
+Leading and trailing whitespace in configuration lines is always ignored.
+.nem
Blank lines in the file, and lines starting with a @# character (ignoring
leading white space) are treated as comments and are ignored. \**Note**\: a
@# character other than at the beginning of a line is not treated specially,
and does not introduce a comment.
-Any non-comment line can be continued by ending it with a backslash. Trailing
-white space after the backslash is ignored, and leading white space at the
-start of continuation lines is also ignored.
+Any non-comment line can be continued by ending it with a backslash.
+.em
+Note that the general rule for whitespace means that trailing white space after
+the backslash is ignored, and leading white space at the start of continuation
+lines is also ignored.
+.nem
Comment lines beginning with @# (but not empty lines) may appear in the middle
of a sequence of continuation lines.
.index format||list item in configuration
.index string list, definition
.rset SECTlistconstruct "~~chapter.~~section"
-The data for some configuration options is a colon-separated list of items.
-Many of these options are shown with type `string list' in the descriptions
-later in this document. Others are listed as `domain list', `host list',
-`address list', or `local part list'. Syntactically, they are all the same;
-however, those other than `string list' are subject to particular kinds of
-interpretation, as described in chapter ~~CHAPdomhosaddlists.
+The data for some configuration options is a list of items, with colon as the
+default separator. Many of these options are shown with type `string list' in
+the descriptions later in this document. Others are listed as `domain list',
+`host list', `address list', or `local part list'. Syntactically, they are all
+the same; however, those other than `string list' are subject to particular
+kinds of interpretation, as described in chapter ~~CHAPdomhosaddlists.
In all these cases, the entire list is treated as a single string as far as the
input syntax is concerned. The \trusted@_users\ setting in section
local_interfaces = 127.0.0.1 : ::::1
.endd
contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address
-@:@:1. IPv6 addresses are going to become more and more common as the new
-protocol gets more widely deployed.
+@:@:1.
.index list||separator, changing
.index IPv6||addresses in lists
-Doubling their colons is an unwelcome chore, so a mechanism was introduced to
-allow the separator character to be changed. If a list begins with a left angle
-bracket, followed by any punctuation character, that character is used instead
-of colon as the list separator. For example, the list above can be rewritten to
-use a semicolon separator like this:
+Doubling colons in IPv6 addresses is an unwelcome chore, so a mechanism was
+introduced to allow the separator character to be changed. If a list begins
+with a left angle bracket, followed by any punctuation character, that
+character is used instead of colon as the list separator. For example, the list
+above can be rewritten to use a semicolon separator like this:
.display asis
local_interfaces = <; 127.0.0.1 ; ::1
.endd
confined to circumstances where they really are needed.
+.em
+.section Empty items in lists
+.rset SECTempitelis "~~chapter.~~section"
+.index list||empty item in
+An empty item at the end of a list is always ignored. In other words, trailing
+separator characters are ignored. Thus, the list in
+.display asis
+senders = user@domain :
+.endd
+contains only a single item. If you want to include an empty string as one item
+in a list, it must not be the last item. For example, this list contains three
+items, the second of which is empty:
+.display asis
+senders = user1@domain : : user2@domain
+.endd
+\**Note**\: there must be whitespace between the two colons, as otherwise they
+are interpreted as representing a single colon data character (and the list
+would then contain just one item). If you want to specify a list that contains
+just one, empty item, you can do it as in this example:
+.display asis
+senders = :
+.endd
+In this case, the first item is empty, and the second is discarded because it
+is at the end of the list.
+.nem
+
+
.section Format of driver configurations
.rset SECTfordricon "~~chapter.~~section"
.index drivers||configuration format
Two different styles of data lookup are implemented:
.numberpars $.
The \*single-key*\ style requires the specification of a file in which to look,
-and a single key to search for. The lookup type determines how the file is
-searched.
+and a single key to search for.
+.em
+The key must be a non-empty string for the lookup to succeed.
+.nem
+The lookup type determines how the file is searched.
.nextp
.index query-style lookup||definition of
The \*query*\ style accepts a generalized database query.
wildcarding of any kind.
.index lookup||lsearch, colons in keys
-In most \%lsearch%\ files, keys are not required to contain colons
-or @# characters, or
-whitespace. However, if you need this feature, it is available. If a key begins
-with a doublequote character, it is terminated only by a matching quote (or end
-of line), and the normal escaping rules apply to its contents (see section
-~~SECTstrings). An optional colon is permitted after quoted keys (exactly as
-for unquoted keys). There is no special handling of quotes for the data part of
-an \%lsearch%\ line.
+.index whitespace||in lsearch key
+In most \%lsearch%\ files, keys are not required to contain colons or @#
+characters, or whitespace. However, if you need this feature, it is available.
+If a key begins with a doublequote character, it is terminated only by a
+matching quote (or end of line), and the normal escaping rules apply to its
+contents (see section ~~SECTstrings). An optional colon is permitted after
+quoted keys (exactly as for unquoted keys). There is no special handling of
+quotes for the data part of an \%lsearch%\ line.
.nextp
.index NIS lookup type
.index lookup||NIS
Like \%lsearch%\, the testing is done case-insensitively. The following forms
of wildcard are recognized:
.numberpars "$*$"
-The string may begin with an asterisk to mean `begins with'. For example:
+The string may begin with an asterisk to mean `ends with'. For example:
.display asis
*.a.b.c data for anything.a.b.c
*fish data for anythingfish
.numberpars $.
.index DNS||as a lookup type
.index lookup||DNS
-\%dnsdb%\: This does a DNS search for a record whose domain name is the supplied
-query. The resulting data is the contents of the record. See section
-~~SECTdnsdb.
+\%dnsdb%\: This does a DNS search for
+.em
+one or more records whose domain names are given in the supplied query. The
+resulting data is the contents of the records.
+.nem
+See section ~~SECTdnsdb.
.nextp
.index Interbase lookup type
.index lookup||Interbase
.nextp
.index lookup||passwd
.index passwd lookup type
+.index \(/etc/passwd)\
\%passwd%\ is a query-style lookup with queries that are just user names. The
lookup calls \*getpwnam()*\ to interrogate the system password data, and on
success, the result string is the same as you would get from an \%lsearch%\
.section Lookup caching
.index lookup||caching
.index caching||lookup data
-An Exim process
-caches the most recent lookup result on a per-file basis for single-key
-lookup types, and keeps the relevant files open. In some types of configuration
-this can lead to many files being kept open for messages with many recipients.
-To avoid hitting the operating system limit on the number of simultaneously
-open files, Exim closes the least recently used file when it needs to open more
-files than its own internal limit, which can be changed via the
-\lookup@_open@_max\ option.
-
-For query-style lookups, a single data cache per lookup type is kept. The files
-are closed and the caches flushed at strategic points during delivery -- for
-example, after all routing is complete.
+.em
+Exim caches all lookup results in order to avoid needless repetition of
+lookups. However, because (apart from the daemon) Exim operates as a collection
+of independent, short-lived processes, this caching applies only within a
+single Exim process. There is no inter-process caching facility.
+
+For single-key lookups, Exim keeps the relevant files open in case there is
+another lookup that needs them. In some types of configuration this can lead to
+many files being kept open for messages with many recipients. To avoid hitting
+the operating system limit on the number of simultaneously open files, Exim
+closes the least recently used file when it needs to open more files than its
+own internal limit, which can be changed via the \lookup@_open@_max\ option.
+
+The single-key lookup files are closed and the lookup caches are flushed at
+strategic points during delivery -- for example, after all routing is complete.
+.nem
.section Quoting lookup data
.index dnsdb lookup
.index lookup||dnsdb
.index DNS||as a lookup type
-The \%dnsdb%\ lookup type uses the DNS as its database. A query consists of a
-record type and a domain name, separated by an equals sign. For example, an
-expansion string could contain:
+The \%dnsdb%\ lookup type uses the DNS as its database. A simple query consists
+of a record type and a domain name, separated by an equals sign. For example,
+an expansion string could contain:
.display asis
${lookup dnsdb{mx=a.b.example}{$value}fail}
.endd
-The supported record types are A, CNAME, MX, NS, PTR, SRV, and TXT,
-and, when Exim is compiled with IPv6 support, AAAA (and A6 if that is also
-configured). If no type is given, TXT is assumed. When the type is PTR, the
-address should be given as normal; it is converted to the necessary inverted
-format internally. For example:
+The supported DNS record types are A, CNAME, MX, NS, PTR, SRV, and TXT, and,
+when Exim is compiled with IPv6 support, AAAA (and A6 if that is also
+configured). If no type is given, TXT is assumed. When the type is PTR,
+.em
+the data can be an IP address, written as normal; inversion and the addition of
+\in-addr.arpa\ or \ip6.arpa\ happens automatically. For example:
.display asis
${lookup dnsdb{ptr=192.168.4.5}{$value}fail}
.endd
+If the data for a PTR record is not a syntactically valid IP address, it is not
+altered and nothing is added.
+
+For any record type, if multiple records are found (or, for A6 lookups, if a
+single record leads to multiple addresses), the data is returned as a
+concatenation, with newline as the default separator. The order, of course,
+depends on the DNS resolver. You can specify a different separator character
+between multiple records by putting a right angle-bracket followed immediately
+by the new separator at the start of the query. For example:
+.display asis
+${lookup dnsdb{>: a=host1.example}}
+.endd
+It is permitted to specify a space as the separator character. Further
+whitespace is ignored.
-.index MX record||in \%dnsdb%\ lookup
-For MX records, both the preference value and the host name are returned,
-separated by a space.
.index SRV record||in \%dnsdb%\ lookup
-For SRV records, the priority, weight, port, and host name are returned,
-separated by spaces. For any record type,
-if multiple records are found (or, for A6 lookups, if a single record leads to
-multiple addresses), the data is returned as a concatenation, separated by
-newlines. The order, of course, depends on the DNS resolver.
+For SRV records, the priority, weight, port, and host name are returned for
+each record, separated by spaces.
+
+.index MX record||in \%dnsdb%\ lookup
+For MX records, both the preference value and the host name are returned for
+each record, separated by a space. However, if you want only host names, you
+can use the pseudo-type MXH:
+.display asis
+${lookup dnsdb{mxh=a.b.example}}
+.endd
+In this case, the preference values are omitted.
+
+.index name server||for enclosing domain
+Another pseudo-type is ZNS (for `zone NS'). It performs a lookup for NS
+records on the given domain, but if none are found, it removes the first
+component of the domain name, and tries again. This process continues until NS
+records are found or there are no more components left (or there is a DNS
+error). In other words, it may return the name servers for a top-level domain,
+but it never returns the root name servers. If there are no NS records for the
+top-level domain, the lookup fails. Consider these examples:
+.display asis
+${lookup dnsdb{zns=xxx.quercite.com}}
+${lookup dnsdb{zns=xxx.edu}}
+.endd
+Assuming that in each case there are no NS records for the full domain name,
+the first returns the name servers for \quercite.com\, and the second returns
+the name servers for \edu\.
+
+You should be careful about how you use this lookup because, unless the
+top-level domain does not exist, the lookup always returns some host names. The
+sort of use to which this might be put is for seeing if the name servers for a
+given domain are on a blacklist. You can probably assume that the name servers
+for the high-level domains such as \com\ or \co.uk\ are not going to be on such
+a list.
+.nem
+.em
+.section Multiple dnsdb lookups
+In the previous section, \%dnsdb%\ lookups for a single domain are described.
+However, you can specify a list of domains or IP addresses in a single
+\%dnsdb%\ lookup. The list is specified in the normal Exim way, with colon as
+the default separator, but with the ability to change this. For example:
+.display asis
+${lookup dnsdb{one.domain.com:two.domain.com}}
+${lookup dnsdb{a=one.host.com:two.host.com}}
+${lookup dnsdb{ptr = <; 1.2.3.4 ; 4.5.6.8}}
+.endd
+In order to retain backwards compatibility, there is one special case: if
+the lookup type is PTR and no change of separator is specified, Exim looks
+to see if the rest of the string is precisely one IPv6 address. In this
+case, it does not treat it as a list.
+
+The data from each lookup is concatenated, with newline separators by default,
+in the same way that multiple DNS records for a single item are handled. A
+different separator can be specified, as described above.
+
+The \%dnsdb%\ lookup fails only if all the DNS lookups fail. If there is a
+temporary DNS error for any of them, the behaviour is controlled by
+an optional keyword followed by a comma that may appear before the record
+type. The possible keywords are `defer@_strict', `defer@_never', and
+`defer@_lax'. With `strict' behaviour, any temporary DNS error causes the
+whole lookup to defer. With `never' behaviour, a temporary DNS error is
+ignored, and the behaviour is as if the DNS lookup failed to find anything.
+With `lax' behaviour, all the queries are attempted, but a temporary DNS
+error causes the whole lookup to defer only if none of the other lookups
+succeed. The default is `lax', so the following lookups are equivalent:
+.display asis
+${lookup dnsdb{defer_lax,a=one.host.com:two.host.com}}
+${lookup dnsdb{a=one.host.com:two.host.com}}
+.endd
+Thus, in the default case, as long as at least one of the DNS lookups
+yields some data, the lookup succeeds.
+.nem
.section More about LDAP
be preceded by any number of `<<name>>=<<value>>' settings, separated by
spaces. If a value contains spaces it must be enclosed in double quotes, and
when double quotes are used, backslash is interpreted in the usual way inside
-them.
-
-The following names are recognized:
+them. The following names are recognized:
.display
-CONNECT $rm{set a connection timeout}
-.newline
DEREFERENCE $rm{set the dereferencing parameter}
+.newline
+.em
+NETTIME $rm{set a timeout for a network operation}
+.nem
+.newline
USER $rm{set the DN, for authenticating the LDAP bind}
PASS $rm{set the password, likewise}
SIZE $rm{set the limit for the number of entries returned}
The value of the \\DEREFERENCE\\ parameter must be one of the words `never',
`searching', `finding', or `always'.
+.em
+The name \\CONNECT\\ is an obsolete name for \\NETTIME\\, retained for
+backwards compatibility. This timeout (specified as a number of seconds) is
+enforced from the client end for operations that can be carried out over a
+network. Specifically, it applies to network connections and calls to the
+\*ldap@_result()*\ function. If the value is greater than zero, it is used if
+\\LDAP@_OPT@_NETWORK@_TIMEOUT\\ is defined in the LDAP headers (OpenLDAP), or
+if \\LDAP@_X@_OPT@_CONNECT@_TIMEOUT\\ is defined in the LDAP headers (Netscape
+SDK 4.1). A value of zero forces an explicit setting of `no timeout' for
+Netscape SDK; for OpenLDAP no action is taken.
+
+The \\TIME\\ parameter (also a number of seconds) is passed to the server to
+set a server-side limit on the time taken to complete a search.
+.nem
+
Here is an example of an LDAP query in an Exim lookup that uses some of these
values. This is a single line, folded for ease of reading:
.display asis
connection timeout (the system timeout is used), no user or password, no limit
on the number of entries returned, and no time limit on queries.
-The time limit for connection is given in seconds; zero means use the default.
-This facility is available in Netscape SDK 4.1; it may not be available in
-other LDAP implementations. Exim uses the given value if
-\\LDAP@_X@_OPT@_CONNECT@_TIMEOUT\\ is defined in the LDAP headers.
-
When a DN is quoted in the \\USER=\\ setting for LDAP authentication, Exim
removes any URL quoting that it may contain before passing it LDAP. Apparently
some libraries do this for themselves, but some do not. Removing the URL
.endd
The \%ldap%\ lookup type generates an error if more than one entry matches the
-search filter, whereas \%ldapm%\ permits this case, and inserts a newline in the
-result between the data from different entries. It is possible for multiple
-values to be returned for both \%ldap%\ and \%ldapm%\, but in the former case you
-know that whatever values are returned all came from a single entry in the
+search filter, whereas \%ldapm%\ permits this case, and inserts a newline in
+the result between the data from different entries. It is possible for multiple
+values to be returned for both \%ldap%\ and \%ldapm%\, but in the former case
+you know that whatever values are returned all came from a single entry in the
directory.
In the common case where you specify a single attribute in your LDAP query, the
If a MySQL query is issued that does not request any data (an insert, update,
or delete command), the result of the lookup is the number of rows affected.
-
+.em
+\**Warning**\: this can be misleading. If an update does not actually change
+anything (for example, setting a field to the value it already has), the result
+is zero because no rows are affected.
+.nem
.section Special PostgreSQL features
.section Expansion of lists
.index expansion||of lists
-Each list is expanded as a single string before it is used. If the expansion is
-forced to fail, Exim behaves as if the item it is testing (domain, host,
-address, or local part) is not in the list. Other expansion failures cause
-temporary errors.
+.em
+Each list is expanded as a single string before it is used. The result of
+expansion must be a list, possibly containing empty items, which is split up
+into separate items for matching. By default, colon is the separator character,
+but this can be varied if necessary. See sections ~~SECTlistconstruct and
+~~SECTempitelis for details of the list syntax; the second of these discusses
+the way you specify empty list items.
+.nem
+
+If the string expansion is forced to fail, Exim behaves as if the item it is
+testing (domain, host, address, or local part) is not in the list. Other
+expansion failures cause temporary errors.
If an item in a list is a regular expression, backslashes, dollars and possibly
other special characters in the expression must be protected against
\"@\N"\, whereas the second uses the expansion to obtain a list of unwanted
senders based on the receiving domain.
-After expansion, the list is split up into separate items for matching.
-Normally, colon is used as the separator character, but this can be varied if
-necessary, as described in section ~~SECTlistconstruct.
.section Negated items in lists
hosts_lookup = pgsql;\
select ip from hostlist where ip='$sender_host_address'
.endd
-The value of \$sender@_host@_address$\ for an IPv6 address uses colon
-separators. You can use the \sg\ expansion item to change this if you need to.
-If you want to use masked IP addresses in database queries, you can use the
-\mask\ expansion operator.
+The value of \$sender@_host@_address$\ for an IPv6 address contains colons. You
+can use the \sg\ expansion item to change this if you need to. If you want to
+use masked IP addresses in database queries, you can use the \mask\ expansion
+operator.
If the query contains a reference to \$sender@_host@_name$\, Exim automatically
looks up the host name if has not already done so. (See section
host name before running the query, unless the search type was preceded by
\"net-"\. This is no longer the case. For backwards compatibility, \"net-"\ is
still recognized for query-style lookups, but its presence or absence has no
-effect. (Of course, for single-key lookups, \"net-"\ $it{is} important.)
+effect. (Of course, for single-key lookups, \"net-"\ $it{is} important.
+See section ~~SECThoslispatsikey.)
.section Mixing wildcarded host names and addresses in host lists
.endd
The presence of the colon creates an empty item. If you do not provide any
data, the list is empty and matches nothing. The empty sender can also be
-detected by a regular expression that matches an empty string.
+detected by a regular expression that matches an empty string,
+.em
+and by a query-style lookup that succeeds when \$sender@_address$\ is empty.
-The following kinds of pattern are supported in address lists:
+The following kinds of address list pattern can match any address, including
+the empty address that is characteristic of bounce message senders:
+.nem
.numberpars $.
+.em
+As explained above, if a pattern item is empty, it matches the empty address
+(and no others).
+.nem
+.nextp
.index regular expressions||in address list
.index address list||regular expression in
If (after expansion) a pattern starts with `@^', a regular expression match is
The \"@\N"\ sequences are removed by the expansion, so the item does start
with `@^' by the time it is being interpreted as an address pattern.
.nextp
-.index @@@@ with single-key lookup
-.index address list||@@@@ lookup type
-.index address list||split local part and domain
-If a pattern starts with `@@@@' followed by a single-key lookup item
-(for example, \"@@@@lsearch;/some/file"\), the address that is being checked is
-split into a local part and a domain. The domain is looked up in the file. If
-it is not found, there is no match. If it is found, the data that is looked up
-from the file is treated as a colon-separated list of local part patterns, each
-of which is matched against the subject local part in turn.
-
-.index asterisk||in address list
-The lookup may be a partial one, and/or one involving a search for a default
-keyed by `$*$' (see section ~~SECTdefaultvaluelookups). The local part patterns
-that are looked up can be regular expressions or begin with `$*$', or even be
-further lookups. They may also be independently negated. For example, with
+.index address list||lookup for complete address
+Complete addresses can be looked up by using a pattern that starts with a
+lookup type terminated by a semicolon, followed by the data for the lookup. For
+example:
.display asis
-deny senders = @@dbm;/etc/reject-by-domain
+deny senders = cdb;/etc/blocked.senders : \
+ mysql;select address from blocked where \
+ address='${quote_mysql:$sender_address}'
.endd
-the data from which the DBM file is built could contain lines like
+.em
+Both query-style and single-key lookup types can be used. For a single-key
+lookup type, Exim uses the complete address as the key. However, empty keys are
+not supported for single-key lookups, so a match against the empty address
+always fails. This restriction does not apply to query-style lookups.
+
+.nem
+Partial matching for single-key lookups (section ~~SECTpartiallookup) cannot be
+used, and is ignored if specified, with an entry being written to the panic
+log.
+.index @*@@ with single-key lookup
+However, you can configure lookup defaults, as described in section
+~~SECTdefaultvaluelookups, but this is useful only for the `$*$@@' type of
+default. For example, with this lookup:
.display asis
-baddomain.com: !postmaster : *
+accept senders = lsearch*@;/some/file
.endd
-to reject all senders except \postmaster\ from that domain.
-.index local part||starting with !
-If a local part that actually begins with an exclamation mark is required, it
-has to be specified using a regular expression. In \%lsearch%\ files, an entry
-may be split over several lines by indenting the second and subsequent lines,
-but the separating colon must still be included at line breaks. White space
-surrounding the colons is ignored. For example:
+the file could contains lines like this:
.display asis
-aol.com: spammer1 : spammer2 : ^[0-9]+$ :
- spammer3 : spammer4
+user1@domain1.example
+*@domain2.example
+.endd
+and for the sender address \*nimrod@@jaeger.example*\, the sequence of keys
+that are tried is:
+.display asis
+nimrod@jaeger.example
+*@jaeger.example
+*
+.endd
+\**Warning 1**\: Do not include a line keyed by `$*$' in the file, because that
+would mean that every address matches, thus rendering the test useless.
+
+\**Warning 2**\: Do not confuse these two kinds of item:
+.display asis
+deny recipients = dbm*@;/some/file
+deny recipients = *@dbm;/some/file
+.endd
+The first does a whole address lookup, with defaulting, as just described,
+because it starts with a lookup type. The second matches the local part and
+domain independently, as described in a bullet point below.
+.endp
+
+
+.em
+The following kinds of address list pattern can match only non-empty addresses.
+If the subject address is empty, a match against any of these pattern types
+always fails.
+.nem
+
+.numberpars $.
+.index @@@@ with single-key lookup
+.index address list||@@@@ lookup type
+.index address list||split local part and domain
+If a pattern starts with `@@@@' followed by a single-key lookup item
+(for example, \"@@@@lsearch;/some/file"\), the address that is being checked is
+split into a local part and a domain. The domain is looked up in the file. If
+it is not found, there is no match. If it is found, the data that is looked up
+from the file is treated as a colon-separated list of local part patterns, each
+of which is matched against the subject local part in turn.
+
+.index asterisk||in address list
+The lookup may be a partial one, and/or one involving a search for a default
+keyed by `$*$' (see section ~~SECTdefaultvaluelookups). The local part patterns
+that are looked up can be regular expressions or begin with `$*$', or even be
+further lookups. They may also be independently negated. For example, with
+.display asis
+deny senders = @@dbm;/etc/reject-by-domain
+.endd
+the data from which the DBM file is built could contain lines like
+.display asis
+baddomain.com: !postmaster : *
+.endd
+to reject all senders except \postmaster\ from that domain.
+.index local part||starting with !
+If a local part that actually begins with an exclamation mark is required, it
+has to be specified using a regular expression. In \%lsearch%\ files, an entry
+may be split over several lines by indenting the second and subsequent lines,
+but the separating colon must still be included at line breaks. White space
+surrounding the colons is ignored. For example:
+.display asis
+aol.com: spammer1 : spammer2 : ^[0-9]+$ :
+ spammer3 : spammer4
.endd
As in all colon-separated lists in Exim, a colon can be included in an item by
doubling.
lookup, but in this case, the chaining facility is not available. The lookup
can only return a single list of local parts.
.nextp
-.index address list||lookup for complete address
-Complete addresses can be looked up by using a pattern that
-starts with a lookup type terminated by a semicolon, follwed by the data for
-the lookup.
-For example:
-.display asis
-deny senders = cdb;/etc/blocked.senders : \
- mysql;select address from blocked where \
- address='${quote_mysql:$sender_address}'
-.endd
-For a single-key lookup type, Exim uses the complete address as the key.
-Partial matching (section ~~SECTpartiallookup) cannot be used, and is ignored
-if specified, with an entry being written to the panic log.
-
-.index @*@@ with single-key lookup
-You can configure lookup defaults, as described in section
-~~SECTdefaultvaluelookups, but this is useful only for the `$*$@@' type of
-default. For example, with this lookup:
-.display asis
-accept senders = lsearch*@;/some/file
-.endd
-the file could contains lines like this:
-.display asis
-user1@domain1.example
-*@domain2.example
-.endd
-and for the sender address \*nimrod@@jaeger.example*\, the sequence of keys
-that are tried is:
-.display asis
-nimrod@jaeger.example
-*@jaeger.example
-*
-.endd
-\**Warning 1**\: Do not include a line keyed by `$*$' in the file, because that
-would mean that every address matches, thus rendering the test useless.
-
-\**Warning 2**\: Do not confuse these two kinds of item:
-.display asis
-deny recipients = dbm*@;/some/file
-deny recipients = *@dbm;/some/file
-.endd
-The first does a whole address lookup, with defaulting, as just described,
-because it starts with a lookup type. The second matches the local part and
-domain independently, as described in the next paragraph.
-.nextp
-If a pattern contains an @@ character, but is not a regular expression
-and does not begin with a lookup type
-as described above, 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, the domain is checked in exactly the same way as for a pattern in a
-domain list. For example, the domain can be wildcarded, refer to a named list,
-or be a lookup:
+If a pattern contains an @@ character, but is not a regular expression and does
+not begin with a lookup type as described above, 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, the domain is checked in exactly the same
+way as for a pattern in a domain list. For example, the domain can be
+wildcarded, refer to a named list, or be a lookup:
.display asis
deny senders = *@*.spamming.site:\
*@+hostile_domains:\
specified using a regular expression, because otherwise the exclamation mark is
treated as a sign of negation.
.nextp
-If a pattern is not one of the above syntax forms, that is, if a pattern which
-is not a regular expression or a lookup does not contain an @@ character, it is
-matched against the domain part of the subject address. The only two formats
-that are recognized this way are a literal domain, or a domain pattern that
-starts with $*$. In both these cases, the effect is the same as if \"*@@"\
-preceded the pattern.
+If a pattern is not one of the above syntax forms, that is, if a
+.em
+non-empty
+.nem
+pattern that is not a regular expression or a lookup does not contain an @@
+character, it is matched against the domain part of the subject address. The
+only two formats that are recognized this way are a literal domain, or a domain
+pattern that starts with $*$. In both these cases, the effect is the same as if
+\"*@@"\ preceded the pattern.
.endp
\**Warning**\: there is an important difference between the address list items
using \-be-\ for reading files to which they do not have access.
+.em
+.section Forced expansion failure
+.rset SECTforexpfai "~~chapter.~~section"
+.index expansion||forced failure
+A number of expansions that are described in the following section have
+alternative `true' and `false' substrings, enclosed in curly brackets. Which
+one is used depends on some condition that is evaluated as part of the
+expansion. If, instead of a `false' substring, the word `fail' is used (not in
+curly brackets), the entire string expansion fails in a way that can be
+detected by the code that requested the expansion. This is called `forced
+expansion failure', and its consequences depend on the circumstances. In some
+cases it is no different from any other expansion failure, but in others a
+different action may be taken. Such variations are mentioned in the
+documentation of the option that is being expanded.
+.nem
+
+
.section Expansion items
.rset SECTexpansionitems "~~chapter.~~section"
The following items are recognized in expanded strings. White space may be used
.display
@$@{extract@{Z@}@{A=... B=...@}@{@$value@} fail @}
.endd
-@{<<string2>>@} must be present for `fail' to be recognized. When this syntax
-is used, if the extraction fails, the entire string expansion fails in a way
-that can be detected by the code in Exim which requested the expansion. This is
-called `forced expansion failure', and its consequences depend on the
-circumstances. In some cases it is no different from any other expansion
-failure, but in others a different action may be taken. Such variations are
-mentioned in the documentation of the option which is expanded.
+This forces an expansion failure (see section ~~SECTforexpfai); @{<<string2>>@}
+must be present for `fail' to be recognized.
.item "@$@{extract@{<<number>>@}@{<<separators>>@}@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
The difference between \rheader\, \bheader\, and \header\ is in the way the
data in the header line is interpreted.
.numberpars $.
+.index whitespace||in header lines
\rheader\ gives the original `raw' content of the header line, with no
processing at all, and without the removal of leading and trailing whitespace.
.nextp
\*hmac@_md5@_hex()*\ function in Perl.
-
.item "@${if <<condition>> @{<<string1>>@}@{<<string2>>@}@}"
.index expansion||conditional
If <<condition>> is true, <<string1>> is expanded and replaces the whole item;
-otherwise <<string2>> is used. For example,
+otherwise <<string2>> is used. The available conditions are described in
+section ~~SECTexpcond below. For example:
.display asis
${if eq {$local_part}{postmaster} {yes}{no} }
.endd
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 is forced to fail if the condition is not true. The
-available conditions are described in section ~~SECTexpcond below.
+case, the expansion is forced to fail if the condition is not true (see section
+~~SECTforexpfai).
+
+.em
+If both strings are omitted, the result is the string \"true"\ if the condition
+is true, and the empty string if the condition is false. This makes it less
+cumbersome to write custom ACL and router conditions. For example, instead of
+.display asis
+condition = ${if >{$acl_m4}{3}{true}{false}}
+.endd
+you can use
+.display asis
+condition = ${if >{$acl_m4}{3}}
+.endd
+.nem
.item "@$@{length@{<<string1>>@}@{<<string2>>@}@}"
During its expansion, the variable \$value$\ contains the data returned by the
lookup. Afterwards it reverts to the value it had previously (at the outer
level it is empty). If the lookup fails, <<string2>> is expanded and replaces
-the entire item. If @{<<string2>>@} is omitted, the replacement is null on
-failure. Alternatively, <<string2>> can itself be a nested lookup, thus
-providing a mechanism for looking up a default value when the original lookup
-fails.
+the entire item. If @{<<string2>>@} is omitted, the replacement is the empty
+string on failure. If <<string2>> is provided, it can itself be a nested
+lookup, thus providing a mechanism for looking up a default value when the
+original lookup fails.
If a nested lookup is used as part of <<string1>>, \$value$\ contains the data
for the outer lookup while the parameters of the second lookup are expanded,
lookup fail.
Instead of @{<<string2>>@} the word `fail' can appear, and in this case, if the
-lookup fails, the entire expansion is forced to fail. If both @{<<string1>>@}
-and @{<<string2>>@} are omitted, the result is the looked up value in the case
-of a successful lookup, and nothing in the case of failure.
+lookup fails, the entire expansion is forced to fail (see section
+~~SECTforexpfai). If both @{<<string1>>@} and @{<<string2>>@} are omitted, the
+result is the looked up value in the case of a successful lookup, and nothing
+in the case of failure.
For single-key lookups, the string `partial' is permitted to precede the
search type in order to do partial matching, and $*$ or $*$@@ may follow a
@$@{substr@_<<n>>@_<<m>>:<<string>>@}
.endd
The second number is optional (in both notations).
+.em
+If it is absent in the simpler format, the preceding underscore must also be
+omitted.
+.nem
The \substr\ item can be used to extract more general substrings than \length\.
The first number, <<n>>, is a starting offset, and <<m>> is the length
.endd
yields `1'.
-If the second number is omitted from \substr\, the remainder of the string is
-taken if the offset was positive. If it was negative, all characters in the
+When the second number is omitted from \substr\, the remainder of the string is
+taken if the offset is positive. If it is negative, all characters in the
string preceding the offset point are taken. For example, an offset of -1 and
-no length yields all but the last character of the string.
+no length, as in these semantically identical examples:
+.display asis
+${substr_-1:abcde}
+${substr{-1}{abcde}}
+.endd
+yields all but the last character of the string, that is, `abcd'.
This operator encodes text according to the rules of RFC 2047. This is an
encoding that is used in header lines to encode non-ASCII characters. It is
assumed that the input string is in the encoding specified by the
-\headers@_charset\ option, which defaults to ISO-8859-1.
-If the string contains only characters in the range 33--126, and no instances
-of the characters
+\headers@_charset\ option, which defaults to ISO-8859-1. If the string contains
+only characters in the range 33--126, and no instances of the characters
.display asis
? = ( ) < > @ , ; : \ " . [ ] _
.endd
-it is not modified. Otherwise, the result is the RFC 2047 encoding, as a single
-`coded word'.
+it is not modified. Otherwise, the result is the RFC 2047 encoding of the
+string,
+.em
+using as many `coded words' as necessary to encode all the characters.
+.nem
.item "@$@{sha1:<<string>>@}"
incorrect on 32-bit systems for files larger than 2GB.
+.em
+.item "@$@{str2b64:<<string>>@}"
+.index expansion||base64 encoding
+.index base64 encoding||in string expansion
+This operator converts a string into one that is base64 encoded.
+.nem
+
+
.item "@$@{strlen:<<string>>@}"
.index expansion||string length
.index string||length in expansion
SHA-1 digest. If the length is not 28 or 40, the comparison fails.
.nextp
.index \*crypt()*\
-\@{crypt@}\ calls the \*crypt()*\ function, which uses only the first eight
-characters of the password.
+\@{crypt@}\ calls the \*crypt()*\ function,
+.em
+which traditionally used to use only the first eight characters of the
+password. However, in modern operating systems this is no longer true, and in
+many cases the entire password is used, whatever its length.
+.nem
.nextp
.index \*crypt16()*\
\@{crypt16@}\ calls the \*crypt16()*\ function (also known as \*bigcrypt()*\),
-which uses up to 16 characters of the password.
+which
+.em
+was orginally created to use up to 16 characters of the password. Again, in
+modern operating systems, more characters may be used.
+.nem
.endp
Exim has its own version of \*crypt16()*\ (which is just a double call to
\*crypt()*\). For operating systems that have their own version, setting
set \\RADIUS@_CONFIG@_FILE\\ in \(Local/Makefile)\ to specify the location of
the Radius client configuration file in order to build Exim with Radius
support.
+.em
+With just that one setting, Exim expects to be linked with the \radiusclient\
+library. You can also link Exim with the \libradius\ library that comes with
+FreeBSD. To do this, set
+.display asis
+RADIUS_LIB_TYPE=RADLIB
+.endd
+in \(Local/Makefile)\, in addition to setting \\RADIUS@_CONFIGURE@_FILE\\.
+.nem
You may also have to supply a suitable setting in \\EXTRALIBS\\ so that the
Radius library can be found when Exim is linked.
+
The string specified by \\RADIUS@_CONFIG@_FILE\\ is expanded and passed to the
Radius client library, which calls the Radius server. The condition is true if
the authentication is successful. For example
.rset SECTexpvar "~~chapter.~~section"
.index expansion||variables, list of
-The variables that are available for use in expansion strings are:
+.em
+This section contains an alphabetical list of all the expansion variables. Some
+of them are available only when Exim is compiled with specific options such as
+support for TLS or the content scanning extension.
+.nem
.push
.indent 2em
-.tempindent 0
.index numerical variables (\$1$\, \$2$\, etc)
+.tempindent 0
\$0$\, \$1$\, etc: When a \match\ expansion condition succeeds, these
variables contain the captured substrings identified by the regular expression
during subsequent processing of the success string of the containing \if\
option in routers. The value then remains with the address while it is
processed by subsequent routers and eventually a transport. If the transport is
handling multiple addresses, the value from the first address is used. See
-chapter ~~CHAProutergeneric for more details.
-\**Note**\: the contents of \$address@_data$\ are visible in user filter files.
+chapter ~~CHAProutergeneric for more details. \**Note**\: the contents of
+\$address@_data$\ are visible in user filter files.
-If \$address@_data$\ is set when the routers are called to verify an address
-from an ACL, the final value remains available in subsequent conditions in the
-ACL statement. If routing the address caused it to be redirected to a single
-address, the child address is also routed as part of the verification, and in
-this case the final value of \$address@_data$\ is from the child's routing.
+.em
+If \$address@_data$\ is set when the routers are called from an ACL to verify
+a recipient address, the final value is still in the variable for subsequent
+conditions and modifiers of the ACL statement. If routing the address caused it
+to be redirected to just one address, the child address is also routed as part
+of the verification, and in this case the final value of \$address@_data$\ is
+from the child's routing.
+
+If \$address@_data$\ is set when the routers are called from an ACL to verify a
+sender address, the final value is also preserved, but this time in
+\$sender@_address@_data$\, to distinguish it from data from a recipient
+address.
+
+In both cases (recipient and sender verification), the value does not persist
+after the end of the current ACL statement. If you want to preserve
+these values for longer, you can save them in ACL variables.
+.nem
.tempindent 0
\$address@_file$\: When, as a result of aliasing, forwarding, or filtering, a
of times it has been compiled. This serves to distinguish different
compilations of the same version of the program.
+.em
+.tempindent 0
+\$demime@_errorlevel$\: This variable is available when Exim is compiled with
+the content-scanning extension and the obsolete \demime\ condition. For
+details, see section ~~SECTdemimecond.
+
+.tempindent 0
+\$demime@_reason$\: This variable is available when Exim is compiled with the
+content-scanning extension and the obsolete \demime\ condition. For details,
+see section ~~SECTdemimecond.
+.nem
+
.index black list (DNS)
.tempindent 0
\$dnslist@_domain$\: When a client host is found to be on a DNS (black) list,
.tempindent 0
\$exim@_uid$\: This variable contains the numerical value of the Exim user id.
+.em
+.tempindent 0
+\$found@_extension$\: This variable is available when Exim is compiled with the
+content-scanning extension and the obsolete \demime\ condition. For details,
+see section ~~SECTdemimecond.
+.nem
+
.tempindent 0
\$header@_<<name>>$\: This is not strictly an expansion variable. It is
expansion syntax for inserting the message header line with the given name.
\$host@_address$\:
This variable is set to the remote host's IP address whenever \$host$\ is set
for a remote connection.
+.em
+It is also set to the IP address that is being checked when the
+\ignore@_target@_hosts\ option is being processed.
+.nem
.tempindent 0
\$host@_data$\:
message = $host_data
.endd
+.em
.index host||name lookup, failure of
.tempindent 0
-\$host@_lookup@_failed$\:
-This variable contains `1' if the message came from a remote host and there was
-an attempt to look up the host's name from its IP address, but the attempt
-failed. Otherwise the value of the variable is `0'.
-Exim checks that a forward lookup of at least one of the names it receives from
-a reverse lookup yields the original IP address. If this is not the case, Exim
-does not accept the looked up name(s), and \$host@_lookup@_failed$\ is set to
-`1'. Thus, being able to find a name from an IP address (for example, the
-existence of a PTR record in the DNS) is not sufficient on its own for the
-success of a host name lookup.
+\$host@_lookup@_deferred$\:
+This variable normally contains `0', as does \$host@_lookup@_failed$\. When a
+message comes from a remote host and there is an attempt to look up the host's
+name from its IP address, and the attempt is not successful, one of these
+variables is set to `1'.
+.numberpars $.
+If the lookup receives a definite negative response (for example, a DNS lookup
+succeeded, but no records were found), \$host@_lookup@_failed$\ is set to `1'.
+.nextp
+If there is any kind of problem during the lookup, such that Exim cannot
+tell whether or not the host name is defined (for example, a timeout for a DNS
+lookup), \$host@_lookup@_deferred$\ is set to `1'.
+.endp
+Looking up a host's name from its IP address consists of more than just a
+single reverse lookup. Exim checks that a forward lookup of at least one of the
+names it receives from a reverse lookup yields the original IP address. If this
+is not the case, Exim does not accept the looked up name(s), and
+\$host@_lookup@_failed$\ is set to `1'. Thus, being able to find a name from an
+IP address (for example, the existence of a PTR record in the DNS) is not
+sufficient on its own for the success of a host name lookup. If the reverse
+lookup succeeds, but there is a lookup problem such as a timeout when checking
+the result, the name is not accepted, and \$host@_lookup@_deferred$\ is set to
+`1'. See also \$sender@_host@_name$\.
+
+.tempindent 0
+\$host@_lookup@_failed$\: See \$host@_lookup@_deferred$\.
+.nem
.tempindent 0
\$inode$\:
contains the DN from the last entry in the most recently successful LDAP
lookup.
-
.tempindent 0
\$load@_average$\:
This variable contains the system load average, multiplied by 1000 to that it
values in these variables are \"(uid@_t)(-1)"\ and \"(gid@_t)(-1)"\,
respectively.
-
.tempindent 0
\$localhost@_number$\: This contains the expanded value of the
\localhost@_number\ option. The expansion happens after the main options have
been read.
+.em
+.tempindent 0
+\$log@_inodes$\: The number of free inodes in the disk partition where Exim's
+log files are being written. The value is recalculated whenever the variable is
+referenced. If the relevant file system does not have the concept of inodes,
+the value of is -1. See also the \check@_log@_inodes\ option.
+
+.tempindent 0
+\$log@_space$\: The amount of free space (as a number of kilobytes) in the disk
+partition where Exim's log files are being written. The value is recalculated
+whenever the variable is referenced. If the operating system does not have the
+ability to find the amount of free space (only true for experimental systems),
+the space value is -1. See also the \check@_log@_space\ option.
+.nem
+
.tempindent 0
\$mailstore@_basename$\: This variable is set only when doing deliveries in
`mailstore' format in the \%appendfile%\ transport. During the expansion of the
written, that is, the name without the `.tmp', `.env', or `.msg' suffix. At all
other times, this variable is empty.
+.em
+.tempindent 0
+\$malware@_name$\: This variable is available when Exim is compiled with the
+content-scanning extension. It is set to the name of the virus that was found
+when the ACL \malware\ condition is true (see section ~~SECTscanvirus).
+.nem
+
.index message||age of
.tempindent 0
\$message@_age$\: This variable is set at the start of a delivery attempt to
.index body of message||size
.index message||body, size
.tempindent 0
-\$message@_body@_size$\: When a message is being processed, this variable
+\$message@_body@_size$\: When a message is being delivered, this variable
contains the size of the body in bytes. The count starts from the character
after the blank line that separates the body from the header. Newlines are
-included in the count. See also \$message@_size$\ and \$body@_linecount$\.
+included in the count. See also \$message@_size$\, \$body@_linecount$\, and
+\$body@_zerocount$\.
.tempindent 0
\$message@_headers$\:
expansion of the \maildir@_tag\ option in the \%appendfile%\ transport while
doing a delivery in maildir format, the value of \$message@_size$\ is the
precise size of the file that has been written. See also
-\$message@_body@_size$\ and \$body@_linecount$\.
+\$message@_body@_size$\, \$body@_linecount$\, and \$body@_zerocount$\.
.index \\RCPT\\||value of \$message@_size$\
While running an ACL at the time of an SMTP \\RCPT\\ command, \$message@_size$\
-1
if no size was given. The value may not, of course, be truthful.
+.em
+.tempindent 0
+\$mime@_$\\*xxx*\: A number of variables whose names start with \$mime$\ are
+available when Exim is compiled with the content-scanning extension. For
+details, see section ~~SECTscanmimepart.
+.nem
+
.tempindent 0
\$n0$\ -- \$n9$\: These variables are counters that can be incremented by means
of the \add\ command in filter files.
.tempindent 0
\$original@_local@_part$\: When a top-level address is being processed for
delivery, this contains the same value as \$local@_part$\, unless a prefix or
-suffix was removed from the local part, in which case \$original@_local@_part$\
-contains the full local part. When a `child' address (for example, generated by
-an alias, forward, or filter file) is being processed, this variable contains
-the full local part of the original address. If the router that did the
-redirection processed the local part case-insensitively, the value in
-\$original@_local@_part$\ is in lower case. This variable differs from
-\$parent@_local@_part$\ only when there is more than one level of aliasing or
-forwarding. When more than one address is being delivered in a single transport
-run, \$original@_local@_part$\ is not set.
+suffix was removed from the local part, because \$original@_local@_part$\
+always contains the full local part. When a `child' address (for example,
+generated by an alias, forward, or filter file) is being processed, this
+variable contains the full local part of the original address.
+
+If the router that did the redirection processed the local part
+case-insensitively, the value in \$original@_local@_part$\ is in lower case.
+This variable differs from \$parent@_local@_part$\ only when there is more than
+one level of aliasing or forwarding. When more than one address is being
+delivered in a single transport run, \$original@_local@_part$\ is not set.
If new an address is created by means of a \deliver\ command in a system
filter, it is set up with an artificial `parent' address. This has the local
.tempindent 0
\$received@_protocol$\: When a message is being processed, this variable
-contains the name of the protocol by which it was received. See also the
-\-oMr-\ option.
+contains the name of the protocol by which it was received.
+.em
+Most of the names used by Exim are defined by RFCs 821, 2821, and 3848. They
+start with `smtp' (the client used \\HELO\\) or `esmtp' (the client used
+\\EHLO\\). This can be followed by `s' for secure (encrypted) and/or `a' for
+authenticated. Thus, for example, if the protocol is set to `esmtpsa', the
+message was received over an encrypted SMTP connection and the client was
+successfully authenticated.
+
+Exim uses the protocol name `smtps' for the case when encryption is
+automatically set up on connection without the use of \\STARTTLS\\ (see
+\tls@_on@_connect@_ports\), and the client uses \\HELO\\ to initiate the
+encrypted SMTP session. The name `smtps' is also used for the rare situation
+where the client initially uses \\EHLO\\, sets up an encrypted connection using
+\\STARTTLS\\, and then uses \\HELO\\ afterwards.
+
+The \-oMr-\ option provides a way of specifying a custom protocol name for
+messages that are injected locally by trusted callers. This is commonly used to
+identify messages that are being re-injected after some kind of scanning.
+.nem
.tempindent 0
\$recipient@_data$\: This variable is set after an indexing lookup success in
The variable is not set for a lookup that is used as part of the string
expansion that all such lists undergo before being interpreted.
+.em
+.tempindent 0
+\$recipient@_verify@_failure$\: In an ACL, when a recipient verification fails,
+this variable contains information about the failure. It is set to one of the
+following words:
+.numberpars " "
+`qualify': The address was unqualified (no domain), and the message
+was neither local nor came from an exempted host.
+.nextp
+`route': Routing failed.
+.nextp
+`mail': Routing succeeded, and a callout was attempted; rejection occurred at
+or before the \\MAIL\\ command (that is, on initial connection, \\HELO\\, or
+\\MAIL\\).
+.nextp
+`recipient': The \\RCPT\\ command in a callout was rejected.
+.nextp
+`postmaster': The postmaster check in a callout was rejected.
+.endp
+The main use of this variable is expected to be to distinguish between
+rejections of \\MAIL\\ and rejections of \\RCPT\\.
+.nem
+
.tempindent 0
\$recipients$\: This variable contains a list of envelope recipients for a
message. A comma and a space separate the addresses in the replacement text.
However, the variable is not generally available, to prevent exposure of Bcc
recipients in unprivileged users' filter files. You can use \$recipients$\ only
+in these two cases:
.numberpars
In a system filter file.
.nextp
-In the \\DATA\\ or non-SMTP ACL, that is, in the final ACL for accepting a
-message.
+.em
+In the ACLs associated with the \\DATA\\ command, that is, the ACLs defined by
+\acl@_smtp@_predata\ and \acl@_smtp@_data\.
+.nem
.endp
.tempindent 0
messages, the value of this variable is the empty string.
See also \$return@_path$\.
+.em
+.tempindent 0
+\$sender@_address@_data$\: If \$address@_data$\ is set when the routers are
+called from an ACL to verify a sender address, the final value is preserved in
+\$sender@_address@_data$\, to distinguish it from data from a recipient
+address. The value does not persist after the end of the current ACL statement.
+If you want to preserve it for longer, you can save it in an ACL variable.
+.nem
+
.tempindent 0
\$sender@_address@_domain$\: The domain portion of \$sender@_address$\.
If the host name has not previously been looked up, a reference to
\$sender@_host@_name$\ triggers a lookup (for messages from remote hosts).
A looked up name is accepted only if it leads back to the original IP address
-via a forward lookup. If either the reverse or the forward lookup fails, or if
-the forward lookup does not yield the original IP address,
+via a forward lookup. If either the reverse or the forward lookup fails
+.em
+to find any data,
+.nem
+or if the forward lookup does not yield the original IP address,
\$sender@_host@_name$\ remains empty, and \$host@_lookup@_failed$\ is set to
`1'.
+.em
+However, if either of the lookups cannot be completed (for example, there is a
+DNS timeout), \$host@_lookup@_deferred$\ is set to `1', and
+\$host@_lookup@_failed$\ remains set to `0'.
+
+Once \$host@_lookup@_failed$\ is set to `1', Exim does not try to look up the
+host name again if there is a subsequent reference to \$sender@_host@_name$\
+in the same Exim process, but it does try again if \$sender@_host@_deferred$\
+is set to `1'.
+.nem
Exim does not automatically look up every calling host's name. If you want
maximum efficiency, you should arrange your configuration so that it avoids
three items are present in the parentheses, a newline and tab are inserted into
the string, to improve the formatting of the ::Received:: header.
+.em
+.tempindent 0
+\$sender@_verify@_failure$\: In an ACL, when a sender verification fails, this
+variable contains information about the failure. The details are the same as
+for \$recipient@_verify@_failure$\.
+
+.tempindent 0
+\$smtp@_active@_hostname$\: During an SMTP session, this variable contains the
+value of the active host name, as specified by the \smtp@_active@_hostname\
+option. The value of \$smtp@_active@_hostname$\ is saved with any message that
+is received, so its value can be consulted during routing and delivery.
+.nem
+
.index \\AUTH\\||argument
.index \\EXPN\\||argument
.index \\ETRN\\||argument
filter files. For example, a system filter could set a value indicating how
likely it is that a message is junk mail.
+.em
+.tempindent 0
+\$spam@_$\\*xxx*\: A number of variables whose names start with \$spam$\ are
+available when Exim is compiled with the content-scanning extension. For
+details, see section ~~SECTscanspamass.
+.nem
+
.tempindent 0
\$spool@_directory$\: The name of Exim's spool directory.
+.em
+.tempindent 0
+\$spool@_inodes$\: The number of free inodes in the disk partition where Exim's
+spool files are being written. The value is recalculated whenever the variable
+is referenced. If the relevant file system does not have the concept of inodes,
+the value of is -1.
+See also the \check@_spool@_inodes\ option.
+
+.tempindent 0
+\$spool@_space$\: The amount of free space (as a number of kilobytes) in the
+disk partition where Exim's spool files are being written. The value is
+recalculated whenever the variable is referenced. If the operating system does
+not have the ability to find the amount of free space (only true for
+experimental systems), the space value is -1. For example, to check in an ACL
+that there is at least 50 megabytes free on the spool, you could write:
+.display asis
+condition = ${if > {$spool_space}{50000}}
+.endd
+See also the \check@_spool@_space\ option.
+.nem
+
.tempindent 0
\$thisaddress$\: This variable is set only during the processing of the
\foranyaddress\ command in a filter file. Its use is explained in the
.endd
in your \(Local/Makefile)\ and then build Exim in the normal way.
+.section Setting up so Perl can be used
Access to Perl subroutines is via a global configuration option called
.index \perl@_startup\
\perl@_startup\ and an expansion string operator \@$@{perl ...@}\. If there is
There is also a command line option \-pd-\ (for delay) which suppresses the
initial startup, even if \perl@_at@_start\ is set.
+.section Calling Perl subroutines
When the configuration file includes a \perl@_startup\ option you can make use
of the string expansion item to call the Perl subroutines that are defined
by the \perl@_startup\ code. The operator is used in any of the following
.endd
The return value of the Perl subroutine is evaluated in a scalar context before
it is passed back to Exim to be inserted into the expanded string. If the
-return value is \*undef*\, the expansion fails in the same way as an explicit
-`fail' on an \@$@{if ...@}\ or \@$@{lookup...@}\ item.
-If the subroutine aborts by obeying Perl's \die\ function, the expansion fails
-with the error message that was passed to \die\.
+return value is \*undef*\, the expansion is forced to fail in the same way as
+an explicit `fail' on an \@$@{if ...@}\ or \@$@{lookup...@}\ item. If the
+subroutine aborts by obeying Perl's \die\ function, the expansion fails with
+the error message that was passed to \die\.
+.section Calling Exim functions from Perl
Within any Perl code called from Exim, the function \*Exim@:@:expand@_string*\
is available to call back into Exim's string expansion function. For example,
the Perl code
main log, adding a leading timestamp. In this case, you should not supply a
terminating newline.
+.em
+.section Use of standard output and error by Perl
+.index Perl||standard output and error
+You should not write to the standard error or output streams from within your
+Perl code, as it is not defined how these are set up. In versions of Exim
+before 4.50, it is possible for the standard output or error to refer to the
+SMTP connection during message reception via the daemon. Writing to this stream
+is certain to cause chaos. From Exim 4.50 onwards, the standard output and
+error streams are connected to \(/dev/null)\ in the daemon. The chaos is
+avoided, but the output is lost.
+
+.index Perl||\warn\, use of
+The Perl \warn\ statement writes to the standard error stream by default. Calls
+to \warn\ may be embedded in Perl modules that you use, but over which you have
+no control. When Exim starts up the Perl interpreter, it arranges for output
+from the \warn\ statement to be written to the Exim main log. You can change
+this by including appropriate Perl magic somewhere in your Perl code. For
+example, to discard \warn\ output completely, you need this:
+.display asis
+$SIG{__WARN__} = sub { };
+.endd
+Whenever a \warn\ is obeyed, the anonymous subroutine is called. In this
+example, the code for the subroutine is empty, so it does nothing, but you can
+include any Perl code that you like. The text of the \warn\ message is passed
+as the first subroutine argument.
+.nem
.
value of \daemon@_smtp@_ports\ is no longer relevant in this example.)
+.em
+.section Support for the obsolete SSMTP (or SMTPS) protocol
+.rset SECTsupobssmt "~~chapter.~~section"
+.index ssmtp protocol
+.index smtps protocol
+.index SMTP||ssmtp protocol
+.index SMTP||smtps protocol
+Exim supports the obsolete SSMTP protocol (also known as SMTPS) that was used
+before the \\STARTTLS\\ command was standardized for SMTP. Some legacy clients
+still use this protocol. If the \tls@_on@_connect@_ports\ option is set to a
+list of port numbers, connections to those ports must use SSMTP. The most
+common use of this option is expected to be
+.display asis
+tls_on_connect_ports = 465
+.endd
+because 465 is the usual port number used by the legacy clients. There is also
+a command line option \-tls-on-connect-\, which forces all ports to behave in
+this way when a daemon is started.
+
+\**Warning**\: Setting \tls@_on@_connect@_ports\ does not of itself cause the
+daemon to listen on those ports. You must still specify them in
+\daemon@_smtp@_ports\, \local@_interfaces\, or the \-oX-\ option. (This is
+because \tls@_on@_connect@_ports\ applies to \inetd\ connections as well as to
+connections via the daemon.)
+.nem
+
+
.section IPv6 address scopes
IPv6 addresses have `scopes', and a host with multiple hardware interfaces
can, in principle, have the same link-local IPv6 address on different
percent sign followed by something (often the interface name) has been
adopted in some cases, leading to addresses like this:
.display asis
-3ffe:2101:12:1:a00:20ff:fe86:a061%eth0
+fe80::202:b3ff:fe03:45c1%eth0
.endd
To accommodate this usage, a percent sign followed by an arbitrary string is
allowed at the end of an IPv6 address. By default, Exim calls \*getaddrinfo()*\
.section Examples of starting a listening daemon
The default case in an IPv6 environment is
.display asis
-daemon_smtp_port = smtp
+daemon_smtp_ports = smtp
local_interfaces = <; ::0 ; 0.0.0.0
.endd
This specifies listening on the smtp port on all IPv6 and IPv4 interfaces.
.display asis
local_interfaces = 192.168.34.67 : 192.168.34.67
.endd
-\**Note**\: such a setting excludes listening on the loopback interfaces.
+\**Warning**\: such a setting excludes listening on the loopback interfaces.
.section Recognising the local host
-
.
.
.
types and default values. For ease of finding a particular option, they appear
in alphabetical order in section ~~SECTalomo below. However, because there are
now so many options, they are first listed briefly in functional groups, as an
-aid to finding the name of the option you are looking for.
-Some options are listed in more than one group.
+aid to finding the name of the option you are looking for. Some options are
+listed in more than one group.
.set savedisplayflowcheck ~~displayflowcheck
.set displayflowcheck 0
\keep@_malformed\ $t$rm{for broken files -- should not happen}
\localhost@_number\ $t$rm{for unique message ids in clusters}
\message@_body@_visible\ $t$rm{how much to show in \$message@_body$\}
+.newline
+.em
+\mua@_wrapper\ $t$rm{run in `MUA wrapper' mode}
+.nem
+.newline
\print@_topbitchars\ $t$rm{top-bit characters are printing}
\timezone\ $t$rm{force time zone}
.endd
.section Logging
.display flow rm
.tabs 31
+.em
+\hosts@_connection@_nolog\ $t$rm{exemption from connect logging}
+.nem
+.newline
\log@_file@_path\ $t$rm{override compiled-in value}
\log@_selector\ $t$rm{set/unset optional logging}
\log@_timezone\ $t$rm{add timezone to log lines}
\acl@_smtp@_helo\ $t$rm{set ACL for \\EHLO\\ or \\HELO\\}
\acl@_smtp@_mail\ $t$rm{set ACL for \\MAIL\\}
\acl@_smtp@_mailauth\ $t$rm{set ACL for \\AUTH\\ on \\MAIL\\ command}
+.newline
+.em
+\acl@_smtp@_mime\ $t$rm{set ACL for MIME parts}
+\acl@_smtp@_predata\ $t$rm{set ACL for start of data}
+\acl@_smtp@_quit\ $t$rm{set ACL for \\QUIT\\}
+.nem
+.newline
\acl@_smtp@_rcpt\ $t$rm{set ACL for \\RCPT\\}
\acl@_smtp@_starttls\ $t$rm{set ACL for \\STARTTLS\\}
\acl@_smtp@_vrfy\ $t$rm{set ACL for \\VRFY\\}
+.newline
+.em
+\av@_scanner\ $t$rm{specify virus scanner}
+.nem
+.newline
\header@_maxsize\ $t$rm{total size of message header}
\header@_line@_maxsize\ $t$rm{individual header line limit}
\helo@_accept@_junk@_hosts\ $t$rm{allow syntactic junk from these hosts}
\local@_scan@_timeout\ $t$rm{timeout for \*local@_scan()*\}
\message@_size@_limit\ $t$rm{for all messages}
\percent@_hack@_domains\ $t$rm{recognize %-hack for these domains}
+.newline
+.em
+\spamd@_address\ $t$rm{set interface to SpamAssassin}
+.nem
+.newline
.endd
.section Callout cache
.tabs 31
\tls@_advertise@_hosts\ $t$rm{advertise TLS to these hosts}
\tls@_certificate\ $t$rm{location of server certificate}
-.newline
\tls@_crl\ $t$rm{certificate revocation list}
-.newline
\tls@_dhparam\ $t$rm{DH parameters for server}
+.newline
+.em
+\tls@_on@_connect@_ports\ $t$rm{specify SSMTP (SMTPS) ports}
+.nem
+.newline
\tls@_privatekey\ $t$rm{location of server private key}
\tls@_remember@_esmtp\ $t$rm{don't reset after starting TLS}
-.newline
\tls@_require@_ciphers\ $t$rm{specify acceptable cipers}
-.newline
\tls@_try@_verify@_hosts\ $t$rm{try to verify client certificate}
\tls@_verify@_certificates\ $t$rm{expected client certificates}
\tls@_verify@_hosts\ $t$rm{insist on client certificate verify}
Those options that undergo string expansion before use are marked with $**$.
.fi
-.startconf
+.startconf main
.index \\8BITMIME\\
.index 8-bit characters
This option defines the ACL that is run when a non-SMTP message is on the point
of being accepted. See chapter ~~CHAPACL for further details.
-.index ~~ACL||on SMTP connection
-.conf acl@_smtp@_connect string$**$ unset
-This option defines the ACL that is run when an SMTP connection is received.
-See chapter ~~CHAPACL for further details.
-
.index ~~ACL||setting up for SMTP commands
.index \\AUTH\\||ACL for
.conf acl@_smtp@_auth string$**$ unset
This option defines the ACL that is run when an SMTP \\AUTH\\ command is
received. See chapter ~~CHAPACL for further details.
-.index \\DATA\\, ACL for
+.index ~~ACL||on SMTP connection
+.conf acl@_smtp@_connect string$**$ unset
+This option defines the ACL that is run when an SMTP connection is received.
+See chapter ~~CHAPACL for further details.
+
+.index \\DATA\\, ACL for
.conf acl@_smtp@_data string$**$ unset
This option defines the ACL that is run after an SMTP \\DATA\\ command has been
processed and the message itself has been received, but before the final
a \\MAIL\\ command. See chapter ~~CHAPACL for details of ACLs, and chapter
~~CHAPSMTPAUTH for details of authentication.
+.em
+.index MIME content scanning||ACL for
+.conf acl@_smtp@_mime string$**$ unset
+This option is available when Exim is built with the content-scanning
+extension. It defines the ACL that is run for each MIME part in a message. See
+section ~~SECTscanmimepart for details.
+
+.conf acl@_smtp@_predata string$**$ unset
+This option defines the ACL that is run when an SMTP \\DATA\\ command is
+received, before the message itself is received. See chapter ~~CHAPACL for
+further details.
+
+.index \\QUIT\\||ACL for
+.conf acl@_smtp@_quit string$**$ unset
+This option defines the ACL that is run when an SMTP \\QUIT\\ command is
+received. See chapter ~~CHAPACL for further details.
+.nem
+
.index \\RCPT\\||ACL for
.conf acl@_smtp@_rcpt string$**$ unset
This option defines the ACL that is run when an SMTP \\RCPT\\ command is
though there are big problems'. See also \timeout@_frozen@_after\ and
\ignore@_bounce@_errors@_after\.
+.em
+.conf av@_scanner string "see below"
+This option is available if Exim is built with the content-scanning extension.
+It specifies which anti-virus scanner to use. The default value is:
+.display asis
+sophie:/var/run/sophie
+.endd
+If the value of \av@_scanner\ starts with dollar character, it is expanded
+before use. See section ~~SECTscanvirus for further details.
+.nem
+
.conf bi@_command string unset
.index \-bi-\ option
This option supplies the name of a command that is run when Exim is called with
.index disk space, checking
.index spool directory||checking space
The four \check@_...\ options allow for checking of disk resources before a
-message is accepted. \check@_spool@_space\ and \check@_spool@_inodes\ check the
-spool partition if either value is greater than zero, for example:
+message is accepted.
+.em
+When any of these options are set, they apply to all incoming messages. If you
+want to apply different checks to different kinds of message, you can do so
+by testing the the variables \$log@_inodes$\, \$log@_space$\,
+\$spool@_inodes$\, and \$spool@_space$\ in an ACL with appropriate additional
+conditions.
+.nem
+
+\check@_spool@_space\ and \check@_spool@_inodes\ check the spool partition if
+either value is greater than zero, for example:
.display asis
check_spool_space = 10M
check_spool_inodes = 100
.endd
-The spool partition is the one which contains the directory defined by
+The spool partition is the one that contains the directory defined by
\\SPOOL@_DIRECTORY\\ in \(Local/Makefile)\. It is used for holding messages in
transit.
.index warning of delay
.index delay warning, specifying
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, no warnings are
-sent. The data is a colon-separated list of times after which to send warning
-messages. Up to 10 times may be given. If a message has been on the queue for
-longer than the last time, the last interval between the times is used to
-compute subsequent warning times. For example, with
+intervals specified by this option. The data is a colon-separated list of times
+after which to send warning messages.
+.em
+If the value of the option is an empty string or a zero time, no warnings are
+sent.
+.nem
+Up to 10 times may be given. If a message has been on the queue for longer than
+the last time, the last interval between the times is used to compute
+subsequent warning times. For example, with
.display asis
delay_warning = 4h:8h:24h
.endd
.display asis
dns_again_means_nonexist = *.in-addr.arpa
.endd
+.em
+This option applies to all DNS lookups that Exim does. The \%dnslookup%\ router
+has some options of its own for controlling what happens when lookups for MX or
+SRV records give temporary errors. These more specific options are applied
+after the global option.
+.nem
.index DNS||pre-check of name syntax
.conf dns@_check@_names@_pattern string "see below"
addresses are removed from the recipients list. This is also how Smail behaves.
However, other Sendmail documentation (the O'Reilly book) states that command
line addresses are added to those obtained from the header lines. When
-\extract@_addresses@_remove@_arguments\ is true (the default), Exim subtracts
+\extract__addresses__remove__arguments\ is true (the default), Exim subtracts
argument headers. If it is set false, Exim adds rather than removes argument
addresses.
many extra times to find a user or a group, waiting for one second between
retries.
+.index \(/etc/passwd)\, multiple reading of
+.em
+You should not set this option greater than zero if your user information is in
+a traditional \(/etc/passwd)\ file, because it will cause Exim needlessly to
+search the file multiple times for non-existent users, and also cause delay.
+.nem
+
.conf freeze@_tell "string list, comma separated" unset
.index freezing messages||sending a message when freezing
On encountering certain errors, or when configured to do so in a system filter,
incoming messages at a later stage, such as after \\RCPT\\ commands. See
chapter ~~CHAPACL.
+.em
+.conf hosts@_connection@_nolog "host list$**$" unset
+.index host||not logging connections from
+This option defines a list of hosts for which connection logging does not
+happen, even though the \smtp@_connection\ log selector is set. For example,
+you might want not to log SMTP connections from local processes, or from
+127.0.0.1, or from your local LAN. This option is consulted in the main loop of
+the daemon; you should therefore strive to restrict its value to a short inline
+list of IP addresses and networks. To disable logging SMTP connections from
+local processes, you must create a host list with an empty item. For example:
+.display asis
+hosts_connection_nolog = :
+.endd
+If the \smtp@_connection\ log selector is not set, this option has no effect.
+.nem
+
.conf hosts@_treat@_as@_local "domain list$**$" unset
.index local host||domains treated as
.index host||treated as local
.index ::From:: header line||disabling checking of
When a message is submitted locally (that is, not over a TCP/IP connection) by
an untrusted user, Exim removes any existing ::Sender:: header line, and checks
-that the ::From:: header line matches the login of the calling user. You can
-use \local@_from@_prefix\ and \local@_from@_suffix\ to permit affixes on the
-local part. If the ::From:: header line does not match, Exim adds a ::Sender::
-header with an address constructed from the calling user's login and the
-default qualify domain.
+that the ::From:: header line matches
+.em
+the login of the calling user and the domain specified by \qualify@_domain\.
+
+\**Note**\: An unqualified address (no domain) in the ::From:: header in a
+locally submitted message is automatically qualified by Exim, unless the
+\-bnq-\ command line option is used.
+.nem
+
+You can use \local@_from@_prefix\ and \local@_from@_suffix\ to permit affixes
+on the local part. If the ::From:: header line does not match, Exim adds a
+::Sender:: header with an address constructed from the calling user's login and
+the default qualify domain.
If \local@_from@_check\ is set false, the ::From:: header check is disabled,
and no ::Sender:: header is ever added. If, in addition, you want to retain
These options affect only the header lines in the message. The envelope sender
is still forced to be the login id at the qualify domain unless
\untrusted@_set@_sender\ permits the user to supply an envelope sender.
-Section ~~SECTthesenhea has more details about ::Sender:: processing.
+
+.em
+For messages received over TCP/IP, an ACL can specify `submission mode' to
+request similar header line checking. See section ~~SECTthesenhea, which has
+more details about ::Sender:: processing.
+.nem
.conf local@_from@_prefix string unset
This option controls which network interfaces are used by the daemon for
listening; they are also used to identify the local host when routing. Chapter
~~CHAPinterfaces contains a full description of this option and the related
-options \extra@_local@_interfaces\ and \hosts@_treat@_as@_local\. The default
-value for \local@_interfaces\ is
+options
+.em
+\daemon@_smtp@_ports\, \extra@_local@_interfaces\, \hosts@_treat@_as@_local\,
+and \tls@_on@_connect@_ports\.
+.nem
+The default value for \local@_interfaces\ is
.display asis
local_interfaces = 0.0.0.0
.endd
standard utilities for handling such moved messages, and they do not show up in
lists generated by \-bp-\ or by the Exim monitor.
+.em
+.conf mua@_wrapper boolean false
+Setting this option true causes Exim to run in a very restrictive mode in which
+it passes messages synchronously to a smart host. Chapter ~~CHAPnonqueueing
+contains a full description of this facility.
+.nem
+
.conf mysql@_servers "string list" unset
.index MySQL||server list
This option provides a list of MySQL servers and associated connection data, to
.conf qualify@_domain string "see below"
.index domain||for qualifying addresses
.index address||qualification
-This option 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
-\sender@_unqualified@_hosts\ or \recipient@_unqualified@_hosts\ (as
-appropriate), in which case incoming addresses are qualified with
-\qualify@_domain\ or \qualify@_recipient\ as necessary. Internally, Exim always
-works with fully qualified addresses.
-If \qualify@_domain\ is not set, it defaults to the \primary@_hostname\ value.
+This option specifies the domain name that is added to any envelope sender
+addresses that do not have a domain qualification. It also applies to
+recipient addresses if \qualify@_recipient\ is not set.
+.em
+Unqualified addresses are accepted by default only for locally-generated
+messages.
+
+Qualification is also applied to addresses in header lines such as ::From:: and
+::To:: for locally-generated messages, unless the \-bnq-\ command line option
+is used.
+.nem
+
+Messages from external sources must always contain fully qualified addresses,
+unless the sending host matches \sender@_unqualified@_hosts\ or
+\recipient@_unqualified@_hosts\ (as appropriate), in which case incoming
+addresses are qualified with \qualify@_domain\ or \qualify@_recipient\ as
+necessary. Internally, Exim always works with fully qualified envelope
+addresses. If \qualify@_domain\ is not set, it defaults to the
+\primary@_hostname\ value.
.conf qualify@_recipient string "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 recipient addresses, unless the sending host matches
-\recipient@_unqualified@_hosts\,
-in which case incoming recipient addresses are qualified with
-\qualify@_recipient\.
-If \qualify@_recipient\ is not set, it defaults to the \qualify@_domain\ value.
+.em
+This option allows you to specify a different domain for qualifying recipient
+addresses to the one that is used for senders. See \qualify@_domain\ above.
+.nem
.conf queue@_domains "domain list$**$" unset
.index domain||specifying non-immediate delivery
.index queue runner||processing messages in order
If this option is set, queue runs happen in order of message arrival instead of
in an arbitrary order. For this to happen, a complete list of the entire queue
-must be set up before the deliveries start. When the queue is all in a single
-directory (the default), this happens anyway, but if \split@_spool@_directory\
-is set it does not -- for delivery in random order, the sub-directories are
-processed one at a time (in random order), to avoid setting up one huge list.
-Thus, setting \queue@_run@_in@_order\ with \split@_spool@_directory\ may
-degrade performance when the queue is large. In most situations,
-\queue@_run@_in@_order\ should not be set.
+must be set up before the deliveries start. When the queue is all held in a
+single directory (the default),
+.em
+a single list is created for both the ordered and the non-ordered cases.
+However, if \split@_spool@_directory\ is set, a single list is not created when
+\queue@_run@_in@_order\ is false. In this case, the sub-directories are
+processed one at a time (in a random order), and this avoids setting up one
+huge list for the whole queue. Thus, setting \queue@_run@_in@_order\ with
+\split@_spool@_directory\ may degrade performance when the queue is large,
+because of the extra work in setting up the single, large list. In most
+situations, \queue@_run@_in@_order\ should not be set.
+.nem
.conf queue@_run@_max integer 5
.index queue runner||maximum number of
then take place at once is \queue@_run@_max\ multiplied by
\remote@_max@_parallel\.
-If it is purely remote deliveries you want to control, 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.
+If it is purely remote deliveries you want to control, use
+\queue@_smtp@_domains\ 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.
.conf remote@_sort@_domains "domain list$**$" unset
.index sorting remote deliveries
several different hosts. At the start of an SMTP connection, its value is
expanded and used instead of the value of \$primary@_hostname$\ in SMTP
responses. For example, it is used as domain name in the response to an
-incoming \\HELO\\ or \\EHLO\\ command. If this option is unset, or if its
-expansion is forced to fail, or if the expansion results in an empty string,
-the value of \$primary@_hostname$\ is used. Other expansion failures cause a
-message to be written to the main and panic logs, and the SMTP command receives
-a temporary error. Typically, the value of \smtp@_active@_hostname\ depends on
-the incoming interface address. For example:
+incoming \\HELO\\ or \\EHLO\\ command.
+.em
+It is also used in \\HELO\\ commands for callout verification.
+The active hostname is placed in the \$smtp__active__hostname$\ variable, which
+is saved with any messages that are received. It is therefore available for use
+in routers and transports when the message is later delivered.
+.nem
+
+If this option is unset, or if its expansion is forced to fail, or if the
+expansion results in an empty string, the value of \$primary@_hostname$\ is
+used. Other expansion failures cause a message to be written to the main and
+panic logs, and the SMTP command receives a temporary error. Typically, the
+value of \smtp@_active@_hostname\ depends on the incoming interface address.
+For example:
.display asis
smtp_active_hostname = ${if eq{$interface_address}{10.0.0.1}\
{cox.mydomain}{box.mydomain}}
.endd
-If you set \smtp@_active@_hostname\, you probably also want to set
-\smtp@_banner\, since its default value references \$primary@_hostname$\.
.conf smtp@_banner string$**$ "see below"
.index SMTP||welcome banner
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:
.display asis
-smtp_banner = $primary_hostname ESMTP Exim $version_number \
- $tod_full
+.em
+smtp_banner = $smtp_active_hostname ESMTP Exim \
+ $version_number $tod_full
+.nem
.endd
Failure to expand the string causes a panic error. If you want to create a
multiline response to the initial SMTP connection, use `@\n' in the string at
The SMTP protocol specification requires the client to wait for a response from
the server at certain points in the dialogue. Without \\PIPELINING\\ these
synchronization points are after every command; with \\PIPELINING\\ they are
-fewer, but they still exist. Some spamming sites send out a complete set of
-SMTP commands without waiting for any response. Exim protects against this by
-rejecting a message if the client has sent further input when it should not
-have. The error response `554 SMTP synchronization error' is sent, and the
-connection is dropped. Testing for this error cannot be perfect because of
-transmission delays (unexpected input may be on its way but not yet received
-when Exim checks). However, it does detect many instances. The check can be
-disabled by setting \smtp@_enforce@_sync\ false.
-See also \pipelining@_advertise@_hosts\.
+fewer, but they still exist.
+
+Some spamming sites send out a complete set of SMTP commands without waiting
+for any response. Exim protects against this by rejecting a message if the
+client has sent further input when it should not have. The error response `554
+SMTP synchronization error' is sent, and the connection is dropped. Testing for
+this error cannot be perfect because of transmission delays (unexpected input
+may be on its way but not yet received when Exim checks). However, it does
+detect many instances.
+
+.em
+The check can be globally disabled by setting \smtp@_enforce@_sync\ false.
+If you want to disable the check selectively (for example, only for certain
+hosts), you can do so by an appropriate use of a \control\ modifier in an ACL
+(see section ~~SECTcontrols). See also \pipelining@_advertise@_hosts\.
+.nem
.conf smtp@_etrn@_command string$**$ unset
.index \\ETRN\\||command to be run
550 failing address in "From" header is: <user@dom.ain
.endd
+.em
+.conf spamd@_address string "$tt{127.0.0.1 783}"
+This option is available when Exim is compiled with the content-scanning
+extension. It specifies how Exim connects to SpamAssassin's \spamd\ daemon. See
+section ~~SECTscanspamass for more details.
+.nem
+
.conf split@_spool@_directory boolean false
.index multiple spool directories
.index spool directory||split
This is used only for OpenSSL. When Exim is linked with GnuTLS, this option is
ignored. See section ~~SECTopenvsgnu for further details.
+.em
+.conf tls@_on@_connect@_ports "string list" unset
+This option specifies a list of incoming SSMTP (aka SMTPS) ports that should
+operate the obsolete SSMTP (SMTPS) protocol, where a TLS session is immediately
+set up without waiting for the client to issue a \\STARTTLS\\ command. For
+further details, see section ~~SECTsupobssmt.
+.nem
+
.conf tls@_privatekey string$**$ unset
.index TLS||server private key, location of
-The value of this option is expanded, and must then be the absolute path to
-a file which contains the server's private key.
-If this option is unset, the private key is assumed to be in the same file as
-the server's certificates. See chapter ~~CHAPTLS for further details.
+The value of this option is expanded, and must then be the absolute path to a
+file which contains the server's private key. If this option is unset, the
+private key is assumed to be in the same file as the server's certificates. See
+chapter ~~CHAPTLS for further details.
.conf tls@_remember@_esmtp boolean false
.index TLS||esmtp state, remembering
.index TLS||requiring specific ciphers
.index cipher||requiring specific
This option controls which ciphers can be used for incoming TLS connections.
-(The \%smtp%\ transport has an option of the same name for controlling outgoing
-connections.) This option is expanded for each connection, so can be varied for
+The \%smtp%\ transport has an option of the same name for controlling outgoing
+connections. This option is expanded for each connection, so can be varied for
different clients if required. The value of this option must be a list of
permitted cipher suites. The OpenSSL and GnuTLS libraries handle cipher control
-in somewhat different ways. Details are given in section ~~SECTreqciphsslgnu.
+in somewhat different ways.
+.em
+If GnuTLS is being used, the client controls the preference order of the
+available ciphers.
+.nem
+Details are given in sections ~~SECTreqciphssl and ~~SECTreqciphgnu.
.conf tls@_try@_verify@_hosts "host list$**$" unset
.index TLS||client certificate verification
This chapter describes the generic options that apply to all routers,
identifying those that are preconditions. For a general description of how a
-router operates, see sections ~~SECTrunindrou and ~~SECTrouprecon. The second
-of these sections specifies the order in which the preconditions are tested.
-The order of expansion of the options that provide data for a transport is:
-\errors@_to\, \headers@_add\, \headers@_remove\, \transport\.
+router operates, see sections ~~SECTrunindrou and ~~SECTrouprecon. The latter
+specifies the order in which the preconditions are tested. The order of
+expansion of the options that provide data for a transport is: \errors@_to\,
+\headers@_add\, \headers@_remove\, \transport\.
-.startconf
+.startconf routers
.conf address@_data string$**$ unset
.index router||data attached to address
file = ${extract{mailbox}{$address_data}}
.endd
This makes the configuration file less messy, and also reduces the number of
-lookups. (Exim does cache the most recent lookup, but there may be several
-addresses in a message which cause lookups to occur.)
+lookups (though Exim does cache lookups).
The \address@_data\ facility is also useful as a means of passing information
-from one router to another,
-and from a router to a transport. In addition, if \address@_data\ is set by a
-router when verifying an address from an ACL, its value is available for use in
-the rest of the ACL statement.
+from one router to another, and from a router to a transport. In addition, if
+.em
+\$address@_data$\ is set by a router when verifying a recipient address from an
+ACL, it remains available for use in the rest of the ACL statement. After
+verifying a sender, the value is transferred to \$sender@_address@_data$\.
+.nem
.conf address@_test "boolean (precondition)" true
part lists (for example, \local@_parts\), case-sensitive matching can be turned
on by `+caseful' as a list item. See section ~~SECTcasletadd for more details.
+.em
+The value of the \$local@_part$\ variable is forced to lower case while a
+router is running unless \caseful@_local@_part\ is set. When a router assigns
+an address to a transport, the value of \$local@_part$\ when the transport runs
+is the same as it was in the router. Similarly, when a router generates child
+addresses by aliasing or forwarding, the values of \$original@_local@_part$\
+and \$parent@_local@_part$\ are those that were used by the redirecting router.
+
+This option applies to the processing of an address by a router. When a
+recipient address is being processed in an ACL, there is a separate \control\
+modifier that can be used to specify case-sensitive processing within the ACL
+(see section ~~SECTcontrols).
+.nem
.conf check@_local@_user "boolean (precondition)" false
.index local user, checking in router
.index router||checking for local user
+.index \(/etc/passwd)\
When this option is true, Exim checks that the local part of the recipient
address (with affixes removed if relevant) is the name of an account on the
local system. The check is done by calling the \*getpwnam()*\ function rather
than trying to read \(/etc/passwd)\ directly. This means that other methods of
holding password data (such as NIS) are supported. If the local part is a local
user, \$home$\ is set from the password data, and can be tested in other
-preconditions that are evaluated after this one
-(the order of evaluation is given in section ~~SECTrouprecon). However, the
-value of \$home$\ can be overridden by \router@_home@_directory\.
-If the local part is not a local user, the router is skipped.
+preconditions that are evaluated after this one (the order of evaluation is
+given in section ~~SECTrouprecon). However, the value of \$home$\ can be
+overridden by \router@_home@_directory\. If the local part is not a local user,
+the router is skipped.
If you want to check that the local part is either the name of a local user
or matches something else, you cannot combine \check@_local@_user\ with a
up a home directory) do not occur when a \%passwd%\ lookup is used in a
\local@_parts\ (or any other) precondition.
+
.conf condition "string$**$ (precondition)" unset
.index router||customized precondition
This option specifies a general precondition test that has to succeed for the
-router to be called. The string is expanded, and if the result is a forced
-failure or an empty string or one of the strings `0' or `no' or `false'
-(checked without regard to the case of the letters), the router is skipped, and
-the address is offered to the next one. This provides a means of applying
-special-purpose conditions to the running of routers.
+router to be called. The \condition\ option is the last precondition to be
+evaluated (see section ~~SECTrouprecon). The string is expanded, and if the
+result is a forced failure, or an empty string, or one of the strings `0' or
+`no' or `false' (checked without regard to the case of the letters), the router
+is skipped, and the address is offered to the next one.
+.em
+If the result is any other value, the router is run (as this is the last
+precondition to be evaluated, all the other preconditions must be true).
+
+The \condition\ option provides a means of applying custom conditions to the
+running of routers. Note that in the case of a simple conditional expansion,
+the default expansion values are exactly what is wanted. For example:
+.display asis
+condition = ${if >{$message_age}{600}}
+.endd
+Because of the default behaviour of the string expansion, this is equivalent to
+.display asis
+condition = ${if >{$message_age}{600}{true}{}}
+.endd
+.nem
If the expansion fails (other than forced failure) delivery is deferred. Some
-of the other options below are common special cases that could in fact be
-specified using \condition\.
-Note that \condition\ is the last precondition to be evaluated (see
-section ~~SECTrouprecon).
+of the other precondition options are common special cases that could in fact
+be specified using \condition\.
.conf debug@_print string$**$ unset
.conf headers@_add string$**$ unset
.index header lines||adding
.index router||adding header lines
+.em
This option specifies a string of text that is expanded at routing time, and
-associated with any addresses that are processed by the router
-when delivering a message. This option has no effect when an address is just
-being verified.
+associated with any addresses that are accepted by the router. However, this
+option has no effect when an address is just being verified. The way in which
+the text is used to add header lines at transport time is described in section
+~~SECTheadersaddrem.
The \headers@_add\ option is expanded after \errors@_to\, but before
-\headers@_remove\ and \transport\.
-If the expanded string is empty, or if the expansion is forced to fail, the
-option has no effect. Other expansion failures are treated as configuration
-errors. The expanded string must be in the form of one or more RFC 2822 header
-lines, separated by newlines (coded as `@\n'). For example:
-.display asis
-headers_add = X-added-header: added by $primary_hostname\n\
- X-added-second: another added header line
-.endd
-Exim does not check the syntax of these added header lines. If an address
-passes through several routers as a result of aliasing or forwarding
-operations, any \headers@_add\ or \headers@_remove\ specifications are
-cumulative. This does not apply for multiple routers that result from the use
-of `unseen'.
-
-At transport time, all the original headers listed in \headers__remove\ are
-removed. If there are multiple instances of any listed header, they are all
-removed.
-Then the new headers specified by \headers@_add\ are added, in the order in
-which they were attached to the address. Finally, any additional headers
-specified by the transport are added. It is not possible to remove headers
-added to an address by \headers@_add\.
-
-Because the addition does not happen until transport time, header lines that
-are added by \headers@_add\ are not accessible by means of the \$header@_xxx$\
-expansion syntax. Conversely, header lines that are removed by
-\headers@_remove\ remain visible.
+\headers@_remove\ and \transport\. If the expanded string is empty, or if the
+expansion is forced to fail, the option has no effect. Other expansion failures
+are treated as configuration errors.
-Addresses with different \headers@_add\ or \headers@_remove\ settings cannot be
-delivered together in a batch. The \headers@_add\ option cannot be used for a
-\%redirect%\ router that has the \one@_time\ option set.
+\**Warning**\: The \headers@_add\ option cannot be used for a \%redirect%\
+router that has the \one@_time\ option set.
+.nem
.conf headers@_remove string$**$ unset
.index header lines||removing
.index router||removing header lines
-The string is expanded at routing time and is then associated with any
-addresses that are processed by the router when delivering a message. This
-option has no effect when an address is being verified. The \headers@_remove\
-option is expanded after \errors@_to\ and \headers@_add\, but before
-\transport\. If the expansion is forced to fail, the option has no effect.
-Other expansion failures are treated as configuration errors.
-
-After expansion, the string must consist of a colon-separated list of header
-names. This is confusing, because header names themselves are often terminated
-by colons. In this case, the colons are the list separators, not part of the
-names.
-For example:
-.display asis
-headers_remove = return-receipt-to:acknowledge-to
-.endd
-The list is used at transport time as described under \headers@_add\ above. The
-\headers@_remove\ option cannot be used for a \%redirect%\ router that has the
-\one@_time\ option set.
+.em
+This option specifies a string of text that is expanded at routing time, and
+associated with any addresses that are accepted by the router. However, this
+option has no effect when an address is just being verified. The way in which
+the text is used to remove header lines at transport time is described in
+section ~~SECTheadersaddrem.
+
+The \headers@_remove\ option is expanded after \errors@_to\ and \headers@_add\,
+but before \transport\. If the expansion is forced to fail, the option has no
+effect. Other expansion failures are treated as configuration errors.
+
+\**Warning**\: The \headers@_remove\ option cannot be used for a \%redirect%\
+router that has the \one@_time\ option set.
+.nem
+
.conf ignore@_target@_hosts "host list$**$" unset
.index IP address||discarding
.display asis
ignore_target_hosts = 127.0.0.1
.endd
-on the relevant router.
-If all the hosts found by a \%dnslookup%\ router are discarded in this way, the
-router declines. In a conventional configuration, an attempt to mail to such a
-domain would then normally provoke the `unrouteable domain' error, and an
-attempt to verify an address in the domain would fail.
+on the relevant router. If all the hosts found by a \%dnslookup%\ router are
+discarded in this way, the router declines. In a conventional configuration, an
+attempt to mail to such a domain would normally provoke the `unrouteable
+domain' error, and an attempt to verify an address in the domain would fail.
Similarly, if \ignore@_target@_hosts\ is set on an \%ipliteral%\ router, the
router declines if presented with one of the listed addresses.
addresses. Because, like all host lists, the value of \ignore@_target@_hosts\
is expanded before use as a list, it is possible to make it dependent on the
domain that is being routed.
+.em
+During its expansion, \$host@_address$\ is set to the IP address that is being
+checked.
+.nem
user is not permitted to read one of the directories on the file's path.
\**Warning 2**\: Even when Exim is running as root while delivering a message,
-\*stat()*\ can yield \\EACCES\\ for a file on an NFS directory that is mounted
+\*stat()*\ can yield \\EACCES\\ for a file in an NFS directory that is mounted
without root access.
+.em
+In this case, if a check for access by a particular user is requested, Exim
+creates a subprocess that runs as that user, and tries the check again in that
+process.
-In both cases,
-the default action is to consider this a configuration error, and routing is
-deferred because the existence or non-existence of the file cannot be
-determined. However, in some circumstances it may be desirable to treat this
-condition as if the file did not exist. If the file name (or the exclamation
-mark that precedes the file name for non-existence) is preceded by a plus sign,
-the \\EACCES\\ error is treated as if the file did not exist. For example:
+The default action for handling an unresolved \\EACCES\\ is to consider it to
+be caused by a configuration error,
+.nem
+and routing is deferred because the existence or non-existence of the file
+cannot be determined. However, in some circumstances it may be desirable to
+treat this condition as if the file did not exist. If the file name (or the
+exclamation mark that precedes the file name for non-existence) is preceded by
+a plus sign, the \\EACCES\\ error is treated as if the file did not exist. For
+example:
.display asis
require_files = +/some/file
.endd
This option specifies the transport to be used when a router accepts an address
and sets it up for delivery. A transport is never needed if a router is used
only for verification. The value of the option is expanded at routing time,
-after the expansion of \errors@_to\,
-\headers@_add\, and \headers@_remove\,
-and result must be the name of one of the configured transports. If it is
-not, delivery is deferred.
+after the expansion of \errors@_to\, \headers@_add\, and \headers@_remove\, and
+result must be the name of one of the configured transports. If it is not,
+delivery is deferred.
The \transport\ option is not used by the \%redirect%\ router, but it does have
some private options that set up transports for pipe and file deliveries (see
.set runningfoot "dnslookup router"
.index \%dnslookup%\ router
.index routers||\%dnslookup%\
-The \%dnslookup%\ router looks up the hosts that handle mail for the given
-domain in the DNS. A transport must always be set for this router, unless
-\verify@_only\ is set.
+The \%dnslookup%\ router looks up the hosts that handle mail for the
+recipient's domain in the DNS. A transport must always be set for this router,
+unless \verify@_only\ is set.
If SRV support is configured (see \check@_srv\ below), Exim first searches for
SRV records. If none are found, or if SRV support is not configured,
address record, is the local host, or matches \hosts__treat__as__local\, what
happens is controlled by the generic \self\ option.
-There are a number of private options that can be used to vary the way the DNS
-lookup is handled.
+.em
+.section Problems with DNS lookups
+.rset SECTprowitdnsloo "~~chapter.~~section"
+There have been problems with DNS servers when SRV records are looked up.
+Some mis-behaving servers return a DNS error or timeout when a non-existent
+SRV record is sought. Similar problems have in the past been reported for
+MX records. The global \dns@_again@_means@_nonexist\ option can help with this
+problem, but it is heavy-handed because it is a global option.
+
+For this reason, there are two options, \srv@_fail@_domains\ and
+\mx@_fail@_domains\, that control what happens when a DNS lookup in a
+\%dnslookup%\ router results in a DNS failure or a `try again' response. If an
+attempt to look up an SRV or MX record causes one of these results, and the
+domain matches the relevant list, Exim behaves as if the DNS had responded `no
+such record'. In the case of an SRV lookup, this means that the router proceeds
+to look for MX records; in the case of an MX lookup, it proceeds to look for A
+or AAAA records, unless the domain matches \mx@_domains\, in which case routing
+fails.
+.nem
+
+
+.section Private options for dnslookup
+The private options for the \%dnslookup%\ router are as follows:
-.startconf
+.startconf dnslookup
+
.index options||\%dnslookup%\ router
.conf check@_secondary@_mx boolean false
.index MX record||checking for secondary
.conf check@_srv string$**$ unset
.index SRV record||enabling use of
-The dnslookup router supports the use of SRV records (see RFC 2782) in
+The \%dnslookup%\ router supports the use of SRV records (see RFC 2782) in
addition to MX and address records. The support is disabled by default. To
enable SRV support, set the \check@_srv\ option to the name of the service
required. For example,
normal way.
When the expansion succeeds, the router searches first for SRV records for
-the given service (it assumes TCP protocol). A single SRV record with the
-host name \"."\ indicates `no such service for this domain'; if this is
-encountered, the router declines. If other kinds of SRV record are found,
-they are used to construct a host list for delivery according to the rules
-of RFC 2782. MX records are not sought in this case.
-
-However, when no SRV records are found, MX records (and address records)
-are sought in the traditional way. In other words, SRV records take
-precedence over MX records, just as MX records take precedence over address
-records. Note that this behaviour is not sanctioned by RFC 2782, though a
-previous draft RFC defined it. It is apparently believed that MX records
-are sufficient for email and that SRV records should not be used for this
-purpose. However, SRV records have an additional `weight' feature which
-some people might find useful when trying to split an SMTP load between
-hosts of different power.
+the given service (it assumes TCP protocol). A single SRV record with a
+host name that consists of just a single dot indicates `no such service for
+this domain'; if this is encountered, the router declines. If other kinds of
+SRV record are found, they are used to construct a host list for delivery
+according to the rules of RFC 2782. MX records are not sought in this case.
+
+When no SRV records are found, MX records (and address records) are sought in
+the traditional way. In other words, SRV records take precedence over MX
+records, just as MX records take precedence over address records. Note that
+this behaviour is not sanctioned by RFC 2782, though a previous draft RFC
+defined it. It is apparently believed that MX records are sufficient for email
+and that SRV records should not be used for this purpose. However, SRV records
+have an additional `weight' feature which some people might find useful when
+trying to split an SMTP load between hosts of different power.
+
+.em
+See section ~~SECTprowitdnsloo above for a discussion of Exim's behaviour when
+there is a DNS lookup error.
+.nem
.conf mx@_domains "domain list$**$" unset
.index MX record||required to exist
has no MX record should be bounced immediately instead of being routed using
the address record.
+.em
+.conf mx@_fail@_domains "domain list$**$" unset
+If the DNS lookup for MX records for one of the domains in this list causes a
+DNS lookup error, Exim behaves as if no MX records were found. See section
+~~SECTprowitdnsloo for more discussion.
+.nem
+
+
.conf qualify@_single boolean true
.index DNS||resolver options
.index DNS||qualifying single-component names
record, because any domain that does not have its own MX record matches the
local wildcard.
+
+.em
+.conf srv@_fail@_domains "domain list$**$" unset
+If the DNS lookup for SRV records for one of the domains in this list causes a
+DNS lookup error, Exim behaves as if no SRV records were found. See section
+~~SECTprowitdnsloo for more discussion.
+.nem
+
+
.conf widen@_domains "string list" unset
.index domain||partial, widening
If a DNS lookup fails and this option is set, each of its strings in turn is
.index \%iplookup%\ router
.index routers||\%iplookup%\
The \%iplookup%\ router was written to fulfil a specific requirement in
-Cambridge University. For this reason, it is not included in the binary of Exim
-by default. If you want to include it, you must set
+Cambridge University (which in fact no longer exists). For this reason, it is
+not included in the binary of Exim by default. If you want to include it, you
+must set
.display asis
ROUTER_IPLOOKUP=yes
.endd
Since \%iplookup%\ is just a rewriting router, a transport must not be
specified for it.
-.startconf
+.startconf iplookup
.index options||\%iplookup%\ router
.conf hosts string unset
The private options for the \%manualroute%\ router are as follows:
-.startconf
+.startconf manualroute
.index options||\%manualroute%\ router
.conf host@_find@_failed string "freeze"
etc) to skip this router for most addresses, it could sensibly be used in
special cases, even on a busy host. There are the following private options:
-.startconf
+.startconf queryprogram
.index options||\%queryprogram%\ router
.conf command string$**$ unset
This option must be set. It specifies the command that is to be run. The
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 (case-insensitive):
+containing up to five fields, separated by white space.
+.em
+The maximum length of the line is 1023 characters. Longer lines are silently
+truncated.
+.nem
+The first field is one of the following words (case-insensitive):
.numberpars $.
\*Accept*\: routing succeeded; the remaining fields specify what to do (see
below).
.display asis
accept hosts=x1.y.example:x2.y.example data="rule1"
.endd
-routes the address to the default transport, with a host list containing two
-hosts. When the transport runs, the string `rule1' is in \$address@_data$\.
+routes the address to the default transport, passing a list of two hosts. When
+the transport runs, the string `rule1' is in \$address@_data$\.
X.Employee: :fail: Gone away, no forwarding address
.endd
In the case of an address that is being verified from an ACL or as the subject
-of a \\VRFY\\ command, the text is included in the SMTP error response by
-default. In an ACL, an explicitly provided message overrides the default, but
-the default message is available in the variable \$acl@_verify@_message$\ and
-can therefore be included in a custom message if this is desired. Exim sends a
-451 SMTP code for a :::defer::, and 550 for :::fail::. In non-SMTP cases the
-text is included in the error message that Exim generates.
+of a
+.index \\VRFY\\||error text, display of
+\\VRFY\\ command, the text is included in the SMTP error response by
+default.
+.em
+.index \\EXPN\\||error text, display of
+The text is not included in the response to an \\EXPN\\ command.
+.nem
+
+In an ACL, an explicitly provided message overrides the default, but the
+default message is available in the variable \$acl@_verify@_message$\ and can
+therefore be included in a custom message if this is desired. Exim sends a 451
+SMTP code for a :::defer::, and 550 for :::fail::. In non-SMTP cases the text
+is included in the error message that Exim generates.
The private options for the \%redirect%\ router are as follows:
-.startconf
+.startconf redirect
.index options||\%redirect%\ router
.conf allow@_defer boolean false
Setting this option allows Exim to interpret redirection data that starts with
`@#Exim filter' or `@#Sieve filter' as a set of filtering instructions. There
are some features of Exim filter files that some administrators may wish to
-lock out; see the \forbid@_filter@_xxx\ options below. The filter is run using
-the uid and gid set by the generic \user\ and \group\ options. These take their
-defaults from the password data if \check@_local@_user\ is set, so in the
-normal case of users' personal filter files, the filter is run as the relevant
-user. When \allow@_filter\ is set true, Exim insists that either
-\check@_local@_user\ or \user\ is set.
+lock out; see the \forbid@_filter@_xxx\ options below.
+.em
+It is also possible to lock out Exim filters or Sieve filters while allowing
+the other type; see \forbid@_exim@_filter\ and \forbid@_sieve@_filter\.
+.nem
+
+The filter is run using the uid and gid set by the generic \user\ and \group\
+options. These take their defaults from the password data if
+\check@_local@_user\ is set, so in the normal case of users' personal filter
+files, the filter is run as the relevant user. When \allow@_filter\ is set
+true, Exim insists that either \check@_local@_user\ or \user\ is set.
.conf allow@_freeze boolean false
If this option is true, the :::blackhole:: item may not appear in a redirection
list.
+.em
+.conf forbid@_exim@_filter boolean false
+If this option is set true, only Sieve filters are permitted when
+\allow@_filter\ is true.
+.nem
+
+
.conf forbid@_file boolean false
.index delivery||to file, forbidding
.index Sieve filter||forbidding delivery to a file
.conf forbid@_filter@_reply boolean false
If this option is true, this router may not generate an automatic reply
-message. Automatic replies can be generated only from Exim filter files, not
-from traditional forward files or Sieve filters. This option is forced to be
-true if \one@_time\ is set.
+message. Automatic replies can be generated only from Exim
+.em
+or Sieve filter files, not from traditional forward files.
+.nem
+This option is forced to be true if \one@_time\ is set.
.conf forbid@_filter@_run boolean false
If this option is true, string expansions in Exim filter files are not allowed
specifies delivery to a pipe, either from an Exim filter or from a conventional
forward file. This option is forced to be true if \one@_time\ is set.
+.em
+.conf forbid@_sieve@_filter boolean false
+If this option is set true, only Exim filters are permitted when
+\allow@_filter\ is true.
+.nem
+
+
.conf hide@_child@_in@_errmsg boolean false
.index bounce message||redirection details, suppressing
If this option is true, it prevents Exim from quoting a child address if it
list is in addition to the local user's primary group when \check@_local@_user\
is set. See \check@_group\ above.
-.conf qualify@_domain string$**$ unset
-If this option is set and an unqualified address (one without a domain) is
-generated, it is qualified with the domain specified by expanding this string,
-instead of the global setting in \qualify@_recipient\. If the expansion fails,
-the router declines. If you want to revert to the default, you can have the
-expansion generate \$qualify@_recipient$\.
-
.conf pipe@_transport string$**$ unset
A \%redirect%\ router sets up a direct delivery to a pipe when a string starting
with a vertical bar character is specified as a new `address'. The transport
This should normally be a \%pipe%\ transport.
When the transport is run, the pipe command is in \$address@_pipe$\.
+.conf qualify@_domain string$**$ unset
+If this option is set and an unqualified address (one without a domain) is
+generated, it is qualified with the domain specified by expanding this string,
+instead of the global setting in \qualify@_recipient\. If the expansion fails,
+the router declines. If you want to revert to the default, you can have the
+expansion generate \$qualify@_recipient$\.
+
.conf qualify@_preserve@_domain boolean false
.index domain||in redirection, preserving
.index preserving domain in redirection
subject to address rewriting. Otherwise, they are treated like new addresses
and are rewritten according to the global rewriting rules.
+
+.em
+.conf sieve@_vacation@_directory string$**$ unset
+.index Sieve filter||vacation directory
+To enable the `vacation' extension for Sieve filters, you must set
+\sieve@_vacation@_directory\ to the directory where vacation databases are held
+(do not put anything else in that directory), and ensure that the
+\reply@_transport\ option refers to an \%autoreply%\ transport.
+.nem
+
+
.conf skip@_syntax@_errors boolean false
.index forward file||broken
.index address redirection||broken files
so it is passed to the following routers.
.index Sieve filter||syntax errors in
-Currently, any syntax errors in a Sieve filter file cause the `keep' action to
-occur. The values of \skip@_syntax@_errors\, \syntax@_errors@_to\, and
+.em
+Syntax errors in a Sieve filter file cause the `keep' action to
+occur. This action is specified by RFC 3028.
+.nem
+The values of \skip@_syntax@_errors\, \syntax@_errors@_to\, and
\syntax@_errors@_text\ are not used.
\skip@_syntax@_errors\ can be used to specify that errors in users' forward
Exim also sets a specific current directory while running the transport; for
some transports a home directory setting is also relevant. The \%pipe%\
-transport is the only one which sets up environment variables; see section
+transport is the only one that sets up environment variables; see section
~~SECTpipeenv for details.
The values used for the uid, gid, and the directories may come from several
\user\ options. However, values may also be given in the transport's own
configuration, and these override anything that comes from the router.
+
+.em
+.section Concurrent deliveries
+.index concurrent deliveries
+.index simultaneous deliveries
+If two different messages for the same local recpient arrive more or less
+simultaneously, the two delivery processes are likely to run concurrently. When
+the \%appendfile%\ transport is used to write to a file, Exim applies locking
+rules to stop concurrent processes from writing to the same file at the same
+time.
+
+However, when you use a \%pipe%\ transport, it is up to you to arrange any
+locking that is needed. Here is a silly example:
+.display asis
+my_transport:
+ driver = pipe
+ command = /bin/sh -c 'cat >>/some/file'
+.endd
+This is supposed to write the message at the end of the file. However, if two
+messages arrive at the same time, the file will be scrambled. You can use the
+\exim@_lock\ utility program (see section ~~SECTmailboxmaint) to lock a file
+using the same algorithm that Exim itself uses.
+.nem
+
+
.section Uids and gids
.rset SECTenvuidgid "~~chapter.~~section"
.index local transports||uid and gid
.index transport||generic options for
The following generic options apply to all transports:
-.startconf
+.startconf transports
.conf body@_only boolean false
.index transport||body only
.index message||transporting body only
.conf headers@_add string$**$ unset
.index header lines||adding in transport
.index transport||header lines, adding
-This option specifies a string of text which is expanded and added to the
-header portion of a message as it is transported. If the result of the
-expansion is an empty string, or if the expansion is forced to fail, no action
-is taken. Other expansion failures are treated as errors and cause the delivery
-to be deferred. The expanded string should be in the form of one or more RFC
-2822 header lines, separated by newlines (coded as `@\n'), for example:
-.display asis
-headers_add = X-added: this is a header added at $tod_log\n\
- X-added: this is another
-.endd
-Exim does not check the syntax of these added header lines. They are added at
-the end of the existing header lines. If you include a blank line within the
-string, you can subvert this facility into adding text at the start of the
-message's body. This is not recommended. Additional header lines can also be
-specified by routers. See chapter ~~CHAProutergeneric and section
-~~SECTheadersaddrem.
+.em
+This option specifies a string of text that is expanded and added to the header
+portion of a message as it is transported, as described in section
+~~SECTheadersaddrem. Additional header lines can also be specified by routers.
+If the result of the expansion is an empty string, or if the expansion is
+forced to fail, no action is taken. Other expansion failures are treated as
+errors and cause the delivery to be deferred.
+.nem
.conf headers@_only boolean false
.index transport||header lines only
.conf headers@_remove string$**$ unset
.index header lines||removing
.index transport||header lines, removing
-This option is expanded; the result must consist of a colon-separated list of
-header names, not including the terminating colon, for example:
-.display asis
-headers_remove = return-receipt-to:acknowledge-to
-.endd
-Any existing headers matching those names are not included in any message that
-is transmitted by the transport.
-If the result of the expansion is an empty string, or if the expansion is
-forced to fail, no action is taken. Other expansion failures are treated as
+.em
+This option specifies a string that is expanded into a list of header names;
+these headers are omitted from the message as it is transported, as described
+in section ~~SECTheadersaddrem. Header removal can also be specified by
+routers. If the result of the expansion is an empty string, or if the expansion
+is forced to fail, no action is taken. Other expansion failures are treated as
errors and cause the delivery to be deferred.
-
-If there are multiple instances of a header, they are all removed. However,
-added headers may have these names. Thus it is possible to replace a header by
-specifying it in \headers@_remove\ and supplying the replacement in
-\headers@_add\. Headers to be removed can also be specified by routers. See
-chapter ~~CHAProutergeneric and section ~~SECTheadersaddrem.
+.nem
.conf headers@_rewrite string unset
.index transport||header lines, rewriting
(this in fact is done from a third process, to avoid deadlock).
The command must be specified as an absolute path.
+.em
+The lines of the message that are written to the transport filter are
+terminated by newline (`@\n').
+.nem
The message is passed to the filter before any SMTP-specific processing, such
as turning `@\n' into `@\r@\n' and escaping lines beginning with a dot, and
also before any processing implied by the settings of \check@_string\ and
\escape@_string\ in the \%appendfile%\ or \%pipe%\ transports.
-The filter's standard output is read and written to the message's destination.
+.em
+The standard error for the filter process is set to the same destination as its
+standard output; this is read and written to the message's ultimate
+destination.
+.nem
The filter can perform any transformations it likes, but of course should take
care not to break RFC 2822 syntax. A demonstration Perl script is provided in
\(util/transport-filter.pl)\; this makes a few arbitrary modifications just to
the \size@_addition\ option on the \%smtp%\ transport, either to allow for
additions to the message, or to disable the use of \\SIZE\\ altogether.
-The value of the option is the command string for starting up the filter, which
-is run directly from Exim, not under a shell. The string is parsed by Exim in
-the same way as a command string for the \%pipe%\ transport: Exim breaks it up
-into arguments and then expands each argument separately. The special argument
-\$pipe@_addresses$\ is replaced by a number of arguments, one for each address
-that applies to this delivery. (This isn't an ideal name for this feature here,
-but as it was already implemented for the \%pipe%\ transport, it seemed sensible
-not to change it.)
+The value of the \transport@_filter\ option is the command string for starting
+the filter, which is run directly from Exim, not under a shell. The string is
+parsed by Exim in the same way as a command string for the \%pipe%\ transport:
+Exim breaks it up into arguments and then expands each argument separately. The
+special argument \$pipe@_addresses$\ is replaced by a number of arguments, one
+for each address that applies to this delivery. (This isn't an ideal name for
+this feature here, but as it was already implemented for the \%pipe%\
+transport, it seemed sensible not to change it.)
.index \$host$\
.index \$host@_address$\
.endd
The filter process is run under the same uid and gid as the normal delivery.
For remote deliveries this is the Exim uid/gid by default.
+.em
+The command should normally yield a zero return code. A non-zero code is taken
+to mean that the transport filter failed in some way. Delivery of the message
+is deferred. It is not possible to cause a message to be bounced from a
+transport filter.
+.nem
If a transport filter is set on an autoreply transport, the original message is
passed through the filter as it is being copied into the newly generated
.section Private options for appendfile
.index options||\%appendfile%\ transport
-.startconf
+.startconf appendfile
.conf allow@_fifo boolean false
.index fifo (named pipe)
When this option is true, Exim attempts to create any missing superior
directories for the file that it is about to write. A created directory's mode
is given by the \directory@_mode\ option.
+.em
+The group ownership of a newly created directory is highly dependent on the
+operating system (and possibly the file system) that is being used. For
+example, in Solaris, if the parent directory has the setgid bit set, its group
+is propagated to the child; if not, the currently set group is used. However,
+in FreeBSD, the parent's group is always used.
+.nem
.conf create@_file string "anywhere"
This option constrains the location of files and directories that are created
exists and is older than this value, it is assumed to have been left behind by
accident, and Exim attempts to remove it.
+.em
+.conf mailbox@_filecount string$**$ unset
+.index mailbox||specifying size of
+.index size||of mailbox
+If this option is set, it is expanded, and the result is taken as the current
+number of files in the mailbox. It must be a decimal number, optionally
+followed by K or M. This provides a way of obtaining this information from an
+external source that maintains the data.
+
+.conf mailbox@_size string$**$ unset
+.index mailbox||specifying size of
+.index size||of mailbox
+If this option is set, it is expanded, and the result is taken as the current
+size the mailbox. It must be a decimal number, optionally followed by K or M.
+This provides a way of obtaining this information from an external source that
+maintains the data. This is likely to be helpful for maildir deliveries where
+it is computationally expensive to compute the size of a mailbox.
+.nem
+
.conf maildir@_format boolean false
.index maildir format||specifying
If this option is set with the \directory\ option, the delivery is into a new
the parent directory instead of the current directory when calculating the
amount of space used.
+.em
+One problem with delivering into a multi-file mailbox is that it is
+computationally expensive to compute the size of the mailbox for quota
+checking. Various approaches have been taken to reduce the amount of work
+needed. The next two sections describe two of them. A third alternative is to
+use some external process for maintaining the size data, and use the expansion
+of the \mailbox@_size\ option as a way of importing it into Exim.
+.nem
+
.section Using tags to record message sizes
If \maildir@_tag\ is set, the string is expanded for each delivery.
.index transports||\%autoreply%\
.index \%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. It
-is usually run as the result of mail filtering, a `vacation' message being the
-standard example. However, it can also be run directly from a router like any
-other transport. To reduce the possibility of message cascades, messages
-created by the \%autoreply%\ transport always have empty envelope sender
-addresses, like bounce messages.
+the message to be transmitted. Instead, it generates a new mail message.
+.em
+If the router that passes the message to this transport does not have the
+\unseen\ option set, the original message (for the current recipient) is not
+delivered anywhere. However, when the \unseen\ option is set on the router that
+passes the message to this transport, routing of the address continues, so
+another router can set up a normal message delivery.
+.nem
+
+The \%autoreply%\ transport is usually run as the result of mail filtering, a
+`vacation' message being the standard example. However, it can also be run
+directly from a router like any other transport. To reduce the possibility of
+message cascades, messages created by the \%autoreply%\ transport always have
+empty envelope sender addresses, like bounce messages.
The parameters of the message to be sent can be specified in the configuration
by options described below. However, these are used only when the address
.section Private options for autoreply
-.startconf
+.startconf autoreply
.index options||\%autoreply%\ transport
.conf bcc string$**$ unset
This specifies the addresses that are to receive `blind carbon copies' of the
.conf mode "octal integer" 0600
If either the log file or the `once' file has to be created, this mode is used.
+.em
+.conf never@_mail "address list$**$" unset
+If any run of the transport creates a message with a recipient that matches any
+item in the list, that recipient is quietly discarded. If all recipients are
+discarded, no message is created.
+.nem
+
.conf once string$**$ unset
This option names a file or DBM database in which a record of each
::To:: recipient is kept when the message is specified by the transport.
.conf subject string$**$ unset
This specifies the contents of the ::Subject:: header when the message is
specified by the transport.
+.em
+It is tempting to quote the original subject in automatic responses. For
+example:
+.display asis
+subject = Re: $h_subject:
+.endd
+There is a danger in doing this, however. It may allow a third party to
+subscribe your users to an opt-in mailing list, provided that the list accepts
+bounce messages as subscription confirmations. Well-managed lists require a
+non-bounce message to confirm a subscription, so the danger is relatively
+small.
+.nem
.conf text string$**$ unset
This specifies a single string to be used as the body of the message when the
The private options of the \%lmtp%\ transport are as follows:
-.startconf
+.startconf lmtp
.index options||\%lmtp%\ transport
.conf batch@_id string$**$ unset
.index transports||\%pipe%\
.index \%pipe%\ transport
The \%pipe%\ transport is used to deliver messages via a pipe to a command
-running in another process. This can happen in one of two ways:
+running in another process.
+.em
+One example is the
+use of \%pipe%\ as a pseudo-remote transport for passing messages to some other
+delivery mechanism (such as UUCP). Another is the use by individual users to
+automatically process their incoming messages. The \%pipe%\ transport can be
+used in one of the following ways:
+.nem
.numberpars $.
-A router routes an address to a transport in the normal way, and the transport
+A router routes one address to a transport in the normal way, and the transport
is configured as a \%pipe%\ transport. In this case, \$local@_part$\ contains
-the address (as usual), and the command which is run is specified by the
-\command\ option on the transport. An example of this is the use of \%pipe%\ as
-a pseudo-remote transport for passing messages to some other delivery mechanism
-(such as UUCP).
+the local part of the address (as usual), and the command that is run is
+specified by the \command\ option on the transport.
+.nextp
+.em
+If the \batch@_max\ option is set greater than 1 (the default), the transport
+can be called upon to handle more than one address in a single run. In this
+case, \$local@_part$\ is not set (because it is not unique). However, the
+pseudo-variable \$pipe@_addresses$\ (described in section ~~SECThowcommandrun
+below) contains all the addresses that are being handled.
+.nem
.nextp
A router redirects an address directly to a pipe command (for example, from an
alias or forward file). In this case, \$local@_part$\ contains the local part
directories are also controllable. See chapter ~~CHAPenvironment for details of
the local delivery environment.
+
+.em
+.section Concurrent delivery
+If two messages arrive at almost the same time, and both are routed to a pipe
+delivery, the two pipe transports may be run concurrently. You must ensure that
+any pipe commands you set up are robust against this happening. If the commands
+write to a file, the \exim@_lock\ utility might be of use.
+.nem
+
+
.section Returned status and data
.index \%pipe%\ transport||returned data
If the command exits with a non-zero return code, the delivery is deemed to
.section Private options for pipe
.index options||\%pipe%\ transport
-.startconf
+
+.startconf pipe
.conf allow@_commands "string list$**$" unset
.index \%pipe%\ transport||permitted commands
return code that is neither zero nor one of the return codes listed in
\temp@_errors\ (that is, the delivery failed), the first line of output is
written to the main log.
+.em
+This option and \log@_output\ are mutually exclusive. Only one of them may be
+set.
+.nem
.conf log@_output boolean 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.
+.em
+This option and \log@_fail@_output\ are mutually exclusive. Only one of them
+may be set.
+.nem
.conf max@_output integer 20K
This specifies the maximum amount of output that the command may produce on its
is, the delivery failed), the output is returned in the bounce message.
However, if the message has a null sender (that is, it is itself a bounce
message), output from the command is discarded.
+.em
+This option and \return@_output\ are mutually exclusive. Only one of them may
+be set.
+.nem
.conf return@_output boolean false
If this option is true, and the command produced any output, the delivery is
However, if the message has a null sender (that is, it is a bounce message),
output from the command is always discarded, whatever the setting of this
option.
+.em
+This option and \return@_fail@_output\ are mutually exclusive. Only one of them
+may be set.
+.nem
.conf temp@_errors "string list" "see below"
.index \%pipe%\ transport||temporary failure
The private options of the \%smtp%\ transport are as follows:
.index options||\%smtp%\ transport
-.startconf
+.startconf smtp
.conf allow@_localhost boolean false
.index local host||sending to
.index fallback||hosts specified on transport
.index limit||number of MX tried
.index MX record||maximum tried
This option limits the number of IP addresses that are tried for any one
-delivery
-in cases where there are temporary delivery errors.
-Section ~~SECTvalhosmax describes in detail how the value of this option is
-used.
+delivery in cases where there are temporary delivery errors. Section
+~~SECTvalhosmax describes in detail how the value of this option is used.
+
+.em
+.conf hosts@_max@_try@_hardlimit integer 50
+This is an additional check on the maximum number of IP addresses that Exim
+tries for any one delivery. Section ~~SECTvalhosmax describes its use and why
+it exists.
+.nem
.conf hosts@_nopass@_tls "host list$**$" unset
.index TLS||passing connection
.index TLS||requiring specific ciphers
.index cipher||requiring specific
The value of this option must be a list of permitted cipher suites, for use
-when setting up an
-outgoing encrypted connection. (There is a global option of the same name for
-controlling incoming connections.)
-The values of \$host$\ and \$host@_address$\ are set to the name and address of
-the server during the expansion. See chapter ~~CHAPTLS for details of TLS; note
-that this option is used in different ways by OpenSSL and GnuTLS (see section
-~~SECTreqciphsslgnu).
+when setting up an outgoing encrypted connection. (There is a global option of
+the same name for controlling incoming connections.) The values of \$host$\ and
+\$host@_address$\ are set to the name and address of the server during the
+expansion. See chapter ~~CHAPTLS for details of TLS; note that this option is
+used in different ways by OpenSSL and GnuTLS (see sections ~~SECTreqciphssl and
+~~SECTreqciphgnu).
+.em
+For GnuTLS, the order of the ciphers is a preference order.
+.nem
.conf tls@_tempfail@_tryclear boolean true
When the server host is not in \hosts@_require@_tls\, and there is a problem in
.endconf
-.section How the value of hosts@_max@_try is used
+.section How the limits for the number of hosts to try are used
.rset SECTvalhosmax "~~chapter.~~section"
.index host||maximum number to try
.index limit||hosts, maximum number tried
+.em
+There are two options that are concerned with the number of hosts that are
+tried when an SMTP delivery takes place. They are \hosts@_max@_try\ and
+\hosts@_max@_try@_hardlimit\.
+.nem
+
The \hosts@_max@_try\ option limits the number of hosts that are tried
for a single delivery. However, despite the term `host' in its name, the option
actually applies to each IP address independently. In other words, a multihomed
limits are also not counted, even when they are tried. This means that when
some IP addresses are past their retry limits, more than the value of
\hosts@_max@_retry\ may be tried. The reason for this behaviour is to ensure
-that all IP addresses are considered before timing out an email address.
+that all IP addresses are considered before timing out an email address (but
+see below for an exception).
Secondly, when the \hosts@_max@_try\ limit is reached, Exim looks down the host
list to see if there is a subsequent host with a different (higher valued) MX.
-If there is, that host is used next, and the current IP address is used but not
-counted. This behaviour helps in the case of a domain with a retry rule that
-hardly ever delays any hosts, as is now explained:
+If there is, that host is considered next, and the current IP address is used
+but not counted. This behaviour helps in the case of a domain with a retry rule
+that hardly ever delays any hosts, as is now explained:
Consider the case of a long list of hosts with one MX value, and a few with a
higher MX value. If \hosts@_max@_try\ is small (the default is 5) only a few
Unfortunately, these are exactly the domains that tend to resolve to long lists
of hosts. The short retry time means that the lowest MX hosts are tried every
time. The attempts may be in a different order because of random sorting, but
-without the special MX check mentioned about, the higher MX hosts would never
-be tried at all because the lower MX hosts are never all past their retry
-times.
-
-With the special check, Exim tries least one address from each MX value, even
-if the \hosts@_max@_try\ limit has already been reached.
-
-
+without the special MX check, the higher MX hosts would never be tried
+.em
+until all the lower MX hosts had timed out (which might be several days),
+because there are always some lower MX hosts that have reached their retry
+times. With the special check, Exim considers at least one IP address from each
+MX value at every delivery attempt, even if the \hosts@_max@_try\ limit has
+already been reached.
+
+The above logic means that \hosts@_max@_try\ is not a hard limit, and in
+particular, Exim normally eventually tries all the IP addresses before timing
+out an email address. When \hosts@_max@_try\ was implemented, this seemed a
+reasonable thing to do. Recently, however, some lunatic DNS configurations have
+been set up with hundreds of IP addresses for some domains. It can
+take a very long time indeed for an address to time out in these cases.
+
+The \hosts@_max@_try@_hardlimit\ option was added to help with this problem.
+Exim never tries more than this number of IP addresses; if it hits this limit
+and they are all timed out, the email address is bounced, even though not all
+possible IP addresses have been tried.
+.nem
.section Retry rules
.index retry||rules
-Each retry rule occupies one line and consists of three parts, separated by
-white space: a pattern, an error name, and a list of retry parameters. The
-pattern must be enclosed in double quotes if it contains white space. The rules
-are searched in order until one is found whose pattern matches the failing host
-or address.
+.em
+Each retry rule occupies one line and consists of three or four parts,
+separated by white space: a pattern, an error name, an optional list of sender
+addresses, and a list of retry parameters. The pattern and sender lists must be
+enclosed in double quotes if they contain white space. The rules are searched in
+order until one is found where the pattern, error name, and sender list (if
+present) match the failing host or address, the error that occurred, and the
+message's sender, respectively.
+.nem
The pattern is any single item that may appear in an address list (see section
~~SECTaddresslist). It is in fact processed as a one-item address list, which
part.
.index regular expressions||in retry rules
-\**Warning**\: If you use a regular expression in a routing rule, it must match
-a complete address, not just a domain, because that is how regular expressions
-work in address lists.
+\**Warning**\: If you use a regular expression in a routing rule pattern, it
+must match a complete address, not just a domain, because that is how regular
+expressions work in address lists.
.display
^@\Nxyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Wrong\
^@\N[^@@]+@@xyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Right\
.index retry||specific errors, specifying
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:
-.numberpars " "
-\*auth@_failed*\: authentication failed when trying to send to a host in the
-\hosts@_require@_auth\ list in an \%smtp%\ transport
-.nextp
-\*refused@_MX*\: connection refused from a host obtained from an MX record
-.nextp
-\*refused@_A*\: connection refused from a host not obtained from an MX record
-.nextp
-\*refused*\: any connection refusal
-.nextp
-\*timeout@_connect@_MX*\: connection timeout from a host obtained from an MX
-record
-.nextp
-\*timeout@_connect@_A*\: connection timeout from a host not obtained from an MX
-record
-.nextp
-\*timeout@_connect*\: any connection timeout
-.nextp
-\*timeout@_MX*\: any timeout from a host obtained from an MX
-record
-.nextp
-\*timeout@_A*\: any timeout from a host not obtained from an MX
-record
-.nextp
-\*timeout*\: any timeout
-.nextp
-\*quota*\: quota exceeded in local delivery by \%appendfile%\
-.nextp
+.em
+
+.push
+.indent 2em
+.tempindent 0
+\auth@_failed\: Authentication failed when trying to send to a host in the
+\hosts@_require@_auth\ list in an \%smtp%\ transport.
+
+.tempindent 0
+\rcpt@_4xx\: A 4\*xx*\ error was received for an outgoing \\RCPT\\ command.
+Either the first or both of the x's can be given as specific digits, for
+example: \"rcpt@_45x"\ or \"rcpt@_436"\. For example, to recognize 452 errors
+given to \\RCPT\\ commands by a particular host, and have retries every ten
+minutes and a one-hour timeout, you could set up a retry rule of this form:
+.display asis
+the.host.name rcpt_452 F,1h,10m
+.endd
+These errors apply to both outgoing SMTP (the \%smtp%\ transport) and outgoing
+LMTP (either the \%lmtp%\ transport, or the \%smtp%\ transport in LMTP mode).
+Note, however, that they apply only to responses to \\RCPT\\ commands.
+
+.tempindent 0
+\refused@_MX\: A connection to a host obtained from an MX record was refused.
+
+.tempindent 0
+\refused@_A\: A connection to a host not obtained from an MX record was
+refused.
+
+.tempindent 0
+\refused\: A connection was refused.
+
+.tempindent 0
+\timeout@_connect@_MX\: A connection attempt to a host obtained from an MX
+record timed out.
+
+.tempindent 0
+\timeout@_connect@_A\: A connection attempt to a host not obtained from an MX
+record timed out.
+
+.tempindent 0
+\timeout@_connect\: A connection attempt timed out.
+
+.tempindent 0
+\timeout@_MX\: There was a timeout while connecting or during an SMTP session
+with a host obtained from an MX record.
+
+.tempindent 0
+\timeout@_A\: There was a timeout while connecting or during an SMTP session
+with a host not obtained from an MX record.
+
+.tempindent 0
+\timeout\: There was a timeout while connecting or during an SMTP session.
+
+.tempindent 0
+\quota\: A mailbox quota was exceeded in a local delivery by the
+\%appendfile%\ transport.
+
.index quota||error testing in retry rule
.index retry||quota error testing
-\*quota@_*\<<time>>: quota exceeded in local delivery, and the mailbox has not
-been read for <<time>>. For example, \*quota@_4d*\ applies to a quota error
-when the mailbox has not been read for four days.
+.tempindent 0
+\quota@_\<<time>>: A mailbox quota was exceeded in a local delivery by
+the \%appendfile%\ transport, and the mailbox has not been accessed for
+<<time>>. For example, \*quota@_4d*\ applies to a quota error when the mailbox
+has not been accessed for four days.
+
+.pop
+
.index mailbox||time of last read
-\**Warning**\: It is not always possible to determine a `time of last read' for
-a mailbox:
+The idea of \quota@_\<<time>> is to make it possible to have shorter timeouts
+when the mailbox is full and is not being read by its owner. Ideally, it should
+be based on the last time that the user accessed the mailbox. However, it is
+not always possible to determine this. Exim uses the following heuristic rules:
.numberpars $.
-If the mailbox is a single file, the time of last access is used.
+If the mailbox is a single file, the time of last access (the `atime') is used.
+As no new messages are being delivered (because the mailbox is over quota),
+Exim does not access the file, so this is the time of last user access.
.nextp
.index maildir format||time of last read
For a maildir delivery, the time of last modification of the \(new)\
-subdirectory is used. As the mailbox is over quota, no new files will be
-created in the \(new)\ subdirectory, so any change is assumed to be the result
-of an MUA moving a new message to the \(cur)\ directory when it is first read.
-.nextp
-For other kinds of multi-file delivery, the time of last read cannot be
-obtained, and so a retry rule that uses this type of error field is never
-matched.
-.endp
+subdirectory is used. As the mailbox is over quota, no new files are created in
+the \(new)\ subdirectory, because no new messages are being delivered. Any
+change to the \(new)\ subdirectory is therefore assumed to be the result of an
+MUA moving a new message to the \(cur)\ directory when it is first read. The
+time that is used is therefore the last time that the user read a new message.
+.nextp
+For other kinds of multi-file mailbox, the time of last access cannot be
+obtained, so a retry rule that uses this type of error field is never matched.
.endp
+.nem
The quota errors apply both to system-enforced quotas and to Exim's own quota
mechanism in the \%appendfile%\ transport. The \*quota*\ error also applies
when a local delivery is deferred because a partition is full (the \\ENOSPC\\
error).
-.section Retry rule parameters
+.em
+.section Retry rules for specified senders
+.index retry||rules, sender-specific
+You can specify retry rules that apply only when the failing message has a
+specific sender. In particular, this can be used to define retry rules that
+apply only to bounce messages. The third item in a retry rule can be of this
+form:
+.display
+senders=<<address list>>
+.endd
+The retry timings themselves are then the fourth item. For example:
+.display asis
+* * senders=: F,1h,30m
+.endd
+matches all temporary errors for bounce messages sent to any host. If the
+address list contains white space, it must be enclosed in quotes. For example:
+.display
+a.domain timeout senders="x@b.dom : y@c.dom" G,8h,10m,1.5
+.endd
+When testing retry rules using \-brt-\, you can supply a sender using the \-f-\
+command line option, like this:
+.display asis
+exim -f "" -brt user@dom.ain
+.endd
+If you do not set \-f-\ with \-brt-\, a retry rule that contains a senders list
+is never matched.
+.nem
+
+
+
+.section Retry parameters
.index retry||parameters in rules
-The third field in a retry rule is a sequence of retry parameter sets,
-separated by semicolons. Each set consists of
+The third
+.em
+(or fourth, if a senders list is present)
+.nem
+field in a retry rule is a sequence of retry parameter sets, separated by
+semicolons. Each set consists of
.display
<<letter>>,<<cutoff time>>,<<arguments>>
.endd
.index retry||algorithms
The available algorithms are:
.numberpars $.
-\*F*\: retry at fixed intervals. There is a single time parameter specifying the
-interval.
+\*F*\: retry at fixed intervals. There is a single time parameter specifying
+the interval.
.nextp
-\*G*\: retry at geometrically increasing intervals. The first argument specifies
-a starting value for the interval, and the second a multiplier, which is used
-to increase the size of the interval at each retry.
+\*G*\: retry at geometrically increasing intervals. The first argument
+specifies a starting value for the interval, and the second a multiplier, which
+is used to increase the size of the interval at each retry.
.endp
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
.section Generic options for authenticators
.index authentication||generic options
-.startconf
+.startconf authenticators
.index options||generic, for authenticators
.conf driver string unset
rejected with a 504 error.
When a message is received from an authenticated host, the value of
-\$received@_protocol$\ is set to `asmtp' instead of `esmtp', and
-\$sender@_host@_authenticated$\ contains the name (not the public name) of the
-authenticator driver that successfully authenticated the client from which the
-message was received. This variable is empty if there was no successful
-authentication.
+\$received@_protocol$\ is set to
+.em
+`esmtpa'
+.nem
+instead of `esmtp', and \$sender@_host@_authenticated$\ contains the name (not
+the public name) of the authenticator driver that successfully authenticated
+the client from which the message was received. This variable is empty if there
+was no successful authentication.
When running as a server, \%plaintext%\ performs the authentication test by
expanding a string. It has the following options:
-.startconf
+.startconf plaintext
.index options||\%plaintext%\ authenticator (server)
.conf server@_prompts string$**$ unset
.section Using plaintext in a client
The \%plaintext%\ authenticator has just one client option:
-.startconf
+.startconf plaintext
.index options||\%plaintext%\ authenticator (client)
.conf client@_send string$**$ unset
This authenticator has one server option, which must be set to configure the
authenticator as a server:
-.startconf
+.startconf cram@_md5
.index options||\%cram@_md5%\ authenticator (server)
.conf server@_secret string$**$ unset
.section Using cram@_md5 as a client
When used as a client, the \%cram@_md5%\ authenticator has two options:
-.startconf
+.startconf cram@_md5
.index options||\%cram@_md5%\ authenticator (client)
.conf client@_name string$**$ "the primary host name"
+.
+.
+.
+.
+. ============================================================================
+.chapter The cyrus@_sasl authenticator
+.set runningfoot "cyrus@_sasl authenticator"
+.index \%cyrus@_sasl%\ authenticator
+.index authenticators||\%cyrus@_sasl%\
+.index Cyrus, SASL library
+.em
+The code for this authenticator was provided by Matthew Byng-Maddick of A L
+Digital Ltd (\?http://www.aldigital.co.uk?\).
+
+The \%cyrus@_sasl%\ authenticator provides server support for the Cyrus SASL
+library implementation of the RFC 2222 (`Simple Authentication and Security
+Layer'). This library supports a number of authentication mechanisms, including
+PLAIN and LOGIN, but also several others that Exim does not support directly.
+In particular, there is support for Kerberos authentication.
+
+The \%cyrus@_sasl%\ authenticator provides a gatewaying mechanism directly to
+the Cyrus interface, so if your Cyrus library can do, for example, CRAM-MD5,
+then so can the \%cyrus@_sasl%\ authenticator. By default it uses the public
+name of the driver to determine which mechanism to support.
+
+Where access to some kind of secret file is required, for example in GSSAPI
+or CRAM-MD5, it is worth noting that the authenticator runs as the \*exim*\
+user, and that the Cyrus SASL library has no way of escalating privileges
+by default. You may also find you need to set environment variables,
+depending on the driver you are using.
+
+.section Using cyrus@_sasl as a server
+The \%cyrus@_sasl%\ authenticator has four private options. It puts the
+username (on a successful authentication) into \$1$\.
+
+.startconf cyrus@_sasl
+.conf server@_hostname string$**$ $tt{$primary@_hostname}
+This option selects the hostname that is used when communicating with
+the library. It is up to the underlying SASL plug-in what it does with
+this data.
+
+.conf server@_mech string $tt{public@_name}
+This option selects the authentication mechanism this driver should
+use. It allows you to use a different underlying mechanism from the
+advertised name. For example:
+.display asis
+sasl:
+ driver = cyrus_sasl
+ public_name = X-ANYTHING
+ server_mech = CRAM-MD5
+ server_set_id = $1
+.endd
+
+.conf server@_realm string unset
+This specifies the SASL realm that the server claims to be in.
+
+.conf server@_service string $tt{smtp}
+This is the SASL service that the server claims to implement.
+
+.endconf
+
+For straightforward cases, you do not need to set any of the authenticator's
+private options. All you need to do is to specify an appropriate mechanism as
+the public name. Thus, if you have a SASL library that supports CRAM-MD5 and
+PLAIN, you could have two authenticators as follows:
+.display asis
+sasl_cram_md5:
+ driver = cyrus_sasl
+ public_name = CRAM-MD5
+ server_set_id = $1
+
+sasl_plain:
+ driver = cyrus_sasl
+ public_name = PLAIN
+ server_set_id = $1
+.endd
+
+Cyrus SASL does implement the LOGIN authentication method, even though it is
+not a standard method. It is disabled by default in the source distribution,
+but it is present in many binary distributions.
+
+.nem
+
+
.
.
.section Using spa as a server
The \%spa%\ authenticator has just one server option:
-.startconf
+.startconf spa
.index options||\%spa%\ authenticator (server)
.conf server@_password string$**$ unset
.section Using spa as a client
The \%spa%\ authenticator has the following client options:
-.startconf
+.startconf spa
.index options||\%spa%\ authenticator (client)
.conf client@_domain string$**$ unset
.index GnuTLS
Support for TLS (Transport Layer Security), formerly known as SSL (Secure
Sockets Layer), is implemented by making use of the OpenSSL library or the
-GnuTLS library (Exim requires GnuTLS release 1.0 or later).
-There is no cryptographic code in the Exim distribution itself for implementing
-TLS. In order to use this feature you must install OpenSSL or GnuTLS, and then
-build a version of Exim that includes TLS support (see section
-~~SECTinctlsssl). You also need to understand the basic concepts of encryption
-at a managerial level, and in particular, the way that public keys, private
-keys, and certificates are used.
+GnuTLS library (Exim requires GnuTLS release 1.0 or later). There is no
+cryptographic code in the Exim distribution itself for implementing TLS. In
+order to use this feature you must install OpenSSL or GnuTLS, and then build a
+version of Exim that includes TLS support (see section ~~SECTinctlsssl). You
+also need to understand the basic concepts of encryption at a managerial level,
+and in particular, the way that public keys, private keys, and certificates are
+used.
RFC 2487 defines how SMTP connections can make use of encryption. Once a
connection is established, the client issues a \\STARTTLS\\ command. If the
mechanism. If the negotiation succeeds, the data that subsequently passes
between them is encrypted.
-Exim also has support for legacy clients that do not use the \\STARTTLS\\
-mechanism. Instead, they connect to a different port on the server (usually
-called the `ssmtp' port), and expect to negotiate a TLS session as soon as the
-connection to the server is established. The \-tls-on-connect-\ command line
-option can be used to run an Exim server in this way from \*inetd*\, and it can
-also be used to run a special daemon that operates in this manner (use \-oX-\
-to specify the port).
-
Exim's ACLs can detect whether the current SMTP session is encrypted or not,
and if so, what cipher suite is in use, whether the client supplied a
certificate, and whether or not that certificate was verified. This makes it
in order to get TLS to work.
+.em
+.section Support for the legacy `ssmtp' (aka `smtps') protocol
+.index ssmtp protocol
+.index smtps protocol
+.index SMTP||ssmtp protocol
+.index SMTP||smtps protocol
+Early implementations of encrypted SMTP used a different TCP port from normal
+SMTP, and expected an encryption negotiation to start immediately, instead of
+waiting for a \\STARTTLS\\ command from the client using the standard SMTP
+port. The protocol was called `ssmtp' or `smtps', and port 465 was allocated
+for this purpose.
+
+This approach was abandoned when encrypted SMTP was standardised, but there are
+still some legacy clients that use it. Exim supports these clients by means of
+the \tls@_on@_connect@_ports\ global option. Its value must be a list of port
+numbers; the most common use is expected to be:
+.display asis
+tls_on_connect_ports = 465
+.endd
+The port numbers specified by this option apply to all SMTP connections, both
+via the daemon and via \*inetd*\. You still need to specify all the ports that
+the daemon uses (by setting \daemon@_smtp@_ports\ or \local@_interfaces\ or the
+\-oX-\ command line option) because \tls@_on@_connect@_ports\ does not add an
+extra port -- rather, it specifies different behaviour on a port that is
+defined elsewhere.
+
+There is also a \-tls-on-connect-\ command line option. This overrides
+\tls@_on@_connect@_ports\; it forces the legacy behaviour for all ports.
+.nem
+
+
+
+
.section OpenSSL vs GnuTLS
.index TLS||OpenSSL \*vs*\ GnuTLS
.rset SECTopenvsgnu "~~chapter.~~section"
option).
.nextp
The \tls@_require@_ciphers\ options operate differently, as described in the
-following section.
+following sections.
.endp
-.section Requiring specific ciphers in OpenSSL and GnuTLS
-.rset SECTreqciphsslgnu "~~chapter.~~section"
-.index TLS||requiring specific ciphers
-.index \tls@_require@_ciphers\||OpenSSL \*vs*\ GnuTLS
-This section documents the different ways the \tls@_require@_ciphers\ options
-(the global option and the \%smtp%\ transport option) operate in OpenSSL and
-GnuTLS.
-
-There is a function in the OpenSSL library that can be passed a list of
-cipher suites before the cipher negotiation takes place. This specifies which
-ciphers are acceptable. The list is colon separated and may contain names like
+.section Requiring specific ciphers in OpenSSL
+.rset SECTreqciphssl "~~chapter.~~section"
+.index TLS||requiring specific ciphers (OpenSSL)
+.index \tls@_require@_ciphers\||OpenSSL
+There is a function in the OpenSSL library that can be passed a list of cipher
+suites before the cipher negotiation takes place. This specifies which ciphers
+are acceptable. The list is colon separated and may contain names like
DES-CBC3-SHA. Exim passes the expanded value of \tls@_require@_ciphers\
-directly to this function call. The following quotation from
-the OpenSSL documentation specifies what forms of item are allowed in the
-cipher string:
+directly to this function call. The following quotation from the OpenSSL
+documentation specifies what forms of item are allowed in the cipher string:
.numberpars $.
It can consist of a single cipher suite such as RC4-SHA.
.nextp
.endp
.endp
+
+.section Requiring specific ciphers in GnuTLS
+.rset SECTreqciphgnu "~~chapter.~~section"
+.index TLS||requiring specific ciphers (GnuTLS)
+.index \tls@_require@_ciphers\||GnuTLS
The GnuTLS library does not have a combined function like OpenSSL. Instead,
it allows the caller to specify separate lists of key-exchange methods,
main cipher algorithms, and MAC algorithms. Unfortunately, these lists are
At present, Exim permits only the list of main cipher algorithms to be
changed. The \tls@_require@_ciphers\ option is in the same format as for
OpenSSL. Exim searches each item for the name of available algorithm. For
-example, if the list contains RSA@_ARCFOUR@_SHA then ARCFOUR is recognized.
+example, if the list contains RSA@_AES@_SHA then AES is recognized.
The cipher algorithms list starts out with a default set of algorithms. If
the first item in \tls@_require@_ciphers\ does \*not*\ start with an
tls_require_ciphers = AES : 3DES
.endd
allows only cipher suites that use AES and 3DES. The currently recognized
-algorithms are: ARCFOUR@_128, ARCFOUR@_40, ARCFOUR (both of the preceding),
-AES@_256, AES@_128, AES (both of the preceding), and 3DES.
-
-Unrecognized algorithms are ignored. In a client, the order of the list
-specifies a preference order for the algorithms.
+algorithms are:
+.em
+AES@_256, AES@_128, AES (both of the preceding), 3DES, and ARCFOUR@_128.
+Unrecognized algorithms are ignored. In a server, the order of the list is
+unimportant; the server will advertise the availability of all the relevant
+cipher suites. However, in a client, the order of the list specifies a
+preference order for the algorithms. The first one in the client's list that is
+also advertised by the server is tried first. The default order is as listed
+above.
+.nem
.section Configuring an Exim server to use TLS
trying to deliver the message. It is therefore recommended that you do as much
testing as possible at \\RCPT\\ time.
-.em
-.section The MIME ACLs
-The \acl@_smtp@_mime\ option is available only when Exim is compiled with the
-content-scanning extension. For details, see chapter ~~CHAPexiscan.
-
-
-.section The DATA ACLs
-.index \\DATA\\, ACLs for
-Two ACLs are associated with the \\DATA\\ command. When the command is
-received, the ACL defined by \acl@_smtp@_predata\ is obeyed. This gives you
-control after all the \\RCPT\\ commands, but before the message itself
-is received. It offers the opportunity to give a negative response to the
-\\DATA\\ command itself. Header lines added by \\MAIL\\ or \\RCPT\\ ACLs are
-not visible at this time, but any that are defined here are visible when the
-\acl@_smtp@_data\ ACL is run.
-
-You cannot test the contents of the message, for example, to verify
-addresses in the headers, at \\RCPT\\ time or when the \\DATA\\ command is
-received.
-.nem
-Such tests have to appear in the ACL that is run after the message has been
-received, before the final response to the \\DATA\\ command is sent. This is
-the ACL specified by \acl@_smtp@_data\. At this time, it is no longer possible
-to reject individual recipients. An error response rejects the entire message.
-Unfortunately, it is known that some MTAs do not treat hard (5$it{xx}) errors
-correctly at this point -- they keep the message on their queues and try again
-later, but that is their problem, though it does waste some of your resources.
+.section The non-SMTP ACL
+.index non-smtp message, ACL for
+The non-SMTP ACL applies to all non-interactive incoming messages, that is, it
+applies to batch SMTP as well as to non-SMTP messages. (Batch SMTP is not
+really SMTP.) This ACL is run just before the \*local@_scan()*\ function. Any
+kind of rejection is treated as permanent, because there is no way of sending a
+temporary error for these kinds of message. Many of the ACL conditions (for
+example, host tests, and tests on the state of the SMTP connection such as
+encryption and authentication) are not relevant and are forbidden in this ACL.
.section The connect ACL
.index SMTP||connection, ACL for
testing (if configured).
.em
+.section The DATA ACLs
+.index \\DATA\\, ACLs for
+Two ACLs are associated with the \\DATA\\ command, because it is two-stage
+command, with two responses being sent to the client.
+When the \\DATA\\ command is received, the ACL defined by \acl@_smtp@_predata\
+is obeyed. This gives you control after all the \\RCPT\\ commands, but before
+the message itself is received. It offers the opportunity to give a negative
+response to the \\DATA\\ command before the data is transmitted. Header lines
+added by \\MAIL\\ or \\RCPT\\ ACLs are not visible at this time, but any that
+are defined here are visible when the \acl@_smtp@_data\ ACL is run.
+
+You cannot test the contents of the message, for example, to verify addresses
+in the headers, at \\RCPT\\ time or when the \\DATA\\ command is received. Such
+tests have to appear in the ACL that is run after the message itself has been
+received, before the final response to the \\DATA\\ command is sent. This is
+the ACL specified by \acl@_smtp@_data\, which is the second ACL that is
+associated with the \\DATA\\ command.
+
+For both of these ACLs, it is not possible to reject individual recipients. An
+error response rejects the entire message. Unfortunately, it is known that some
+MTAs do not treat hard (5$it{xx}) responses to the \\DATA\\ command (either
+before or after the data) correctly -- they keep the message on their queues
+and try again later, but that is their problem, though it does waste some of
+your resources.
+
+.section The MIME ACL
+The \acl@_smtp@_mime\ option is available only when Exim is compiled with the
+content-scanning extension. For details, see chapter ~~CHAPexiscan.
+
.section The QUIT ACL
.rset SECTQUITACL "~~chapter.~~section"
.index \\QUIT\\, ACL for
connection is closed. In these special cases, the \\QUIT\\ ACL does not run.
.nem
-.section The non-SMTP ACL
-.index non-smtp message, ACL for
-The non-SMTP ACL applies to all non-interactive incoming messages, that is, it
-applies to batch SMTP as well as to non-SMTP messages. (Batch SMTP is not
-really SMTP.) This ACL is run just before the \*local@_scan()*\ function. Any
-kind of rejection is treated as permanent, because there is no way of sending a
-temporary error for these kinds of message. Many of the ACL conditions (for
-example, host tests, and tests on the state of the SMTP connection such as
-encryption and authentication) are not relevant and are forbidden in this ACL.
-
-
.section Finding an ACL to use
.index ~~ACL||finding which to use
The value of an \acl@_smtp@_$it{xxx}\ option is expanded before use, so you can
For \acl@_not@_smtp\, \acl@_smtp@_auth\, \acl@_smtp@_connect\,
\acl@_smtp@_data\, \acl@_smtp@_helo\, \acl__smtp__mail\, \acl@_smtp@_mailauth\,
.em
-\acl@_smtp@_predata\, \acl@_smtp@_quit\,
+\acl@_smtp@_mime\, \acl@_smtp@_predata\, \acl@_smtp@_quit\,
.nem
-and \acl@_smtp@_starttls\, the action when the ACL is not defined is `accept'.
+and \acl__smtp__starttls\, the action when the ACL is not defined is `accept'.
For the others (\acl@_smtp@_etrn\, \acl@_smtp@_expn\, \acl@_smtp@_rcpt\, and
\acl@_smtp@_vrfy\), the action when the ACL is not defined is `deny'.
.section Data for message ACLs
.index ~~ACL||data for message ACL
-When an ACL for \\MAIL\\, \\RCPT\\, or \\DATA\\ is being run, the variables
-that contain information about the host and the message's sender (for example,
-\$sender@_host@_address$\ and \$sender@_address$\) are set, and can be used in
-ACL statements. In the case of \\RCPT\\ (but not \\MAIL\\ or \\DATA\\),
-\$domain$\ and \$local@_part$\ are set from the argument address.
+.em
+When a \\MAIL\\ or \\RCPT\\ ACL, or either of the \\DATA\\ ACLs, is running,
+the variables that contain information about the host and the message's sender
+(for example, \$sender@_host@_address$\ and \$sender@_address$\) are set, and
+can be used in ACL statements. In the case of \\RCPT\\ (but not \\MAIL\\ or
+\\DATA\\), \$domain$\ and \$local@_part$\ are set from the argument address.
-When an ACL for the \\AUTH\\ parameter of \\MAIL\\ is being run, the variables
+When an ACL for the \\AUTH\\ parameter of \\MAIL\\ is running, the variables
that contain information about the host are set, but \$sender@_address$\ is not
-yet set.
-.em
-Section ~~SECTauthparamail contains a discussion of this parameter and
+yet set. Section ~~SECTauthparamail contains a discussion of this parameter and
how it is used.
-.nem
The \$message@_size$\ variable is set to the value of the \\SIZE\\ parameter on
-the \\MAIL\\ command at \\MAIL\\ and \\RCPT\\ time, or -1 if that parameter was
-not given. Its value is updated to the true message size by the time the ACL
-after \\DATA\\ is run.
+the \\MAIL\\ command at \\MAIL\\, \\RCPT\\ and pre-data time, or to -1 if
+that parameter is not given. The value is updated to the true message size by
+the time the final \\DATA\\ ACL is run (after the message data has been
+received).
The \$rcpt@_count$\ variable increases by one for each \\RCPT\\ command
received. The \$recipients@_count$\ variable increases by one each time a
\\RCPT\\ command is accepted, so while an ACL for \\RCPT\\ is being processed,
-it contains the number of previously accepted recipients. At \\DATA\\ time,
-\$rcpt@_count$\ contains the total number of \\RCPT\\ commands, and
-\$recipients@_count$\ contains the total number of accepted recipients.
+it contains the number of previously accepted recipients. At \\DATA\\ time (for
+both the \\DATA\\ ACLs), \$rcpt@_count$\ contains the total number of \\RCPT\\
+commands, and \$recipients@_count$\ contains the total number of accepted
+recipients.
+.nem
.section ACL verbs
The ACL verbs are as follows:
.numberpars $.
+.index \accept\, ACL verb
\accept\: If all the conditions are met, the ACL returns `accept'. If any of
the conditions are not met, what happens depends on whether \endpass\ appears
among the conditions (for syntax see below). If the failing condition is before
command is accepted if verification succeeds. However, if verification fails,
the ACL yields `deny', because the failing condition is after \endpass\.
.nextp
+.index \defer\, ACL verb
\defer\: If all the conditions are met, the ACL returns `defer' which, in an
SMTP session, causes a 4\*xx*\ response to be given. For a non-SMTP ACL,
\defer\ is the same as \deny\, because there is no way of sending a temporary
\%redirect%\ router and \":defer:"\ while verifying, but the \defer\ verb can
be used in any ACL, and even for a recipient it might be a simpler approach.
.nextp
+.index \deny\, ACL verb
\deny\: If all the conditions are met, the ACL returns `deny'. If any of the
conditions are not met, control is passed to the next ACL statement. For
example,
.endd
rejects commands from hosts that are on a DNS black list.
.nextp
+.index \discard\, ACL verb
\discard\: This verb behaves like \accept\, except that it returns `discard'
from the ACL instead of `accept'. It is permitted only on ACLs that are
concerned with receiving messages, and it causes recipients to be discarded.
\\DATA\\ do not appear in the log line when the \log@_recipients\ log selector
is set.
.nextp
+.index \drop\, ACL verb
\drop\: This verb behaves like \deny\, except that an SMTP connection is
forcibly closed after the 5\*xx*\ error message has been sent. For example:
.display asis
There is no difference between \deny\ and \drop\ for the connect-time ACL. The
connection is always dropped after sending a 550 response.
.nextp
+.index \require\, ACL verb
\require\: If all the conditions are met, control is passed to the next ACL
statement. If any of the conditions are not met, the ACL returns `deny'. For
example, when checking a \\RCPT\\ command,
passes control to subsequent statements only if the message's sender can be
verified. Otherwise, it rejects the command.
.nextp
+.index \warn\, ACL verb
\warn\: If all the conditions are met, a header line is added to an incoming
message and/or a line is written to Exim's main log. In all cases, control
passes to the next ACL statement. The text of the added header line and the log
.startitems
.item "control = <<text>>"
+.index \control\, ACL modifier
.em
This modifier affects the subsequent processing of the SMTP connection or of an
-incoming message that is accepted. As there are now quite a few controls that
-can be applied, they are described separately in section ~~SECTcontrols below.
+incoming message that is accepted. The effect of the first type of control
+lasts for the duration of the connection, whereas the effect of the second type
+lasts only until the current message has been received. The message-specific
+controls always apply to the whole message, not to individual recipients,
+even if the \control\ modifier appears in a \\RCPT\\ ACL.
+
+As there are now quite a few controls that can be applied, they are described
+separately in section ~~SECTcontrols.
.nem
-
-Once one of these controls is set, it remains set for the message. For example,
-if \control\ is used in a \\RCPT\\ ACL, it applies to the whole message, not
-just the individual recipient. The \control\ modifier can be used in several
-different ways. For example:
+The \control\ modifier can be used in several different ways. For example:
.numberpars $.
It can be at the end of an \accept\ statement:
.display asis
This example of \warn\ does not contain \message\, \log@_message\, or
\logwrite\, so it does not add anything to the message and does not write a log
entry.
+.nextp
+.em
+If you want to apply a control unconditionally, you can use it with a \require\
+verb. For example:
+.display asis
+require control = no_multiline_response
+.nem
+.endd
.endp
.item "delay = <<time>>"
+.index \delay\, ACL modifier
.index \-bh-\ option
This modifier causes Exim to wait for the time interval before proceeding. The
time is given in the usual Exim notation. This modifier may appear in any ACL.
.endd
.item endpass
+.index \endpass\, ACL modifier
This modifier, which has no argument, is recognized only in \accept\
statements. It marks the boundary between the conditions whose failure causes
control to pass to the next statement, and the conditions whose failure causes
the ACL to return `deny'. See the description of \accept\ above.
.item "log@_message = <<text>>"
+.index \log@_message\, ACL modifier
This modifier sets up a message that is used as part of the log message if the
ACL denies access or a \warn\ statement's conditions are true. For example:
.display asis
logging rejections.
.item "logwrite = <<text>>"
+.index \logwrite\, ACL modifier
.index log||in ACL, immediate
This modifier writes a message to a log file as soon as it is encountered when
processing an ACL. (Compare \log@_message\, which, except in the case of
.endd
.item "message = <<text>>"
+.index \message\, ACL modifier
This modifier sets up a text string that is expanded and used as an error
message if the current statement causes the ACL to deny access. The expansion
happens at the time Exim decides that access is to be denied, not at the time
use a \message\ modifier, or make use of \$acl@_verify@_message$\.
.item "set <<acl@_name>> = <<value>>"
+.index \set\, ACL modifier
This modifier puts a value into one of the ACL variables (see section
~~SECTaclvariables).
.em
.section Use of the control modifier
.rset SECTcontrols "~~chapter.~~section"
-.index \control\ modifier
+.index \control\, ACL modifier
The \control\ modifier supports the following settings:
.startitems
\$local@_part$\ are lower cased before ACL processing. If
`caseful@_local@_part' is specified, any uppercase letters in the original
local part are restored in \$local@_part$\ for the rest of the ACL, or until a
-control that sets `caselower@_local@_part' is encountered. However, this
-applies only to local part handling that takes place directly in the ACL (for
-example, as a key in lookups). If a test to verify the recipient is obeyed, the
-case-related handling of the local part during the verification is controlled
-by the router configuration (see the \caseful@_local@_part\ generic router
-option).
+control that sets `caselower@_local@_part' is encountered.
+
+This control affects only the current recipient. Moreover, it applies only to
+local part handling that takes place directly in the ACL (for example, as a key
+in lookups). If a test to verify the recipient is obeyed, the case-related
+handling of the local part during the verification is controlled by the router
+configuration (see the \caseful@_local@_part\ generic router option).
This facility could be used, for example, to add a spam score to local parts
containing upper case letters. For example, using \$acl@_m4$\ to accumulate the
state of the switch (it is true by default). See the description of this option
in chapter ~~CHAPmainconfig for details of SMTP synchronization checking.
-These two controls can appear in any ACL except the one for the non-SMTP
+The effect of these two controls lasts for the remainder of the SMTP
+connection. They can appear in any ACL except the one for the non-SMTP
messages. The most straightforward place to put them is in the ACL defined by
\acl@_smtp@_connect\, which is run at the start of an incoming SMTP connection,
before the first synchronization check. The expected use is to turn off the
This control is permitted only for the \\MAIL\\, \\RCPT\\, and \\DATA\\ ACLs,
in other words, only when an SMTP message is being received. If Exim accepts
the message, instead the final 250 response, a 550 rejection message is sent.
-However, Exim proceeds to deliver the message as normal.
+However, Exim proceeds to deliver the message as normal. The control applies
+only to the current message, not to any subsequent ones that may be received in
+the same SMTP connection.
The text for the 550 response is taken from the \control\ modifier. If no
message is supplied, the following is used:
.display asis
-550-Your message has been rejected but is being
+550-Your message has been rejected but is being
550-kept for evaluation.
-550-If it was a legit message, it may still be
+550-If it was a legitimate message, it may still be
550 delivered to the target recipient(s).
.endd
This facilty should be used with extreme caution.
.index frozen messages||forcing in ACL
This control is permitted only for the \\MAIL\\, \\RCPT\\, \\DATA\\, and
non-SMTP ACLs, in other words, only when a message is being received. If the
-message is accepted, it is placed on Exim's queue and frozen.
+message is accepted, it is placed on Exim's queue and frozen. The control
+applies only to the current message, not to any subsequent ones that may be
+received in the same SMTP connection.
+
+
+.item "control = no@_mbox@_unspool"
+This control is available when Exim is compiled with the content scanning
+extension. Content scanning may require a copy of the current message, or parts
+of it, to be written in `mbox format' to a spool file, for passing to a virus
+or spam scanner. Normally, such copies are deleted when they are no longer
+needed. If this control is set, the copies are not deleted. The control
+applies only to the current message, not to any subsequent ones that may be
+received in the same SMTP connection. It is provided for debugging purposes and
+is unlikely to be useful in production.
.item "control = no@_multiline@_response"
might get close to that. So this facility, which is after all only a sop to
broken clients, is implemented by doing two very easy things:
.numberpars
-Extra information that is normally output as part of a rejection
-caused by sender verification failure is omitted. Only the final line
-(typically `sender verification failed') is sent.
+Extra information that is normally output as part of a rejection caused by
+sender verification failure is omitted. Only the final line (typically `sender
+verification failed') is sent.
.nextp
If a \message\ modifier supplies a multiline response, only the first
line is output.
.endp
The setting of the switch can, of course, be made conditional on the
-calling host.
+calling host. Its effect lasts until the end of the SMTP connection.
.item "control = queue@_only"
non-SMTP ACLs, in other words, only when a message is being received. If the
message is accepted, it is placed on Exim's queue and left there for delivery
by a subsequent queue runner. No immediate delivery process is started. In
-other words, it has the effect of the \queue@_only\ global option for just the
-one message.
+other words, it has the effect as the \queue@_only\ global option. However, the
+control applies only to the current message, not to any subsequent ones that
+may be received in the same SMTP connection.
.item "control = submission/<<options>>"
.index submission mode
This control is permitted only for the \\MAIL\\, \\RCPT\\, and start of data
ACLs (the latter is the one defined by \acl@_smtp@_predata\). Setting it tells
-Exim that the message is a submission from a local MUA. In this case, Exim
-operates in `submission mode', and applies certain fixups to the message if
-necessary. For example, it add a ::Date:: header line if one is not present.
-This control is not permitted in the \\DATA\\ ACL, because that is too late
-(the message has already been created).
+Exim that the current message is a submission from a local MUA. In this case,
+Exim operates in `submission mode', and applies certain fixups to the message
+if necessary. For example, it add a ::Date:: header line if one is not present.
+This control is not permitted in the \acl@_smtp@_data\ ACL, because that is too
+late (the message has already been created).
Chapter ~~CHAPmsgproc describes the processing that Exim applies to messages.
Section ~~SECTsubmodnon covers the processing that happens in submission mode;
-the available options for this control are described there.
+the available options for this control are described there. The control applies
+only to the current message, not to any subsequent ones that may be received in
+the same SMTP connection.
.enditems
.nem
.rset SECTaddheadwarn "~~chapter.~~section"
.index header lines||adding in an ACL
.index header lines||position of added lines
+.index \warn\, ACL verb
+.index \message\, ACL modifier
The \message\ modifier can be used on a \warn\ statement to add an extra header
line to an incoming message, as in this example:
.display asis
.item "acl = <<name of acl or ACL string or file name >>"
.index ~~ACL||nested
.index ~~ACL||indirect
+.index \acl\, ACL condition
The possible values of the argument are the same as for the
\acl@_smtp@_$it{xxx}\ options. The named or inline ACL is run. If it returns
`accept' the condition is true; if it returns `deny' the condition is false. If
commands for different local users or different local domains.
.item "authenticated = <<string list>>"
+.index \authenticated\, ACL condition
.index authentication||ACL checking
.index ~~ACL||testing for authentication
If the SMTP connection is not authenticated, the condition is false. Otherwise,
.endd
.item "condition = <<string>>"
+.index \condition\, ACL condition
.index customizing||ACL condition
.index ~~ACL||customized test
+.index ~~ACL||testing, customized
This feature allows you to make up custom conditions. If the result of
expanding the string is an empty string, the number zero, or one of the strings
`no' or `false', the condition is false. If the result is any non-zero number,
.em
.item "decode = <<location>>"
+.index \decode\, ACL condition
This condition is available only when Exim is compiled with the
content-scanning extension, and it is allowed only the the ACL defined by
\acl@_smtp@_mime\. It causes the current MIME part to be decoded into a file.
.item "dnslists = <<list of domain names and other data>>"
+.index \dnslists\, ACL condition
.index DNS list||in ACL
.index black list (DNS)
.index ~~ACL||testing a DNS list
here. See sections ~~SECTmorednslists--~~SECTmorednslistslast for details.
.item "domains = <<domain list>>"
+.index \domains\, ACL condition
.index domain||ACL checking
.index ~~ACL||testing a recipient domain
This condition is relevant only after a \\RCPT\\ command. It checks that the
until the next \domains\ test.
.item "encrypted = <<string list>>"
+.index \encrypted\, ACL condition
.index encryption||checking in an ACL
.index ~~ACL||testing for encryption
If the SMTP connection is not encrypted, the condition is false. Otherwise, the
.endd
.item "hosts = << host list>>"
+.index \hosts\, ACL condition
.index host||ACL checking
.index ~~ACL||testing the client host
This condition tests that the calling host matches the host list. If you have
which gives a custom error message for each denied host.
.item "local@_parts = <<local part list>>"
+.index \local@_parts\, ACL condition
.index local part||ACL checking
.index ~~ACL||testing a local part
This condition is relevant only after a \\RCPT\\ command. It checks that the
.em
.item "malware = <<option>>"
+.index \malware\, ACL condition
+.index ~~ACL||virus scanning
+.index ~~ACL||scanning for viruses
This condition is available only when Exim is compiled with the
content-scanning extension. It causes the incoming message to be scanned for
viruses. For details, see chapter ~~CHAPexiscan.
.em
.item "mime@_regex = <<list of regular expressions>>"
+.index \mime@_regex\, ACL condition
+.index ~~ACL||testing by regex matching
This condition is available only when Exim is compiled with the
content-scanning extension, and it is allowed only the the ACL defined by
\acl@_smtp@_mime\. It causes the current MIME part to be scanned for a match
.item "recipients = <<address list>>"
+.index \recipients\, ACL condition
.index recipient||ACL checking
.index ~~ACL||testing a recipient
This condition is relevant only after a \\RCPT\\ command. It checks the entire
.em
.item "regex = <<list of regular expressions>>"
+.index \regex\, ACL condition
+.index ~~ACL||testing by regex matching
This condition is available only when Exim is compiled with the
content-scanning extension. It causes the incoming message to be scanned
for a match with any of the regular expressions. For details, see chapter
.item "sender@_domains = <<domain list>>"
+.index \sender@_domains\, ACL condition
.index sender||ACL checking
.index ~~ACL||testing a sender domain
This condition tests the domain of the sender of the message against the given
be used to influence the sender checking.
.item "senders = <<address list>>"
+.index \senders\, ACL condition
.index sender||ACL checking
.index ~~ACL||testing a sender
This condition tests the sender of the message against the given list. To test
.em
.item "spam = <<username>>"
+.index \spam\, ACL condition
+.index ~~ACL||scanning for spam
This condition is available only when Exim is compiled with the
content-scanning extension. It causes the incoming message to be scanned by
SpamAssassin. For details, see chapter ~~CHAPexiscan.
.item "verify = certificate"
+.index \verify\, ACL condition
.index TLS||client certificate verification
.index certificate||verification of client
.index ~~ACL||certificate verification
+.index ~~ACL||testing a TLS certificate
This condition is true in an SMTP session if the session is encrypted, and a
certificate was received from the client, and the certificate was verified. The
server requests a certificate only if the client matches \tls@_verify@_hosts\
or \tls@_try@_verify@_hosts\ (see chapter ~~CHAPTLS).
.item "verify = header@_sender/<<options>>"
+.index \verify\, ACL condition
.index ~~ACL||verifying sender in the header
.index header lines||verifying the sender in
.index sender||verifying in header
.endd
.item "verify = header@_syntax"
+.index \verify\, ACL condition
.index ~~ACL||verifying header syntax
.index header lines||verifying syntax
.index verifying||header syntax
and this condition can be used to reject such messages.
.item "verify = helo"
+.index \verify\, ACL condition
.index ~~ACL||verifying HELO/EHLO
.index \\HELO\\||verifying
.index \\EHLO\\||verifying
to request it.
.item "verify = recipient/<<options>>"
+.index \verify\, ACL condition
.index ~~ACL||verifying recipient
.index recipient||verifying
.index verifying||recipient
.item "verify = reverse@_host@_lookup"
+.index \verify\, ACL condition
.index ~~ACL||verifying host reverse lookup
.index host||verifying reverse lookup
This condition ensures that a verified host name has been looked up from the IP
.item "verify = sender/<<options>>"
+.index \verify\, ACL condition
.index ~~ACL||verifying sender
.index sender||verifying
.index verifying||sender
-This condition is relevant only after a
-\\MAIL\\ or \\RCPT\\ command, or after a message has been received (the
-\acl@_smtp@_data\ or \acl@_not@_smtp\ ACLs).
+This condition is relevant only after a \\MAIL\\ or \\RCPT\\ command, or after
+a message has been received (the \acl@_smtp@_data\ or \acl@_not@_smtp\ ACLs).
If the message's sender is empty (that is, this is a bounce message), the
-condition is true. Otherwise, the sender address is verified. Details of
-verification are given later, starting at section ~~SECTaddressverification.
-Exim caches the result of sender verification, to avoid doing it more than once
-per message.
-
-.item "verify = sender=address/<<options>>"
+condition is true. Otherwise, the sender address is verified.
+.em
+If there is data in the \$address@_data$\ variable at the end of routing, its
+value is placed in \$sender__address__data$\ at the end of verification. This
+value can be used in subsequent conditions and modifiers in the same ACL
+statement. It does not persist after the end of the current statement. If you
+want to preserve the value for longer, you can save it in an ACL variable.
+
+Details of verification are given later, starting at section
+~~SECTaddressverification. Exim caches the result of sender verification, to
+avoid doing it more than once per message.
+
+.item "verify = sender=<<address>>/<<options>>"
+.index \verify\, ACL condition
This is a variation of the previous option, in which a modified address is
verified as a sender.
.
.
. ============================================================================
-.chapter Content scanning using the `exiscan' features
+.chapter Content scanning
.set runningfoot "content scanning"
.rset CHAPexiscan "~~chapter"
.index content scanning
.em
-The content-scanning extension of Exim, also known as `exiscan', was originally
-implemented as a patch by Tom Kistner. The code was integrated into the main
-source for Exim release 4.50, and Tom continues to maintain it. Most of the
-wording of this chapter is taken from Tom's exiscan specification.
+The content-scanning extension of Exim, formerly known as `exiscan', was
+originally implemented as a patch by Tom Kistner. The code was integrated into
+the main source for Exim release 4.50, and Tom continues to maintain it. Most
+of the wording of this chapter is taken from Tom's specification.
If you want to include the content-scanning features when you compile Exim, you
need to arrange for \\WITH@_CONTENT@_SCAN\\ to be defined in your
\regex\, and \spam\. These can be used in the ACL that is run at the end of
message reception (the \acl@_smtp@_data\ ACL).
.nextp
+An additional control feature (`no@_mbox@_unspool') that saves spooled copies
+of messages, or parts of messages, for debugging purposes.
+.nextp
Additional expansion variables that are set in the new ACL and by the new
conditions.
.nextp
expect an MBOX-like structure inside that file. The file is created when the
first content scanning facility is called. Subsequent calls to content
scanning conditions open the same file again. The directory is recursively
-removed when the \acl@_smtp@_data\ ACL has finished running. When the MIME
-ACL decodes files, they are put into that same directory by default.
+removed when the \acl@_smtp@_data\ ACL has finished running, unless
+.display asis
+control = no_mbox_unspool
+.endd
+has been encountered. When the MIME ACL decodes files, they are put into the
+same directory by default.
.section Scanning for viruses
.nextp
.index virus scanners||clamd
\clamd\: This daemon-type scanner is GPL and free. You can get it at
-\?http://www.clamav.net/?\. Clamd does not seem to unpack MIME containers,
-so it is recommended to unpack MIME attachments in the MIME ACL. It takes one option:
-either the path and name of a UNIX socket file, or a hostname or IP number, and
-a port, separated by space, as in the second of these examples:
+\?http://www.clamav.net/?\. Clamd does not seem to unpack MIME containers, so
+it is recommended to unpack MIME attachments in the MIME ACL. It takes one
+option: either the path and name of a UNIX socket file, or a hostname or IP
+number, and a port, separated by space, as in the second of these examples:
.display asis
av_scanner = clamd:/opt/clamd/socket
av_scanner = clamd:192.168.2.100 1234
.endd
-If the option is unset, the default is \(/tmp/clamd)\.
+If the option is unset, the default is \(/tmp/clamd)\. Thanks to David Saez for
+contributing the code for this scanner.
.nextp
.index virus scanners||command line interface
\cmdline\: This is the keyword for the generic command line scanner interface.
It can be used to attach virus scanners that are invoked from the shell. This
-scanner type takes 3 mantadory options:
+scanner type takes 3 mandatory options:
.numberpars
The full path and name of the scanner binary, with all command line options,
and a placeholder (%s) for the directory to scan.
sure that this expression matches on `virus found'. This is called the
`trigger' expression.
.nextp
-Another regular expression, containing exactly one pair of parentheses, to match the
-name of the virus found in the scanners output. This is called the `name'
-expression.
+Another regular expression, containing exactly one pair of parentheses, to
+match the name of the virus found in the scanners output. This is called the
+`name' expression.
.endp
For example, Sophos Sweep reports a virus on a line like this:
.display asis
.endp
When \av@_scanner\ is correctly set, you can use the \malware\ condition in the
-DATA ACL.
-
-The \malware\ condition caches its results, so when you use it multiple times
-for the same message, the actual scanning process is only carried out once.
-
-\av@_scanner\ is expanded each time \malware\ is called. This makes
-it possible to use different scanners. See further below for an example.
-However, using expandable items in \av@_scanner\ disables the result caching
-of the \malware\ condition.
-
-The condition takes a right-hand argument that is expanded before
+\\DATA\\ ACL. The \av@_scanner\ option is expanded each time \malware\ is
+called. This makes it possible to use different scanners. See further below for
+an example. The \malware\ condition caches its results, so when you use it
+multiple times for the same message, the actual scanning process is only
+carried out once. However, using expandable items in \av@_scanner\ disables
+this caching, in which case each use of the \malware\ condition causes a new
+scan of the message.
+
+The \malware\ condition takes a right-hand argument that is expanded before
use. It can then be one of
.numberpars $.
`true', `*', or `1', in which case the message is scanned for viruses. The
queried in a random fashion. When a server fails to respond
to the connection attempt, all other servers are tried
until one succeeds. If no server responds, the \spam\
-condition defers.
+condition defers.
\**Warning**\: It is not possible to use the UNIX socket connection method with
multiple \spamd\ servers.
+The spamd_address variable is expanded before use if it starts with a dollar
+sign. In this case, the expansion may return a string that is used as the
+list so that multiple spamd servers can be the result of an expansion.
+
Here is a simple example of the use of the \spam\ condition in a DATA ACL:
.display asis
deny message = This message was classified as SPAM
integer value. For example `34' or `305'. This is useful for numeric
comparisons in conditions. This variable is special; it is saved with the
message, and written to Exim's spool file. This means that it can be used
-during the whole life of the message on your Exim system, in particualr, in
+during the whole life of the message on your Exim system, in particular, in
routers or transports during the later delivery phase.
.tempindent 0
.pop
-The \spam\ condition caches its results. If you call it again with the same user
-name, it does not scan again, but rather returns the same values as before.
+The \spam\ condition caches its results unless expansion in spamd_address was
+used. If you call it again with the same user name, it does not scan again,
+but rather returns the same values as before.
The \spam\ condition returns DEFER if there is any error while running the
-message through SpamAssassin. If you want to treat DEFER as FAIL (to pass on to
-the next ACL statement block), append \"/defer@_ok"\ to the right-hand side of
-the spam condition, like this:
+message through SpamAssassin or if the expansion of spamd_address failed. If
+you want to treat DEFER as FAIL (to pass on to the next ACL statement block),
+append \"/defer_ok"\ to the right-hand side of the spam condition, like this:
.display asis
deny message = This message was classified as SPAM
spam = joe/defer_ok
The \acl@_smtp@_mime\ global option defines an ACL that is called once for each
MIME part of a message, including multipart types, in the sequence of their
position in the message.
-
+
This ACL is called (possibly many times) just before the \acl@_smtp@_data\ ACL,
but only if the message has a ::MIME-Version:: header. When a call to the MIME
ACL does not yield `accept', ACL processing is aborted and the appropriate
result code is sent to the remote client. The \acl@_smtp@_data\ ACL is not
called in this circumstance.
-At the start of the MIME ACL, a number of variables are set from the header
-information for the relevant MIME part. These are described below. The contents
-of the MIME part are not by default decoded into a disk file except for MIME
-parts whose content-type is `message/rfc822'. If you want to decode a MIME part
+At the start of the MIME ACL, a number of variables are set from the header
+information for the relevant MIME part. These are described below. The contents
+of the MIME part are not by default decoded into a disk file except for MIME
+parts whose content-type is `message/rfc822'. If you want to decode a MIME part
into a disk file, you can use the \decode\ modifier. The general syntax is:
.display
decode = [/<<path>>/]<<filename>>
cover letter, and 0 (false) for an attachment. At present, the algorithm is as
follows:
.numberpars
-The outermost MIME part of a message always a cover letter.
+The outermost MIME part of a message is always a cover letter.
.nextp
If a multipart/alternative or multipart/related MIME part is a cover letter, so
are all MIME subparts within that multipart.
.endp
As an example, the following will ban `HTML mail' (including that sent with
-alternative plain text), while allowing HTML files to be attached. HTML
+alternative plain text), while allowing HTML files to be attached. HTML
coverletter mail attached to non-HMTL coverletter mail will also be allowed:
.display asis
deny message = HTML mail is not accepted here
.pop
-
-
.section Scanning with regular expressions
.rset SECTscanregex "~~chapter.~~section"
.index content scanning||with regular expressions
.index regular expressions||content scanning with
-You can specify your own custom regular expression matches on the full body of
+You can specify your own custom regular expression matches on the full body of
the message, or on individual MIME parts.
The \regex\ condition takes one or more regular expressions as arguments and
extension blocking. It uses a simpler interface to MIME decoding than the MIME
ACL functionality, but provides no additional facilities. Please note that this
condition is deprecated and kept only for for backward compatibility. You must
-set the WITH_OLD_DEMIME option in the Makefile at build time to be able to use
-the \demime\ condition.
+set the \\WITH@_OLD@_DEMIME\\ option in \(Local/Makefile)\ at build time to be
+able to use the \demime\ condition.
The \demime\ condition unpacks MIME containers in the message. It detects
errors in MIME containers and can match file extensions found in the message
.tempindent 0
\$found@_extension$\: When the \demime\ condition is true, this variable
contains the file extension it found.
-
-.pop
-
+
+.pop
+
Both \$demime@_errorlevel$\ and \$demime@_reason$\ are set by the first call of
the \demime\ condition, and are not changed on subsequent calls.
.index policy control||by local scan function
In these days of email worms, viruses, and ever-increasing spam, some sites
-want to apply a lot of checking to messages before accepting them. You can do a
-certain amount through string expansions and the \condition\ condition in the
-ACL that runs after the SMTP \\DATA\\ command or the ACL for non-SMTP messages
-(see chapter ~~CHAPACL), but this has its limitations.
+want to apply a lot of checking to messages before accepting them.
+.em
+The content scanning extension (chapter ~~CHAPexiscan) has facilities for
+passing messages to external virus and spam scanning software. You can also do
+.nem
+a certain amount in Exim itself through string expansions and the \condition\
+condition in the ACL that runs after the SMTP \\DATA\\ command or the ACL for
+non-SMTP messages (see chapter ~~CHAPACL), but this has its limitations.
-To allow for even more general checking that can be customized to a site's own
-requirements, there is the possibility of linking Exim with a private message
-scanning function, written in C. If you want to run code that is written in
-something other than C, you can of course use a little C stub to call it.
+To allow for further customization to a site's own requirements, there is the
+possibility of linking Exim with a private message scanning function, written
+in C. If you want to run code that is written in something other than C, you
+can of course use a little C stub to call it.
The local scan function is run once for every incoming message, at the point
when Exim is just about to accept the message.
~~SECTmemhanloc below for a discussion of memory handling.
.item "void header@_add(int type, char *format, ...)"
-This function allows you to add additional header lines. The first argument is
-the type, and should normally be a space character. The second argument is a
-format string and any number of substitution arguments as for \*sprintf()*\.
-You may include internal newlines if you want, and you must ensure that the
-string ends with a newline.
+.em
+This function allows you to an add additional header line at the end of the
+existing ones.
+.nem
+The first argument is the type, and should normally be a space character. The
+second argument is a format string and any number of substitution arguments as
+for \*sprintf()*\. You may include internal newlines if you want, and you must
+ensure that the string ends with a newline.
+
+.em
+.item "void header@_add@_at@_position(BOOL after, uschar *name, BOOL topnot, int type, char *$nh{format}, ...)"
+This function adds a new header line at a specified point in the header
+chain. The header itself is specified as for \*header@_add()*\.
+
+If \name\ is NULL, the new header is added at the end of the chain if \after\
+is true, or at the start if \after\ is false. If \name\ is not NULL, the header
+lines are searched for the first non-deleted header that matches the name. If
+one is found, the new header is added before it if \after\ is false. If \after\
+is true, the new header is added after the found header and any adjacent
+subsequent ones with the same name (even if marked `deleted'). If no matching
+non-deleted header is found, the \topnot\ option controls where the header is
+added. If it is true, addition is at the top; otherwise at the bottom. Thus, to
+add a header after all the ::Received:: headers, or at the top if there are no
+::Received:: headers, you could use
+.display asis
+header_add_at_position(TRUE, US"Received", TRUE,
+ ' ', "X-xxx: ...");
+.endd
+Normally, there is always at least one non-deleted ::Received:: header, but
+there may not be if \received@_header@_text\ expands to an empty string.
+
+
+.item "void header@_remove(int occurrence, uschar *name)"
+This function removes header lines. If \occurrence\ is zero or negative, all
+occurrences of the header are removed. If occurrence is greater than zero, that
+particular instance of the header is removed. If no header(s) can be found that
+match the specification, the function does nothing.
+
+
+.item "BOOL header@_testname(header@_line *hdr, uschar *name, int length, BOOL notdel)"
+This function tests whether the given header has the given name. It is not just
+a string comparison, because whitespace is permitted between the name and the
+colon. If the \notdel\ argument is true, a false return is forced for all
+`deleted' headers; otherwise they are not treated specially. For example:
+.display asis
+if (header_testname(h, US"X-Spam", 6, TRUE)) ...
+.endd
+.nem
+
.item "uschar *lss@_b64encode(uschar *cleartext, int length)"
.index base64 encoding||functions for \*local@_scan()*\ use
US"postmaster@mydom.example";
.endd
+.em
+.item "BOOL receive@_remove@_recipient(uschar *recipient)"
+This is a convenience function to remove a named recipient from the
+list of recipients. It returns true if a recipient was removed, and
+false if no matching recipient could be found. The argument must be a
+complete email address.
+.nem
+
+
.item "uschar *rfc2047@_decode(uschar *string, BOOL lencheck, uschar *target, int zeroval, int *lenptr, uschar **error)"
This function decodes strings that are encoded according to RFC 2047. Typically
these are the contents of header lines. First, each encoded `word' is decoded
The pool setting applies to all functions that get dynamic memory, including
\*expand@_string()*\, \*store@_get()*\, and the \*string@_xxx()*\ functions.
-There is also a convenience function called \*store@_get@_perm()*\ that gets a
+There is also a convenience function called \*store__get__perm()*\ that gets a
block of memory from the permanent pool while preserving the value of
\store@_pool\.
You can run simple tests of a system filter in the same way as for a user
filter, but you should use \-bF-\ rather than \-bf-\, so that features that
are permitted only in system filters are recognized.
+.em
+If you want to test the combined effect of a system filter and a user filter,
+you can use both \-bF-\ and \-bf-\ on the same command line.
+.nem
.section Contents of a system filter
The language used to specify system filters is the same as for users' filter
.section Adding and removing headers in a system filter
-.index header lines||adding in system filter
-.index header lines||removing in system filter
+.rset SECTaddremheasys "~~chapter.~~section"
+.index header lines||adding, in system filter
+.index header lines||removing, in system filter
.index filter||header lines, adding/removing
Two filter commands that are available only in system filters are:
-.display asis
+.display
headers add <<string>>
headers remove <<string>>
.endd
-The argument for the \headers add\ is a string which is expanded and then added
+The argument for the \headers add\ is a string that is expanded and then added
to the end of the message's headers. It is the responsibility of the filter
maintainer to make sure it conforms to RFC 2822 syntax. Leading white space is
ignored, and if the string is otherwise empty, or if the expansion is forced to
fail, the command has no effect.
-If the message is not delivered at the first attempt, header lines that were
-added by the system filter are stored with the message, and so are still
-present at the next delivery attempt. For that reason, it is usual to make the
-\headers add\ command conditional on \first@_delivery\.
-
You can use `@\n' within the string, followed by white space, to specify
continued header lines. More than one header may be added in one command by
including `@\n' within the string without any following white space. For
be placed before the backslash that continues the input string, because white
space after input continuations is ignored.
-Header lines that are added by a system filter are visible to users' filter
-files and to all routers and transports.
-
The argument for \headers remove\ is a colon-separated list of header names.
This command applies only to those headers that are stored with the message;
those that are added at delivery time (such as ::Envelope-To:: and
-::Return-Path::) cannot be removed by this means.
-If there is more than one header with the same name, they are all removed.
+::Return-Path::) cannot be removed by this means. If there is more than one
+header with the same name, they are all removed.
+
+.em
+The \headers\ command in a system filter makes an immediate change to the set
+of header lines that was received with the message (with possible additions
+from ACL processing). Subsequent commands in the system filter operate on the
+modified set, which also forms the basis for subsequent message delivery.
+Unless further modified during routing or transporting, this set of headers is
+used for all recipients of the message.
+
+During routing and transporting, the variables that refer to the contents of
+header lines refer only to those lines that are in this set. Thus, header lines
+that are added by a system filter are visible to users' filter files and to all
+routers and transports. This contrasts with the manipulation of header lines by
+routers and transports, which is not immediate, but which instead is saved up
+until the message is actually being written (see section ~~SECTheadersaddrem).
+
+If the message is not delivered at the first attempt, header lines that were
+added by the system filter are stored with the message, and so are still
+present at the next delivery attempt. Header lines that were removed are still
+present, but marked `deleted' so that they are not transported with the
+message. For this reason, it is usual to make the \headers\ command conditional
+on \first@_delivery\ so that the set of header lines is not modified more than
+once.
+
+Because header modification in a system filter acts immediately, you have to
+use an indirect approach if you want to modify the contents of a header line.
+For example:
+.display asis
+headers add "Old-Subject: $h_subject:"
+headers remove "Subject"
+headers add "Subject: new subject (was: $h_old-subject:)"
+headers remove "Old-Subject"
+.endd
+.nem
+
.section Setting an errors address in a system filter
+
.
.
.
.
. ============================================================================
-.chapter Customizing bounce and warning messages
-.set runningfoot "customizing messages"
-.rset CHAPemsgcust "~~chapter"
-When a message fails to be delivered, or remains on the queue for more than a
-configured amount of time, Exim sends a message to the original sender, or
-to an alternative configured address. The text of these messages is built into
-the code of Exim, but it is possible to change it, either by adding a single
-string, or by replacing each of the paragraphs by text supplied in a file.
+.chapter Message processing
+.set runningfoot "message processing"
+.rset CHAPmsgproc "~~chapter"
+.index message||general processing
+Exim performs various transformations on the sender and recipient addresses of
+all 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, and the addition or
+removal of header lines while delivering, happens when a message is received,
+before it is placed on Exim's queue.
-The ::From:: and ::To:: header lines are automatically generated; you can cause
-a ::Reply-To:: line to be added by setting the \errors@_reply@_to\ option. Exim
-also adds the line
-.display asis
-Auto-Submitted: auto-generated
-.endd
-to all warning and bounce messages,
+Some of the automatic processing takes place by default only for
+`locally-originated' messages. This adjective is used to describe messages that
+are not received over TCP/IP, but instead are passed to an Exim process on its
+standard input. This includes the interactive `local SMTP' case that is set up
+by the \-bs-\ command line option.
-.section Customizing bounce messages
-.index customizing||bounce message
-.index bounce message||customizing
-If \bounce@_message@_text\ is set, its contents are included in the default
-message immediately after `This message was created automatically by mail
-delivery software.' The string is not expanded. It is not used if
-\bounce@_message@_file\ is set.
+\**Note**\: messages received over TCP/IP on the loopback interface (127.0.0.1
+or @:@:1) are not considered to be locally-originated. Exim does not treat the
+loopback interface specially in any way.
+.em
+If you want the loopback interface to be treated specially, you must ensure
+that there are appropriate entries in your ACLs.
+.nem
-When \bounce@_message@_file\ is set, it must point to a template file for
-constructing error messages. The file consists of a series of text items,
-separated by lines consisting of exactly four asterisks. If the file cannot be
-opened, default text is used and a message is written to the main and panic
-logs. If any text item in the file is empty, default text is used for that
-item.
-Each item of text that is read from the file is expanded, and there are two
-expansion variables which can be of use here: \$bounce@_recipient$\ is set to
-the recipient of an error message while it is being created, and
-\$return@_size@_limit$\ contains the value of the \return@_size@_limit\ option,
-rounded to a whole number.
+.section Submission mode for non-local messages
+.rset SECTsubmodnon "~~chapter.~~section"
+.index message||submission
+.index submission mode
+.em
+Processing that happens automatically for locally-originated messages can also
+be requested for other messages. The term `submission mode' is used to describe
+this state. Submisssion mode is set by the modifier
+.display asis
+control = submission
+.endd
+in a \\MAIL\\, \\RCPT\\, or pre-data ACL for an incoming SMTP message (see
+sections ~~SECTACLmodi and ~~SECTcontrols). This makes Exim treat the message
+as a local submission, and is normally used when the source of the message is
+known to be an MUA running on a client host (as opposed to an MTA). For
+example, to set submission mode for messages originating on the IPv4 loopback
+interface, you could include the following in the \\MAIL\\ ACL:
+.display asis
+warn hosts = 127.0.0.1
+ control = submission
+.endd
+There are some options that can be used when setting submission mode. A slash
+is used to separate options. For example:
+.display asis
+control = submission/sender_retain
+.endd
+Specifying \sender@_retain\ has the effect of setting \local@_sender@_retain\
+true and \local@_from@_check\ false for the current incoming message. The first
+of these allows an existing ::Sender:: header in the message to remain, and the
+second suppresses the check to ensure that ::From:: matches the authenticated
+sender. With this setting, Exim still fixes up messages by adding ::Date:: and
+::Message-ID:: header lines if they are missing, but makes no attempt to check
+sender authenticity in header lines.
-The items must appear in the file in the following order:
-.numberpars $.
-The first item is included in the headers, and should include at least a
-::Subject:: header. Exim does not check the syntax of these headers.
-.nextp
-The second item forms the start of the error message. After it, Exim lists the
-failing addresses with their error messages.
-.nextp
-The third item is used to introduce any text from pipe transports that is to be
-returned to the sender. It is omitted if there is no such text.
-.nextp
-The fourth item is used to introduce the copy of the message that is returned
-as part of the error report.
-.nextp
-The fifth item is added after the fourth one if the returned message is
-truncated because it is bigger than \return@_size@_limit\.
-.nextp
-The sixth item is added after the copy of the original message.
-.endp
-The default state (\bounce@_message@_file\ unset) is equivalent to the
-following file, in which the sixth item is empty. The ::Subject:: line has been
-split into two here in order to fit it on the page:
-.if ~~sys.fancy
-.display flow asis
-.fontgroup 0
-.font 54
-.else
-.rule
-.display flow asis
-.linelength 80em
-.indent 0
-.fi
-Subject: Mail delivery failed
- ${if eq{$sender_address}{$bounce_recipient}{: returning message to sender}}
-****
-This message was created automatically by mail delivery software.
+A submission mode setting may also specify a domain to be used when generating
+a ::From:: or ::Sender:: header. For example:
+.display asis
+control = submission/domain=some.domain
+.endd
+The domain may be empty. How this value is used is described in sections
+~~SECTthefrohea and ~~SECTthesenhea.
+.nem
-A message ${if eq{$sender_address}{$bounce_recipient}{that you sent }{sent by
- <$sender_address>
-}}could not be delivered to all of its recipients.
-The following address(es) failed:
-****
-The following text was generated during the delivery attempt(s):
-****
------- This is a copy of the message, including all the headers. ------
-****
------- The body of the message is $message_size characters long; only the first
------- $return_size_limit or so are included here.
-****
-.endd
-.if !~~sys.fancy
-.rule
-.fi
+.section Line endings
+.rset SECTlineendings "~~chapter.~~section"
+.index line endings
+.index carriage return
+.index linefeed
+RFC 2821 specifies that CRLF (two characters: carriage-return, followed by
+linefeed) is the line ending for messages transmitted over the Internet using
+SMTP over TCP/IP. However, within individual operating systems, different
+conventions are used. For example, Unix-like systems use just LF, but others
+use CRLF or just CR.
-.section Customizing warning messages
-.rset SECTcustwarn "~~chapter.~~section"
-.index customizing||warning message
-.index warning of delay||customizing the message
-The option
-\warn@_message@_file\
-can be pointed at a template file for use when
-warnings about message delays are created. In this case there are only three
-text sections:
+Exim was designed for Unix-like systems, and internally, it stores messages
+using the system's convention of a single LF as a line terminator. When
+receiving a message, all line endings are translated to this standard format.
+Originally, it was thought that programs that passed messages directly to an
+MTA within an operating system would use that system's convention. Experience
+has shown that this is not the case; for example, there are Unix applications
+that use CRLF in this circumstance. For this reason, and for compatibility with
+other MTAs, the way Exim handles line endings for all messages is now as
+follows:
.numberpars $.
-The first item is included in the headers, and should include at least a
-::Subject:: header. Exim does not check the syntax of these headers.
+LF not preceded by CR is treated as a line ending.
.nextp
-The second item forms the start of the warning message. After it, Exim lists
-the delayed addresses.
+CR is treated as a line ending; if it is immediately followed by LF, the LF
+is ignored.
.nextp
-The third item then ends the message.
+The sequence `CR, dot, CR' does not terminate an incoming SMTP message,
+nor a local message in the state where a line containing only a dot is a
+terminator.
+.nextp
+If a bare CR is encountered within a header line, an extra space is added after
+the line terminator so as not to end the header line. The reasoning behind this
+is that bare CRs in header lines are most likely either to be mistakes, or
+people trying to play silly games.
+.nextp
+If the first header line received in a message ends with CRLF, a subsequent
+bare LF in a header line is treated in the same way as a bare CR in a header
+line.
.endp
-The default state is equivalent to the following file, except that the line
-starting `A message' has been split here, in order to fit it on the page:
-.if ~~sys.fancy
-.display asis
-.fontgroup 0
-.font 54
-.else
-.rule
-.display asis
-.linelength 80em
-.indent 0
-.fi
-.newline
-Subject: Warning: message $message_id delayed $warn_message_delay
-****
-This message was created automatically by mail delivery software.
-
-A message ${if eq{$sender_address}{$warn_message_recipients}
- {that you sent }{sent by
- <$sender_address>
-}}has not been delivered to all of its recipients after
-more than $warn_message_delay on the queue on $primary_hostname.
-.newline
-The message identifier is: $message_id
-The subject of the message is: $h_subject
-The date of the message is: $h_date
+.section Unqualified addresses
+.index unqualified addresses
+.index address||qualification
+By default, Exim expects every envelope 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
+requirement to accept unqualified addresses from specific hosts or IP networks.
-The following address(es) have not yet been delivered:
-****
-No action is required on your part. Delivery attempts will continue for
-some time, and this warning may be repeated at intervals if the message
-remains undelivered. Eventually the mail delivery software will give up,
-and when that happens, the message will be returned to you.
-.endd
-.if !~~sys.fancy
-.rule
-.fi
-except that in the default state the subject and date lines are omitted if no
-appropriate headers exist. During the expansion of this file,
-\$warn@_message@_delay$\
-is set to the delay time in one of the forms `<<n>> minutes'
-or `<<n>> hours', and
-\$warn@_message@_recipients$\
-contains a list of recipients for the warning message. There may be more than
-one if there are multiple addresses with different \errors@_to\ settings on the
-routers that handled them.
+Exim has two options that separately control which hosts may send unqualified
+sender or receipient addresses in SMTP commands, namely
+\sender__unqualified__hosts\ and \recipient__unqualified__hosts\. In both
+cases, if an unqualified address is accepted, it is qualified by adding the
+value of \qualify__domain\ or \qualify__recipient\, as appropriate.
+.index \qualify@_domain\
+.index \qualify@_recipient\
+.em
+Unqualified addresses in header lines are automatically qualified for messages
+that are locally originated, unless the \-bnq-\ option is given on the command
+line. For messages received over SMTP, unqualified addresses in header lines
+are qualified only if unqualified addresses are permitted in SMTP commands. In
+other words, such qualification is also controlled by
+\sender__unqualified__hosts\ and \recipient__unqualified__hosts\,
+.nem
+.section The UUCP From line
+.index `From' line
+.index UUCP||`From' line
+.index sender||address
+.index \uucp@_from@_pattern\
+.index \uucp@_from@_sender\
+.index envelope sender
+.index Sendmail compatibility||`From' line
+Messages that have come from UUCP (and some other applications) often begin
+with a line containing the envelope sender and a timestamp, following the word
+`From'. Examples of two common formats are:
+.display asis
+From a.oakley@berlin.mus Fri Jan 5 12:35 GMT 1996
+From f.butler@berlin.mus Fri, 7 Jan 97 14:00:00 GMT
+.endd
+This line precedes the RFC 2822 header lines. For compatibility with Sendmail,
+Exim recognizes such lines at the start of messages that are submitted to it
+via the command line (that is, on the standard input). It does not recognize
+such lines in incoming SMTP messages, unless the sending host matches
+\ignore@_fromline@_hosts\ or the \-bs-\ option was used for a local message and
+\ignore@_fromline@_local\ is set. The recognition is controlled by a regular
+expression that is defined by the \uucp@_from@_pattern\ option, whose default
+value matches the two common cases shown above and puts the address that
+follows `From' into \$1$\.
-.
-.
-.
-. ============================================================================
-.chapter Some common configuration requirements
-.set runningfoot "common configuration requirements"
-.rset CHAPcomconreq "~~chapter"
-This chapter discusses some configuration requirements that seem to be fairly
-common. More examples and discussion can be found in the Exim book.
+.index numerical variables (\$1$\, \$2$\, etc)||in `From ' line handling
+When the caller of Exim for a non-SMTP message that contains a `From' line is a
+trusted user, the message's sender address is constructed by expanding the
+contents of \uucp@_sender@_address\, whose default value is `@$1'. This is then
+parsed as an RFC 2822 address. If there is no domain, the local part is
+qualified with \qualify@_domain\ unless it is the empty string. However, if the
+command line \-f-\ option is used, it overrides the `From' line.
+If the caller of Exim is not trusted, the `From' line is recognized, but the
+sender address is not changed. This is also the case for incoming SMTP messages
+that are permitted to contain `From' lines.
-.section Sending mail to a smart host
-.index smart host||example router
-If you want to send all mail for non-local domains to a `smart host', you
-should replace the default \%dnslookup%\ router with a router which does the
-routing explicitly:
-.display asis
-send_to_smart_host:
- driver = manualroute
- route_list = !+local_domains smart.host.name
- transport = remote_smtp
-.endd
-You can use the smart host's IP address instead of the name if you wish.
+Only one `From' line is recognized. If there is more than one, the second is
+treated as a data line that starts the body of the message, as it is not valid
+as a header line. This also happens if a `From' line is present in an incoming
+SMTP message from a source that is not permitted to send them.
-.section Using Exim to handle mailing lists
-.rset SECTmailinglists "~~chapter.~~section"
-.index mailing lists
-Exim can be used to run simple mailing lists, but for large and/or complicated
-requirements, the use of additional specialized mailing list software such as
-Majordomo or Mailman is recommended.
+.section Resent- header lines
+.index \Resent@-\ header lines
+RFC 2822 makes provision for sets of header lines starting with the string
+\"Resent-"\ to be added to a message when it is resent by the original
+recipient to somebody else. These headers are ::Resent-Date::, ::Resent-From::,
+::Resent-Sender::, ::Resent-To::, ::Resent-Cc::, ::Resent-Bcc:: and
+::Resent-Message-ID::. The RFC says:
-The \%redirect%\ router 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\ router option can be used to run these
-lists in a separate domain from normal mail. For example:
+\*Resent fields are strictly informational. They MUST NOT be used in the normal
+processing of replies or other such automatic actions on messages.*\
+
+This leaves things a bit vague as far as other processing actions such as
+address rewriting are concerned. Exim treats \Resent@-\ header lines as
+follows:
+.numberpars $.
+A ::Resent-From:: line that just contains the login id of the submitting user
+is automatically rewritten in the same way as ::From:: (see below).
+.nextp
+If there's a rewriting rule for a particular header line, it is also applied to
+\Resent@-\ header lines of the same type. For example, a rule that rewrites
+::From:: also rewrites ::Resent-From::.
+.nextp
+For local messages, if ::Sender:: is removed on input, ::Resent-Sender:: is also
+removed.
+.nextp
+For a locally-submitted message,
+if there are any \Resent@-\ header lines but no ::Resent-Date::,
+::Resent-From::, or ::Resent-Message-Id::, they are added as necessary. It is
+the contents of ::Resent-Message-Id:: (rather than ::Message-Id::) which are
+included in log lines in this case.
+.nextp
+The logic for adding ::Sender:: is duplicated for ::Resent-Sender:: when any
+\Resent@-\ header lines are present.
+.endp
+
+
+.section The Auto-Submitted: header line
+Whenever Exim generates a bounce or a delay warning message, it includes the
+header line
.display asis
-lists:
- driver = redirect
- domains = lists.example
- file = /usr/lists/$local_part
- forbid_pipe
- forbid_file
- errors_to = $local_part-request@lists.example
- no_more
+Auto-Submitted: auto-generated
.endd
-This router is skipped for domains other than \*lists.example*\. For addresses
-in that domain, it looks for a file that matches the local part. If there is no
-such file, the router declines, but because \no@_more\ is set, no subsequent
-routers are tried, and so the whole delivery fails.
-The \forbid@_pipe\ and \forbid@_file\ options prevent a local part from being
-expanded into a file name or a pipe delivery, which is usually inappropriate in
-a mailing list.
-.index \errors@_to\
-The \errors@_to\ option specifies that any 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.
+.section The Bcc: header line
+.index ::Bcc:: header line
+If Exim is called with the \-t-\ option, to take recipient addresses from a
+message's header, it removes any ::Bcc:: header line that may exist (after
+extracting its addresses). If \-t-\ is not present on the command line, any
+existing ::Bcc:: is not removed.
-For example, using the configuration above, mail sent to
-\*dicts@@lists.example*\ is passed on to those addresses contained in
-\(/usr/lists/dicts)\, with error reports directed to
-\*dicts-request@@lists.example*\, provided that this address can be verified.
-There could be a file called \(/usr/lists/dicts-request)\ containing
-the address(es) of this particular list's manager(s), but other approaches,
-such as setting up an earlier router (possibly using the \local@_part@_prefix\
-or \local@_part@_suffix\ options) to handle addresses of the form \owner-xxx\
-or \xxx-request\, are also possible.
+.section The Date: header line
+.index ::Date:: header line
+If a locally-generated
+or submission-mode
+message has no ::Date:: header line, Exim adds one, using the current date and
+time.
+.section The Delivery-date: header line
+.index ::Delivery-date:: header line
+.index \delivery@_date@_remove\
+::Delivery-date:: header lines are not part of the standard RFC 2822 header
+set. Exim can be configured to add them to the final delivery of messages. (See
+the generic \delivery@_date@_add\ transport option.) They should not be present
+in messages in transit. If the \delivery@_date@_remove\ configuration option is
+set (the default), Exim removes ::Delivery-date:: header lines from incoming
+messages.
-.section Syntax errors in mailing lists
-.index mailing lists||syntax errors in
-If an entry in redirection data contains a syntax error, Exim normally defers
-delivery of the original address. That means that a syntax error in a mailing
-list holds up all deliveries to the list. This may not be appropriate when a
-list is being maintained automatically from data supplied by users, and the
-addresses are not rigorously checked.
+.section The Envelope-to: header line
+.index ::Envelope-to:: header line
+.index \envelope@_to@_remove\
+::Envelope-to:: header lines are not part of the standard RFC 2822 header set.
+Exim can be configured to add them to the final delivery of messages. (See the
+generic \envelope@_to@_add\ transport option.) They should not be present in
+messages in transit. If the \envelope@_to@_remove\ configuration option is set
+(the default), Exim removes ::Envelope-to:: header lines from incoming
+messages.
-If the \skip@_syntax@_errors\ option is set, the \%redirect%\ router just skips
-entries that fail to parse, noting the incident in the log. If in addition
-\syntax@_errors@_to\ is set to a verifiable address, a message is sent to it
-whenever a broken address is skipped. It is usually appropriate to set
-\syntax@_errors@_to\ to the same address as \errors@_to\.
+.section The From: header line
+.rset SECTthefrohea "~~chapter.~~section"
+.index ::From:: header line
+.index Sendmail compatibility||`From' line
+.index message||submission
+.index submission mode
+If a submission-mode message does not contain a ::From:: header line, Exim adds
+one if either of the following conditions is true:
+.numberpars $.
+The envelope sender address is not empty (that is, this is not a bounce
+message). The added header line copies the envelope sender address.
+.nextp
+The SMTP session is authenticated and \$authenticated@_id$\ is not empty.
+.em
+.numberpars alpha
+If no domain is specified by the submission control, the local part is
+\$authenticated@_id$\ and the domain is \$qualify@_domain$\.
+.nextp
+If a non-empty domain is specified by the submission control, the local part is
+\$authenticated@_id$\, and the the domain is the specified domain.
+.nextp
+If an empty domain is specified by the submission control,
+\$authenticated@_id$\ is assumed to be the complete address.
+.endp
+.nem
+.endp
+A non-empty envelope sender takes precedence.
+If a locally-generated incoming message does not contain a ::From:: header
+line, Exim adds one containing the sender's address. The calling user's login
+name and full name are used to construct the address, as described in section
+~~SECTconstr. They are obtained from the password data by calling
+\*getpwuid()*\ (but see the \unknown@_login\ configuration option). The address
+is qualified with \qualify@_domain\.
-.section Re-expansion of mailing lists
-.index mailing lists||re-expansion of
-Exim remembers every individual address to which a message has been delivered,
-in order to avoid duplication, but it normally stores only the original
-recipient addresses with a message. If all the deliveries to a mailing list
-cannot be done at the first attempt, the mailing list is re-expanded when the
-delivery is next tried. This means that alterations to the list are taken into
-account at each delivery attempt, so addresses that have been added to
-the list since the message arrived will therefore receive a copy of the
-message, even though it pre-dates their subscription.
+For compatibility with Sendmail, if an incoming, non-SMTP message has a
+::From:: header line containing just the unqualified login name of the calling
+user, this is replaced by an address containing the user's login name and full
+name as described in section ~~SECTconstr.
-If this behaviour is felt to be undesirable, the \one@_time\ option can be set
-on the \%redirect%\ router. If this is done, any addresses generated by the
-router that fail to deliver at the first attempt are added to the message as
-`top level' addresses, and the parent address that generated them is marked
-`delivered'. Thus, expansion of the mailing list does not happen again at the
-subsequent delivery attempts. The disadvantage of this is that if any of the
-failing addresses are incorrect, correcting them in the file has no effect on
-pre-existing messages.
+.section The Message-ID: header line
+.index ::Message-ID:: header line
+.index message||submission
+If a locally-generated or submission-mode incoming message does not contain a
+::Message-ID:: or ::Resent-Message-ID:: header line, Exim adds one to the
+message. If there are any ::Resent-:: headers in the message, it creates
+::Resent-Message-ID::. 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 line by setting the
+.index \message@_id@_header@_text\
+\message@_id@_header@_text\ and/or \message__id__header__domain\ options.
-The original top-level address is remembered with each of the generated
-addresses, and is output in any log messages. However, any intermediate parent
-addresses are not recorded. This makes a difference to the log only if the
-\all@_parents\ selector is set, but for mailing lists there is normally only
-one level of expansion anyway.
+.section The Received: header line
+.index ::Received:: header line
+A ::Received:: header line is added at the start of every message. The contents
+are defined by the \received@_header@_text\ configuration option, and Exim
+automatically adds a semicolon and a timestamp to the configured string.
-.section Closed mailing lists
-.index mailing lists||closed
-The examples so far have assumed open mailing lists, to which anybody may
-send mail. It is also possible to set up closed lists, where mail is accepted
-from specified senders only. This is done by making use of the generic
-\senders\ option to restrict the router that handles the list.
+The ::Received:: header is generated as soon as the message's header lines have
+been received. At this stage, the timestamp in the ::Received:: header line is
+the time that the message started to be received. This is the value that is
+seen by the \\DATA\\ ACL and by the \*local@_scan()*\ function.
-The following example uses the same file as a list of recipients and as a list
-of permitted senders. It requires three routers:
-.display asis
-lists_request:
- driver = redirect
- domains = lists.example
- local_part_suffix = -request
- file = /usr/lists/$local_part$local_part_suffix
- no_more
+Once a message is accepted, the timestamp in the ::Received:: header line is
+changed to the time of acceptance, which is (apart from a small delay while the
+-H spool file is written) the earliest time at which delivery could start.
-lists_post:
- driver = redirect
- domains = lists.example
- senders = ${if exists {/usr/lists/$local_part}\
- {lsearch;/usr/lists/$local_part}{*}}
- file = /usr/lists/$local_part
- forbid_pipe
- forbid_file
- errors_to = $local_part-request@lists.example
- no_more
-lists_closed:
- driver = redirect
- domains = lists.example
- allow_fail
- data = :fail: $local_part@lists.example is a closed mailing list
-.endd
-All three routers have the same \domains\ setting, so for any other domains,
-they are all skipped. The first router runs only if the local part ends in
-\@-request\. It handles messages to the list manager(s) by means of an open
-mailing list.
+.section The Return-path: header line
+.index ::Return-path:: header line
+.index \return@_path@_remove\
+::Return-path:: header lines are defined as something an MTA may insert when
+it does the final delivery of messages. (See the generic \return@_path@_add\
+transport option.) 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:: header lines from incoming messages.
-The second router runs only if the \senders\ precondition is satisfied. It
-checks for the existence of a list that corresponds to the local part, and then
-checks that the sender is on the list by means of a linear search. It is
-necessary to check for the existence of the file before trying to search it,
-because otherwise Exim thinks there is a configuration error. If the file does
-not exist, the expansion of \senders\ is $*$, which matches all senders. This
-means that the router runs, but because there is no list, declines, and
-\no@_more\ ensures that no further routers are run. The address fails with an
-`unrouteable address' error.
-The third router runs only if the second router is skipped, which happens when
-a mailing list exists, but the sender is not on it. This router forcibly fails
-the address, giving a suitable error message.
+.section The Sender: header line
+.rset SECTthesenhea "~~chapter.~~section"
+.index ::Sender:: header line
+.index message||submission
+For a locally-originated message from an untrusted user, Exim may remove an
+existing ::Sender:: header line, and it may add a new one. You can modify these
+actions by setting \local@_sender@_retain\ true or \local@_from@_check\ false.
+When a local message is received from an untrusted user and
+\local@_from@_check\ is true (the default), a check is made to see if the
+address given in the ::From:: header line is the correct (local) sender of the
+message. The address that is expected has the login name as the local part and
+the value of \qualify@_domain\ as the domain. Prefixes and suffixes for the
+local part can be permitted by setting \local@_from@_prefix\ and
+\local@_from@_suffix\ appropriately. If ::From:: does not contain the correct
+sender, a ::Sender:: line is added to the message.
+If you set \local@_from@_check\ false, this checking does not occur. However,
+the removal of an existing ::Sender:: line still happens, unless you also set
+\local@_sender@_retain\ to be true. It is not possible to set both of these
+options true at the same time.
-.section Virtual domains
-.rset SECTvirtualdomains "~~chapter.~~section"
-.index virtual domains
-.index domain||virtual
-The phrase \*virtual domain*\ is unfortunately used with two rather different
-meanings:
-.numberpars $.
-A domain for which there are no real mailboxes; all valid local parts are
-aliases for other email addresses. Common examples are organizational
-top-level domains and `vanity' domains.
+.em
+.index submission mode
+By default, no processing of ::Sender:: header lines is done for messages
+received over TCP/IP or for messages submitted by trusted users. However, when
+a message is received over TCP/IP in submission mode, and \sender@_retain\ is
+not specified on the submission control, the following processing takes place:
+
+First, any existing ::Sender:: lines are removed. Then, if the SMTP session is
+authenticated, and \$authenticated@_id$\ is not empty, a sender address is
+created as follows:
+.numberpars $.
+If no domain is specified by the submission control, the local part is
+\$authenticated@_id$\ and the domain is \$qualify@_domain$\.
.nextp
-One of a number of independent domains that are all handled by the same host,
-with mailboxes on that host, but where the mailbox owners do not necessarily
-have login accounts on that host.
+If a non-empty domain is specified by the submission control, the local part is
+\$authenticated@_id$\, and the the domain is the specified domain.
+.nextp
+If an empty domain is specified by the submission control,
+\$authenticated@_id$\ is assumed to be the complete address.
.endp
-The first usage is probably more common, and does seem more `virtual' than the
-second. This kind of domain can be handled in Exim with a straightforward
-aliasing router. One approach is to create a separate alias file for each
-virtual domain. Exim can test for the existence of the alias file to determine
-whether the domain exists. The \%dsearch%\ lookup type is useful here, leading
-to a router of this form:
-.display asis
-virtual:
- driver = redirect
- domains = dsearch;/etc/mail/virtual
- data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
- no_more
-.endd
-The \domains\ option specifies that the router is to be skipped, unless there
-is a file in the \(/etc/mail/virtual)\ directory whose name is the same as the
-domain that is being processed. When the router runs, it looks up the local
-part in the file to find a new address (or list of addresses). The \no@_more\
-setting ensures that if the lookup fails (leading to \data\ being an empty
-string), Exim gives up on the address without trying any subsequent routers.
-
-This one router can handle all the virtual domains because the alias file names
-follow a fixed pattern. Permissions can be arranged so that appropriate people
-can edit the different alias files. A successful aliasing operation results in
-a new envelope recipient address, which is then routed from scratch.
+This address is compared with the address in the ::From:: header line. If they
+are different, a ::Sender:: header line containing the created address is
+added. Prefixes and suffixes for the local part in ::From:: can be permitted by
+setting \local@_from@_prefix\ and \local@_from@_suffix\ appropriately.
+.nem
-The other kind of `virtual' domain can also be handled in a straightforward
-way. One approach is to create a file for each domain containing a list of
-valid local parts, and use it in a router like this:
-.display asis
-my_domains:
- driver = accept
- domains = dsearch;/etc/mail/domains
- local_parts = lsearch;/etc/mail/domains/$domain
- transport = my_mailboxes
-.endd
-The address is accepted if there is a file for the domain, and the local part
-can be found in the file. The \domains\ option is used to check for the file's
-existence because \domains\ is tested before the \local@_parts\ option (see
-section ~~SECTrouprecon). You can't use \require@_files\, because that option
-is tested after \local@_parts\. The transport is as follows:
-.display asis
-my_mailboxes:
- driver = appendfile
- file = /var/mail/$domain/$local_part
- user = mail
-.endd
-This uses a directory of mailboxes for each domain. The \user\ setting is
-required, to specify which uid is to be used for writing to the mailboxes.
-The configuration shown here is just one example of how you might support this
-requirement. There are many other ways this kind of configuration can be set
-up, for example, by using a database instead of separate files to hold all the
-information about the domains.
+.section Adding and removing header lines in routers and transports
+.index header lines||adding, in router or transport
+.index header lines||removing, in router or transport
+.rset SECTheadersaddrem "~~chapter.~~section"
+.em
+When a message is delivered, the addition and removal of header lines can be
+specified in a system filter, or on any of the routers and transports that
+process the message. Section ~~SECTaddremheasys contains details about
+modifying headers in a system filter.
+In contrast to what happens in a system filter, header modifications that are
+specified on routers and transports apply only to the particular recipient
+addresses that are being processed by those routers and transports. These
+changes do not actually take place until a copy of the message is being
+transported. Therefore, they do not affect the basic set of header lines, and
+they do not affect the values of the variables that refer to header lines.
-.section Multiple user mailboxes
-.rset SECTmulbox "~~chapter.~~section"
-.index multiple mailboxes
-.index mailbox||multiple
-.index local part||prefix
-.index local part||suffix
-Heavy email users often want to operate with multiple mailboxes, into which
-incoming mail is automatically sorted. A popular way of handling this is to
-allow users to use multiple sender addresses, so that replies can easily be
-identified. Users are permitted to add prefixes or suffixes to their local
-parts for this purpose. The wildcard facility of the generic router options
-\local@_part@_prefix\ and \local@_part@_suffix\ can be used for this. For
-example, consider this router:
+For both routers and transports, the result of expanding a \headers@_add\
+option must be in the form of one or more RFC 2822 header lines, separated by
+newlines (coded as `@\n'). For example:
.display asis
-userforward:
- driver = redirect
- check_local_user
- file = $home/.forward
- local_part_suffix = -*
- local_part_suffix_optional
- allow_filter
-.endd
-It 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:
-.display asis
-if $local_part_suffix contains -special then
- save /home/$local_part/Mail/special
-endif
+headers_add = X-added-header: added by $primary_hostname\n\
+ X-added-second: another added header line
.endd
-If the filter file does not exist, or does not deal with such addresses, they
-fall through to subsequent routers, and, assuming no subsequent use of the
-\local@_part@_suffix\ option is made, they presumably fail. Thus, users have
-control over which suffixes are valid.
+Exim does not check the syntax of these added header lines.
-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:
+The result of expanding \headers@_remove\ must consist of a colon-separated
+list of header names. This is confusing, because header names themselves are
+often terminated by colons. In this case, the colons are the list separators,
+not part of the names. For example:
.display asis
-userforward:
- driver = redirect
- check_local_user
- file = $home/.forward$local_part_suffix
- local_part_suffix = -*
- local_part_suffix_optional
- allow_filter
+headers_remove = return-receipt-to:acknowledge-to
.endd
-If there is no suffix, \(.forward)\ is used; if the suffix is \*-special*\, for
-example, \(.forward-special)\ is used. Once again, if the appropriate file
-does not exist, or does not deal with the address, it is passed on to
-subsequent routers, which could, if required, look for an unqualified
-\(.forward)\ file to use as a default.
-
-.section Simplified vacation processing
-.index vacation processing
-The traditional way of running the \*vacation*\ program is for a user to set up
-a pipe command in a \(.forward)\ file
-(see section ~~SECTspecitredli for syntax details).
-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:
+When \headers@_add\ or \headers@_remove\ is specified on a router, its value is
+expanded at routing time, and then associated with all addresses that are
+accepted by that router, and also with any new addresses that it generates. If
+an address passes through several routers as a result of aliasing or
+forwarding, the changes are cumulative.
+.index \unseen\ option
+However, this does not apply to multiple routers that result from the use of
+the \unseen\ option. Any header modifications that were specified by the
+`unseen' router or its predecessors apply only to the `unseen' delivery.
+
+Addresses that end up with different \headers@_add\ or \headers@_remove\
+settings cannot be delivered together in a batch, so a transport is always
+dealing with a set of addresses that have the same header-processing
+requirements.
+
+The transport starts by writing the original set of header lines that arrived
+with the message, possibly modified by the system filter. As it writes out
+these lines, it consults the list of header names that were attached to the
+recipient address(es) by \headers@_remove\ options in routers, and it also
+consults the transport's own \headers@_remove\ option. Header lines whose names
+are on either of these lists are not written out. If there are multiple
+instances of any listed header, they are all skipped.
+
+After the remaining original header lines have been written, new header
+lines that were specified by routers' \headers@_add\ options are written, in
+the order in which they were attached to the address. These are followed by any
+header lines specified by the transport's \headers@_add\ option.
+
+This way of handling header line modifications in routers and transports has
+the following consequences:
.numberpars $.
-A local part prefix such as `vacation-' can be specified on a router which
-can cause the message to be delivered directly to the \*vacation*\ program, or
-alternatively can use Exim's \%autoreply%\ transport. The contents of a user's
-\(.forward)\ file are then much simpler. For example:
+The original set of header lines, possibly modified by the system filter,
+remains `visible', in the sense that the \$header@_$\\*xxx*\ variables refer to
+it, at all times.
+.nextp
+Header lines that are added by a router's
+\headers@_add\ option are not accessible by means of the \$header@_$\\*xxx*\
+expansion syntax in subsequent routers or the transport.
+.nextp
+Conversely, header lines that are specified for removal by \headers@_remove\ in
+a router remain visible to subsequent routers and the transport.
+.nextp
+Headers added to an address by \headers@_add\ in a router cannot be removed by
+a later router or by a transport.
+.nextp
+An added header can refer to the contents of an original header that is to be
+removed, even it has the same name as the added header. For example:
.display asis
-spqr, vacation-spqr
+headers_remove = subject
+headers_add = Subject: new subject (was: $h_subject:)
.endd
-.nextp
-The \require@_files\ generic router 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.
.endp
-Another advantage of both these methods is that they both work even when the
-use of arbitrary pipes by users is locked out.
+\**Warning**\: The \headers@_add\ and \headers@_remove\ options cannot be used
+for a \%redirect%\ router that has the \one@_time\ option set.
+.nem
-.section Taking copies of mail
-.index message||copying every
-Some installations have policies that require archive copies of all messages to
-be made. A single copy of each message can easily be taken by an appropriate
-command in a system filter, which could, for example, use a different file for
-each day's messages.
-
-There is also a shadow transport mechanism that can be used to take copies of
-messages that are successfully delivered by local transports, one copy per
-delivery. This could be used, $it{inter alia}, to implement automatic
-notification of delivery by sites that insist on doing such things.
-.section Intermittently connected hosts
-.index intermittently connected hosts
-It has become 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.
+.section Constructed addresses
+.rset SECTconstr "~~chapter.~~section"
+.index address||constructed
+.index constructed address
+When Exim constructs a sender address for a locally-generated message, it uses
+the form
+.display
+<<user name>> <$$<<login>>@@<<qualify@_domain>>$$>
+.endd
+For example:
+.display asis
+Zaphod Beeblebrox <zaphod@end.univ.example>
+.endd
+The user name is obtained from the \-F-\ command line option if set, or
+otherwise by looking up the calling user by \*getpwuid()*\ and extracting 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
+upper cased, 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.
-Exim was designed for use on permanently connected hosts, and so it is not
-particularly well-suited to use in an intermittently connected environment.
-Nevertheless there are some features that can be used.
+In all cases, the user name is made to conform to RFC 2822 by quoting all or
+parts of it if necessary. In addition, if it contains any non-printing
+characters, it is encoded as described in RFC 2047, which defines a way of
+including non-ASCII characters in header lines.
+The value of the \headers@_charset\ option specifies the name of the encoding
+that is used (the characters are assumed to be in this encoding).
+The setting of \print@_topbitchars\ controls whether characters with the top
+bit set (that is, with codes greater than 127) count as printing characters or
+not.
-.section Exim on the upstream server host
-It is tempting to arrange for incoming mail for the intermittently connected
-host to remain on Exim's queue until the client connects. However, this
-approach does not scale very well. Two different kinds of waiting message are
-being mixed up in the same queue -- those that cannot be delivered because of
-some temporary problem, and those that are waiting for their destination host
-to connect. This makes it hard to manage the queue, as well as wasting
-resources, because each queue runner scans the entire queue.
-A better approach is to separate off those messages that are waiting for an
-intermittently connected host. This can be done by delivering these messages
-into local files in batch SMTP, `mailstore', or other envelope-preserving
-format, from where they are transmitted by other software when their
-destination connects. This makes it easy to collect all the mail for one host
-in a single directory, and to apply local timeout rules on a per-message basis
-if required.
+.section Case of local parts
+.index case of local parts
+.index local part||case of
+RFC 2822 states that the case of letters in the local parts of addresses cannot
+be assumed to be non-significant. Exim preserves the case of local parts of
+addresses, but by default it uses a lower-cased form when it is routing,
+because on most Unix systems, usernames are in lower case and case-insensitive
+routing is required. However, any particular router can be made to use the
+original case for local parts by setting the \caseful@_local@_part\ generic
+router option.
-On a very small scale, leaving the mail on Exim's queue can be made to work. If
-you are doing this, you should configure Exim with a long retry period for the
-intermittent host. For example:
-.display
-cheshire.wonderland.fict.example * F,5d,24h
+.index mixed-case login names
+If you must have mixed-case user names on your system, the best way to proceed,
+assuming you want case-independent handling of incoming email, is to set up
+your first router to convert incoming local parts in your domains to the
+correct case by means of a file lookup. For example:
+.display asis
+correct_case:
+ driver = redirect
+ domains = +local_domains
+ data = ${lookup{$local_part}cdb\
+ {/etc/usercased.cdb}{$value}fail}\
+ @$domain
.endd
-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 section ~~SECTETRN)
-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.
+For this router, the local part is forced to lower case by the default action
+(\caseful@_local@_part\ is not set). The lower-cased local part is used to look
+up a new local part in the correct case. If you then set \caseful@_local@_part\
+on any subsequent routers which process your domains, they will operate on
+local parts with the correct case in a case-sensitive manner.
-If the connecting hosts do not have fixed IP addresses, that is, if a host is
-issued with a different IP address each time it connects, Exim's retry
-mechanisms on the holding host get confused, because the IP address is normally
-used as part of the key string for holding retry information. This can be
-avoided by unsetting \retry__include__ip__address\ on the \%smtp%\ transport.
-Since this has disadvantages for permanently connected hosts, it is best to
-arrange a separate transport for the intermittently connected ones.
+.section Dots in local parts
+.index dot||in local part
+.index local part||dots in
+RFC 2822 forbids empty components in local parts. That is, an unquoted local
+part may not begin or end with a dot, nor have two consecutive dots in the
+middle. However, it seems that many MTAs do not enforce this, so Exim permits
+empty components for compatibility.
-.section Exim on the intermittently connected client host
-The value of \smtp@_accept@_queue@_per@_connection\ should probably be
-increased, or even set to zero (that is, disabled) on the intermittently
-connected host, so that all incoming messages down a single connection get
-delivered immediately.
-
-.index SMTP||passed connection
-.index SMTP||multiple deliveries
-.index multiple SMTP deliveries
-Mail waiting to be sent from an intermittently connected host will probably
-not have been routed, because without a connection DNS lookups are not
-possible. This means that if a normal queue run is done at connection time,
-each message is likely to be sent in a separate SMTP session. This can be
-avoided by starting the queue run with a command line option beginning with
-\-qq-\ instead of \-q-\. In this case, the queue is scanned twice. In the first
-pass, routing is done but no deliveries take place. The second pass is a normal
-queue run; since all the messages have been previously routed, those destined
-for the same host are likely to get sent as multiple deliveries in a single
-SMTP connection.
+.section Rewriting addresses
+.index 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 ~~CHAPrewrite. The headers that may be affected by this are ::Bcc::,
+::Cc::, ::From::, ::Reply-To::, ::Sender::, and ::To::.
+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
+.display asis
+To: hare@teaparty
+.endd
+might get rewritten as
+.display asis
+To: hare@teaparty.wonderland.fict.example
+.endd
+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 $it{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.
.
-
.
.
.
.
. ============================================================================
-.chapter Message processing
-.set runningfoot "message processing"
-.rset CHAPmsgproc "~~chapter"
-.index message||general processing
-Exim performs various transformations on the sender and recipient addresses of
-all 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, and the addition or
-removal of header lines while delivering, happens when a message is received,
-before it is placed on Exim's queue.
-
-Some of the automatic processing takes place
-by default
-only for `locally-originated' messages. This adjective is used to describe
-messages that are not received over TCP/IP, but instead are passed to an Exim
-process on its standard input. This includes the interactive `local SMTP' case
-that is set up by the \-bs-\ command line option. \**Note**\: messages received
-over TCP/IP on the loopback interface (127.0.0.1 or @:@:1) are not considered
-to be locally-originated. Exim does not treat the loopback interface specially
-in any way.
-
-
-.section Submission mode for non-local messages
-.rset SECTsubmodnon "~~chapter.~~section"
-
-.index message||submission
-Processing that happens automatically for locally-originated messages can also
-be requested for other messages. This is done by obeying the modifier
-.display asis
-control = submission
-.endd
-in one of the ACLs that are run for an incoming message (see section
-~~SECTACLmodi). This makes Exim treat the message as a local submission, and is
-normally used when the source of the message is known to be an MUA running on a
-client host (as opposed to an MTA). In the descriptions below, the term
-`submission mode' is used to describe this state.
+.chapter Customizing bounce and warning messages
+.set runningfoot "customizing messages"
+.rset CHAPemsgcust "~~chapter"
+When a message fails to be delivered, or remains on the queue for more than a
+configured amount of time, Exim sends a message to the original sender, or
+to an alternative configured address. The text of these messages is built into
+the code of Exim, but it is possible to change it, either by adding a single
+string, or by replacing each of the paragraphs by text supplied in a file.
-When a ::From:: or ::Sender:: header is generated in submission mode, the value
-of \qualify@_domain\ is used by default. However, it is possible to specify
-another domain by a setting such as
+The ::From:: and ::To:: header lines are automatically generated; you can cause
+a ::Reply-To:: line to be added by setting the \errors@_reply@_to\ option. Exim
+also adds the line
.display asis
-control = submission/domain=some.other.domain
+Auto-Submitted: auto-generated
.endd
+to all warning and bounce messages,
+.section Customizing bounce messages
+.index customizing||bounce message
+.index bounce message||customizing
+If \bounce@_message@_text\ is set, its contents are included in the default
+message immediately after `This message was created automatically by mail
+delivery software.' The string is not expanded. It is not used if
+\bounce@_message@_file\ is set.
+When \bounce@_message@_file\ is set, it must point to a template file for
+constructing error messages. The file consists of a series of text items,
+separated by lines consisting of exactly four asterisks. If the file cannot be
+opened, default text is used and a message is written to the main and panic
+logs. If any text item in the file is empty, default text is used for that
+item.
-.section Line endings
-.rset SECTlineendings "~~chapter.~~section"
-.index line endings
-.index carriage return
-.index linefeed
-RFC 2821 specifies that CRLF (two characters: carriage-return, followed by
-linefeed) is the line ending for messages transmitted over the Internet using
-SMTP over TCP/IP. However, within individual operating systems, different
-conventions are used. For example, Unix-like systems use just LF, but others
-use CRLF or just CR.
+Each item of text that is read from the file is expanded, and there are two
+expansion variables which can be of use here: \$bounce@_recipient$\ is set to
+the recipient of an error message while it is being created, and
+\$return@_size@_limit$\ contains the value of the \return@_size@_limit\ option,
+rounded to a whole number.
-Exim was designed for Unix-like systems, and internally, it stores messages
-using the system's convention of a single LF as a line terminator. When
-receiving a message, all line endings are translated to this standard format.
-Originally, it was thought that programs that passed messages directly to an
-MTA within an operating system would use that system's convention. Experience
-has shown that this is not the case; for example, there are Unix applications
-that use CRLF in this circumstance. For this reason, and for compatibility with
-other MTAs, the way Exim handles line endings for all messages is now as
-follows:
+The items must appear in the file in the following order:
.numberpars $.
-LF not preceded by CR is treated as a line ending.
+The first item is included in the headers, and should include at least a
+::Subject:: header. Exim does not check the syntax of these headers.
.nextp
-CR is treated as a line ending; if it is immediately followed by LF, the LF
-is ignored.
+The second item forms the start of the error message. After it, Exim lists the
+failing addresses with their error messages.
.nextp
-The sequence `CR, dot, CR' does not terminate an incoming SMTP message,
-nor a local message in the state where a line containing only a dot is a
-terminator.
+The third item is used to introduce any text from pipe transports that is to be
+returned to the sender. It is omitted if there is no such text.
.nextp
-If a bare CR is encountered within a header line, an extra space is added after
-the line terminator so as not to end the header line. The reasoning behind this
-is that bare CRs in header lines are most likely either to be mistakes, or
-people trying to play silly games.
+The fourth item is used to introduce the copy of the message that is returned
+as part of the error report.
.nextp
-If the first header line received in a message ends with CRLF, a subsequent
-bare LF in a header line is treated in the same way as a bare CR in a header
-line.
+The fifth item is added after the fourth one if the returned message is
+truncated because it is bigger than \return@_size@_limit\.
+.nextp
+The sixth item is added after the copy of the original message.
.endp
+The default state (\bounce@_message@_file\ unset) is equivalent to the
+following file, in which the sixth item is empty. The ::Subject:: line has been
+split into two here in order to fit it on the page:
+.if ~~sys.fancy
+.display flow asis
+.fontgroup 0
+.font 54
+.else
+.rule
+.display flow asis
+.linelength 80em
+.indent 0
+.fi
+Subject: Mail delivery failed
+ ${if eq{$sender_address}{$bounce_recipient}{: returning message to sender}}
+****
+This message was created automatically by mail delivery software.
+A message ${if eq{$sender_address}{$bounce_recipient}{that you sent }{sent by
+ <$sender_address>
-.section Unqualified addresses
-.index unqualified addresses
-.index address||qualification
-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 requirement to
-accept unqualified addresses from specific hosts or IP networks.
+}}could not be delivered to all of its recipients.
+The following address(es) failed:
+****
+The following text was generated during the delivery attempt(s):
+****
+------ This is a copy of the message, including all the headers. ------
+****
+------ The body of the message is $message_size characters long; only the first
+------ $return_size_limit or so are included here.
+****
+.endd
+.if !~~sys.fancy
+.rule
+.fi
-Exim has two options that separately control which hosts may send unqualified
-sender or receipient addresses in SMTP commands, namely
-\sender__unqualified__hosts\ and \recipient__unqualified__hosts\. In both
-cases, if an unqualified address is accepted, it is qualified by adding the
-value of \qualify__domain\ or \qualify__recipient\, as appropriate.
-.index \qualify@_domain\
-.index \qualify@_recipient\
+.section Customizing warning messages
+.rset SECTcustwarn "~~chapter.~~section"
+.index customizing||warning message
+.index warning of delay||customizing the message
+The option
+\warn@_message@_file\
+can be pointed at a template file for use when
+warnings about message delays are created. In this case there are only three
+text sections:
+.numberpars $.
+The first item is included in the headers, and should include at least a
+::Subject:: header. Exim does not check the syntax of these headers.
+.nextp
+The second item forms the start of the warning message. After it, Exim lists
+the delayed addresses.
+.nextp
+The third item then ends the message.
+.endp
+The default state is equivalent to the following file, except that the line
+starting `A message' has been split here, in order to fit it on the page:
+.if ~~sys.fancy
+.display asis
+.fontgroup 0
+.font 54
+.else
+.rule
+.display asis
+.linelength 80em
+.indent 0
+.fi
+.newline
+Subject: Warning: message $message_id delayed $warn_message_delay
+****
+This message was created automatically by mail delivery software.
+A message ${if eq{$sender_address}{$warn_message_recipients}
+ {that you sent }{sent by
-.section The UUCP From line
-.index `From' line
-.index UUCP||`From' line
-.index sender||address
-.index \uucp@_from@_pattern\
-.index \uucp@_from@_sender\
-.index envelope sender
-.index Sendmail compatibility||`From' line
-Messages that have come from UUCP (and some other applications) often begin
-with a line containing the envelope sender and a timestamp, following the word
-`From'. Examples of two common formats are:
-.display asis
-From a.oakley@berlin.mus Fri Jan 5 12:35 GMT 1996
-From f.butler@berlin.mus Fri, 7 Jan 97 14:00:00 GMT
-.endd
-This line precedes the RFC 2822 header lines. For compatibility with Sendmail,
-Exim recognizes such lines at the start of messages that are submitted to it
-via the command line (that is, on the standard input). It does not recognize
-such lines in incoming SMTP messages, unless the sending host matches
-\ignore@_fromline@_hosts\ or the \-bs-\ option was used for a local message and
-\ignore@_fromline@_local\ is set. The recognition is controlled by a regular
-expression that is defined by the \uucp@_from@_pattern\ option, whose default
-value matches the two common cases shown above and puts the address that
-follows `From' into \$1$\.
+ <$sender_address>
-.index numerical variables (\$1$\, \$2$\, etc)||in `From ' line handling
-When the caller of Exim for a non-SMTP message that contains a `From' line is a
-trusted user, the message's sender address is constructed by expanding the
-contents of \uucp@_sender@_address\, whose default value is `@$1'. This is then
-parsed as an RFC 2822 address. If there is no domain, the local part is
-qualified with \qualify@_domain\ unless it is the empty string. However, if the
-command line \-f-\ option is used, it overrides the `From' line.
+}}has not been delivered to all of its recipients after
+more than $warn_message_delay on the queue on $primary_hostname.
+.newline
-If the caller of Exim is not trusted, the `From' line is recognized, but the
-sender address is not changed. This is also the case for incoming SMTP messages
-that are permitted to contain `From' lines.
+The message identifier is: $message_id
+The subject of the message is: $h_subject
+The date of the message is: $h_date
-Only one `From' line is recognized. If there is more than one, the second is
-treated as a data line that starts the body of the message, as it is not valid
-as a header line. This also happens if a `From' line is present in an incoming
-SMTP message from a source that is not permitted to send them.
+The following address(es) have not yet been delivered:
+****
+No action is required on your part. Delivery attempts will continue for
+some time, and this warning may be repeated at intervals if the message
+remains undelivered. Eventually the mail delivery software will give up,
+and when that happens, the message will be returned to you.
+.endd
+.if !~~sys.fancy
+.rule
+.fi
+except that in the default state the subject and date lines are omitted if no
+appropriate headers exist. During the expansion of this file,
+\$warn@_message@_delay$\
+is set to the delay time in one of the forms `<<n>> minutes'
+or `<<n>> hours', and
+\$warn@_message@_recipients$\
+contains a list of recipients for the warning message. There may be more than
+one if there are multiple addresses with different \errors@_to\ settings on the
+routers that handled them.
-.section Resent- header lines
-.index \Resent@-\ header lines
-RFC 2822 makes provision for sets of header lines starting with the string
-\"Resent-"\ to be added to a message when it is resent by the original
-recipient to somebody else. These headers are ::Resent-Date::, ::Resent-From::,
-::Resent-Sender::, ::Resent-To::, ::Resent-Cc::, ::Resent-Bcc:: and
-::Resent-Message-ID::. The RFC says:
-\*Resent fields are strictly informational. They MUST NOT be used in the normal
-processing of replies or other such automatic actions on messages.*\
-This leaves things a bit vague as far as other processing actions such as
-address rewriting are concerned. Exim treats \Resent@-\ header lines as
-follows:
-.numberpars $.
-A ::Resent-From:: line that just contains the login id of the submitting user
-is automatically rewritten in the same way as ::From:: (see below).
-.nextp
-If there's a rewriting rule for a particular header line, it is also applied to
-\Resent@-\ header lines of the same type. For example, a rule that rewrites
-::From:: also rewrites ::Resent-From::.
-.nextp
-For local messages, if ::Sender:: is removed on input, ::Resent-Sender:: is also
-removed.
-.nextp
-For a locally-submitted message,
-if there are any \Resent@-\ header lines but no ::Resent-Date::,
-::Resent-From::, or ::Resent-Message-Id::, they are added as necessary. It is
-the contents of ::Resent-Message-Id:: (rather than ::Message-Id::) which are
-included in log lines in this case.
-.nextp
-The logic for adding ::Sender:: is duplicated for ::Resent-Sender:: when any
-\Resent@-\ header lines are present.
-.endp
+.
+.
+.
+. ============================================================================
+.chapter Some common configuration requirements
+.set runningfoot "common configuration requirements"
+.rset CHAPcomconreq "~~chapter"
+This chapter discusses some configuration requirements that seem to be fairly
+common. More examples and discussion can be found in the Exim book.
-.section The Auto-Submitted: header line
-Whenever Exim generates a bounce or a delay warning message, it includes the
-header line
+.section Sending mail to a smart host
+.index smart host||example router
+If you want to send all mail for non-local domains to a `smart host', you
+should replace the default \%dnslookup%\ router with a router which does the
+routing explicitly:
.display asis
-Auto-Submitted: auto-generated
+send_to_smart_host:
+ driver = manualroute
+ route_list = !+local_domains smart.host.name
+ transport = remote_smtp
.endd
+You can use the smart host's IP address instead of the name if you wish.
+.em
+If you are using Exim only to submit messages to a smart host, and not for
+receiving incoming messages, you can arrange for it to do the submission
+synchronously by setting the \mua@_wrapper\ option (see chapter
+~~CHAPnonqueueing).
+.nem
-.section The Bcc: header line
-.index ::Bcc:: header line
-If Exim is called with the \-t-\ option, to take recipient addresses from a
-message's header, it removes any ::Bcc:: header line that may exist (after
-extracting its addresses). If \-t-\ is not present on the command line, any
-existing ::Bcc:: is not removed.
+.section Using Exim to handle mailing lists
+.rset SECTmailinglists "~~chapter.~~section"
+.index mailing lists
+Exim can be used to run simple mailing lists, but for large and/or complicated
+requirements, the use of additional specialized mailing list software such as
+Majordomo or Mailman is recommended.
-.section The Date: header line
-.index ::Date:: header line
-If a locally-generated
-or submission-mode
-message has no ::Date:: header line, Exim adds one, using the current date and
-time.
+The \%redirect%\ router 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\ router option can be used to run these
+lists in a separate domain from normal mail. For example:
+.display asis
+lists:
+ driver = redirect
+ domains = lists.example
+ file = /usr/lists/$local_part
+ forbid_pipe
+ forbid_file
+ errors_to = $local_part-request@lists.example
+ no_more
+.endd
+This router is skipped for domains other than \*lists.example*\. For addresses
+in that domain, it looks for a file that matches the local part. If there is no
+such file, the router declines, but because \no@_more\ is set, no subsequent
+routers are tried, and so the whole delivery fails.
-.section The Delivery-date: header line
-.index ::Delivery-date:: header line
-.index \delivery@_date@_remove\
-::Delivery-date:: header lines are not part of the standard RFC 2822 header
-set. Exim can be configured to add them to the final delivery of messages. (See
-the generic \delivery@_date@_add\ transport option.) They should not be present
-in messages in transit. If the \delivery@_date@_remove\ configuration option is
-set (the default), Exim removes ::Delivery-date:: header lines from incoming
-messages.
+The \forbid@_pipe\ and \forbid@_file\ options prevent a local part from being
+expanded into a file name or a pipe delivery, which is usually inappropriate in
+a mailing list.
-.section The Envelope-to: header line
-.index ::Envelope-to:: header line
-.index \envelope@_to@_remove\
-::Envelope-to:: header lines are not part of the standard RFC 2822 header set.
-Exim can be configured to add them to the final delivery of messages. (See the
-generic \envelope@_to@_add\ transport option.) They should not be present in
-messages in transit. If the \envelope@_to@_remove\ configuration option is set
-(the default), Exim removes ::Envelope-to:: header lines from incoming
-messages.
+.index \errors@_to\
+The \errors@_to\ option specifies that any 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.
-.section The From: header line
-.index ::From:: header line
-.index Sendmail compatibility||`From' line
-If a submission-mode message does not contain a ::From:: header line, Exim adds
-one if either of the following conditions is true:
-.numberpars alpha
-The envelope sender address is not empty (that is, this is not a bounce
-message); the added header line copies the envelope sender address.
-.nextp
-The SMTP session is authenticated and \$authenticated@_id$\ is not empty; the
-added header's local part is \$authenticated@_id$\ and the domain is
-the domain specified on the submission control, or \$qualify@_domain$\ if that
-is not set.
-.endp
-A non-empty envelope sender takes precedence.
+For example, using the configuration above, mail sent to
+\*dicts@@lists.example*\ is passed on to those addresses contained in
+\(/usr/lists/dicts)\, with error reports directed to
+\*dicts-request@@lists.example*\, provided that this address can be verified.
+There could be a file called \(/usr/lists/dicts-request)\ containing
+the address(es) of this particular list's manager(s), but other approaches,
+such as setting up an earlier router (possibly using the \local@_part@_prefix\
+or \local@_part@_suffix\ options) to handle addresses of the form \owner-xxx\
+or \xxx-request\, are also possible.
-If a locally-generated incoming message does not contain a ::From:: header
-line, Exim adds one containing the sender's address. The calling user's login
-name and full name are used to construct the address, as described in section
-~~SECTconstr. They are obtained from the password data by calling
-\*getpwuid()*\ (but see the \unknown@_login\ configuration option). The address
-is qualified with \qualify@_domain\.
-For compatibility with Sendmail, if an incoming, non-SMTP message has a
-::From:: header line containing just the unqualified login name of the calling
-user, this is replaced by an address containing the user's login name and full
-name as described in section ~~SECTconstr.
+.section Syntax errors in mailing lists
+.index mailing lists||syntax errors in
+If an entry in redirection data contains a syntax error, Exim normally defers
+delivery of the original address. That means that a syntax error in a mailing
+list holds up all deliveries to the list. This may not be appropriate when a
+list is being maintained automatically from data supplied by users, and the
+addresses are not rigorously checked.
-.section The Message-ID: header line
-.index ::Message-ID:: header line
-If a locally-generated
-or submission-mode
-incoming message does not contain a ::Message-ID:: or ::Resent-Message-ID::
-header line, Exim adds one to the message. If there are any ::Resent-:: headers
-in the message, it creates ::Resent-Message-ID::. 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 line by setting the
-.index \message@_id@_header@_text\
-\message@_id@_header@_text\ and/or \message__id__header__domain\ options.
+If the \skip@_syntax@_errors\ option is set, the \%redirect%\ router just skips
+entries that fail to parse, noting the incident in the log. If in addition
+\syntax@_errors@_to\ is set to a verifiable address, a message is sent to it
+whenever a broken address is skipped. It is usually appropriate to set
+\syntax@_errors@_to\ to the same address as \errors@_to\.
-.section The Received: header line
-.index ::Received:: header line
-A ::Received:: header line is added at the start of every message. The contents
-are defined by the \received@_header@_text\ configuration option, and Exim
-automatically adds a semicolon and a timestamp to the configured string.
+.section Re-expansion of mailing lists
+.index mailing lists||re-expansion of
+Exim remembers every individual address to which a message has been delivered,
+in order to avoid duplication, but it normally stores only the original
+recipient addresses with a message. If all the deliveries to a mailing list
+cannot be done at the first attempt, the mailing list is re-expanded when the
+delivery is next tried. This means that alterations to the list are taken into
+account at each delivery attempt, so addresses that have been added to
+the list since the message arrived will therefore receive a copy of the
+message, even though it pre-dates their subscription.
-The ::Received:: header is generated as soon as the message's header lines have
-been received. At this stage, the timestamp in the ::Received:: header line is
-the time that the message started to be received. This is the value that is
-seen by the \\DATA\\ ACL and by the \*local@_scan()*\ function.
+If this behaviour is felt to be undesirable, the \one@_time\ option can be set
+on the \%redirect%\ router. If this is done, any addresses generated by the
+router that fail to deliver at the first attempt are added to the message as
+`top level' addresses, and the parent address that generated them is marked
+`delivered'. Thus, expansion of the mailing list does not happen again at the
+subsequent delivery attempts. The disadvantage of this is that if any of the
+failing addresses are incorrect, correcting them in the file has no effect on
+pre-existing messages.
-Once a message is accepted, the timestamp in the ::Received:: header line is
-changed to the time of acceptance, which is (apart from a small delay while the
--H spool file is written) the earliest time at which delivery could start.
+The original top-level address is remembered with each of the generated
+addresses, and is output in any log messages. However, any intermediate parent
+addresses are not recorded. This makes a difference to the log only if the
+\all@_parents\ selector is set, but for mailing lists there is normally only
+one level of expansion anyway.
-.section The Return-path: header line
-.index ::Return-path:: header line
-.index \return@_path@_remove\
-::Return-path:: header lines are defined as something an MTA may insert when
-it does the final delivery of messages. (See the generic \return@_path@_add\
-transport option.) 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:: header lines from incoming messages.
+.section Closed mailing lists
+.index mailing lists||closed
+The examples so far have assumed open mailing lists, to which anybody may
+send mail. It is also possible to set up closed lists, where mail is accepted
+from specified senders only. This is done by making use of the generic
+\senders\ option to restrict the router that handles the list.
+The following example uses the same file as a list of recipients and as a list
+of permitted senders. It requires three routers:
+.display asis
+lists_request:
+ driver = redirect
+ domains = lists.example
+ local_part_suffix = -request
+ file = /usr/lists/$local_part$local_part_suffix
+ no_more
-.section The Sender: header line
-.rset SECTthesenhea "~~chapter.~~section"
-.index ::Sender:: header line
-For a locally-originated message from an untrusted user, Exim may remove an
-existing ::Sender:: header line, and it may add a new one. You can modify these
-actions by setting \local@_sender@_retain\ true or \local@_from@_check\ false.
+lists_post:
+ driver = redirect
+ domains = lists.example
+ senders = ${if exists {/usr/lists/$local_part}\
+ {lsearch;/usr/lists/$local_part}{*}}
+ file = /usr/lists/$local_part
+ forbid_pipe
+ forbid_file
+ errors_to = $local_part-request@lists.example
+ no_more
-When a local message is received from an untrusted user and
-\local@_from@_check\ is true (the default), a check is made to see if the
-address given in the ::From:: header line is the correct (local) sender of the
-message. The address that is expected has the login name as the local part and
-the value of \qualify@_domain\ as the domain. Prefixes and suffixes for the
-local part can be permitted by setting \local@_from@_prefix\ and
-\local@_from@_suffix\ appropriately. If ::From:: does not contain the correct
-sender, a ::Sender:: line is added to the message.
+lists_closed:
+ driver = redirect
+ domains = lists.example
+ allow_fail
+ data = :fail: $local_part@lists.example is a closed mailing list
+.endd
+All three routers have the same \domains\ setting, so for any other domains,
+they are all skipped. The first router runs only if the local part ends in
+\@-request\. It handles messages to the list manager(s) by means of an open
+mailing list.
-If you set \local@_from@_check\ false, this checking does not occur. However,
-the removal of an existing ::Sender:: line still happens, unless you also set
-\local@_sender@_retain\ to be true. It is not possible to set both of these
-options true at the same time.
+The second router runs only if the \senders\ precondition is satisfied. It
+checks for the existence of a list that corresponds to the local part, and then
+checks that the sender is on the list by means of a linear search. It is
+necessary to check for the existence of the file before trying to search it,
+because otherwise Exim thinks there is a configuration error. If the file does
+not exist, the expansion of \senders\ is $*$, which matches all senders. This
+means that the router runs, but because there is no list, declines, and
+\no@_more\ ensures that no further routers are run. The address fails with an
+`unrouteable address' error.
+
+The third router runs only if the second router is skipped, which happens when
+a mailing list exists, but the sender is not on it. This router forcibly fails
+the address, giving a suitable error message.
+
+
+
+.section Virtual domains
+.rset SECTvirtualdomains "~~chapter.~~section"
+.index virtual domains
+.index domain||virtual
+The phrase \*virtual domain*\ is unfortunately used with two rather different
+meanings:
+.numberpars $.
+A domain for which there are no real mailboxes; all valid local parts are
+aliases for other email addresses. Common examples are organizational
+top-level domains and `vanity' domains.
+.nextp
+One of a number of independent domains that are all handled by the same host,
+with mailboxes on that host, but where the mailbox owners do not necessarily
+have login accounts on that host.
+.endp
+The first usage is probably more common, and does seem more `virtual' than the
+second. This kind of domain can be handled in Exim with a straightforward
+aliasing router. One approach is to create a separate alias file for each
+virtual domain. Exim can test for the existence of the alias file to determine
+whether the domain exists. The \%dsearch%\ lookup type is useful here, leading
+to a router of this form:
+.display asis
+virtual:
+ driver = redirect
+ domains = dsearch;/etc/mail/virtual
+ data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
+ no_more
+.endd
+The \domains\ option specifies that the router is to be skipped, unless there
+is a file in the \(/etc/mail/virtual)\ directory whose name is the same as the
+domain that is being processed. When the router runs, it looks up the local
+part in the file to find a new address (or list of addresses). The \no@_more\
+setting ensures that if the lookup fails (leading to \data\ being an empty
+string), Exim gives up on the address without trying any subsequent routers.
+
+This one router can handle all the virtual domains because the alias file names
+follow a fixed pattern. Permissions can be arranged so that appropriate people
+can edit the different alias files. A successful aliasing operation results in
+a new envelope recipient address, which is then routed from scratch.
+
+The other kind of `virtual' domain can also be handled in a straightforward
+way. One approach is to create a file for each domain containing a list of
+valid local parts, and use it in a router like this:
+.display asis
+my_domains:
+ driver = accept
+ domains = dsearch;/etc/mail/domains
+ local_parts = lsearch;/etc/mail/domains/$domain
+ transport = my_mailboxes
+.endd
+The address is accepted if there is a file for the domain, and the local part
+can be found in the file. The \domains\ option is used to check for the file's
+existence because \domains\ is tested before the \local@_parts\ option (see
+section ~~SECTrouprecon). You can't use \require@_files\, because that option
+is tested after \local@_parts\. The transport is as follows:
+.display asis
+my_mailboxes:
+ driver = appendfile
+ file = /var/mail/$domain/$local_part
+ user = mail
+.endd
+This uses a directory of mailboxes for each domain. The \user\ setting is
+required, to specify which uid is to be used for writing to the mailboxes.
+
+The configuration shown here is just one example of how you might support this
+requirement. There are many other ways this kind of configuration can be set
+up, for example, by using a database instead of separate files to hold all the
+information about the domains.
+
+
+.section Multiple user mailboxes
+.rset SECTmulbox "~~chapter.~~section"
+.index multiple mailboxes
+.index mailbox||multiple
+.index local part||prefix
+.index local part||suffix
+Heavy email users often want to operate with multiple mailboxes, into which
+incoming mail is automatically sorted. A popular way of handling this is to
+allow users to use multiple sender addresses, so that replies can easily be
+identified. Users are permitted to add prefixes or suffixes to their local
+parts for this purpose. The wildcard facility of the generic router options
+\local@_part@_prefix\ and \local@_part@_suffix\ can be used for this. For
+example, consider this router:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+It 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:
+.display asis
+if $local_part_suffix contains -special then
+ save /home/$local_part/Mail/special
+endif
+.endd
+If the filter file does not exist, or does not deal with such addresses, they
+fall through to subsequent routers, and, assuming no subsequent use of the
+\local@_part@_suffix\ option is made, they presumably fail. Thus, users have
+control over which 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:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward$local_part_suffix
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+If there is no suffix, \(.forward)\ is used; if the suffix is \*-special*\, for
+example, \(.forward-special)\ is used. Once again, if the appropriate file
+does not exist, or does not deal with the address, it is passed on to
+subsequent routers, which could, if required, look for an unqualified
+\(.forward)\ file to use as a default.
+
+
+.section Simplified vacation processing
+.index vacation processing
+The traditional way of running the \*vacation*\ program is for a user to set up
+a pipe command in a \(.forward)\ file
+(see section ~~SECTspecitredli for syntax details).
+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:
+.numberpars $.
+A local part prefix such as `vacation-' can be specified on a router which
+can cause the message to be delivered directly to the \*vacation*\ program, or
+alternatively can use Exim's \%autoreply%\ transport. The contents of a user's
+\(.forward)\ file are then much simpler. For example:
+.display asis
+spqr, vacation-spqr
+.endd
+.nextp
+The \require@_files\ generic router 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.
+.endp
+Another advantage of both these methods is that they both work even when the
+use of arbitrary pipes by users is locked out.
-By default, no processing of ::Sender:: header lines is done for messages
-received by TCP/IP or for messages submitted by trusted users. However, when a
-message is received over TCP/IP in submission mode, ::Sender:: header lines are
-always removed. If the SMTP session is authenticated, and \$authenticated@_id$\
-is not empty, a sender address is created with \$authenticated@_id$\ as the
-local part and either the domain specified in the submission control or, if
-that is not specified, \$qualify@_domain$\ as the domain. This is compared with
-the address in the ::From:: header line. If they are different, a ::Sender::
-header line is added. Prefixes and suffixes for the local part in ::From:: can
-be permitted by setting \local@_from@_prefix\ and \local@_from@_suffix\
-appropriately.
-
-
-.section Adding and removing header lines
-.index header lines||adding
-.index header lines||removing
-.rset SECTheadersaddrem "~~chapter.~~section"
-When a message is delivered, the addition and removal of header lines can be
-specified on any of the routers and transports, and also in the system filter.
-Changes specified in the system filter affect all deliveries of a message.
-Header changes specified on a router affect all addresses handled by that
-router, and also any new addresses it generates. If an address passes through
-several routers, the changes are cumulative. When a message is processed by a
-transport, the message's original set of header lines is output, except for
-those named in any \headers@_remove\ options that the address has encountered
-as it was processed, and any in the transport's own \headers@_remove\ option.
-Then the new header lines from \headers@_add\ options are output.
+.section Taking copies of mail
+.index message||copying every
+Some installations have policies that require archive copies of all messages to
+be made. A single copy of each message can easily be taken by an appropriate
+command in a system filter, which could, for example, use a different file for
+each day's messages.
+There is also a shadow transport mechanism that can be used to take copies of
+messages that are successfully delivered by local transports, one copy per
+delivery. This could be used, $it{inter alia}, to implement automatic
+notification of delivery by sites that insist on doing such things.
-.section Constructed addresses
-.rset SECTconstr "~~chapter.~~section"
-.index address||constructed
-.index constructed address
-When Exim constructs a sender address for a locally-generated message, it uses
-the form
-.display
-<<user name>> <$$<<login>>@@<<qualify@_domain>>$$>
-.endd
-For example:
-.display asis
-Zaphod Beeblebrox <zaphod@end.univ.example>
-.endd
-The user name is obtained from the \-F-\ command line option if set, or
-otherwise by looking up the calling user by \*getpwuid()*\ and extracting 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
-upper cased, 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 2822 by quoting all or
-parts of it if necessary. In addition, if it contains any non-printing
-characters, it is encoded as described in RFC 2047, which defines a way of
-including non-ASCII characters in header lines.
-The value of the \headers@_charset\ option specifies the name of the encoding
-that is used (the characters are assumed to be in this encoding).
-The setting of \print@_topbitchars\ controls whether characters with the top
-bit set (that is, with codes greater than 127) count as printing characters or
-not.
+.section Intermittently connected hosts
+.index intermittently connected hosts
+It has become 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.
+Exim was designed for use on permanently connected hosts, and so it is not
+particularly well-suited to use in an intermittently connected environment.
+Nevertheless there are some features that can be used.
-.section Case of local parts
-.index case of local parts
-.index local part||case of
-RFC 2822 states that the case of letters in the local parts of addresses cannot
-be assumed to be non-significant. Exim preserves the case of local parts of
-addresses, but by default it uses a lower-cased form when it is routing,
-because on most Unix systems, usernames are in lower case and case-insensitive
-routing is required. However, any particular router can be made to use the
-original case for local parts by setting the \caseful@_local@_part\ generic
-router option.
+.section Exim on the upstream server host
+It is tempting to arrange for incoming mail for the intermittently connected
+host to remain on Exim's queue until the client connects. However, this
+approach does not scale very well. Two different kinds of waiting message are
+being mixed up in the same queue -- those that cannot be delivered because of
+some temporary problem, and those that are waiting for their destination host
+to connect. This makes it hard to manage the queue, as well as wasting
+resources, because each queue runner scans the entire queue.
-.index mixed-case login names
-If you must have mixed-case user names on your system, the best way to proceed,
-assuming you want case-independent handling of incoming email, is to set up
-your first router to convert incoming local parts in your domains to the
-correct case by means of a file lookup. For example:
-.display asis
-correct_case:
- driver = redirect
- domains = +local_domains
- data = ${lookup{$local_part}cdb\
- {/etc/usercased.cdb}{$value}fail}\
- @$domain
-.endd
-For this router, the local part is forced to lower case by the default action
-(\caseful@_local@_part\ is not set). The lower-cased local part is used to look
-up a new local part in the correct case. If you then set \caseful@_local@_part\
-on any subsequent routers which process your domains, they will operate on
-local parts with the correct case in a case-sensitive manner.
+A better approach is to separate off those messages that are waiting for an
+intermittently connected host. This can be done by delivering these messages
+into local files in batch SMTP, `mailstore', or other envelope-preserving
+format, from where they are transmitted by other software when their
+destination connects. This makes it easy to collect all the mail for one host
+in a single directory, and to apply local timeout rules on a per-message basis
+if required.
+On a very small scale, leaving the mail on Exim's queue can be made to work. If
+you are doing this, you should configure Exim with a long retry period for the
+intermittent host. For example:
+.display
+cheshire.wonderland.fict.example * F,5d,24h
+.endd
+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 section ~~SECTETRN)
+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.
-.section Dots in local parts
-.index dot||in local part
-.index local part||dots in
-RFC 2822 forbids empty components in local parts. That is, an unquoted local
-part may not begin or end with a dot, nor have two consecutive dots in the
-middle. However, it seems that many MTAs do not enforce this, so Exim permits
-empty components for compatibility.
+If the connecting hosts do not have fixed IP addresses, that is, if a host is
+issued with a different IP address each time it connects, Exim's retry
+mechanisms on the holding host get confused, because the IP address is normally
+used as part of the key string for holding retry information. This can be
+avoided by unsetting \retry__include__ip__address\ on the \%smtp%\ transport.
+Since this has disadvantages for permanently connected hosts, it is best to
+arrange a separate transport for the intermittently connected ones.
-.section Rewriting addresses
-.index 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 ~~CHAPrewrite. The headers that may be affected by this are ::Bcc::,
-::Cc::, ::From::, ::Reply-To::, ::Sender::, and ::To::.
+.section Exim on the intermittently connected client host
+The value of \smtp@_accept@_queue@_per@_connection\ should probably be
+increased, or even set to zero (that is, disabled) on the intermittently
+connected host, so that all incoming messages down a single connection get
+delivered immediately.
-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
-.display asis
-To: hare@teaparty
-.endd
-might get rewritten as
-.display asis
-To: hare@teaparty.wonderland.fict.example
-.endd
-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.
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+Mail waiting to be sent from an intermittently connected host will probably
+not have been routed, because without a connection DNS lookups are not
+possible. This means that if a normal queue run is done at connection time,
+each message is likely to be sent in a separate SMTP session. This can be
+avoided by starting the queue run with a command line option beginning with
+\-qq-\ instead of \-q-\. In this case, the queue is scanned twice. In the first
+pass, routing is done but no deliveries take place. The second pass is a normal
+queue run; since all the messages have been previously routed, those destined
+for the same host are likely to get sent as multiple deliveries in a single
+SMTP connection.
-Strictly, one should not do $it{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.
+.
+.
+.
+.
+. ============================================================================
+.chapter Using Exim as a non-queueing client
+.set runningfoot "non-queueing client"
+.rset CHAPnonqueueing "~~chapter"
+.index client, non-queueing
+.index smart host||queueing, suppressing
+.em
+On a personal computer, it is a common requirement for all
+email to be sent to a `smart host'. There are plenty of MUAs that can be
+configured to operate that way, for all the popular operating systems.
+However, there are some MUAs for Unix-like systems that cannot be so
+configured: they submit messages using the command line interface of
+\(/usr/sbin/sendmail)\. Furthermore, utility programs such as \*cron*\ submit
+messages this way.
+
+If the personal computer runs continuously, there is no problem, because it can
+run a conventional MTA that handles delivery to the smart host, and deal with
+any delays via its queueing mechanism. However, if the computer does not run
+continuously or runs different operating systems at different times, queueing
+email is not desirable.
+
+There is therefore a requirement for something that can provide the
+\(/usr/sbin/sendmail)\ interface but deliver messages to a smart host without
+any queueing or retrying facilities. Furthermore, the delivery to the smart
+host should be synchronous, so that if it fails, the sending MUA is immediately
+informed. In other words, we want something that extends an MUA that submits
+to a local MTA via the command line so that it behaves like one that submits
+to a remote smart host using TCP/SMTP.
+
+There are a number of applications (for example, there is one called \*ssmtp*\)
+that do this job. However, people have found them to be lacking in various
+ways. For instance, you might want to allow aliasing and forwarding to be done
+before sending a message to the smart host.
+
+Exim already had the necessary infrastructure for doing this job. Just a few
+tweaks were needed to make it behave as required, though it is somewhat of an
+overkill to use a fully-featured MTA for this purpose.
+
+.index \mua@_wrapper\
+There is a Boolean global option called \mua@_wrapper\, defaulting false.
+Setting \mua@_wrapper\ true causes Exim to run in a special mode where it
+assumes that it is being used to `wrap' a command-line MUA in the manner
+just described. As well as setting \mua@_wrapper\, you also need to provide a
+compatible router and transport configuration. Typically there will be just one
+router and one transport, sending everything to a smart host.
+
+When run in MUA wrapping mode, the behaviour of Exim changes in the
+following ways:
+.numberpars alpha
+A daemon cannot be run, nor will Exim accept incoming messages from \*inetd*\.
+In other words, the only way to submit messages is via the command line.
+.nextp
+Each message is synchonously delivered as soon as it is received (\-odi-\ is
+assumed). All queueing options (\queue@_only\, \queue@_smtp@_domains\,
+\control\ in an ACL, etc.) are quietly ignored. The Exim reception process does
+not finish until the delivery attempt is complete. If the delivery is
+successful, a zero return code is given.
+.nextp
+Address redirection is permitted, but the final routing for all addresses must
+be to the same remote transport, and to the same list of hosts. Furthermore,
+the return address (envelope sender) must be the same for all recipients, as
+must any added or deleted header lines. In other words, it must be possible to
+deliver the message in a single SMTP transaction, however many recipients there
+are.
+.nextp
+If these conditions are not met, or if routing any address results in a failure
+or defer status, or if Exim is unable to deliver all the recipients
+successfully to one of the smart hosts, delivery of the entire message fails.
+.nextp
+Because no queueing is allowed, all failures are treated as permanent; there is
+no distinction between 4\*xx*\ and 5\*xx*\ SMTP response codes from the smart
+host. Furthermore, because only a single yes/no response can be given to the
+caller, it is not possible to deliver to some recipients and not others. If
+there is an error (temporary or permanent) for any recipient, all are failed.
+.nextp
+If more than one smart host is listed, Exim will try another host after a
+connection failure or a timeout, in the normal way. However, if this kind of
+failure happens for all the hosts, the delivery fails.
+.nextp
+When delivery fails, an error message is written to the standard error stream
+(as well as to Exim's log), and Exim exits to the caller with a return code
+value 1. The message is expunged from Exim's spool files. No bounce messages
+are ever generated.
+.nextp
+No retry data is maintained, and any retry rules are ignored.
+.nextp
+A number of Exim options are overridden: \deliver@_drop@_privilege\ is forced
+true, \max@_rcpt\ in the smtp transport is forced to `unlimited',
+\remote@_max@_parallel\ is forced to one, and fallback hosts are ignored.
+.endp
+The overall effect is that Exim makes a single synchronous attempt to deliver
+the message, failing if there is any kind of problem. Because no local
+deliveries are done and no daemon can be run, Exim does not need root
+privilege. It should be possible to run it setuid to \*exim*\ instead of setuid
+to \*root*\. See section ~~SECTrunexiwitpri for a general discussion about the
+advantages and disadvantages of running without root privilege.
+.nem
.index authentication||logging
.index \\AUTH\\||logging
For all messages, the P field specifies the protocol used to receive the
-message. This is set to `asmtp' for messages received from hosts which have
-authenticated themselves using the SMTP \\AUTH\\ command. In this case there is
-an additional item A= followed by the name of the authenticator that was used.
-If an authenticated identification was set up by the authenticator's
-\server@_set@_id\ option, this is logged too, separated by a colon from the
-authenticator name.
+message. This is set to
+.em
+`esmtpa'
+.nem
+for messages received from hosts that have authenticated themselves using the
+SMTP \\AUTH\\ command. In this case there is an additional item A= followed by
+the name of the authenticator that was used. If an authenticated identification
+was set up by the authenticator's \server@_set@_id\ option, this is logged too,
+separated by a colon from the authenticator name.
The id field records the existing message id, if present.
.index size||of message
.tabs 8
A $t $rm{authenticator name (and optional id)}
C $t $rm{SMTP confirmation on delivery}
-.newline
CV $t $rm{certificate verification status}
DN $t $rm{distinguished name from peer certificate}
-DT $t $rm{time taken for a delivery}
+.newline
+.em
+DT $t $rm{on \"=>"\ lines: time taken for a delivery}
+.nem
.newline
F $t $rm{sender address (on delivery lines)}
H $t $rm{host name and IP address}
-.newline
I $t $rm{local interface used}
-.newline
id $t $rm{message id for incoming message}
P $t $rm{on \"<="\ lines: protocol used}
.newline
- $t $rm{on \"=>"\ lines: return path}
-QT $t $rm{time spent on queue}
+.em
+ $t $rm{on \"=>"\ and \"**"\ lines: return path}
+QT $t $rm{on \"=>"\ lines: time spent on queue so far}
+ $t $rm{on `Completed' lines: time spent on queue}
+.nem
.newline
R $t $rm{on \"<="\ lines: reference for local bounce}
- $t $rm{on \"=>"\ lines: router name}
+.newline
+.em
+ $t $rm{on \"=>"\ \"**"\ and \"=="\ lines: router name}
+.nem
+.newline
S $t $rm{size of message}
ST $t $rm{shadow transport name}
T $t $rm{on \"<="\ lines: message subject (topic)}
- $t $rm{on \"=>"\ lines: transport name}
+.newline
+.em
+ $t $rm{on \"=>"\ \"**"\ and \"=="\ lines: transport name}
+.nem
+.newline
U $t $rm{local user or RFC 1413 identity}
X $t $rm{TLS cipher suite}
.endd
arguments $t $rm{command line arguments}
*connection@_reject $t $rm{connection rejections}
*delay@_delivery $t $rm{immediate delivery delayed}
-.newline
deliver@_time $t $rm{time taken to perform delivery}
-.newline
delivery@_size $t $rm{add S=nnn to => lines}
*dnslist@_defer $t $rm{defers of DNS list (aka RBL) lookups}
*etrn $t $rm{ETRN commands}
*host@_lookup@_failed $t $rm{as it says}
-.newline
ident@_timeout $t $rm{timeout for ident connection}
-.newline
incoming@_interface $t $rm{incoming interface on <= lines}
incoming@_port $t $rm{incoming port on <= lines}
*lost@_incoming@_connection $t $rm{as it says (includes timeouts)}
-.newline
outgoing@_port $t $rm{add remote port to => lines}
-.newline
*queue@_run $t $rm{start and end queue runs}
.newline
- queue@_time $t $rm{time on queue}
+.em
+ queue@_time $t $rm{time on queue for one recipient}
+ queue@_time@_overall $t $rm{time on queue for whole message}
+.nem
.newline
received@_recipients $t $rm{recipients on <= lines}
received@_sender $t $rm{sender on <= lines}
*rejected@_header $t $rm{header contents on reject log}
*retry@_defer $t $rm{`retry time not reached'}
-.newline
return@_path@_on@_delivery $t $rm{put return path on => and ** lines}
-.newline
sender@_on@_delivery $t $rm{add sender to => lines}
*size@_reject $t $rm{rejection because too big}
*skip@_delivery $t $rm{delivery skipped in a queue run}
-.newline
smtp@_confirmation $t $rm{SMTP confirmation on => lines}
-.newline
smtp@_connection $t $rm{SMTP connections}
smtp@_incomplete@_transaction $t $rm{incomplete SMTP transactions}
smtp@_protocol@_error $t $rm{SMTP protocol errors}
smtp@_syntax@_error $t $rm{SMTP syntax errors}
subject $t $rm{contents of ::Subject:: on <= lines}
-.newline
tls@_certificate@_verified $t $rm{certificate verification status}
-.newline
*tls@_cipher $t $rm{TLS cipher suite on <= and => lines}
tls@_peerdn $t $rm{TLS peer DN on <= and => lines}
.nextp
.index log||queue time
\queue@_time\: The amount of time the message has been in the queue on the
-local host is logged as QT=<<time>>, for example, \"QT=3m45s"\. The clock
-starts when Exim starts to receive the message, so it includes reception time
-as well as the delivery time of the current address.
+local host is logged as QT=<<time>>
+.em
+on delivery (\"=>"\) lines, for example, \"QT=3m45s"\. The clock starts when
+Exim starts to receive the message, so it includes reception time as well as
+the delivery time for the current address. This means that it may be longer
+than the difference between the arrival and delivery log line times, because
+the arrival log line is not written until the message has been successfully
+received.
+.nem
+
+.nextp
+.em
+\queue@_time@_overall\: The amount of time the message has been in the queue on
+the local host is logged as QT=<<time>> on `Completed' lines, for
+example, \"QT=3m45s"\. The clock starts when Exim starts to receive the
+message, so it includes reception time as well as the total delivery time.
+.nem
.nextp
.index log||recipients
\received@_recipients\: The recipients of a message are listed in the main log
.index log||return path
\return@_path@_on@_delivery\: The return path that is being transmitted with
the message is included in delivery and bounce lines, using the tag P=.
+.em
+This is omitted if no delivery actually happens, for example, if routing fails,
+or if delivery is to \(/dev/null)\ or to \":blackhole:"\.
+.nem
.nextp
.index log||sender on delivery
\sender@_on@_delivery\: The message's sender address is added to every delivery
\skip@_delivery\: A log line is written whenever a message is skipped during a
queue run because it is frozen or because another process is already delivering
it.
+.em
+.index `spool file is locked'
+The message that is written is `spool file is locked'.
+.nem
.nextp
.index log||smtp confirmation
.index SMTP||logging confirmation
.index log||SMTP connections
.index SMTP||logging connections
\smtp@_connection\: A log line is written whenever an SMTP connection is
-established or closed. (By contrast, \lost@_incoming@_connection\ applies only
-when the closure is unexpected.) This applies to connections from local
-processes that use \-bs-\ as well as to TCP/IP connections. If a connection is
-dropped in the middle of a message, a log line is always written, whether this
-selector is set or not, but otherwise nothing is written at the start and end
-of connections unless this selector is enabled.
+established or closed,
+.em
+unless the connection is from a host that matches \hosts@_connection@_nolog\.
+.nem
+(In contrast, \lost__incoming__connection\ applies only when the closure is
+unexpected.) This applies to connections from local processes that use \-bs-\
+as well as to TCP/IP connections. If a connection is dropped in the middle of a
+message, a log line is always written, whether or not this selector is set, but
+otherwise nothing is written at the start and end of connections unless this
+selector is enabled.
For TCP/IP connections to an Exim daemon, the current number of connections is
included in the log message for each new connection, but note that the count is
.display rm
.tabs 22
~~SECTfinoutwha \*exiwhat*\ $t $rm{list what Exim processes are doing}
-.newline
~~SECTgreptheque \*exiqgrep*\ $t $rm{grep the queue}
-.newline
~~SECTsumtheque \*exiqsumm*\ $t $rm{summarize the queue}
~~SECTextspeinf \*exigrep*\ $t $rm{search the main log}
-.newline
~~SECTexipick \*exipick*\ $t $rm{select messages on various criteria}
-.newline
~~SECTcyclogfil \*exicyclog*\ $t $rm{cycle (rotate) log files}
~~SECTmailstat \*eximstats*\ $t $rm{extract statistics from the log}
~~SECTcheckaccess \*exim@_checkaccess*\ $t $rm{check address acceptance from given IP}
a line describing what it is doing to the file \(exim-process.info)\ in the
Exim spool directory. The \*exiwhat*\ script sends the signal to all Exim
processes it can find, having first emptied the file. It then waits for one
-second to allow the Exim processes to react before displaying the results.
-In order to run \*exiwhat*\ successfully you have to have sufficient privilege to
+second to allow the Exim processes to react 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.
-Unfortunately, the \*ps*\ command which \*exiwhat*\ uses to find Exim processes
+.em
+\**Warning**\: This is not an efficient process. It is intended for occasional
+use by system administrators. It is not sensible, for example, to set up a
+script that sends \\SIGUSR1\\ signals to Exim processes at short intervals.
+.nem
+
+Unfortunately, the \*ps*\ command that \*exiwhat*\ uses to find Exim processes
varies in different operating systems. 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
.index cycling logs
.index \*exicyclog*\
The \*exicyclog*\ script can be used to cycle (rotate) \*mainlog*\ and
-\*rejectlog*\ files. This is not necessary if only syslog is being used,
-or if you are using log files with datestamps in their names (see section
-~~SECTdatlogfil).
-Some operating systems have their own standard mechanisms for log cycling, and
-these can be used instead of \*exicyclog*\ if preferred.
-
-Each time \*exicyclog*\ is run the file names get `shuffled down' by one. If the
-main log file name is \(mainlog)\ (the default) then when \*exicyclog*\ is run
-\(mainlog)\ becomes \(mainlog.01)\, the previous \(mainlog.01)\ becomes
+\*rejectlog*\ files. This is not necessary if only syslog is being used, or if
+you are using log files with datestamps in their names (see section
+~~SECTdatlogfil). Some operating systems have their own standard mechanisms for
+log cycling, and these can be used instead of \*exicyclog*\ if preferred.
+
+Each time \*exicyclog*\ is run the file names get `shuffled down' by one. If
+the main log file name is \(mainlog)\ (the default) then when \*exicyclog*\ is
+run \(mainlog)\ becomes \(mainlog.01)\, the previous \(mainlog.01)\ becomes
\(mainlog.02)\ and so on, up to a limit which is set in the script, and which
-defaults to 10. Reject logs are handled similarly.
+defaults to 10.
+.em
+Log files whose numbers exceed the limit are discarded.
+.nem
+Reject logs are handled similarly.
+
+.em
+If the limit is greater than 99, the script uses 3-digit numbers such as
+\(mainlog.001)\, \(mainlog.002)\, etc. If you change from a number less than 99
+to one that is greater, or \*vice versa*\, you will have to fix the names of
+any existing log files.
+.nem
If no \(mainlog)\ file exists, the script does nothing. Files that `drop off'
the end are deleted. All files with numbers greater than 01 are compressed,
Serializing delivery to a specific host (when \serialize@_hosts\ is set in an
\%smtp%\ transport)
.endp
+
+.section exim@_dumpdb
.index \*exim@_dumpdb*\
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
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 (unless \no@_retry@_include@_ip@_address\ is set on the \%smtp%\
-transport).
-If the remote port is not the standard one (port 25), it is added to the IP
-address.
-Then there follows an error code, an additional error code, and a
-textual description of the error.
+transport). If the remote port is not the standard one (port 25), it is added
+to the 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
may be routed to several alternative hosts, and Exim makes no effort to keep
cross-references.
+
+.section exim@_tidydb
.index \*exim@_tidydb*\
The \*exim@_tidydb*\ utility program is used to tidy up the contents of the
hints databases. If run with no options, it removes all records from a database
message ids in database records are those of messages that are still on the
queue. Message ids for messages that no longer exist are removed from
\*wait-*\$it{xxx} records, and if this leaves any records empty, they are
-deleted. For the \*retry*\ database, records whose keys are non-existent message
-ids are removed. The \*exim@_tidydb*\ utility outputs comments on the standard
-output whenever it removes information from the database.
+deleted. For the \*retry*\ database, records whose keys are non-existent
+message ids are removed. The \*exim@_tidydb*\ utility outputs comments on the
+standard output whenever it removes information from the database.
-Removing records from a DBM file does not normally make the file smaller, but
-all the common DBM libraries are able to re-use the space that is released.
-It is therefore suggested that \*exim@_tidydb*\ be run periodically on all the
-hints databases, but at a quiet time of day, because it requires a database to
-be locked (and therefore inaccessible to Exim) while it does its work.
+.em
+Certain records are automatically removed by Exim when they are no longer
+needed, but others are not. For example, if all the MX hosts for a domain are
+down, a retry record is created for each one. If the primary MX host comes back
+first, its record is removed when Exim successfully delivers to it, but the
+records for the others remain because Exim has not tried to use those hosts.
+
+It is important, therefore, to run \*exim@_tidydb*\ periodically on all the
+hints databases. You should do this at a quiet time of day, because it requires
+a database to be locked (and therefore inaccessible to Exim) while it does its
+work. Removing records from a DBM file does not normally make the file smaller,
+but all the common DBM libraries are able to re-use the space that is released.
+After an initial phase of increasing in size, the databases normally reach a
+point at which they no longer get any bigger, as long as they are regularly
+tidied.
+
+\**Warning**\: If you never run \*exim@_tidydb*\, the space used by the hints
+databases is likely to keep on increasing.
+.nem
+
+.section exim@_fixdb
.index \*exim@_fixdb*\
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
.section Running Exim without privilege
+.rset SECTrunexiwitpri "~~chapter.~~section"
.index privilege, running without
.index unprivileged running
.index root privilege||running without
been received. Such a re-invocation is a waste of resources because it has no
effect.
-If restarting the daemon is not an issue (for example, if \*inetd*\ is being
-used instead of a daemon), having the binary setuid to the Exim user seems a
-clean approach, but there is one complication:
+If restarting the daemon is not an issue (for example, if
+.em
+\mua@_wrapper\ is set, or
+.nem
+\*inetd*\ is being used instead of a daemon), having the binary setuid to the
+Exim user seems a clean approach, but there is one complication:
In this style of operation, Exim is running with the real uid and gid set to
those of the calling process, and the effective uid/gid set to Exim's values.
However, there are no restrictions on remote deliveries. If you are running a
gateway host that does no local deliveries, setting \deliver@_drop@_privilege\
gives more security at essentially no cost.
+.em
+If you are using the \mua@_wrapper\ facility (see chapter ~~CHAPnonqueueing),
+\deliver@_drop@_privilege\ is forced to be true.
+.nem
.section Delivering to local files
variable. The string itself starts at the beginning of the next line, and is
followed by a newline character. It may contain internal newlines.
.nextp
+.em
+\-active@_hostname <<hostname>>-\: This is present if, when the message was
+received over SMTP, the value of \$smtp@_active@_hostname$\ was different to
+the value of \$primary@_hostname$\.
+.nem
+.nextp
\-allow@_unqualified@_recipient-\: This is present if unqualified recipient
addresses are permitted in header lines (to stop such addresses from being
qualified if rewriting occurs at transport time). Local messages that were
\-body@_linecount <<number>>-\: This records the number of lines in the body of
the message, and is always present.
.nextp
+.em
+\-body@_zerocount <<number>>-\: This records the number of binary zero bytes in
+the body of the message, and is present if the number is greater than zero.
+.nem
+.nextp
\-deliver@_firsttime-\: This is written when a new message is first added to
the spool. When the spool file is updated after a deferral, it is omitted.
.nextp
untrusted local caller (used to ensure that the caller is displayed in queue
listings).
.nextp
+.em
+\-spam@_score@_int-\: If a message was scanned by SpamAssassin, this is
+present. It records the value of \$spam@_score@_int$\.
+.nem
+.nextp
\-tls@_certificate@_verified-\: A TLS certificate was received from the client
that sent this message, and the certificate was verified by the server.
.nextp