////////////////////////////////////////////////////////////////////////////
-$Cambridge: exim/doc/doc-docbook/spec.ascd,v 1.1 2005/06/16 10:32:31 ph10 Exp $
+$Cambridge: exim/doc/doc-docbook/spec.ascd,v 1.3 2005/11/15 16:10:50 ph10 Exp $
This is the primary source of the Exim Manual. It is an AsciiDoc document
that is converted into DocBook XML for subsequent conversion into printing
:author: Philip Hazel
:copyright: University of Cambridge
:cpyear: 2005
-:date: 13 May 2005
+:date: 01 November 2005
:doctitleabbrev: The Exim MTA
-:revision: 4.50
+:revision: 4.60
//////////////////////////////////////////////////////////////////////////////
:ACL: access control lists (ACLs)
:star: *
-:previousversion: 4.40
-:version: 4.50
+:previousversion: 4.50
+:version: 4.60
////////////////////////////////////////////////////////////////////////////
<secondary>rewriting</secondary>
<see><emphasis>rewriting</emphasis></see>
</indexterm>
+<indexterm role="concept">
+ <primary>Bounce Address Tag Validation</primary>
+ <see><emphasis>BATV</emphasis></see>
+</indexterm>
+<indexterm role="concept">
+ <primary>Client SMTP Authorization</primary>
+ <see><emphasis>CSA</emphasis></see>
+</indexterm>
<indexterm role="concept">
<primary>CR character</primary>
<see><emphasis>carriage return</emphasis></see>
<primary>maximum</primary>
<see><emphasis>limit</emphasis></see>
</indexterm>
+<indexterm role="concept">
+ <primary>monitor</primary>
+ <see><emphasis>Exim monitor</emphasis></see>
+</indexterm>
<indexterm role="concept">
<primary>no_<emphasis>xxx</emphasis></primary>
<see>entry for xxx</see>
used on intermittently connected hosts with suitable configuration adjustments.
Configuration files currently exist for the following operating systems: AIX,
-BSD/OS (aka BSDI), Darwin (Mac OS X), DGUX, FreeBSD, GNU/Hurd, GNU/Linux,
-HI-OSF (Hitachi), HP-UX, IRIX, MIPS RISCOS, NetBSD, OpenBSD, QNX, SCO, SCO
-SVR4.2 (aka UNIX-SV), Solaris (aka SunOS5), SunOS4, Tru64-Unix (formerly
-Digital UNIX, formerly DEC-OSF1), Ultrix, and Unixware. Some of these operating
-systems are no longer current and cannot easily be tested, so the configuration
-files may no longer work in practice.
+BSD/OS (aka BSDI), Darwin (Mac OS X), DGUX, Dragonfly, FreeBSD, GNU/Hurd,
+GNU/Linux, HI-OSF (Hitachi), HI-UX, HP-UX, IRIX, MIPS RISCOS, NetBSD, OpenBSD,
+OpenUNIX, QNX, SCO, SCO SVR4.2 (aka UNIX-SV), Solaris (aka SunOS5), SunOS4,
+Tru64-Unix (formerly Digital UNIX, formerly DEC-OSF1), Ultrix, and Unixware.
+Some of these operating systems are no longer current and cannot easily be
+tested, so the configuration files may no longer work in practice.
There are also configuration files for compiling Exim in the Cygwin environment
that can be installed on systems running Windows. However, this document does
with the latest release of Exim. (Note that the earlier book about Exim,
published by O'Reilly, covers Exim 3, and many things have changed in Exim 4.)
+[revisionflag="changed"]
+cindex:[Debian,information sources]
+If you are using a Debian distribution of Exim, you will find information about
+Debian-specific features in the file
+&&&&
+_/usr/share/doc/exim4-base/README.Debian_
+&&&&
+The command ^man update-exim.conf^ is another source of Debian-specific
+information.
+
cindex:[_doc/NewStuff_]
cindex:[_doc/ChangeLog_]
cindex:[change log]
~~~~~~~~~~~~~~~~~
cindex:[web site]
cindex:[FTP site]
-The primary distribution site for Exim is currently the University of
+The primary site for Exim source distributions 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 web site and an FTP site at
%exim.org%. These are now also hosted at the University of Cambridge. The
*http://www.egroups.com/list/exim-users[]*, an archiving system with searching
capabilities.
+[revisionflag="changed"]
+cindex:[Debian,mailing list for]
+If you are using a Debian distribution of Exim, you may wish to subscribe to
+the Debian-specific mailing list, which is
+'pkg-exim4-users@lists.alioth.debian.org'.
+
Exim training
~~~~~~~~~~~~~
cindex:[training courses]
-From time to time (approximately annually at the time of writing),
-lecture-based training courses are run by the author of Exim in Cambridge, UK.
-Details can be found on the web site
-*http://www-tus.csx.cam.ac.uk/courses/exim/[]*.
+From time to time (approximately annually at the time of writing), training
+courses are run by the author of Exim in Cambridge, UK. Details can be found on
+the web site *http://www-tus.csx.cam.ac.uk/courses/exim/[]*.
Bug reports
cindex:[reporting bugs]
Reports of obvious bugs should be emailed to 'bugs@exim.org'. However, if
you are unsure whether some behaviour is a bug or not, the best thing to do is
-to post a message to the 'exim-users' mailing list and have it discussed.
+to post a message to the 'exim-dev' mailing list and have it discussed.
cindex:[remote delivery, definition of]
The terms 'local delivery' and 'remote delivery' are used to distinguish
delivery to a file or a pipe on the local host from delivery by SMTP over
-TCP/IP to a remote host.
+TCP/IP to another host. As far as Exim is concerned, all hosts other than the
+host it is running on are 'remote'.
cindex:[return path,definition of]
'Return path' is another name that is used for the sender address in a
contributed by Nigel Metheringham of (at the time he contributed it) Planet
Online Ltd. which contains the following statements:
+
+++++++++++++++++++++++
+<blockquote>
+++++++++++++++++++++++
++
Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd
+
This program is free software; you can redistribute it and/or modify it under
from Dan Bernstein's implementation (which has no license restrictions applied
to it).
+
+++++++++++++++++++++++
+</blockquote>
+++++++++++++++++++++++
++
The implementation is completely contained within the code of Exim.
It does not link against an external cdb library.
Sabourenkov. The permission notice appears below, in accordance with the
conditions expressed therein.
+
+++++++++++++++++++++++
+<blockquote>
+++++++++++++++++++++++
++
Copyright (c) 2001 Carnegie Mellon University. All rights reserved.
+
Redistribution and use in source and binary forms, with or without
details, please contact
+
&&&
-Office of Technology Transfer
-Carnegie Mellon University
-5000 Forbes Avenue
-Pittsburgh, PA 15213-3890
-(412) 268-4387, fax: (412) 268-7395
-tech-transfer@andrew.cmu.edu
+ Office of Technology Transfer
+ Carnegie Mellon University
+ 5000 Forbes Avenue
+ Pittsburgh, PA 15213-3890
+ (412) 268-4387, fax: (412) 268-7395
+ tech-transfer@andrew.cmu.edu
&&&
+///
+The need to indent that block explicitly is a pain.
+///
. Redistributions of any form whatsoever must retain the following
acknowledgment:
+
-'This product includes software developed by Computing Services
-at Carnegie Mellon University (*http://www.cmu.edu/computing/[]*).'
+``This product includes software developed by Computing Services
+at Carnegie Mellon University (*http://www.cmu.edu/computing/[]*).''
+
CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-. cindex:[monitor]
+///
+Note, no "+" line there, because we want to terminate the inner list item
+before ending the block quote.
+///
++
+++++++++++++++++++++++
+</blockquote>
+++++++++++++++++++++++
+
+- cindex:[Exim monitor,acknowledgement]
cindex:[X-windows]
cindex:[Athena]
The Exim Monitor program, which is an X-Window application, includes
This code is copyright by DEC and MIT, and their permission notice appears
below, in accordance with the conditions expressed therein.
+
+++++++++++++++++++++++
+<blockquote>
+++++++++++++++++++++++
++
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
++
+++++++++++++++++++++++
+</blockquote>
+++++++++++++++++++++++
-. Many people have contributed code fragments, some large, some small, that were
+- 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.
system (Mac OS X) and when Exim is compiled to run under Cygwin, base 36
(avoiding the use of lower case letters) is used instead, because the message
id is used to construct file names, and the names of files in those systems are
-not case-sensitive.
+not always case-sensitive.
cindex:[pid (process id),re-use of]
The detail of the contents of the message id have changed as Exim has evolved.
~~~~~~~~~~~~~~
cindex:[receiving mail]
cindex:[message,reception]
-The only way Exim can receive mail from a remote host is using SMTP over
-TCP/IP, in which case the sender and recipient addresses are tranferred using
+The only way Exim can receive mail from another host is using SMTP over
+TCP/IP, in which case the sender and recipient addresses are transferred using
SMTP commands. However, from a locally running process (such as a user's MUA),
there are several possibilities:
and can also freeze individual messages by hand if necessary. In addition, an
administrator can force a delivery error, causing a bounce message to be sent.
-cindex:[%auto_thaw%]
-There is an option called %auto_thaw%, which can be used to cause Exim to
-retry frozen messages after a certain time. When this is set, no message will
-remain on the queue for ever, because the delivery timeout will eventually be
-reached. Delivery failure reports (bounce messages) that reach this timeout are
-discarded.
-
+[revisionflag="changed"]
cindex:[%timeout_frozen_after%]
-There is also an option called %timeout_frozen_after%, which discards frozen
-messages after a certain time.
+cindex:[%ignore_bounce_errors_after%]
+There are options called %ignore_bounce_errors_after% and
+%timeout_frozen_after%, which discard frozen messages after a certain time.
+The first applies only to frozen bounces, the second to any frozen messages.
cindex:[message,log file for]
cindex:[log,file for each message]
While Exim is working on a message, it writes information about each delivery
-attempt to the main log file. This includes successful, unsuccessful, and
+attempt to its main log file. This includes successful, unsuccessful, and
delayed deliveries for each recipient (see chapter <<CHAPlog>>). The log lines
are also written to a separate 'message log' file for each message. These
logs are solely for the benefit of the administrator, and are normally deleted
the driver's features in general.
A 'router' is a driver that operates on an address, either determining how
-its delivery should happen, by routing it to a specific transport, or
+its delivery should happen, by assigning it to a specific transport, or
converting the address into one or more new addresses (for example, via an
alias file). A router may also explicitly choose to fail an address, causing it
to be bounced.
An address is processed by passing it to each configured router instance in
turn, subject to certain preconditions, until a router accepts the address or
specifies that it should be bounced. We will describe this process in more
-detail shortly. As a simple example, the diagram below illustrates how each
-recipient address in a message is processed in a small configuration of three
-routers that are configured in various ways.
+detail shortly. First, as a simple example, we consider how each recipient
+address in a message is processed in a small configuration of three routers.
-To make this a more concrete example, we'll describe it in terms of some actual
+To make this a more concrete example, it is described in terms of some actual
routers, but remember, this is only an example. You can configure Exim's
routers in many different ways, and there may be any number of routers in a
configuration.
its own domain name), and the router is run for addresses that do 'not'
match. Typically, this is a router that looks up domains in the DNS in order to
find the hosts to which this address routes. If it succeeds, the address is
-queued for a suitable SMTP transport; if it does not succeed, the router is
+assigned to a suitable SMTP transport; if it does not succeed, the router is
configured to fail the address.
-///
-The example pictured could be a configuration of this type. The second and
-third routers can only be run for addresses for which the preconditions for
-the first router are not met. If one of these preconditions checks the
-domain, the second and third routers are run only for domains that are somehow
-special to the local host.
-///
-
-The second router does redirection -- also known as aliasing and forwarding.
-When it generates one or more new addresses from the original, each of them is
-routed independently from the start. Otherwise, the router may cause an address
-to fail, or it may simply decline to handle the address, in which case the
-address is passed to the next router.
+The second router is reached only when the domain is recognized as one that
+``belongs'' to the local host. This router does redirection -- also known as
+aliasing and forwarding. When it generates one or more new addresses from the
+original, each of them is routed independently from the start. Otherwise, the
+router may cause an address to fail, or it may simply decline to handle the
+address, in which case the address is passed to the next router.
The final router in many configurations is one that checks to see if the
address belongs to a local mailbox. The precondition may involve a check to
the router is run. What happens next depends on the outcome, which is one of
the following:
-- 'accept': The router accepts the address, and either queues it for a
+- 'accept': The router accepts the address, and either assigns it to a
transport, or generates one or more ``child'' addresses. Processing the original
address ceases,
cindex:[%unseen% option]
passed to the next router. Normally, however, an 'accept' return marks the
end of routing.
+
-cindex:[case of local parts]
-cindex:[address duplicate, discarding]
-If child addresses are generated, Exim checks to see whether they are
-duplicates of any existing recipient addresses. During this check, local parts
-are treated as case-sensitive. Duplicate addresses are discarded. Each of the
-remaining child addresses is then processed independently, starting with the
-first router by default. It is possible to change this by setting the
-%redirect_router% option to specify which router to start at for child
-addresses. Unlike %pass_router% (see below) the router specified by
+Any child addresses generated by the router are processed independently,
+starting with the first router by default. It is possible to change this by
+setting the %redirect_router% option to specify which router to start at for
+child addresses. Unlike %pass_router% (see below) the router specified by
%redirect_router% may be anywhere in the router configuration.
- 'pass': The router recognizes the address, but cannot handle it itself. It
- 'decline': The router declines to accept the address because it does not
recognize it at all. By default, the address is passed to the next router, but
this can be prevented by setting the %no_more% option. When %no_more% is set,
-all the remaining routers are skipped.
+all the remaining routers are skipped. In effect, %no_more% converts 'decline'
+into 'fail'.
- 'fail': The router determines that the address should fail, and queues it for
the generation of a bounce message. There is no further processing of the
original address unless %unseen% is set on the router.
-- 'defer': The router cannot handle the address at the present time. (A database
-may be offline, or a DNS lookup may have timed out.) No further processing of
-the address happens in this delivery attempt. It is tried again next time the
-message is considered for delivery.
+- 'defer': The router cannot handle the address at the present time. (A
+database may be offline, or a DNS lookup may have timed out.) No further
+processing of the address happens in this delivery attempt. It is tried again
+next time the message is considered for delivery.
- 'error': There is some error in the router (for example, a syntax error in
its configuration). The action is as for defer.
If an address reaches the end of the routers without having been accepted by
-any of them, it is bounced as unrouteable.
-The default error message in this situation is ``unrouteable address'', but you
-can set your own message by making use of the %cannot_route_message% option.
-This can be set for any router; the value from the last router that ``saw''
-the address is used.
+any of them, it is bounced as unrouteable. The default error message in this
+situation is ``unrouteable address'', but you can set your own message by
+making use of the %cannot_route_message% option. This can be set for any
+router; the value from the last router that ``saw'' the address is used.
Sometimes while routing you want to fail a delivery when some conditions are
met but others are not, instead of passing the address on for further routing.
facility for this purpose.
+Duplicate addresses
+~~~~~~~~~~~~~~~~~~~
+
+[revisionflag="changed"]
+cindex:[case of local parts]
+cindex:[address duplicate, discarding]
+Once routing is complete, Exim scans the addresses that are assigned to local
+and remote transports, and discards any duplicates that it finds. During this
+check, local parts are treated as case-sensitive.
+
[[SECTrouprecon]]
- Routers can be designated for use only when verifying an address, as
opposed to routing it for delivery. The %verify_only% option controls this.
-- Certain routers can be explicitly skipped when running the routers to check an
-address given in the SMTP EXPN command (see the %expn% option).
+- Individual routers can be explicitly skipped when running the routers to
+check an address given in the SMTP EXPN command (see the %expn% option).
-- If the %domains% option is set, the domain of the address must be in the set of
-domains that it defines.
+- If the %domains% option is set, the domain of the address must be in the set
+of domains that it defines.
-- If the %local_parts% option is set, the local part of the address must be in
+- cindex:[$local_part_prefix$]
+cindex:[$local_part$]
+cindex:[$local_part_suffix$]
+If the %local_parts% option is set, the local part of the address must be in
the set of local parts that it defines. If %local_part_prefix% or
%local_part_suffix% is in use, the prefix or suffix is removed from the local
part before this check. If you want to do precondition tests on local parts
that uses the variables $local_part$, $local_part_prefix$, and
$local_part_suffix$ as necessary.
-- If the %check_local_user% option is set, the local part must be the name of
-an account on the local host.
-If this check succeeds, the uid and gid of the local user are placed in
-$local_user_uid$ and $local_user_gid$; these values can be used in the
-remaining preconditions.
+- cindex:[$local_user_uid$]
+cindex:[$local_user_gid$]
+cindex:[$home$]
+If the %check_local_user% option is set, the local part must be the name of
+an account on the local host. If this check succeeds, the uid and gid of the
+local user are placed in $local_user_uid$ and $local_user_gid$ and the user's
+home directory is placed in $home$; these values can be used in the remaining
+preconditions.
- If the %router_home_directory% option is set, it is expanded at this point,
because it overrides the value of $home$. If this expansion were left till
- cindex:[routing,loops in]
cindex:[loop,while routing]
-A router that accepts an address may set up a local or a remote transport for
-it. However, the transport is not run at this time. Instead, the address is
-placed on a list for the particular transport, to be run later. Alternatively,
-the router may generate one or more new addresses (typically from alias,
-forward, or filter files). New addresses are fed back into this process from
-the top, but in order to avoid loops, a router ignores any address which has an
-identically-named ancestor that was processed by itself.
+A router that accepts an address may assign it to a local or a remote transport. However, the transport is not run at this time. Instead, the address is
+placed on a list for the particular transport, which will be run later.
+Alternatively, the router may generate one or more new addresses (typically
+from alias, forward, or filter files). New addresses are fed back into this
+process from the top, but in order to avoid loops, a router ignores any address
+which has an identically-named ancestor that was processed by itself.
- When all the routing has been done, addresses that have been successfully
handled are passed to their assigned transports. When local transports are
intervals, or use some other means (such as 'cron') to start them. If you do
not arrange for queue runners to be run, messages that fail temporarily at the
first attempt will remain on your queue for ever. A queue runner process works
-it way through the queue, one message at a time, trying each delivery that has
+its way through the queue, one message at a time, trying each delivery that has
passed its retry time.
You can run several queue runners at once.
If a bounce message (either locally generated or received from a remote host)
itself suffers a permanent delivery failure, the message is left on the queue,
but it is frozen, awaiting the attention of an administrator. There are options
-which can be used to make Exim discard such failed messages, or to keep them
+that can be used to make Exim discard such failed messages, or to keep them
for only a short time (see %timeout_frozen_after% and
%ignore_bounce_errors_after%).
be logged.
cindex:[content scanning,specifying at build time]
-Exim's interfaces for calling virus and spam scanning sofware directly from
+Exim's interfaces for calling virus and spam scanning software directly from
access control lists are not compiled by default. If you want to include these
facilities, you need to set
Support for iconv()
~~~~~~~~~~~~~~~~~~~
cindex:['iconv()' support]
+cindex:[RFC 2047]
The contents of header lines in messages may be encoded according to the rules
described RFC 2047. This makes it possible to transmit characters that are not
in the ASCII character set, and to label them as being in a particular
+Output from ``make''
+~~~~~~~~~~~~~~~~~~~~
+
+[revisionflag="changed"]
+The output produced by the 'make' process for compile lines is often very
+unreadable, because these lines can be very long. For this reason, the normal
+output is suppressed by default, and instead output similar to that which
+appears when compiling the 2.6 Linux kernel is generated: just a short line for
+each module that is being compiled or linked. However, it is still possible to
+get the full output, by calling 'make' like this:
+
+ FULLECHO='' make -e
+
+The value of FULLECHO defaults to ``@'', the flag character that suppresses
+command reflection in 'make'. When you ask for the full output, it is
+given in addition to the the short output.
+
+
+
[[SECToverride]]
Overriding build-time options for Exim
LOOKUP_NISPLUS=yes
and similar settings apply to the other lookup types. They are all listed in
-_src/EDITME_. In most cases the relevant include files and interface
+_src/EDITME_. In many cases the relevant include files and interface
libraries need to be installed before compiling Exim.
cindex:[cdb,including support for]
-However, in the case of cdb, which is included in the binary only if
-
- LOOKUP_CDB=yes
-
-is set, the code is entirely contained within Exim, and no external include
+However, there are some optional lookup types (such as cdb) for which
+the code is entirely contained within Exim, and no external include
files or libraries are required. When a lookup type is not included in the
binary, attempts to configure Exim to use it cause run time configuration
errors.
cindex:[X11 libraries, location of]
The location of the X11 libraries is something that varies a lot between
-operating systems, and of course there are different versions of X11 to cope
+operating systems, and there may be different versions of X11 to cope
with. Exim itself makes no use of X11, but if you are compiling the Exim
monitor, the X11 libraries must be available.
The following three variables are set in _OS/Makefile-Default_:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[installing Exim]
cindex:[BIN_DIRECTORY]
-The command 'make install' runs the 'exim_install' script with no
-arguments. The script copies binaries and utility scripts into the directory
-whose name is specified by the BIN_DIRECTORY setting in
-_Local/Makefile_.
+The command 'make install' runs the 'exim_install' script with no arguments.
+The script copies binaries and utility scripts into the directory whose name is
+specified by the BIN_DIRECTORY setting in _Local/Makefile_.
+cindex:[setuid,installing Exim with]
+The install script copies files only if they are newer than the files they are
+going to replace. The Exim binary is required to be owned by root and have the
+'setuid' bit set, for normal configurations. Therefore, you must run 'make
+install' as root so that it can set up the Exim binary in this way. However, in
+some special situations (for example, if a host is doing no local deliveries)
+it may be possible to run Exim without making the binary setuid root (see
+chapter <<CHAPsecurity>> for details).
cindex:[CONFIGURE_FILE]
Exim's run time configuration file is named by the CONFIGURE_FILE setting
other than the name of the local host are routed using the DNS, with delivery
over SMTP.
-cindex:[setuid,installing Exim with]
-The install script copies files only if they are newer than the files they are
-going to replace. The Exim binary is required to be owned by root and have the
-'setuid' bit set, for normal configurations. Therefore, you must run 'make
-install' as root so that it can set up the Exim binary in this way. However, in
-some special situations (for example, if a host is doing no local deliveries)
-it may be possible to run Exim without making the binary setuid root (see
-chapter <<CHAPsecurity>> for details).
-
It is possible to install Exim for special purposes (such as building a binary
distribution) in a private part of the file system. You can do this by a
command such as
This can be done by passing messages directly to Exim, without going through a
user agent. For example:
- exim -v postmaster@your.domain.example
- From: user@your.domain.example
- To: postmaster@your.domain.example
- Subject: Testing Exim
+....
+exim -v postmaster@your.domain.example
+From: user@your.domain.example
+To: postmaster@your.domain.example
+Subject: Testing Exim
- This is a test message.
- ^D
+This is a test message.
+^D
+....
The %-v% option causes Exim to output some verification of what it is doing.
In this case you should see copies of three log lines, one for the message's
call the MTA directly. However, if you are running an Exim daemon, you do need
to send it a HUP signal, to make it re-exec itself, and thereby pick up the new
binary. You do not need to stop processing mail in order to install a new
-version of Exim.
+version of Exim. The install script does not modify an existing runtime
+configuration file.
+
test data. A line history is supported.
+
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
+continuations. As in Exim's run time configuration, white space 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
*-bfd*~<'domain'>::
oindex:[%-bfd%]
+cindex:[$qualify_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$.
This option causes debugging information to be written to the standard
error stream. It is restricted to admin users because debugging output may show
database queries that contain password information. Also, the details of users'
-filter files should be protected. When %-d% is used, %-v% is assumed. If
-%-d% is given on its own, a lot of standard debugging data is output. This can
-be reduced, or increased to include some more rarely needed information, by
-following %-d% with a string made up of names preceded by plus or minus
-characters. These add or remove sets of debugging data, respectively. For
+filter files should be protected. When %-d% is used, %-v% is assumed. If %-d%
+is given on its own, a lot of standard debugging data is output. This can be
+reduced, or increased to include some more rarely needed information, by
+directly following %-d% with a string made up of names preceded by plus or
+minus characters. These add or remove sets of debugging data, respectively. For
example, %-d+filter% adds filter debugging, whereas %-d-all+filter% selects
-only filter debugging. The available debugging categories are:
+only filter debugging. Note that no spaces are allowed in the debug setting.
+The available debugging categories are:
+
&&&
`acl ` ACL interpretation
`transport ` transports
`uid ` changes of uid/gid and looking up uid/gid
`verify ` address verification logic
-`all ` all of the above, and also %-v%
+`all ` almost all of the above (see below), and also %-v%
&&&
+
+[revisionflag="changed"]
+The `all` option excludes `memory` when used as `+all`, but includes it for
+`-all`. The reason for this is that `+all` is something that people tend to use
+when generating debug output for Exim maintainers. If `+memory` is included, an
+awful lot of output that is very rarely of interest is generated, so it now has
+to be explicitly requested. However, `-all` does turn everything off.
++
The
cindex:[resolver, debugging output]
cindex:[DNS resolver, debugging output]
to be an admin user. However, there is an option called %prod_requires_admin%
which can be set false to relax this restriction (and also the same requirement
for the %-q%, %-R%, and %-S% options).
++
+[revisionflag="changed"]
+The deliveries happen synchronously, that is, the original Exim process does
+not terminate until all the delivery attempts have finished. No output is
+produced unless there is a serious error. If you want to see what is happening,
+use the %-v% option as well, or inspect Exim's main log.
*-Mar*~<'message~id'>~<'address'>~<'address'>~...::
oindex:[%-Mar%]
+
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
+process exits. See chapter <<CHAPnonqueueing>> for a way of setting up a
restricted configuration that never queues messages.
*-oMr*~<'protocol~name'>::
oindex:[%-oMr%]
cindex:[protocol,incoming -- specifying for local message]
+cindex:[$received_protocol$]
See %-oMa% above for general remarks about the %-oM% options. The %-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
If ALT_CONFIG_PREFIX is defined _in Local/Makefile_, it specifies a
prefix string with which any file named in a %-C% command line option must
-start. In addition, the file name must not contain the sequence `/../`. There
-is no default setting for ALT_CONFIG_PREFIX; when it is unset, any file
+start. In addition, the file name must not contain the sequence ``##`/../`##''.
+There is no default setting for ALT_CONFIG_PREFIX; when it is unset, any file
name can be used with %-C%.
One-off changes to a configuration can be specified by the %-D% command line
in _Local/Makefile_ before building Exim. Full details of the
'local_scan()' facility are given in chapter <<CHAPlocalscan>>.
-cindex:[configuration file,leading whitespace in]
-cindex:[configuration file,trailing whitespace in]
-cindex:[whitespace,in configuration file]
-Leading and trailing whitespace in configuration lines is always ignored.
+cindex:[configuration file,leading white space in]
+cindex:[configuration file,trailing white space in]
+cindex:[white space,in configuration file]
+Leading and trailing white space in configuration lines is always ignored.
Blank lines in the file, and lines starting with a # character (ignoring
leading white space) are treated as comments and are ignored. *Note*: a
and does not introduce a comment.
Any non-comment line can be continued by ending it with a backslash. 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. Comment lines beginning with # (but not empty lines) may
+the general rule for white space means that trailing white space after the
+backslash and leading white space at the start of continuation
+lines is ignored. Comment lines beginning with # (but not empty lines) may
appear in the middle of a sequence of continuation lines.
A convenient way to create a configuration file is to start from the
space removed. Quotes are not removed. The replacement text can never end with
a backslash character, but this doesn't seem to be a serious limitation.
+[revisionflag="changed"]
+Macros may also be defined between router, transport, authenticator, or ACL
+definitions. They may not, however, be defined within an individual driver or
+ACL, or in the %local_scan%, retry, or rewrite sections of the configuration.
+
+
+Macro substitution
+~~~~~~~~~~~~~~~~~~
Once a macro is defined, all subsequent lines in the file (and any included
files) are scanned for the macro name; if there are several macros, the line is
-scanned for each in turn, in the order in which they are defined. The
+scanned for each in turn, in the order in which the macros are defined. The
replacement text is not re-scanned for the current macro, though it is scanned
for subsequently defined macros. For this reason, a macro name may not contain
the name of a previously defined macro as a substring. You could, for example,
&&&
but putting the definitions in the opposite order would provoke a configuration
-error.
+error. Macro expansion is applied to individual physical lines from the file,
+before checking for line continuation or file inclusion (see above). If a line
+consists solely of a macro name, and the expansion of the macro is empty, the
+line is ignored. A macro at the start of a line may turn the line into a
+comment line or a `.include` line.
+
+
+Redefining macros
+~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+Once defined, the value of a macro can be redefined later in the configuration
+(or in an included file). Redefinition is specified by using '==' instead of
+'='. For example:
+
+ MAC = initial value
+ ...
+ MAC == updated value
+
+Redefinition does not alter the order in which the macros are applied to
+the subsequent lines of the configuration file. It is still the same
+order in which the macros were originally defined. All that changes is
+the macro's value. Redefinition makes it possible to accumulate values.
+For example:
+
+ MAC = initial value
+ ...
+ MAC == MAC and something added
+
+This can be helpful in situations where the configuration file is built
+from a number of other files.
+
+
+Overriding macro values
+~~~~~~~~~~~~~~~~~~~~~~~
+The values set for macros in the configuration file can be overridden by the
+%-D% command line option, but Exim gives up its root privilege when %-D% is
+used, unless called by root or the Exim user. A definition on the command line
+using the %-D% option causes all definitions and redefinitions within the file
+to be ignored.
+
-Macro expansion is applied to individual lines from the file, before checking
-for line continuation or file inclusion (see below). If a line consists solely
-of a macro name, and the expansion of the macro is empty, the line is ignored.
-A macro at the start of a line may turn the line into a comment line or a
-`.include` line.
+Example of macro usage
+~~~~~~~~~~~~~~~~~~~~~~
As an example of macro usage, consider a configuration where aliases are looked
up in a MySQL database. It helps to keep the file less cluttered if long
strings such as SQL statements are defined separately as macros, for example:
address lists. In Exim 4 these are handled better by named lists -- see section
<<SECTnamedlists>>.
-Macros in the configuration file can be overridden by the %-D% command line
-option, but Exim gives up its root privilege when %-D% is used, unless called
-by root or the Exim user.
-
-
Conditional skips in the configuration file
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~
cindex:[format,boolean]
cindex:[boolean configuration values]
+oindex:[%no_%'xxx']
+oindex:[%not_%'xxx']
Options whose type is given as boolean are on/off switches. There are two
different ways of specifying such options: with and without a data value. If
the option name is specified on its own without data, the switch is turned on;
if it is preceded by ``no_'' or ``not_'' the switch is turned off. However,
-boolean options may optionally be followed by an equals sign and one of the
-words ``true'', ``false'', ``yes'', or ``no'', as an alternative syntax. For example,
+boolean options may be followed by an equals sign and one of the words
+``true'', ``false'', ``yes'', or ``no'', as an alternative syntax. For example,
the following two settings have exactly the same effect:
queue_only
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>>.
+``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
-+contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address
-1.
+contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address ::1.
+
+[revisionflag="changed"]
+*Note*: Although leading and trailing white space is ignored in individual list
+items, it is not ignored when parsing the list. The space after the first colon
+in the example above is necessary. If it were not there, the list would be
+interpreted as the two items 127.0.0.1:: and 1.
cindex:[list separator, changing]
cindex:[IPv6,addresses in lists]
senders = user1@domain : : user2@domain
-*Note*: there must be whitespace between the two colons, as otherwise they
+*Note*: there must be white space 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:
detail in its own separate chapter later in this manual.
You can have several routers, transports, or authenticators that are based on
-the same underlying driver (each must have a different name).
+the same underlying driver (each must have a different instance name).
The order in which routers are defined is important, because addresses are
passed to individual routers one by one, in order. The order in which
we aren't actually setting up any controls. We are just defining some domains
and hosts that will be used in the controls that are specified later.
-The next configuration line is a genuine option setting:
+The next two configuration lines are genuine option settings:
acl_smtp_rcpt = acl_check_rcpt
+ acl_smtp_data = acl_check_data
-This option specifies an 'Access Control List' (ACL) which is to be used
-during an incoming SMTP session for every recipient of a message (every
-RCPT command). The name of the list is 'acl_check_rcpt', and we will
-come to its definition below, in the ACL section of the configuration. ACLs
-control which recipients are accepted for an incoming message -- if a
+[revisionflag="changed"]
+These options specify 'Access Control Lists' (ACLs) that are to be used during
+an incoming SMTP session for every recipient of a message (every RCPT command),
+and after the contents of the message have been received, respectively. The
+names of the lists are 'acl_check_rcpt' and 'acl_check_data', and we will come
+to their definitions below, in the ACL section of the configuration. The RCPT
+ACL controls which recipients are accepted for an incoming message -- if a
configuration does not provide an ACL to check recipients, no SMTP mail can be
-accepted.
+accepted. The DATA ACL allows the contents of a message to be checked.
+
+[revisionflag="changed"]
+Two commented-out option settings are next:
+
+[revisionflag="changed"]
+....
+# av_scanner = clamd:/tmp/clamd
+# spamd_address = 127.0.0.1 783
+....
+
+[revisionflag="changed"]
+These are example settings that can be used when Exim is compiled with the
+content-scanning extension. The first specifies the interface to the virus
+scanner, and the second specifies the interface to SpamAssassin. Further
+details are given in chapter <<CHAPexiscan>>.
-Two commented-out options settings are next:
+Two more commented-out options settings follow:
# qualify_domain =
# qualify_recipient =
cindex:[domain literal,recognizing format]
The following line must be uncommented if you want Exim to recognize
addresses of the form 'user@[10.11.12.13]' that is, with a ``domain literal''
-(an IP address) instead of a named domain.
+(an IP address within square brackets) instead of a named domain.
# allow_domain_literals
begin acl
-and it contains the definition of one ACL called 'acl_check_rcpt' that was
-referenced in the setting of %acl_smtp_rcpt% above.
+and it contains the definitions of two ACLs, called 'acl_check_rcpt' and
+'acl_check_data', that were referenced in the settings of %acl_smtp_rcpt% and
+%acl_smtp_data% above.
cindex:[RCPT,ACL for]
-This ACL is used for every RCPT command in an incoming SMTP message. Each
+The first ACL is used for every RCPT command in an incoming SMTP message. Each
RCPT command specifies one of the message's recipients. The ACL statements
are considered in order, until the recipient address is either accepted or
rejected. The RCPT command is then accepted or rejected, according to the
This ACL statement accepts the recipient if the sending host matches the list.
But what does that strange list mean? It doesn't actually contain any host
names or IP addresses. The presence of the colon puts an empty item in the
-list; Exim matches this only if the incoming message didn't come from a remote
-host. The colon is important. Without it, the list itself is empty, and can
-never match anything.
+list; Exim matches this only if the incoming message did not come from a remote
+host, because in that case, the remote hostname is empty. The colon is
+important. Without it, the list itself is empty, and can never match anything.
What this statement is doing is to accept unconditionally all recipients in
messages that are submitted by SMTP from local processes using the standard
input and output (that is, not using TCP/IP). A number of MUAs operate in this
manner.
- deny domains = +local_domains
+ deny message = Restricted characters in address
+ domains = +local_domains
local_parts = ^[.] : ^.*[@%!/|]
- deny domains = !+local_domains
+ deny message = Restricted characters in address
+ domains = !+local_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
These statements are concerned with local parts that contain any of the
This statement requires the sender address to be verified before any subsequent
ACL statement can be used. If verification fails, the incoming recipient
address is refused. Verification consists of trying to route the address, to
-see if a
-bounce
-message could be delivered to it. In the case of remote addresses, basic
-verification checks only the domain, but 'callouts' can be used for more
-verification if required. Section <<SECTaddressverification>> discusses the
-details of address verification.
+see if a bounce message could be delivered to it. In the case of remote
+addresses, basic verification checks only the domain, but 'callouts' can be
+used for more verification if required. Section <<SECTaddressverification>>
+discusses the details of address verification.
+
+ accept hosts = +relay_from_hosts
+ control = submission
+
+[revisionflag="changed"]
+This statement accepts the address if the message is coming from one of the
+hosts that are defined as being allowed to relay through this host. Recipient
+verification is omitted here, because in many cases the clients are dumb MUAs
+that do not cope well with SMTP error responses. For the same reason, the
+second line specifies ``submission mode'' for messages that are accepted. This
+is described in detail in section <<SECTsubmodnon>>; it causes Exim to fix
+messages that are deficient in some way, for example, because they lack a
+'Date:' header line. If you are actually relaying out from MTAs, you should
+probably add recipient verification here, and disable submission mode.
+
+ accept authenticated = *
+ control = submission
+
+[revisionflag="changed"]
+This statement accepts the address if the client host has authenticated itself.
+Submission mode is again specified, on the grounds that such messages are most
+likely to come from MUAs. The default configuration does not define any
+authenticators, which means that no client can in fact authenticate. You will
+need to add authenticator definitions if you want to make use of this ACL
+statement.
....
# deny message = rejected because $sender_host_address is \
accept domains = +local_domains
endpass
- message = unknown user
verify = recipient
This statement accepts the incoming recipient address if its domain is one of
recipient in a local domain cannot be verified, access is denied and the
recipient is rejected.
-cindex:[customizing,ACL failure message]
-The %message% modifier provides a customized error message for the failure.
-
accept domains = +relay_to_domains
endpass
- message = unrouteable address
verify = recipient
This statement accepts the incoming recipient address if its domain is one of
the domains for which this host is a relay, but again, only if the address can
be verified.
- accept hosts = +relay_from_hosts
-
-Control reaches this statement only if the recipient's domain is neither a
-local domain, nor a relay domain. The statement accepts the address if the
-message is coming from one of the hosts that are defined as being allowed to
-relay through this host. Recipient verification is omitted here, because in
-many cases the clients are dumb MUAs that do not cope well with SMTP error
-responses. If you are actually relaying out from MTAs, you should probably add
-recipient verification here.
-
- accept authenticated = *
-
-Control reaches here for attempts to relay to arbitrary domains from arbitrary
-hosts. The statement accepts the address only if the client host has
-authenticated itself. The default configuration does not define any
-authenticators, which means that no client can in fact authenticate. You will
-need to add authenticator definitions if you want to make use of this ACL
-statement.
-
deny message = relay not permitted
The final statement denies access, giving a specific error message. Reaching
the end of the ACL also causes access to be denied, but with the generic
message ``administrative prohibition''.
+ acl_check_data:
+
+[revisionflag="changed"]
+This line marks the start of the second ACL, and names it. Most of the contents
+of this ACL are commented out:
+
+[revisionflag="changed"]
+....
+# deny malware = *
+# message = This message contains a virus \
+# ($malware_name).
+....
+
+[revisionflag="changed"]
+These lines are examples of how to arrange for messages to be scanned for
+viruses when Exim has been compiled with the content-scanning extension, and a
+suitable virus scanner is installed. If the message is found to contain a
+virus, it is rejected with the given custom error message.
+
+[revisionflag="changed"]
+....
+# warn spam = nobody
+# message = X-Spam_score: $spam_score\n\
+# X-Spam_score_int: $spam_score_int\n\
+# X-Spam_bar: $spam_bar\n\
+# X-Spam_report: $spam_report
+....
+
+[revisionflag="changed"]
+These lines are an example of how to arrange for messages to be scanned by
+SpamAssassin when Exim has been compiled with the content-scanning extension,
+and SpamAssassin has been installed. The SpamAssassin check is run with
+`nobody` as its user parameter, and the results are added to the message as a
+series of extra header line. In this case, the message is not rejected,
+whatever the spam score.
+
+ accept
+
+[revisionflag="changed"]
+This final line in the DATA ACL accepts the message unconditionally.
+
Router configuration
userforward:
driver = redirect
check_local_user
+ # local_part_suffix = +* : -*
+ # local_part_suffix_optional
file = $home/.forward
+ # allow_filter
no_verify
no_expn
check_ancestor
- # allow_filter
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
+[revisionflag="changed"]
This is the most complicated router in the default configuration. It is another
redirection router, but this time it is looking for forwarding data set up by
-individual users. The %check_local_user% setting means that the first thing it
-does is to check that the local part of the address is the login name of a
-local user. If it is not, the router is skipped. When a local user is found,
-the file called _.forward_ in the user's home directory is consulted. If it
-does not exist, or is empty, the router declines. Otherwise, the contents of
-_.forward_ are interpreted as redirection data (see chapter <<CHAPredirect>>
-for more details).
+individual users. The %check_local_user% setting specifies a check that the
+local part of the address is the login name of a local user. If it is not, the
+router is skipped. The two commented options that follow %check_local_user%,
+namely:
+
+[revisionflag="changed"]
+....
+# local_part_suffix = +* : -*
+# local_part_suffix_optional
+....
+
+[revisionflag="changed"]
+cindex:[$local_part_suffix$]
+show how you can specify the recognition of local part suffixes. If the first
+is uncommented, a suffix beginning with either a plus or a minus sign, followed
+by any sequence of characters, is removed from the local part and placed in the
+variable $local_part_suffix$. The second suffix option specifies that the
+presence of a suffix in the local part is optional. When a suffix is present,
+the check for a local login uses the local part with the suffix removed.
+
+When a local user account is found, the file called _.forward_ in the user's
+home directory is consulted. If it does not exist, or is empty, the router
+declines. Otherwise, the contents of _.forward_ are interpreted as redirection
+data (see chapter <<CHAPredirect>> for more details).
cindex:[Sieve filter,enabling in default router]
Traditional _.forward_ files contain just a list of addresses, pipes, or
separate document entitled 'Exim's interfaces to mail filtering'.
The %no_verify% and %no_expn% options mean that this router is skipped when
-verifying addresses, or when running as a consequence of an SMTP EXPN
-command.
+verifying addresses, or when running as a consequence of an SMTP EXPN command.
There are two reasons for doing this:
. Whether or not a local user has a _.forward_ file is not really relevant when
It may therefore not be possible for Exim to read users' _.forward_ files at
this time.
-
The setting of %check_ancestor% prevents the router from generating a new
address that is the same as any previous address that was redirected. (This
works round a problem concerning a bad interaction between aliasing and
localuser:
driver = accept
check_local_user
+ # local_part_suffix = +* : -*
+ # local_part_suffix_optional
transport = local_delivery
+[revisionflag="changed"]
The final router sets up delivery into local mailboxes, provided that the local
-part is the name of a local login, by accepting the address and queuing it for
+part is the name of a local login, by accepting the address and assigning it to
the ^local_delivery^ transport. Otherwise, we have reached the end of the
-routers, so the address is bounced.
+routers, so the address is bounced. The commented suffix settings fulfil the
+same purpose as they do for the ^userforward^ router.
The documentation for the syntax and semantics of the regular expressions that
are supported by PCRE is included in plain text in the file
-_doc/pcrepattern.txt_ in the Exim distribution, and also in the HTML
-tarbundle of Exim documentation, and as an appendix to the Exim book
-(*http://www.uit.co.uk/exim-book/[]*).
-
-It describes in detail the features of the regular expressions that PCRE
-supports, so no further description is included here. The PCRE functions are
-called from Exim using the default option settings (that is, with no PCRE
-options set), except that the PCRE_CASELESS option is set when the
+_doc/pcrepattern.txt_ in the Exim distribution, and also in the HTML tarbundle
+of Exim documentation. It describes in detail the features of the regular
+expressions that PCRE supports, so no further description is included here. The
+PCRE functions are called from Exim using the default option settings (that is,
+with no PCRE options set), except that the PCRE_CASELESS option is set when the
matching is required to be case-insensitive.
In most cases, when a regular expression is required in an Exim configuration,
domains = ^\\d{3}\\.example\$
-if you want 'example' to be the top-level domain. (The backslash before the
-\$ is another artefact of string expansion.)
+if you want 'example' to be the top-level domain. The backslash before the
+\$ is needed because string expansion also interprets dollar characters.
. A string that is to be expanded may contain explicit lookup requests. These
cause parts of the string to be replaced by data that is obtained from the
-lookup.
+lookup. String expansions are described in detail in chapter <<CHAPexpand>>.
. Lists of domains, hosts, and email addresses can contain lookup requests as a
way of avoiding excessively long linear lists. In this case, the data that is
succeeds or fails is what really counts. These kinds of list are described in
chapter <<CHAPdomhosaddlists>>.
+[revisionflag="changed"]
+String expansions, lists, and lookups interact with each other in such a way
+that there is no order in which to describe any one of them that does not
+involve references to the others. Each of these three chapters makes more sense
+if you have read the other two first. If you are reading this for the first
+time, be aware that some of it will make a lot more sense after you have read
+chapters <<CHAPdomhosaddlists>> and <<CHAPexpand>>.
+
+
+Examples of different lookup syntax
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is easy to confuse the two different kinds of lookup, especially as the
lists that may contain the second kind are always expanded before being
processed as lists. Therefore, they may also contain lookups of the first kind.
domains = lsearch;/some/file
The first uses a string expansion, the result of which must be a domain list.
-String expansions are described in detail in chapter <<CHAPexpand>>. The
-expansion takes place first, and the file that is searched could contain lines
-like this:
+The expansion takes place before the string is processed as a list, and the
+file that is searched could contain lines like this:
- 192.168.3.4: domain1 : domain2 : ...
- 192.168.1.9: domain3 : domain4 : ...
+ 192.168.3.4: domain1:domain2:...
+ 192.168.1.9: domain3:domain4:...
-Thus, the result of the expansion is a list of domains (and possibly other
-types of item that are allowed in domain lists).
+The result of the expansion (assuming the lookup succeeds) is a list of domains
+(and possibly other types of item that are allowed in domain lists).
-In the second case, the lookup is a single item in a domain list. It causes
+In the second example, the lookup is a single item in a domain list. It causes
Exim to use a lookup to see if the domain that is being processed can be found
in the file. The file could contains lines like this:
Any data that follows the keys is not relevant when checking that the domain
matches the list item.
-It is possible to use both kinds of lookup at once. Consider a file containing
-lines like this:
+It is possible, though no doubt confusing, to use both kinds of lookup at once.
+Consider a file containing lines like this:
192.168.5.6: lsearch;/another/file
causes a second lookup to occur.
The rest of this chapter describes the different lookup types that are
-available. Any of them can be used in either of the circumstances described
-above. The syntax requirements for the two cases are described in chapters
-<<CHAPexpand>> and <<CHAPdomhosaddlists>>, respectively.
+available. Any of them can be used in any part of the configuration where a
+lookup is permitted.
Lookup types
~~~~~~~~~~~~
cindex:[lookup,types of]
cindex:[single-key lookup,definition of]
-Two different styles of data lookup are implemented:
+Two different types of data lookup are implemented:
-- The 'single-key' style requires the specification of a file in which to look,
+- The 'single-key' type requires the specification of a file in which to look,
and a single key to search for. The key must be a non-empty string for the
lookup to succeed. The lookup type determines how the file is searched.
- cindex:[query-style lookup,definition of]
-The 'query' style accepts a generalized database query.
-No particular key value is assumed by Exim for query-style lookups. You can
-use whichever Exim variable(s) you need to construct the database query.
+The 'query-style' type accepts a generalized database query. No particular key
+value is assumed by Exim for query-style lookups. You can use whichever Exim
+variables you need to construct the database query.
The code for each lookup type is in a separate source file that is included in
the binary of Exim only if the corresponding compile-time option is set. The
wildcarding of any kind.
+
cindex:[lookup,lsearch -- colons in keys]
-cindex:[whitespace,in lsearch key]
+cindex:[white space,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.
+characters, or white space. 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
cindex:[lookup,wildlsearch]
cindex:[nwildlsearch lookup type]
cindex:[lookup,nwildlsearch]
-^wildlsearch^ or ^nwildlsearch^: These search a file linearly, like
-^lsearch^, but instead of being interpreted as a literal string, each key may
+^wildlsearch^ or ^nwildlsearch^: These search a file linearly, like ^lsearch^,
+but instead of being interpreted as a literal string, each key in the file may
be wildcarded. The difference between these two lookup types is that for
^wildlsearch^, each key in the file is string-expanded before being used,
whereas for ^nwildlsearch^, no expansion takes place.
--
.. The string may begin with an asterisk to mean ``ends with''. For example:
- *.a.b.c data for anything.a.b.c
- *fish data for anythingfish
+ *.a.b.c data for anything.a.b.c
+ *fish data for anythingfish
.. The string may begin with a circumflex to indicate a regular expression. For
example, for ^wildlsearch^:
- ^\N\d+\.a\.b\N data for <digits>.a.b
+ ^\N\d+\.a\.b\N data for <digits>.a.b
Note the use of `\N` to disable expansion of the contents of the regular
expression. If you are using ^nwildlsearch^, where the keys are not
string-expanded, the equivalent entry is:
- ^\d+\.a\.b data for <digits>.a.b
+ ^\d+\.a\.b data for <digits>.a.b
If the regular expression contains white space or colon characters, you must
either quote it (see ^lsearch^ above), or represent these characters in other
colon. This may be easier than quoting, because if you quote, you have to
escape all the backslashes inside the quotes.
+*Note*: It is not possible to capture substrings in a regular expression match
+for later use, because the results of all lookups are cached. If a lookup is
+repeated, the result is taken from the cache, and no actual pattern matching
+takes place. The values of all the numeric variables are unset after a
+^(n)wildlsearch^ match.
+
.. Although I cannot see it being of much use, the general matching function
that is used to implement ^(n)wildlsearch^ means that the string may begin with
a lookup name terminated by a semicolon, and followed by lookup data. For
example:
- cdb;/some/file data for keys that match the file
+ cdb;/some/file data for keys that match the file
The data that is obtained from the nested lookup is discarded.
--
^pgsql^: The format of the query is an SQL statement that is passed to a
PostgreSQL database. See section <<SECTsql>>.
+[revisionflag="changed"]
+- cindex:[sqlite lookup type]
+cindex:[lookup,sqlite]
+^sqlite^: The format of the query is a file name followed by an SQL statement
+that is passed to an SQLite database. See section <<SECTsqlite>>.
+
- ^testdb^: This is a lookup type that is used for testing Exim. It is
not likely to be useful in normal operation.
~~~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[lookup,temporary error in]
Lookup functions can return temporary error codes if the lookup cannot be
-completed. For example, a NIS or LDAP database might be unavailable. For this
+completed. For example, an SQL or LDAP database might be unavailable. For this
reason, it is not advisable to use a lookup that might do this for critical
options such as a list of local domains.
If the data for a PTR record is not a syntactically valid IP address, it is not
altered and nothing is added.
+cindex:[MX record,in ^dnsdb^ lookup]
+cindex:[SRV record,in ^dnsdb^ lookup]
+For an MX lookup, both the preference value and the host name are returned for
+each record, separated by a space. For an SRV lookup, the priority, weight,
+port, and host name are returned for each record, 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, with newline as the default separator. The order, of course,
${lookup dnsdb{>: a=host1.example}}
It is permitted to specify a space as the separator character. Further
-whitespace is ignored.
-
-cindex:[SRV record,in ^dnsdb^ lookup]
-For SRV records, the priority, weight, port, and host name are returned for
-each record, separated by spaces.
+white space is ignored.
+Pseudo dnsdb record types
+~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[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:
+By default, both the preference value and the host name are returned for
+each MX record, separated by a space. If you want only host names, you can use
+the pseudo-type MXH:
${lookup dnsdb{mxh=a.b.example}}
-In this case, the preference values are omitted.
+In this case, the preference values are omitted, and just the host names are
+returned.
cindex:[name server,for enclosing domain]
Another pseudo-type is ZNS (for ``zone NS''). It performs a lookup for NS
for the high-level domains such as %com% or %co.uk% are not going to be on such
a list.
+[revisionflag="changed"]
+cindex:[CSA,in ^dnsdb^ lookup]
+A third pseudo-type is CSA (Client SMTP Authorization), which looks up SRV
+records according to the CSA rules, which are described in section
+<<SECTverifyCSA>>. Although ^dnsdb^ supports SRV lookups directly, this is not
+sufficient because of the extra parent domain search behaviour of CSA. The
+result of a successful lookup such as:
+
+[revisionflag="changed"]
+....
+${lookup dnsdb {csa=$sender_helo_name}}
+....
+
+[revisionflag="changed"]
+has two space-separated fields: an authorization code and a target host name.
+The authorization code can be ``Y'' for yes, ``N'' for no, ``X'' for explicit
+authorization required but absent, or ``?'' for unknown.
+
Multiple dnsdb lookups
~~~~~~~~~~~~~~~~~~~~~~
-In the previous section, ^dnsdb^ lookups for a single domain are described.
+In the previous sections, ^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:
[[SECTsql]]
+SQL lookups
+~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[SQL lookup types]
+Exim can support lookups in Interbase, MySQL, Oracle, PostgreSQL, and SQLite
+databases. Queries for these databases contain SQL statements, so an example
+might be
+
+....
+${lookup mysql{select mailbox from users where id='userx'}\
+ {$value}fail}
+....
+
+If the result of the query contains more than one field, the data for each
+field in the row is returned, preceded by its name, so the result of
+
+....
+${lookup pgsql{select home,name from users where id='userx'}\
+ {$value}}
+....
+
+might be
+
+ home=/home/userx name="Mister X"
+
+Empty values and values containing spaces are double quoted, with embedded
+quotes escaped by a backslash. If the result of the query contains just one
+field, the value is passed back verbatim, without a field name, for example:
+
+ Mister X
+
+If the result of the query yields more than one row, it is all concatenated,
+with a newline between the data for each row.
+
+
More about MySQL, PostgreSQL, Oracle, and Interbase
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[MySQL,lookup type]
cindex:[Interbase lookup type]
cindex:[lookup,Interbase]
If any MySQL, PostgreSQL, Oracle, or Interbase lookups are used, the
-%mysql_servers%, %pgsql_servers%, %oracle_servers%, or %ibase_servers%
-option (as appropriate) must be set to a colon-separated list of server
-information. Each item in the list is a slash-separated list of four items:
-host name, database name, user name, and password. In the case of Oracle, the
-host name field is used for the ``service name'', and the database name field is
-not used and should be empty. For example:
+%mysql_servers%, %pgsql_servers%, %oracle_servers%, or %ibase_servers% option
+(as appropriate) must be set to a colon-separated list of server information.
+Each item in the list is a slash-separated list of four items: host name,
+database name, user name, and password. In the case of Oracle, the host name
+field is used for the ``service name'', and the database name field is not used
+and should be empty. For example:
- hide oracle_servers = oracle.plc.example//ph10/abcdwxyz
+ hide oracle_servers = oracle.plc.example//userx/abcdwxyz
Because password data is sensitive, you should always precede the setting with
``hide'', to prevent non-admin users from obtaining the setting via the %-bP%
....
For MySQL and PostgreSQL, a host may be specified as <'name'>:<'port'> but
-because this is a colon-separated list, the colon has to be doubled.
-
-For each query, these parameter groups are tried in order until a connection
-and a query succeeds. Queries for these databases are SQL statements, so an
-example might be
-
-....
-${lookup mysql{select mailbox from users where id='ph10'}\
- {$value}fail}
-....
-
-If the result of the query contains more than one field, the data for
-each field in the row is returned, preceded by its name, so the result
-of
-
-....
-${lookup pgsql{select home,name from users where id='ph10'}\
- {$value}}
-....
-
-might be
-
- home=/home/ph10 name="Philip Hazel"
-
-Values containing spaces and empty values are double quoted, with embedded
-quotes escaped by a backslash.
-
-If the result of the query contains just one field, the value is passed back
-verbatim, without a field name, for example:
-
- Philip Hazel
-
-If the result of the query yields more than one row, it is all concatenated,
-with a newline between the data for each row.
+because this is a colon-separated list, the colon has to be doubled. For each
+query, these parameter groups are tried in order until a connection and a query
+succeeds.
The %quote_mysql%, %quote_pgsql%, and %quote_oracle% expansion operators
convert newline, tab, carriage return, and backspace to \n, \t, \r, and \b
characters are not special.
-
Special MySQL features
~~~~~~~~~~~~~~~~~~~~~~
For MySQL, an empty host name or the use of ``localhost'' in %mysql_servers%
is zero because no rows are affected.
-
-
Special PostgreSQL features
~~~~~~~~~~~~~~~~~~~~~~~~~~~
PostgreSQL lookups can also use Unix domain socket connections to the database.
update, or delete command), the result of the lookup is the number of rows
affected.
+[[SECTsqlite]]
+More about SQLite
+~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[lookup,SQLite]
+cindex:[SQLite lookup type]
+SQLite is different to the other SQL lookups because a file name is required in
+addition to the SQL query. An SQLite database is a single file, and there is no
+daemon as in the other SQL databases. The interface to Exim requires the name
+of the file, as an absolute path, to be given at the start of the query. It is
+separated from the query by white space. This means that the path name cannot
+contain white space. Here is a lookup expansion example:
+
+....
+${lookup sqlite {/some/thing/sqlitedb \
+ select name from aliases where id='userx';}}
+....
+
+[revisionflag="changed"]
+In a list, the syntax is similar. For example:
+
+....
+domainlist relay_domains = sqlite;/some/thing/sqlitedb \
+ select * from relays where ip='$sender_host_address';
+....
+
+[revisionflag="changed"]
+The only character affected by the %quote_sqlite% operator is a single
+quote, which it doubles.
+
+[revisionflag="changed"]
+The SQLite library handles multiple simultaneous accesses to the database
+internally. Multiple readers are permitted, but only one process can
+update at once. Attempts to access the database while it is being updated
+are rejected after a timeout period, during which the SQLite library
+waits for the lock to be released. In Exim, the default timeout is set
+to 5 seconds, but it can be changed by means of the %sqlite_lock_timeout%
+option.
A number of Exim configuration options contain lists of domains, hosts,
email addresses, or local parts. For example, the %hold_domains% option
contains a list of domains whose delivery is currently suspended. These lists
-are also used as data in ACL statements (see chapter <<CHAPACL>>).
+are also used as data in ACL statements (see chapter <<CHAPACL>>), and as
+arguments to expansion conditions such as %match_domain%.
Each item in one of these lists is a pattern to be matched against a domain,
host, email address, or local part, respectively. In the sections below, the
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.
+the way to specify empty list items.
If the string expansion is forced to fail, Exim behaves as if the item it is
When a string is being expanded it is copied verbatim from left to right except
when a dollar or backslash character is encountered. A dollar specifies the
-start of a portion of the string which is interpreted and replaced as described
+start of a portion of the string that is interpreted and replaced as described
below in section <<SECTexpansionitems>> onwards. Backslash is used as an escape
character, as described in the following section.
cindex:[expansion,including literal text]
An uninterpreted dollar can be included in an expanded string by putting a
backslash in front of it. A backslash can be used to prevent any special
-character being treated specially in an expansion, including itself. If the
-string appears in quotes in the configuration file, two backslashes are
+character being treated specially in an expansion, including backslash itself.
+If the string appears in quotes in the configuration file, two backslashes are
required because the quotes themselves cause interpretation of backslashes when
the string is read in (see section <<SECTstrings>>).
~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[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.
+alternative ``true'' and ``false'' substrings, enclosed in brace characters
+(which are sometimes called ``curly brackets''). Which of the two strings 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 braces),
+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.
${domain}
+
The second form can be used to separate the name from subsequent alphanumeric
-characters. This form (using curly brackets) is available only for variables;
-it does 'not' apply to message headers. The names of the variables are given
-in section <<SECTexpvar>> below. If the name of a non-existent variable is given,
-the expansion fails.
+characters. This form (using braces) is available only for variables; it does
+'not' apply to message headers. The names of the variables are given in section
+<<SECTexpvar>> below. If the name of a non-existent variable is given, the
+expansion fails.
*\$\{*<'op'>*:*<'string'>*\}*::
cindex:[expansion,operators]
one argument, because it reduces the number of braces and therefore makes the
string easier to understand.
-*\$\{extract\{*<'key'>*\}\{*<'string1'>*\}\{*<'string2'>*\}\{*<'string3'>*\}\}*::
-cindex:[expansion,extracting substrings by key]
-The key and <'string1'> are first expanded separately. Leading and trailing
-whitespace is removed from the key (but not from any of the strings). The key
-must not consist entirely of digits. The expanded <'string1'> must be of the
-form:
-
- <key1> = <value1> <key2> = <value2> ...
+*\$\{dlfunc\{*<'file'>*\}\{*<'function'>*\}\{*<'arg'>*\}\{*<'arg'>*\}...\}*::
+
-where the equals signs and spaces (but not both) are optional. If any of the
-values contain white space, they must be enclosed in double quotes, and any
-values that are enclosed in double quotes are subject to escape processing as
-described in section <<SECTstrings>>. The expanded <'string1'> is searched for
-the value that corresponds to the key. The search is case-insensitive. If the
-key is found, <'string2'> is expanded, and replaces the whole item; otherwise
-<'string3'> is used. During the expansion of <'string2'> the variable $value$
+[revisionflag="changed"]
+This expansion dynamically loads and then calls a locally-written C function.
+This functionality is available only if Exim is compiled with
++
+[revisionflag="changed"]
+....
+ EXPAND_DLFUNC=yes
+....
++
+[revisionflag="changed"]
+set in _Local/Makefile_. Once loaded, Exim remembers the dynamically loaded
+object so that it doesn't reload the same object file in the same Exim process
+(but of course Exim does start new processes frequently).
++
+[revisionflag="changed"]
+There may be from zero to eight arguments to the function. When compiling
+a local function that is to be called in this way, _local_scan.h_ should be
+included. The Exim variables and functions that are defined by that API
+are also available for dynamically loaded functions. The function itself
+must have the following type:
++
+[revisionflag="changed"]
+....
+int dlfunction(uschar **yield, int argc, uschar *argv[])
+....
++
+[revisionflag="changed"]
+Where `uschar` is a typedef for `unsigned char` in _local_scan.h_. The
+function should return one of the following values:
++
+[revisionflag="changed"]
+`OK`: Success. The string that is placed in the variable 'yield' is put into
+the expanded string that is being built.
++
+[revisionflag="changed"]
+`FAIL`: A non-forced expansion failure occurs, with the error message taken
+from 'yield', if it is set.
++
+[revisionflag="changed"]
+`FAIL_FORCED`: A forced expansion failure occurs, with the error message
+taken from 'yield' if it is set.
++
+[revisionflag="changed"]
+`ERROR`: Same as `FAIL`, except that a panic log entry is written.
++
+[revisionflag="changed"]
+When compiling a function that is to be used in this way with gcc,
+you need to add %-shared% to the gcc command. Also, in the Exim build-time
+configuration, you must add %-export-dynamic% to EXTRALIBS.
+
+
+*\$\{extract\{*<'key'>*\}\{*<'string1'>*\}\{*<'string2'>*\}\{*<'string3'>*\}\}*::
+cindex:[expansion,extracting substrings by key]
+The key and <'string1'> are first expanded separately. Leading and trailing
+white space is removed from the key (but not from any of the strings). The key
+must not consist entirely of digits. The expanded <'string1'> must be of the
+form:
+
+ <key1> = <value1> <key2> = <value2> ...
++
+cindex:[$value$]
+where the equals signs and spaces (but not both) are optional. If any of the
+values contain white space, they must be enclosed in double quotes, and any
+values that are enclosed in double quotes are subject to escape processing as
+described in section <<SECTstrings>>. The expanded <'string1'> is searched for
+the value that corresponds to the key. The search is case-insensitive. If the
+key is found, <'string2'> is expanded, and replaces the whole item; otherwise
+<'string3'> is used. During the expansion of <'string2'> the variable $value$
contains the value that has been extracted. Afterwards, it is restored to any
previous value it might have had.
+
*\$\{extract\{*<'number'>*\}\{*<'separators'>*\}\{*<'string1'>*\}\{*<'string2'>*\}\{*<'string3'>*\}\}*::
cindex:[expansion,extracting substrings by number]
The <'number'> argument must consist entirely of decimal digits,
-apart from leading and trailing whitespace, which is ignored.
+apart from leading and trailing white space, which is ignored.
This is what distinguishes this form of %extract% from the previous kind. It
behaves in the same way, except that, instead of extracting a named field, it
extracts from <'string1'> the field whose number is given as the first
data in the header line is interpreted.
+
--
-- cindex:[whitespace,in header lines]
+- cindex:[white space,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.
+processing at all, and without the removal of leading and trailing white space.
- cindex:[base64 encoding,in header lines]
-%bheader% removes leading and trailing whitespace, and then decodes base64 or
+%bheader% removes leading and trailing white space, and then decodes base64 or
quoted-printable MIME ``words'' within the header text, but does no character
set translation. If decoding of what looks superficially like a MIME ``word''
fails, the raw string is returned. If decoding
+
....
headers_add = \
- X-Spam-Scanned: ${primary_hostname} ${message_id} \
+ X-Spam-Scanned: ${primary_hostname} ${message_exim_id} \
${hmac{md5}{SPAMSCAN_SECRET}\
- {${primary_hostname},${message_id},$h_message-id:}}
+ {${primary_hostname},${message_exim_id},$h_message-id:}}
....
+
Then given a message, you can check where it was scanned by looking at the
out the use of this expansion item in filter files.
+*\$\{prvs\{*<'address'>*\}\{*<'secret'>*\}\{*<'keynumber'>*\}\}*::
++
+[revisionflag="changed"]
+cindex:[prvs,expansion item]
+The first argument is a complete email address and the second is secret
+keystring. The third argument, specifying a key number, is optional. If absent,
+it defaults to 0. The result of the expansion is a prvs-signed email address,
+to be typically used with the %return_path% option on an ^smtp^ transport as
+part of a bounce address tag validation (BATV) scheme. For more discussion and
+an example, see section <<SECTverifyPRVS>>.
+
+
+*\$\{prvscheck\{*<'address'>*\}\{*<'secret'>*\}\{*<'string'>*\}\}*::
++
+[revisionflag="changed"]
+cindex:[prvscheck,expansion item]
+This expansion item is the complement of the %prvs% item. It is used for
+checking prvs-signed addresses. If the expansion of the first argument does not
+yield a syntactically valid prvs-signed address, the whole item expands to the
+empty string. When the first argument does expand to a syntactically valid
+prvs-signed address, the second argument is expanded, with the prvs-decoded
+version of the address and the key number extracted from the address in the
+variables $prvscheck_address$ and $prvscheck_keynum$, respectively.
++
+[revisionflag="changed"]
+These two variables can be used in the expansion of the second argument to
+retrieve the secret. The validity of the prvs-signed address is then checked
+against the secret. The result is stored in the variable $prvscheck_result$,
+which is empty for failure or ``1'' for success.
++
+[revisionflag="changed"]
+The third argument is optional; if it is missing, it defaults to an empty
+string. This argument is now expanded. If the result is an empty string, the
+result of the expansion is the decoded version of the address. This is the case
+whether or not the signature was valid. Otherwise, the result of the expansion
+is the expansion of the third argument.
++
+[revisionflag="changed"]
+All three variables can be used in the expansion of the third argument.
+However, once the expansion is complete, only $prvscheck_result$ remains set.
+For more discussion and an example, see section <<SECTverifyPRVS>>.
+
+
*\$\{readfile\{*<'file~name'>*\}\{*<'eol~string'>*\}\}*::
cindex:[expansion,inserting an entire file]
cindex:[file,inserting into expansion]
other command executions from Exim, a shell is not used by default. If you want
a shell, you must explicitly code it.
+
+[revisionflag="changed"]
cindex:[return code,from %run% expansion]
+cindex:[$value$]
If the command succeeds (gives a zero return code) <'string1'> is expanded and
replaces the entire item; during this expansion, the standard output from the
command is in the variable $value$. If the command fails, <'string2'>, if
-present, is expanded. If it is absent, the result is empty. Alternatively,
-<'string2'> can be the word ``fail'' (not in braces) to force expansion failure
-if the command does not succeed. If both strings are omitted, the result is the
-standard output on success, and nothing on failure.
-+
+present, is expanded and used. Once again, during the expansion, the standard
+output from the command is in the variable $value$. If <'string2'> is absent,
+the result is empty. Alternatively, <'string2'> can be the word ``fail'' (not
+in braces) to force expansion failure if the command does not succeed. If both
+strings are omitted, the result is contents of the standard output on success,
+and nothing on failure.
++
+cindex:[$runrc$]
The return code from the command is put in the variable $runrc$, and this
remains set afterwards, so in a filter file you can do things like this:
*\$\{base62:*<'digits'>*\}*::
++
+[revisionflag="changed"]
cindex:[base62]
cindex:[expansion,conversion to base 62]
The string must consist entirely of decimal digits. The number is converted to
-base 62 (sic) and output as a string of six characters, including leading
-zeros. *Note*: Just to be absolutely clear: this is 'not' base64
-encoding.
+base 62 and output as a string of six characters, including leading zeros. In
+the few operating environments where Exim uses base 36 instead of base 62 for
+its message identifiers (because those systems do not have case-sensitive file
+names), base 36 is used by this operator, despite its name. *Note*: Just to be
+absolutely clear: this is 'not' base64 encoding.
*\$\{base62d:*<'base-62~digits'>*\}*::
++
+[revisionflag="changed"]
cindex:[base62]
cindex:[expansion,conversion to base 62]
-The string must consist entirely of base-62 digits. The number is converted to
-decimal and output as a string.
+The string must consist entirely of base-62 digits, or, in operating
+environments where Exim uses base 36 instead of base 62 for its message
+identifiers, base-36 digits. The number is converted to decimal and output as a
+string.
*\$\{domain:*<'string'>*\}*::
*\$\{eval:*<'string'>*\}*::
*\$\{eval10:*<'string'>*\}*::
++
+[revisionflag="changed"]
cindex:[expansion,expression evaluation]
cindex:[expansion,arithmetic expression]
These items supports simple arithmetic in expansion strings. The string (after
expansion) must be a conventional arithmetic expression, but it is limited to
-the four basic operators (plus, minus, times, divide) and parentheses. All
-operations are carried out using integer arithmetic. Plus and minus have a
-lower priority than times and divide; operators with the same priority are
-evaluated from left to right.
+five basic operators (plus, minus, times, divide, remainder) and parentheses.
+All operations are carried out using integer arithmetic. Plus and minus have a
+lower priority than times, divide, and remainder; operators with the same
+priority are evaluated from left to right.
+
For %eval%, numbers may be decimal, octal (starting with ``0'') or hexadecimal
(starting with ``0x''). For %eval10%, all numbers are taken as decimal, even if
respectively. Negative numbers are supported. The result of the computation is
a decimal representation of the answer (without ``K'' or ``M''). For example:
+
+[revisionflag="changed"]
&&&
`\${eval:1+1} ` yields 2
`\${eval:1+2*3} ` yields 7
`\${eval:(1+2)*3} ` yields 9
+`\${eval:2+42%5} ` yields 4
&&&
+
As a more realistic example, in an ACL you might have
*\$\{rfc2047:*<'string'>*\}*::
cindex:[expansion,RFC 2047]
+cindex:[RFC 2047,expansion operator]
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
? = ( ) < > @ , ; : \ " . [ ] _
+
it is not modified. Otherwise, the result is the RFC 2047 encoding of the
-string, using as many ``coded words'' as necessary to encode all the
+string, using as many ``encoded words'' as necessary to encode all the
characters.
The string, after expansion, must be a file path. A call to the 'stat()'
function is made for this path. If 'stat()' fails, an error occurs and the
expansion fails. If it succeeds, the data from the stat replaces the item, as a
-series of <'name'>=<'value'> pairs, where the values are all numerical,
-except for the value of ``smode''. The names are: ``mode'' (giving the mode as a
+series of <'name'>=<'value'> pairs, where the values are all numerical, except
+for the value of ``smode''. The names are: ``mode'' (giving the mode as a
4-digit octal number), ``smode'' (giving the mode in symbolic format as a
-10-character string, as for the 'ls' command), ``inode'', ``device'', ``links'',
-``uid'', ``gid'', ``size'', ``atime'', ``mtime'', and ``ctime''. You can extract individual
-fields using the %extract% expansion item. *Warning*: The file size may be
-incorrect on 32-bit systems for files larger than 2GB.
+10-character string, as for the 'ls' command), ``inode'', ``device'',
+``links'', ``uid'', ``gid'', ``size'', ``atime'', ``mtime'', and ``ctime''. You
+can extract individual fields using the %extract% expansion item.
++
+[revisionflag="changed"]
+The use of the %stat% expansion in users' filter files can be locked out by the
+system administrator. *Warning*: The file size may be incorrect on 32-bit
+systems for files larger than 2GB.
*\$\{str2b64:*<'string'>*\}*::
${if def:header_reply-to:{$h_reply-to:}{$h_from:}}
+
-Note that no %\$% appears before %header_% or %h_% in the condition,
-and that header names must be terminated by colons if white space does not
-follow.
+*Note*: no %\$% appears before %header_% or %h_% in the condition, and the
+header name must be terminated by a colon if white space does not follow.
*eq~\{*<'string1'>*\}\{*<'string2'>*\}*::
cindex:[string,comparison]
combination of conditions using %or%, the subsequent values of the numeric
variables are those of the condition that succeeded.
-*match_domain~\{*<'string1'>*\}\{*<'string2'>*\}*::
+*match_address~\{*<'string1'>*\}\{*<'string2'>*\}*::
See *match_local_part*.
-*match_address~\{*<'string1'>*\}\{*<'string2'>*\}*::
+*match_domain~\{*<'string1'>*\}\{*<'string2'>*\}*::
See *match_local_part*.
+*match_ip~\{*<'string1'>*\}\{*<'string2'>*\}*::
++
+[revisionflag="changed"]
+This condition matches an IP address to a list of IP address patterns. It must
+be followed by two argument strings. The first (after expansion) must be an IP
+address or an empty string. The second (after expansion) is a restricted host
+list that can match only an IP address, not a host name. For example:
++
+[revisionflag="changed"]
+....
+${if match_ip{$sender_host_address}{1.2.3.4:5.6.7.8}{...}{...}}
+....
++
+[revisionflag="changed"]
+The specific types of host list item that are permitted in the list are:
++
+--
+- An IP address, optionally with a CIDR mask.
+
+- A single asterisk, which matches any IP address.
+
+- An empty item, which matches only if the IP address is empty. This could be
+useful for testing for a locally submitted message or one from specific hosts
+in a single test such as
+
+....
+ ${if match_ip{$sender_host_address}{:4.3.2.1:...}{...}{...}}
+....
+
+where the first item in the list is the empty string.
+
+- The item @[] matches any of the local host's interface addresses.
+
+- Lookups are assumed to be ``net-'' style lookups, even if `net-` is not
+specified. Thus, the following are equivalent:
+
+....
+ ${if match_ip{$sender_host_address}{lsearch;/some/file}...
+ ${if match_ip{$sender_host_address}{net-lsearch;/some/file}...
+....
+
+You do need to specify the `net-` prefix if you want to specify a
+specific address mask, for example, by using `net24-`.
+--
++
+[revisionflag="changed"]
+Consult section <<SECThoslispatip>> for further details of these patterns.
+
+
+
*match_local_part~\{*<'string1'>*\}\{*<'string2'>*\}*::
cindex:[domain list,in expansion condition]
cindex:[address list,in expansion condition]
cindex:[local part list,in expansion condition]
-These conditions make it possible to test domain, address, and local
-part lists within expansions. Each condition requires two arguments: an item
-and a list to match. A trivial example is:
+This condition, together with %match_address% and %match_domain%, make it
+possible to test domain, address, and local part lists within expansions. Each
+condition requires two arguments: an item and a list to match. A trivial
+example is:
${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}
+
+
*Note*: Host lists are 'not' supported in this way. This is because
hosts have two identities: a name and an IP address, and it is not clear
-how to specify cleanly how such a test would work. At least, I haven't come
-up with anything yet.
+how to specify cleanly how such a test would work. However, IP addresses can be
+matched using %match_ip%.
*pam~\{*<'string1'>*:*<'string2'>*:...\}*::
cindex:[PAM authentication]
in some releases of GNU/Linux %-ldl% is also needed.
+
The argument string is first expanded, and the result must be a
-colon-separated list of strings. Leading and trailing whitespace is ignored.
+colon-separated list of strings. Leading and trailing white space is ignored.
The PAM module is initialized with the service name ``exim'' and the user name
taken from the first item in the colon-separated data string (<'string1'>). The
remaining items in the data string are passed over in response to requests from
the Radius client configuration file in order to build Exim with Radius
support.
+
+[revisionflag="changed"]
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
+library, using the original API. If you are using release 0.4.0 or later of
+this library, you need to set
++
+[revisionflag="changed"]
+....
+RADIUS_LIB_TYPE=RADIUSCLIENTNEW
+....
++
+[revisionflag="changed"]
+in _Local/Makefile_ when building Exim. You can also link Exim with the
+%libradius% library that comes with FreeBSD. To do this, set
RADIUS_LIB_TYPE=RADLIB
+
during subsequent delivery.
$acl_verify_message$::
-During the expansion of the %message% and %log_message% modifiers in an ACL
-statement after an address verification has failed, this variable contains the
-original failure message that will be overridden by the expanded string.
++
+[revisionflag="changed"]
+cindex:[$acl_verify_message$]
+After an address verification has failed, this variable contains the failure
+message. It retains its value for use in subsequent modifiers. The message can
+be preserved by coding like this:
++
+[revisionflag="changed"]
+....
+warn !verify = sender
+ set acl_m0 = $acl_verify_message
+....
++
+[revisionflag="changed"]
+You can use $acl_verify_message$ during the expansion of the %message% or
+%log_message% modifiers, to include information about the verification failure.
+
$address_data$::
+cindex:[$address_data$]
This variable is set by means of the %address_data% 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,
these values for longer, you can save them in ACL variables.
$address_file$::
+cindex:[$address_file$]
When, as a result of aliasing, forwarding, or filtering, a message is directed
to a specific file, this variable holds the name of the file when the transport
is running. At other times, the variable is empty. For example, using the
to the relevant file.
$address_pipe$::
+cindex:[$address_pipe$]
When, as a result of aliasing or forwarding, a message is directed to a pipe,
this variable holds the pipe command when the transport is running.
$authenticated_id$::
cindex:[authentication,id]
+cindex:[$authenticated_id$]
When a server successfully authenticates a client it may be configured to
preserve some of the authentication information in the variable
$authenticated_id$ (see chapter <<CHAPSMTPAUTH>>). For example, a user/password
authenticator configuration might preserve the user name for use in the
-routers. When a message is submitted locally (that is, not over a TCP
-connection), the value of $authenticated_id$ is the login name of the calling
-process.
+routers. Note that this is not the same information that is saved in
+$sender_host_authenticated$. When a message is submitted locally (that is, not
+over a TCP connection), the value of $authenticated_id$ is the login name of
+the calling process.
$authenticated_sender$::
cindex:[sender,authenticated]
cindex:[authentication,sender]
cindex:[AUTH,on MAIL command]
+cindex:[$authenticated_sender$]
When acting as a server, Exim takes note of the AUTH= parameter on an incoming
SMTP MAIL command if it believes the sender is sufficiently trusted, as
described in section <<SECTauthparamail>>. Unless the data is the string
available during delivery in the $authenticated_sender$ variable. If the sender
is not trusted, Exim accepts the syntax of AUTH=, but ignores the data.
+
+cindex:[$qualify_domain$]
When a message is submitted locally (that is, not over a TCP connection), the
value of $authenticated_sender$ is an address constructed from the login
name of the calling process and $qualify_domain$.
$authentication_failed$::
cindex:[authentication,failure]
+cindex:[$authentication_failed$]
This variable is set to ``1'' in an Exim server if a client issues an AUTH
command that does not succeed. Otherwise it is set to ``0''. This makes it
possible to distinguish between ``did not try to authenticate''
$body_linecount$::
cindex:[message body, line count]
cindex:[body of message,line count]
+cindex:[$body_linecount$]
When a message is being received or delivered, this variable contains the
-number of lines in the message's body.
+number of lines in the message's body. See also $message_linecount$.
$body_zerocount$::
cindex:[message body, binary zero count]
cindex:[body of message,binary zero count]
cindex:[binary zero,in message body]
+cindex:[$body_zerocount$]
When a message is being received or delivered, this variable contains the
number of binary zero bytes in the message's body.
$bounce_recipient$::
+cindex:[$bounce_recipient$]
This is set to the recipient address of a bounce message while Exim is creating
it. It is useful if a customized bounce message text file is in use (see
chapter <<CHAPemsgcust>>).
$bounce_return_size_limit$::
+cindex:[$bounce_return_size_limit$]
This contains the value set in the %bounce_return_size_limit% option, rounded
up to a multiple of 1000. It is useful when a customized error message text
file is in use (see chapter <<CHAPemsgcust>>).
$caller_gid$::
cindex:[gid (group id),caller]
+cindex:[$caller_gid$]
The real group id under which the process that called Exim was running. This is
not the same as the group id of the originator of a message (see
$originator_gid$). If Exim re-execs itself, this variable in the new
$caller_uid$::
cindex:[uid (user id),caller]
+cindex:[$caller_uid$]
The real user id under which the process that called Exim was running. This is
not the same as the user id of the originator of a message (see
$originator_uid$). If Exim re-execs itself, this variable in the new
incarnation normally contains the Exim uid.
$compile_date$::
+cindex:[$compile_date$]
The date on which the Exim binary was compiled.
$compile_number$::
+cindex:[$compile_number$]
The building process for Exim keeps a count of the number
of times it has been compiled. This serves to distinguish different
compilations of the same version of the program.
$demime_errorlevel$::
+cindex:[$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>>.
$demime_reason$::
+cindex:[$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>>.
$dnslist_domain$::
cindex:[black list (DNS)]
+cindex:[$dnslist_domain$]
When a client host is found to be on a DNS (black) list,
the list's domain name is put into this variable so that it can be included in
the rejection message.
$dnslist_text$::
+cindex:[$dnslist_text$]
When a client host is found to be on a DNS (black) list, the
contents of any associated TXT record are placed in this variable.
$dnslist_value$::
+cindex:[$dnslist_value$]
When a client host is found to be on a DNS (black) list,
the IP address from the resource record is placed in this variable.
If there are multiple records, all the addresses are included, comma-space
separated.
$domain$::
-When an address is being routed, or delivered on its own, this
-variable contains the domain. Global address rewriting happens when a message
-is received, so the value of $domain$ during routing and delivery is the
-value after rewriting. $domain$ is set during user filtering, but not during
-system filtering, because a message may have many recipients and the system
-filter is called just once.
+cindex:[$domain$]
+When an address is being routed, or delivered on its own, this variable
+contains the domain. Global address rewriting happens when a message is
+received, so the value of $domain$ during routing and delivery is the value
+after rewriting. $domain$ is set during user filtering, but not during system
+filtering, because a message may have many recipients and the system filter is
+called just once.
+
When more than one address is being delivered at once (for example, several
RCPT commands in one SMTP delivery), $domain$ is set only if they all
set in $domain$ during the expansion of %delay_warning_condition%.
+
The $domain$ variable is also used in some other circumstances:
-
-- When an ACL is running for a RCPT command, $domain$ contains the domain
-of the recipient address.
-*Note:* the domain of the sender address is in $sender_address_domain$
-at MAIL time and at RCPT time. $domain$ is not set for the MAIL
-ACL.
++
+--
+- When an ACL is running for a RCPT command, $domain$ contains the domain of
+the recipient address. The domain of the 'sender' address is in
+$sender_address_domain$ at both MAIL time and at RCPT time. $domain$ is not
+normally set during the running of the MAIL ACL. However, if the sender address
+is verified with a callout during the MAIL ACL, the sender domain is placed in
+$domain$ during the expansions of %hosts%, %interface%, and %port% in the
+^smtp^ transport.
- When a rewrite item is being processed (see chapter <<CHAPrewrite>>), $domain$
contains the domain portion of the address that is being rewritten; it can be
cindex:[%smtp_etrn_command%]
When the %smtp_etrn_command% option is being expanded, $domain$ contains
the complete argument of the ETRN command (see section <<SECTETRN>>).
+--
$domain_data$::
+cindex:[$domain_data$]
When the %domains% option on a router matches a domain by
means of a lookup, the data read by the lookup is available during the running
of the router as $domain_data$. In addition, if the driver routes the
to nothing.
$exim_gid$::
+cindex:[$exim_gid$]
This variable contains the numerical value of the Exim group id.
$exim_path$::
+cindex:[$exim_path$]
This variable contains the path to the Exim binary.
$exim_uid$::
+cindex:[$exim_uid$]
This variable contains the numerical value of the Exim user id.
$found_extension$::
+cindex:[$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>>.
$header_$<'name'>::
-This is not strictly an expansion variable. It is
-expansion syntax for inserting the message header line with the given name.
-Note that the name must be terminated by colon or white space, because it may
-contain a wide variety of characters.
-Note also that braces must 'not' be used.
+This is not strictly an expansion variable. It is expansion syntax for
+inserting the message header line with the given name. Note that the name must
+be terminated by colon or white space, because it may contain a wide variety of
+characters. Note also that braces must 'not' be used.
$home$::
+cindex:[$home$]
When the %check_local_user% option is set for a router, the user's home
directory is placed in $home$ when the check succeeds. In particular, this
means it is set during the running of users' filter files. A router may also
of the environment variable HOME.
$host$::
+cindex:[$host$]
When the ^smtp^ transport is expanding its options for encryption using TLS,
$host$ contains the name of the host to which it is connected. Likewise, when
used in the client part of an authenticator configuration (see chapter
name of the first host.
$host_address$::
+cindex:[$host_address$]
This variable is set to the remote host's IP address whenever $host$ is set for
a remote connection. It is also set to the IP address that is being checked
when the %ignore_target_hosts% option is being processed.
$host_data$::
+cindex:[$host_data$]
If a %hosts% condition in an ACL is satisfied by means of a lookup, the result
of the lookup is made available in the $host_data$ variable. This
allows you, for example, to do things like this:
$host_lookup_deferred$::
cindex:[host name lookup, failure of]
+cindex:[$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
``1''. See also $sender_host_name$.
$host_lookup_failed$::
+cindex:[$host_lookup_failed$]
See $host_lookup_deferred$.
$inode$::
+cindex:[$inode$]
The only time this variable is set is while expanding the %directory_file%
option in the ^appendfile^ transport. The variable contains the inode number
of the temporary file which is about to be renamed. It can be used to construct
a unique name for the file.
$interface_address$::
-When a message is received over a TCP/IP connection, this variable contains the
-address of the local IP interface. See also the %-oMi% command line option.
-This variable can be used in ACLs and also, for example, to make the file name
-for a TLS certificate depend on which interface is being used.
++
+[revisionflag="changed"]
+cindex:[$interface_address$]
+As soon as a server starts processing a TCP/IP connection, this variable is set
+to the address of the local IP interface, and $interface_port$ is set to the
+port number. These values are therefore available for use in the ``connect''
+ACL. See also the %-oMi% command line option. As well as being used in ACLs,
+these variable could be used, for example, to make the file name for a TLS
+certificate depend on which interface and/or port is being used.
$interface_port$::
-When a message is received over a TCP/IP connection, this variable contains the
-local port number. See also the %-oMi% command line option.
-This variable can be used in ACLs and also, for example, to make the file name
-for a TLS certificate depend on which port is being used.
+cindex:[$interface_port$]
+See $interface_address$.
$ldap_dn$::
+cindex:[$ldap_dn$]
This variable, which is available only when Exim is compiled with LDAP support,
contains the DN from the last entry in the most recently successful LDAP
lookup.
$load_average$::
+cindex:[$load_average$]
This variable contains the system load average, multiplied by 1000 to that it
is an integer. For example, if the load average is 0.21, the value of the
variable is 210. The value is recomputed every time the variable is referenced.
$local_part$::
+cindex:[$local_part$]
When an address is being routed, or delivered on its own, this
variable contains the local part. When a number of addresses are being
delivered together (for example, multiple RCPT commands in an SMTP
because a message may have many recipients and the system filter is called just
once.
+
+cindex:[$local_part_prefix$]
+cindex:[$local_part_suffix$]
If a local part prefix or suffix has been recognized, it is not included in the
value of $local_part$ during routing and subsequent delivery. The values of
any prefix or suffix are in $local_part_prefix$ and
%caseful_local_part% option (see chapter <<CHAProutergeneric>>).
$local_part_data$::
+cindex:[$local_part_data$]
When the %local_parts% option on a router matches a local part by means of a
lookup, the data read by the lookup is available during the running of the
router as $local_part_data$. In addition, if the driver routes the address
variable expands to nothing.
$local_part_prefix$::
+cindex:[$local_part_prefix$]
When an address is being routed or delivered, and a
specific prefix for the local part was recognized, it is available in this
variable, having been removed from $local_part$.
$local_part_suffix$::
+cindex:[$local_part_suffix$]
When an address is being routed or delivered, and a
specific suffix for the local part was recognized, it is available in this
variable, having been removed from $local_part$.
$local_scan_data$::
+cindex:[$local_scan_data$]
This variable contains the text returned by the 'local_scan()' function when a
message is received. See chapter <<CHAPlocalscan>> for more details.
$local_user_gid$::
+cindex:[$local_user_gid$]
See $local_user_uid$.
$local_user_uid$::
-This variable and $local_user_gid$ are set to
-the uid and gid after the %check_local_user% router precondition succeeds.
-This means that their values are available for the remaining preconditions
-(%senders%, %require_files%, and %condition%), for the %address_data%
-expansion, and for any router-specific expansions. At all other times, the
-values in these variables are `(uid_t)(-1)` and `(gid_t)(-1)`,
-respectively.
+cindex:[$local_user_uid$]
+This variable and $local_user_gid$ are set to the uid and gid after the
+%check_local_user% router precondition succeeds. This means that their values
+are available for the remaining preconditions (%senders%, %require_files%, and
+%condition%), for the %address_data% expansion, and for any router-specific
+expansions. At all other times, the values in these variables are `(uid_t)(-1)`
+and `(gid_t)(-1)`, respectively.
$localhost_number$::
+cindex:[$localhost_number$]
This contains the expanded value of the
%localhost_number% option. The expansion happens after the main options have
been read.
$log_inodes$::
+cindex:[$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.
$log_space$::
+cindex:[$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
$mailstore_basename$::
-This variable is set only when doing deliveries in
-``mailstore'' format in the ^appendfile^ transport. During the expansion of the
-%mailstore_prefix%, %mailstore_suffix%, %message_prefix%, and
-%message_suffix% options, it contains the basename of the files that are being
-written, that is, the name without the ``.tmp'', ``.env'', or ``.msg'' suffix. At all
-other times, this variable is empty.
+cindex:[$mailstore_basename$]
+This variable is set only when doing deliveries in ``mailstore'' format in the
+^appendfile^ transport. During the expansion of the %mailstore_prefix%,
+%mailstore_suffix%, %message_prefix%, and %message_suffix% options, it contains
+the basename of the files that are being written, that is, the name without the
+``.tmp'', ``.env'', or ``.msg'' suffix. At all other times, this variable is
+empty.
$malware_name$::
+cindex:[$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>>).
$message_age$::
cindex:[message,age of]
-This variable is set at the start of a delivery attempt to
-contain the number of seconds since the message was received. It does not
-change during a single delivery attempt.
+cindex:[$message_age$]
+This variable is set at the start of a delivery attempt to contain the number
+of seconds since the message was received. It does not change during a single
+delivery attempt.
$message_body$::
cindex:[body of message,expansion variable]
cindex:[message body, in expansion]
cindex:[binary zero,in message body]
+cindex:[$message_body$]
This variable contains the initial portion of a message's
body while it is being delivered, and is intended mainly for use in filter
files. The maximum number of characters of the body that are put into the
$message_body_end$::
cindex:[body of message,expansion variable]
cindex:[message body, in expansion]
+cindex:[$message_body_end$]
This variable contains the final portion of a message's
body while it is being delivered. The format and maximum size are as for
$message_body$.
$message_body_size$::
cindex:[body of message,size]
cindex:[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$, $body_linecount$, and
-$body_zerocount$.
+cindex:[$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$, $body_linecount$, and $body_zerocount$.
+
+$message_exim_id$::
++
+[revisionflag="changed"]
+cindex:[$message_exim_id$]
+When a message is being received or delivered, this variable contains the
+unique message id that is generated and used by Exim to identify the message.
+An id is not created for a message until after its header has been successfully
+received. *Note*: This is 'not' the contents of the 'Message-ID:' header line;
+it is the local id that Exim assigns to the message, for example:
+`1BXTIK-0001yO-VA`.
$message_headers$::
This variable contains a concatenation of all the header lines when a message
lines are separated by newline characters.
$message_id$::
-When a message is being received or delivered, this variable contains the
-unique message id that is used by Exim to identify the message.
-An id is not created for a message until after its header has been
-successfully received.
-*Note*: This is 'not' the contents of the 'Message-ID:' header line; it
-is the local id that Exim assigns to the message, for example:
-`1BXTIK-0001yO-VA`.
++
+[revisionflag="changed"]
+This is an old name for $message_exim_id$, which is now deprecated.
+
+$message_linecount$::
++
+[revisionflag="changed"]
+cindex:[$message_linecount$]
+This variable contains the total number of lines in the header and body of the
+message. Compare $body_linecount$, which is the count for the body only. During
+the DATA and content-scanning ACLs, $message_linecount$ contains the number of
+lines received. Before delivery happens (that is, before filters, routers, and
+transports run) the count is increased to include the 'Received:' header line
+that Exim standardly adds, and also any other header lines that are added by
+ACLs. The blank line that separates the message header from the body is not
+counted. Here is an example of the use of this variable in a DATA ACL:
++
+[revisionflag="changed"]
+....
+deny message = Too many lines in message header
+ condition = \
+ ${if <{250}{${eval: $message_linecount - $body_linecount}}}
+....
++
+[revisionflag="changed"]
+In the MAIL and RCPT ACLs, the value is zero because at that stage the
+message has not yet been received.
$message_size$::
cindex:[size,of message]
cindex:[message,size]
+cindex:[$message_size$]
When a message is being processed, this variable contains its size in bytes. In
most cases, the size includes those headers that were received with the
message, but not those (such as 'Envelope-to:') that are added to individual
available when Exim is compiled with the content-scanning extension. For
details, see section <<SECTscanmimepart>>.
-
$n0$ -- $n9$::
These variables are counters that can be incremented by means
of the %add% command in filter files.
$original_domain$::
-When a top-level address is being processed for delivery,
-this contains the same value as $domain$. However, if a ``child'' address (for
-example, generated by an alias, forward, or filter file) is being processed,
-this variable contains the domain of the original address. This differs from
-$parent_domain$ 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_domain$ is not set.
+cindex:[$domain$]
+cindex:[$original_domain$]
+When a top-level address is being processed for delivery, this contains the
+same value as $domain$. However, if a ``child'' address (for example, generated
+by an alias, forward, or filter file) is being processed, this variable
+contains the domain of the original address. This differs from $parent_domain$
+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_domain$ 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
part 'system-filter' and the default qualify domain.
$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, 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.
+cindex:[$local_part$]
+cindex:[$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, 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.
filter, it is set up with an artificial ``parent'' address. This has the local
part 'system-filter' and the default qualify domain.
-
$originator_gid$::
cindex:[gid (group id),of originating user]
cindex:[sender,gid]
-The value of $caller_gid$ that was set when the message
+cindex:[$caller_gid$]
+cindex:[$originator_gid$]
+This variable contains the value of $caller_gid$ that was set when the message
was received. For messages received via the command line, this is the gid of
the sending user. For messages received by SMTP over TCP/IP, this is normally
the gid of the Exim user.
$originator_uid$::
cindex:[uid (user id),of originating user]
cindex:[sender,uid]
-The value of $caller_uid$ that was set when the message
-was received. For messages received via the command line, this is the uid of
-the sending user. For messages received by SMTP over TCP/IP, this is normally
-the uid of the Exim user.
+cindex:[$caller_uid$]
+cindex:[$originaltor_uid$]
+The value of $caller_uid$ that was set when the message was received. For
+messages received via the command line, this is the uid of the sending user.
+For messages received by SMTP over TCP/IP, this is normally the uid of the Exim
+user.
$parent_domain$::
+cindex:[$parent_domain$]
This variable is similar to $original_domain$ (see
above), except that it refers to the immediately preceding parent address.
$parent_local_part$::
+cindex:[$parent_local_part$]
This variable is similar to $original_local_part$
(see above), except that it refers to the immediately preceding parent address.
$pid$::
cindex:[pid (process id),of current process]
+cindex:[$pid$]
This variable contains the current process id.
$pipe_addresses$::
cindex:[filter,transport filter]
cindex:[transport,filter]
-This is not an expansion variable, but is mentioned here
-because the string ``\$pipe_addresses'' is handled specially in the command
-specification for the ^pipe^ transport (chapter <<CHAPpipetransport>>) and in
-transport filters (described under %transport_filter% in chapter
-<<CHAPtransportgeneric>>). It cannot be used in general expansion strings, and
-provokes an ``unknown variable'' error if encountered.
+cindex:[$pipe_addresses$]
+This is not an expansion variable, but is mentioned here because the string
+``\$pipe_addresses'' is handled specially in the command specification for the
+^pipe^ transport (chapter <<CHAPpipetransport>>) and in transport filters
+(described under %transport_filter% in chapter <<CHAPtransportgeneric>>). It
+cannot be used in general expansion strings, and provokes an ``unknown
+variable'' error if encountered.
$primary_hostname$::
-The value set in the configuration file, or read by the
-'uname()' function. If 'uname()' returns a single-component name, Exim
-calls 'gethostbyname()' (or 'getipnodebyname()' where available) in an
-attempt to acquire a fully qualified host name.
-See also $smtp_active_hostname$.
+cindex:[$primary_hostname$]
+This variable contains the value set by %primary_hostname% in the configuration
+file, or read by the 'uname()' function. If 'uname()' returns a
+single-component name, Exim calls 'gethostbyname()' (or 'getipnodebyname()'
+where available) in an attempt to acquire a fully qualified host name. See also
+$smtp_active_hostname$.
+
+
+$prvscheck_address$::
++
+[revisionflag="changed"]
+This variable is used in conjunction with the %prvscheck% expansion item, which
+is described in sections <<SECTexpansionitems>> and <<SECTverifyPRVS>>.
+
+$prvscheck_keynum$::
++
+[revisionflag="changed"]
+This variable is used in conjunction with the %prvscheck% expansion item, which
+is described in sections <<SECTexpansionitems>> and <<SECTverifyPRVS>>.
+
+$prvscheck_result$::
++
+[revisionflag="changed"]
+This variable is used in conjunction with the %prvscheck% expansion item, which
+is described in sections <<SECTexpansionitems>> and <<SECTverifyPRVS>>.
$qualify_domain$::
-The value set for this option in the configuration file.
+cindex:[$qualify_domain$]
+The value set for the %qualify_domain% option in the configuration file.
$qualify_recipient$::
-The value set for this option in the configuration file,
+cindex:[$qualify_recipient$]
+The value set for the %qualify_recipient% option in the configuration file,
or if not set, the value of $qualify_domain$.
$rcpt_count$::
-When a message is being received by SMTP, this variable
-contains the number of RCPT commands received for the current message. If
-this variable is used in a RCPT ACL, its value includes the current
-command.
+cindex:[$rcpt_count$]
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands received for the current message. If this variable is used in a
+RCPT ACL, its value includes the current command.
$rcpt_defer_count$::
-When a message is being received by SMTP, this variable
-contains the number of RCPT commands in the current message that have
-previously been rejected with a temporary (4##'xx') response.
+cindex:[$rcpt_defer_count$]
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands in the current message that have previously been rejected with a
+temporary (4##'xx') response.
$rcpt_fail_count$::
-When a message is being received by SMTP, this variable
-contains the number of RCPT commands in the current message that have
-previously been rejected with a permanent (5##'xx') response.
+cindex:[$rcpt_fail_count$]
+When a message is being received by SMTP, this variable contains the number of
+RCPT commands in the current message that have previously been rejected with a
+permanent (5##'xx') response.
$received_count$::
-This variable contains the number of 'Received:' header
-lines in the message, including the one added by Exim (so its value is always
-greater than zero). It is available in the DATA ACL, the non-SMTP ACL, and
-while routing and delivering.
+cindex:[$received_count$]
+This variable contains the number of 'Received:' header lines in the message,
+including the one added by Exim (so its value is always greater than zero). It
+is available in the DATA ACL, the non-SMTP ACL, and while routing and
+delivering.
$received_for$::
-If there is only a single recipient address in an incoming
-message, this variable contains that address when the 'Received:' header line
-is being built.
+cindex:[$received_for$]
+If there is only a single recipient address in an incoming message, this
+variable contains that address when the 'Received:' header line is being built.
The value is copied after recipient rewriting has happened, but before the
'local_scan()' function is run.
$received_protocol$::
-When a message is being processed, this variable
-contains the name of the protocol by which it was received.
-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.
+cindex:[$received_protocol$]
+When a message is being processed, this variable contains the name of the
+protocol by which it was received. 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
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.
+$received_time$::
++
+[revisionflag="changed"]
+cindex:[$received_time$]
+This variable contains the date and time when the current message was received,
+as a number of seconds since the start of the Unix epoch.
$recipient_data$::
-This variable is set after an indexing lookup success in
-an ACL %recipients% condition. It contains the data from the lookup, and the
-value remains set until the next %recipients% test. Thus, you can do things
-like this:
+cindex:[$recipient_data$]
+This variable is set after an indexing lookup success in an ACL %recipients%
+condition. It contains the data from the lookup, and the value remains set
+until the next %recipients% test. Thus, you can do things like this:
+
&&&
`require recipients = cdb*@;/some/file`
expansion that all such lists undergo before being interpreted.
$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:
+cindex:[$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:
+
--
- ``qualify'': The address was unqualified (no domain), and the message
$recipients$::
+cindex:[$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_count$::
-When a message is being processed, this variable
-contains the number of envelope recipients that came with the message.
-Duplicates are not excluded from the count. While a message is being received
-over SMTP, the number increases for each accepted recipient. It can be
-referenced in an ACL.
+cindex:[$recipients_count$]
+When a message is being processed, this variable contains the number of
+envelope recipients that came with the message. Duplicates are not excluded
+from the count. While a message is being received over SMTP, the number
+increases for each accepted recipient. It can be referenced in an ACL.
$reply_address$::
-When a message is being processed, this variable contains
-the contents of the 'Reply-To:' header line if one exists
-and it is not empty,
-or otherwise the contents of the 'From:' header line.
+cindex:[$reply_address$]
+When a message is being processed, this variable contains the contents of the
+'Reply-To:' header line if one exists and it is not empty, or otherwise the
+contents of the 'From:' header line.
$return_path$::
+cindex:[$return_path$]
When a message is being delivered, this variable contains the return path --
the sender field that will be sent as part of the envelope. It is not enclosed
in <> characters. At the start of routing an address, $return_path$ has the
sender.
$return_size_limit$::
+cindex:[$return_size_limit$]
This is an obsolete name for $bounce_return_size_limit$.
$runrc$::
cindex:[return code,from %run% expansion]
+cindex:[$runrc$]
This variable contains the return code from a command that is run by the
%\$\{run...\}% expansion item. *Warning*: In a router or transport, you cannot
assume the order in which option values are expanded, except for those
another.
$self_hostname$::
-When an address is routed to a supposedly remote host that turns out to be the
-local host, what happens is controlled by the
cindex:[%self% option,value of host name]
-%self% generic router option. One of its values causes the address to be passed
-to another router. When this happens, $self_hostname$ is set to the name of
-the local host that the original router encountered. In other circumstances its
-contents are null.
+cindex:[$self_hostname$]
+When an address is routed to a supposedly remote host that turns out to be the
+local host, what happens is controlled by the %self% generic router option. One
+of its values causes the address to be passed to another router. When this
+happens, $self_hostname$ is set to the name of the local host that the original
+router encountered. In other circumstances its contents are null.
$sender_address$::
-When a message is being processed, this variable contains
-the sender's address that was received in the message's envelope. For bounce
-messages, the value of this variable is the empty string.
-See also $return_path$.
+cindex:[$sender_address$]
+When a message is being processed, this variable contains the sender's address
+that was received in the message's envelope. For bounce messages, the value of
+this variable is the empty string. See also $return_path$.
$sender_address_data$::
+cindex:[$address_data$]
+cindex:[$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.
-
$sender_address_domain$::
+cindex:[$sender_address_domain$]
The domain portion of $sender_address$.
$sender_address_local_part$::
+cindex:[$sender_address_local_part$]
The local part portion of $sender_address$.
$sender_data$::
+cindex:[$sender_data$]
This variable is set after a lookup success in an ACL %senders% condition or in
a router %senders% option. It contains the data from the lookup, and the value
remains set until the next %senders% test. Thus, you can do things like this:
expansion that all such lists undergo before being interpreted.
$sender_fullhost$::
+cindex:[$sender_fullhost$]
When a message is received from a remote host, this variable contains the host
name and IP address in a single string. It ends with the IP address in square
brackets, followed by a colon and a port number if the logging of ports is
the verified host name or to the host's IP address in square brackets.
$sender_helo_name$::
-When a message is received from a remote host that has
-issued a HELO or EHLO command, the argument of that command is placed
-in this variable. It is also set if HELO or EHLO is used when a message
-is received using SMTP locally via the %-bs% or %-bS% options.
+cindex:[$sender_hslo_name$]
+When a message is received from a remote host that has issued a HELO or EHLO
+command, the argument of that command is placed in this variable. It is also
+set if HELO or EHLO is used when a message is received using SMTP locally via
+the %-bs% or %-bS% options.
$sender_host_address$::
-When a message is received from a remote host, this
-variable contains that host's IP address. For locally submitted messages, it is
-empty.
+cindex:[$sender_host_address$]
+When a message is received from a remote host, this variable contains that
+host's IP address. For locally submitted messages, it is empty.
$sender_host_authenticated$::
+cindex:[$sender_host_authenticated$]
This variable contains the name (not the public name) of the authenticator
-driver which successfully authenticated the client from which the message was
-received. It is empty if there was no successful authentication.
+driver that successfully authenticated the client from which the message was
+received. It is empty if there was no successful authentication. See also
+$authenticated_id$.
$sender_host_name$::
+cindex:[$sender_host_name$]
When a message is received from a remote host, this variable contains the
host's name as obtained by looking up its IP address. For messages received by
other means, this variable is empty.
+
+cindex:[$host_lookup_failed$]
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
any data, 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''.
+
+cindex:[$host_lookup_deferred$]
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''.
$sender_host_port$::
-When a message is received from a remote host, this
-variable contains the port number that was used on the remote host.
+cindex:[$sender_host_port$]
+When a message is received from a remote host, this variable contains the port
+number that was used on the remote host.
$sender_ident$::
+cindex:[$sender_ident$]
When a message is received from a remote host, this variable contains the
identification received in response to an RFC 1413 request. When a message has
been received locally, this variable contains the login name of the user that
called Exim.
+$sender_rate_$'xxx'::
++
+[revisionflag="changed"]
+A number of variables whose names begin $sender_rate_$ are set as part of the
+%ratelimit% ACL condition. Details are given in section <<SECTratelimiting>>.
+
$sender_rcvhost$::
-This is provided specifically for use in 'Received:' headers. It starts with
-either the verified host name (as obtained from a
cindex:[DNS,reverse lookup]
cindex:[reverse DNS lookup]
-reverse DNS lookup) or, if there is no verified host name, the IP address in
-square brackets. After that there may be text in parentheses. When the first
-item is a verified host name, the first thing in the parentheses is the IP
-address in square brackets, followed by a colon and a port number if port
-logging is enabled. When the first item is an IP address, the port is recorded
-as ``port='xxxx'##'' inside the parentheses.
+cindex:[$sender_rcvhost$]
+This is provided specifically for use in 'Received:' headers. It starts with
+either the verified host name (as obtained from a reverse DNS lookup) or, if
+there is no verified host name, the IP address in square brackets. After that
+there may be text in parentheses. When the first item is a verified host name,
+the first thing in the parentheses is the IP address in square brackets,
+followed by a colon and a port number if port logging is enabled. When the
+first item is an IP address, the port is recorded as ``port='xxxx'##'' inside
+the parentheses.
+
There may also be items of the form ``helo='xxxx'##'' if HELO or EHLO
was used and its argument was not identical to the real host name or IP
the string, to improve the formatting of the 'Received:' header.
$sender_verify_failure$::
+cindex:[$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$.
$smtp_active_hostname$::
+cindex:[$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.
+$smtp_command$::
++
+[revisionflag="changed"]
+cindex:[$smtp_command$]
+During the processing of an incoming SMTP command, this variable contains the
+entire command. This makes it possible to distinguish between HELO and EHLO in
+the HELO ACL, and also to distinguish between commands such as these:
++
+....
+MAIL FROM:<>
+MAIL FROM: <>
+....
++
+For a MAIL command, extra parameters such as SIZE can be inspected. For a RCPT
+command, the address in $smtp_command$ is the original address before any
+rewriting, whereas the values in $local_part$ and $domain$ are taken from the
+address after SMTP-time rewriting.
+
$smtp_command_argument$::
-cindex:[AUTH,argument]
-cindex:[EXPN,argument]
-cindex:[ETRN,argument]
-cindex:[VRFY,argument]
-While an ACL is running to check an AUTH, EHLO, EXPN, ETRN, HELO, or VRFY
-command, this variable contains the argument for the SMTP command.
++
+[revisionflag="changed"]
+cindex:[SMTP command,argument for]
+cindex:[$smtp_command_argument$]
+While an ACL is running to check an SMTP command, this variable contains the
+argument, that is, the text that follows the command name, with leading white
+space removed. Following the introduction of $smtp_command$, this variable is
+somewhat redundant, but is retained for backwards compatibility.
$sn0$ -- $sn9$::
These variables are copies of the values of the $n0$ -- $n9$ accumulators that
$spool_directory$::
+cindex:[$spool_directory$]
The name of Exim's spool directory.
$spool_inodes$::
+cindex:[$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.
$spool_space$::
+cindex:[$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
$thisaddress$::
+cindex:[$thisaddress$]
This variable is set only during the processing of the %foranyaddress% command
-in a filter file. Its use is explained in the description of that command.
+in a filter file. Its use is explained in the description of that command,
+which can be found in the separate document entitled 'Exim's interfaces to mail
+filtering'.
$tls_certificate_verified$::
-This variable is set to ``1'' if a TLS certificate was verified when the message
-was received, and ``0'' otherwise.
+cindex:[$tls_certificate_verified$]
+This variable is set to ``1'' if a TLS certificate was verified when the
+message was received, and ``0'' otherwise.
$tls_cipher$::
+cindex:[$tls_cipher$]
When a message is received from a remote host over an encrypted SMTP
connection, this variable is set to the cipher suite that was negotiated, for
example DES-CBC3-SHA. In other circumstances, in particular, for message
<<CHAPTLS>> for details of TLS support.
$tls_peerdn$::
- When a message is received from a remote host over an encrypted SMTP
+cindex:[$tls_peerdn$]
+When a message is received from a remote host over an encrypted SMTP
connection, and Exim is configured to request a certificate from the client,
the value of the Distinguished Name of the certificate is made available in the
$tls_peerdn$ during subsequent processing.
$tod_bsdinbox$::
+cindex:[$tod_bsdinbox$]
The time of day and date, in the format required for BSD-style mailbox files,
for example: Thu Oct 17 17:14:09 1995.
$tod_epoch$::
+cindex:[$tod_epoch$]
The time and date as a number of seconds since the start of the Unix epoch.
$tod_full$::
+cindex:[$tod_full$]
A full version of the time and date, for example: Wed, 16 Oct 1995 09:51:40
+0100. The timezone is always given as a numerical offset from UTC, with
positive values used for timezones that are ahead (east) of UTC, and negative
values for those that are behind (west).
$tod_log$::
+cindex:[$tod_log$]
The time and date in the format used for writing Exim's log files, for example:
1995-10-12 15:32:29, but without a timezone.
$tod_logfile$::
+cindex:[$tod_logfile$]
This variable contains the date in the format yyyymmdd. This is the format that
is used for datestamping log files when %log_file_path% contains the `%D`
flag.
$tod_zone$::
+cindex:[$tod_zone$]
This variable contains the numerical value of the local timezone, for example:
-0500.
$tod_zulu$::
+cindex:[$tod_zulu$]
This variable contains the UTC date and time in ``Zulu'' format, as specified by
ISO 8601, for example: 20030221154023Z.
or external command, as described above.
$version_number$::
+cindex:[$version_number$]
The version number of Exim.
$warn_message_delay$::
+cindex:[$warn_message_delay$]
This variable is set only during the creation of a message warning about a
delivery delay. Details of its use are explained in section <<SECTcustwarn>>.
$warn_message_recipients$::
+cindex:[$warn_message_recipients$]
This variable is set only during the creation of a message warning about a
delivery delay. Details of its use are explained in section <<SECTcustwarn>>.
%mysql_servers% as it says
%oracle_servers% as it says
%pgsql_servers% as it says
+%sqlite_lock_timeout% as it says
--------------------------------------------------------------------------
[frame="none"]
`-----------------------------------`-------------------------------------
%daemon_smtp_ports% default ports
+%daemon_startup_retries% number of times to retry
+%daemon_startup_sleep% time to sleep between tries
%extra_local_interfaces% not necessarily listened on
%local_interfaces% on which to listen, with optional ports
%pid_file_path% override compiled-in value
~~~~~~~~~~~~~~~
[frame="none"]
`-----------------------------------`-------------------------------------
-%acl_not_smtp% set ACL for non-SMTP messages
-%acl_smtp_auth% set ACL for AUTH
-%acl_smtp_connect% set ACL for connection
-%acl_smtp_data% set ACL for DATA
-%acl_smtp_etrn% set ACL for ETRN
-%acl_smtp_expn% set ACL for EXPN
-%acl_smtp_helo% set ACL for EHLO or HELO
-%acl_smtp_mail% set ACL for MAIL
-%acl_smtp_mailauth% set ACL for AUTH on MAIL command
-%acl_smtp_mime% set ACL for MIME parts
-%acl_smtp_predata% set ACL for start of data
-%acl_smtp_quit% set ACL for QUIT
-%acl_smtp_rcpt% set ACL for RCPT
-%acl_smtp_starttls% set ACL for STARTTLS
-%acl_smtp_vrfy% set ACL for VRFY
+%acl_not_smtp% ACL for non-SMTP messages
+%acl_not_smtp_mime% ACL for non-SMTP MIME parts
+%acl_smtp_auth% ACL for AUTH
+%acl_smtp_connect% ACL for connection
+%acl_smtp_data% ACL for DATA
+%acl_smtp_etrn% ACL for ETRN
+%acl_smtp_expn% ACL for EXPN
+%acl_smtp_helo% ACL for EHLO or HELO
+%acl_smtp_mail% ACL for MAIL
+%acl_smtp_mailauth% ACL for AUTH on MAIL command
+%acl_smtp_mime% ACL for MIME parts
+%acl_smtp_predata% ACL for start of data
+%acl_smtp_quit% ACL for QUIT
+%acl_smtp_rcpt% ACL for RCPT
+%acl_smtp_starttls% ACL for STARTTLS
+%acl_smtp_vrfy% ACL for VRFY
%av_scanner% specify virus scanner
+%check_rfc2047_length% check length of RFC 2047 ``encoded words''
+%dns_csa_search_limit% control CSA parent search depth
+%dns_csa_use_reverse% en/disable CSA IP reverse search
%header_maxsize% total size of message header
%header_line_maxsize% individual header line limit
%helo_accept_junk_hosts% allow syntactic junk from these hosts
%sender_unqualified_hosts% may send unqualified senders
%smtp_accept_keepalive% some TCP/IP magic
%smtp_accept_max% simultaneous incoming connections
-%smtp_accept_max_nommail% non-mail commands
+%smtp_accept_max_nonmail% non-mail commands
%smtp_accept_max_nonmail_hosts% hosts to which the limit applies
%smtp_accept_max_per_connection% messages per connection
%smtp_accept_max_per_host% connections from one host
%allow_domain_literals% recognize domain literal syntax
%allow_mx_to_ip% allow MX to point to IP address
%allow_utf8_domains% in addresses
+%check_rfc2047_length% check length of RFC 2047 ``encoded words''
%delivery_date_remove% from incoming messages
%envelope_to_remote% from incoming messages
%extract_addresses_remove_arguments%affects %-t% processing
%local_interfaces% for routing checks
%queue_domains% no immediate delivery for these
%queue_only% no immediate delivery at all
-%queue_only_file% no immediate deliveryif file exists
+%queue_only_file% no immediate delivery if file exists
%queue_only_load% no immediate delivery if load is high
%queue_only_override% allow command line to override
%queue_run_in_order% order of arrival
%delay_warning% time schedule
%delay_warning_condition% condition for warning messages
%ignore_bounce_errors_after% discard undeliverable bounces
+%smtp_return_error_details% give detail on rejections
%warn_message_file% content of warning message
--------------------------------------------------------------------------
===
cindex:[{ACL},for non-SMTP messages]
-cindex:[non-SMTP messages, ACL for]
+cindex:[non-SMTP messages, ACLs for]
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.
+oindex:[%acl_not_smtp_mime%]
+`..'=
+%acl_not_smtp_mime%, Use: 'main', Type: 'string'!!, Default: 'unset'
+===
+
+[revisionflag="changed"]
+This option defines the ACL that is run for individual MIME parts of non-SMTP
+messages. It operates in exactly the same way as %acl_smtp_mime% operates for
+SMTP messages.
+
oindex:[%acl_smtp_auth%]
`..'=
%acl_smtp_auth%, Use: 'main', Type: 'string'!!, Default: 'unset'
oindex:[%admin_groups%]
`..'=
-%admin_groups%, Use: 'main', Type: 'string list', Default: 'unset'
+%admin_groups%, Use: 'main', Type: 'string list'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[admin user]
-If the current group or any of the supplementary groups of the caller is in
-this colon-separated list, the caller has admin privileges. If all your system
+This option is expanded just once, at the start of Exim's processing. If the
+current group or any of the supplementary groups of an Exim caller is in this
+colon-separated list, the caller has admin privileges. If all your system
programmers are in a specific group, for example, you can give them all Exim
admin privileges by putting that group in %admin_groups%. However, this does
not permit them to read Exim's spool files (whose group owner is the Exim gid).
auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
+cindex:[$tls_cipher$]
If $tls_cipher$ is empty, the session is not encrypted, and the result of
the expansion is empty, thus matching no hosts. Otherwise, the result of the
expansion is \*, which matches all hosts.
%auto_thaw%, Use: 'main', Type: 'time', Default: '0s'
===
+[revisionflag="changed"]
cindex:[thawing messages]
cindex:[unfreezing messages]
If this option is set to a time greater than zero, a queue runner will try a
-new delivery attempt on any frozen message if this much time has passed since
-it was frozen. This may result in the message being re-frozen if nothing has
-changed since the last attempt. It is a way of saying ``keep on trying, even
-though there are big problems''. See also %timeout_frozen_after% and
-%ignore_bounce_errors_after%.
+new delivery attempt on any frozen message, other than a bounce message, if
+this much time has passed since it was frozen. This may result in the message
+being re-frozen if nothing has changed since the last attempt. It is a way of
+saying ``keep on trying, even though there are big problems''.
+
+*Note*: This is an old option, which predates %timeout_frozen_after% and
+%ignore_bounce_errors_after%. It is retained for compatibility, but it is not
+thought to be very useful any more, and its use should probably be avoided.
oindex:[%av_scanner%]
See %check_spool_space% below.
+oindex:[%check_rfc2047_length%]
+cindex:[RFC 2047,disabling length check]
+`..'=
+%check_rfc2047_length%, User: 'main', Type: 'boolean', Default: 'true'
+===
+
+RFC 2047 defines a way of encoding non-ASCII characters in headers using a
+system of ``encoded words''. The RFC specifies a maximum length for an encoded
+word; strings to be encoded that exceed this length are supposed to use
+multiple encoded words. By default, Exim does not recognize encoded words that
+exceed the maximum length. However, it seems that some software, in violation
+of the RFC, generates overlong encoded words. If %check_rfc2047_length% is set
+false, Exim recognizes encoded words of any length.
+
oindex:[%check_spool_inodes%]
`..'=
The four %check_...% options allow for checking of disk resources before a
message is accepted.
+cindex:[$log_inodes$]
+cindex:[$log_space$]
+cindex:[$spool_inodes$]
+cindex:[$spool_space$]
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.
+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.
%check_spool_space% and %check_spool_inodes% check the spool partition if
listens. See chapter <<CHAPinterfaces>> for details of how it is used. For
backward compatibility, %daemon_smtp_port% (singular) is a synonym.
+oindex:[%daemon_startup_retries%]
+`..'=
+%daemon_startup_retries%, Use: 'main', Type: 'integer', Default: '9'
+===
+
+[revisionflag="changed"]
+cindex:[daemon startup,retrying]
+This option, along with %daemon_startup_sleep%, controls the retrying done by
+the daemon at startup when it cannot immediately bind a listening socket
+(typically because the socket is already in use): %daemon_startup_retries%
+defines the number of retries after the first failure, and
+%daemon_startup_sleep% defines the length of time to wait between retries.
+
+oindex:[%daemon_startup_sleep%]
+`..'=
+%daemon_startup_sleep%, Use: 'main', Type: 'time', Default: '30s'
+===
+
+[revisionflag="changed"]
+See %daemon_startup_retries%.
oindex:[%delay_warning%]
`..'=
%delay_warning_condition%, Use: 'main', Type: 'string'!!, Default: 'see below'
===
+cindex:[$domain$]
The string is expanded at the time a warning message might be sent. If all the
deferred addresses have the same domain, it is set in $domain$ during the
expansion. Otherwise $domain$ is empty. If the result of the expansion is a
If you set %allow_utf8_domains%, you must modify this pattern, or set the
option to an empty string.
+oindex:[%dns_csa_search_limit%]
+`..'=
+%dns_csa_search_limit%, Use: 'main', Type: 'integer', Default: '5'
+===
+
+[revisionflag="changed"]
+This option controls the depth of parental searching for CSA SRV records in the
+DNS, as described in more detail in section <<SECTverifyCSA>>.
+
+
+oindex:[%dns_csa_use_reverse%]
+`..'=
+%dns_csa_use_reverse%, Use: 'main', Type: 'boolean', Default: 'true'
+===
+
+[revisionflag="changed"]
+This option controls whether or not an IP address, given as a CSA domain, is
+reversed and looked up in the reverse DNS, as described in more detail in
+section <<SECTverifyCSA>>.
+
oindex:[%dns_ipv4_lookup%]
`..'=
postmaster@mydomain.example
....
+cindex:[$domain$]
+cindex:[$local_part$]
The address list is expanded before use. The expansion variables
$local_part$ and $domain$ are set from the original recipient of the error
message, and if there was any wildcard matching in the pattern, the expansion
%helo_try_verify_hosts%, Use: 'main', Type: 'host list'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[HELO verifying, optional]
cindex:[EHLO verifying, optional]
-The RFCs mandate that a server must not reject a message because it doesn't
-like the HELO or EHLO command. By default, Exim just checks the syntax
-of these commands (see %helo_accept_junk_hosts% and %helo_allow_chars%
-above). However, some sites like to be stricter. If the calling host matches
-%helo_try_verify_hosts%, Exim checks that the host name given in the HELO
-or EHLO command either:
+By default, Exim just checks the syntax of HELO and EHLO commands (see
+%helo_accept_junk_hosts% and %helo_allow_chars%). However, some sites like to
+do more extensive checking of the data supplied by these commands. The ACL
+condition `verify = helo` is provided to make this possible. Formerly, it was
+necessary also to set this option (%helo_try_verify_hosts%) to force the check
+to occur. From release 4.53 onwards, this is no longer necessary. If the check
+has not been done before `verify = helo` is encountered, it is done at that
+time. Consequently, this option is obsolete. Its specification is retained here
+for backwards compatibility.
-- is an IP literal matching the calling address of the host (the RFCs
-specifically allow this), or
+[revisionflag="changed"]
+When an EHLO or HELO command is received, if the calling host matches
+%helo_try_verify_hosts%, Exim checks that the host name given in the HELO or
+EHLO command either:
+
+- is an IP literal matching the calling address of the host, or
- cindex:[DNS,reverse lookup]
cindex:[reverse DNS lookup]
However, the EHLO or HELO command is not rejected if any of the checks
fail. Processing continues, but the result of the check is remembered, and can
-be detected later in an ACL by the `verify = helo` condition. If you want
-verification failure to cause rejection of EHLO or HELO, use
-%helo_verify_hosts% instead.
-
+be detected later in an ACL by the `verify = helo` condition.
oindex:[%helo_verify_hosts%]
%helo_verify_hosts%, Use: 'main', Type: 'host list'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[HELO verifying, mandatory]
cindex:[EHLO verifying, mandatory]
-For hosts that match this option, Exim checks the host name given in the
-HELO or EHLO in the same way as for %helo_try_verify_hosts%. If the
-check fails, the HELO or EHLO command is rejected with a 550 error, and
-entries are written to the main and reject logs. If a MAIL command is
-received before EHLO or HELO, it is rejected with a
-503
-error.
+Like %helo_try_verify_hosts%, this option is obsolete, and retained only for
+backwards compatibility. For hosts that match this option, Exim checks the host
+name given in the HELO or EHLO in the same way as for %helo_try_verify_hosts%.
+If the check fails, the HELO or EHLO command is rejected with a 550 error, and
+entries are written to the main and reject logs. If a MAIL command is received
+before EHLO or HELO, it is rejected with a 503 error.
oindex:[%hold_domains%]
has obtained, to verify that it yields the IP address that it started with. If
this check fails, Exim behaves as if the name lookup failed.
+cindex:[$host_lookup_failed$]
+cindex:[$sender_host_name$]
After any kind of failure, the host name (in $sender_host_name$) remains
unset, and $host_lookup_failed$ is set to the string ``1''. See also
%dns_again_means_nonexist%, %helo_lookup_domains%, and `verify =
an untrusted user, Exim removes any existing 'Sender:' header line. If you
do not want this to happen, you must set %local_sender_retain%, and you must
also set %local_from_check% to be false (Exim will complain if you do not).
-Section <<SECTthesenhea>> has more details about 'Sender:' processing.
+See also the ACL modifier `control = suppress_local_fixups`. Section
+<<SECTthesenhea>> has more details about 'Sender:' processing.
cindex:[host,locally unique number for]
cindex:[message ids, with multiple hosts]
+cindex:[$localhost_number$]
Exim's message ids are normally unique only within the local host. If
uniqueness among a set of hosts is required, each host must set a different
value for the %localhost_number% option. The string is expanded immediately
===
cindex:[log,timezone for entries]
+cindex:[$tod_log$]
+cindex:[$tod_zone$]
By default, the timestamps on log lines are in local time without the
timezone. This means that if your timezone changes twice a year, the timestamps
in log lines are ambiguous for an hour when the clocks go back. One way of
cindex:[body of message,visible size]
cindex:[message body, visible size]
+cindex:[$message_body$]
+cindex:[$message_body_end$]
This option specifies how much of a message's body is to be included in the
$message_body$ and $message_body_end$ expansion variables.
===
If this variable is set, the string is expanded and used to augment the text of
-the 'Message-id:' header that Exim creates if a
-locally-originated
-incoming message does not have one. The text of this header is required by RFC
-2822 to take the form of an address. By default, Exim uses its internal message
-id as the local part, and the primary host name as the domain. If this option
-is set, it is expanded, and provided the expansion is not forced to fail, and
-does not yield an empty string, the result is inserted into the header
-immediately before the @, separated from the internal message id by a dot. Any
-characters that are illegal in an address are automatically converted into
-hyphens. This means that variables such as $tod_log$ can be used, because
-the spaces and colons will become hyphens.
+the 'Message-id:' header that Exim creates if a locally-originated incoming
+message does not have one. The text of this header is required by RFC 2822 to
+take the form of an address. By default, Exim uses its internal message id as
+the local part, and the primary host name as the domain. If this option is set,
+it is expanded, and provided the expansion is not forced to fail, and does not
+yield an empty string, the result is inserted into the header immediately
+before the @, separated from the internal message id by a dot. Any characters
+that are illegal in an address are automatically converted into hyphens. This
+means that variables such as $tod_log$ can be used, because the spaces and
+colons will become hyphens.
oindex:[%message_logs%]
oindex:[%never_users%]
`..'=
-%never_users%, Use: 'main', Type: 'string list', Default: 'unset'
+%never_users%, Use: 'main', Type: 'string list'!!, Default: 'unset'
===
-Local message deliveries are normally run in processes that are setuid to the
+[revisionflag="changed"]
+This option is expanded just once, at the start of Exim's processing. Local
+message deliveries are normally run in processes that are setuid to the
recipient, and remote deliveries are normally run under Exim's own uid and gid.
It is usually desirable to prevent any deliveries from running as root, as a
safety precaution.
cindex:[name,of local host]
cindex:[host,name of local]
cindex:[local host,name of]
-This specifies the name of the current host. It is used in the default EHLO
-or HELO command for outgoing SMTP messages (changeable via the %helo_data%
-option in the ^smtp^ transport),
-and as the default for %qualify_domain%. If it is not set, Exim calls
-'uname()' to find it. If this fails, Exim panics and dies. If the name
-returned by 'uname()' contains only one component, Exim passes it to
-'gethostbyname()' (or 'getipnodebyname()' when available) in order to
-obtain the fully qualified version.
+cindex:[$primary_hostname$]
+This specifies the name of the current host. It is used in the default EHLO or
+HELO command for outgoing SMTP messages (changeable via the %helo_data% option
+in the ^smtp^ transport), and as the default for %qualify_domain%. The value is
+also used by default in some SMTP response messages from an Exim server. This
+can be changed dynamically by setting %smtp_active_hostname%.
-The value of $primary_hostname$ is also used by default in some SMTP
-response messages from an Exim server. This can be changed dynamically by
-setting %smtp_active_hostname%.
+If %primary_hostname% is not set, Exim calls 'uname()' to find the host name.
+If this fails, Exim panics and dies. If the name returned by 'uname()' contains
+only one component, Exim passes it to 'gethostbyname()' (or 'getipnodebyname()'
+when available) in order to obtain the fully qualified version. The variable
+$primary_hostname$ contains the host name, whether set explicitly by this
+option, or defaulted.
oindex:[%print_topbitchars%]
however, interlock with other processes, so additional queue runners can be
started by other means, or by killing and restarting the daemon.
+[revisionflag="changed"]
+Setting this option to zero does not suppress queue runs; rather, it disables
+the limit, allowing any number of simultaneous queue runner processes to be
+run. If you do not want queue runs to occur, omit the %-q%'xx' setting on the
+daemon's command line.
+
oindex:[%queue_smtp_domains%]
`..'=
``Received:'' and conform to the RFC 2822 specification for 'Received:' header
lines. The default setting is:
+[revisionflag="changed"]
....
received_header_text = Received: \
- ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\
- {${if def:sender_ident {from $sender_ident }}\
- ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\
- by $primary_hostname \
- ${if def:received_protocol {with $received_protocol}} \
- ${if def:tls_cipher {($tls_cipher)\n\t}}\
- (Exim $version_number)\n\t\
- id $message_id\
- ${if def:received_for {\n\tfor $received_for}}
+ ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\
+ {${if def:sender_ident {from ${quote_local_part: $sender_ident} }}\
+ ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\
+ by $primary_hostname \
+ ${if def:received_protocol {with $received_protocol}} \
+ ${if def:tls_cipher {($tls_cipher)\n\t}}\
+ (Exim $version_number)\n\t\
+ ${if def:sender_address {(envelope-from <$sender_address>)\n\t}}\
+ id $message_exim_id\
+ ${if def:received_for {\n\tfor $received_for}}
....
-Note the use of quotes, to allow the sequences `\n` and `\t` to be used
-for newlines and tabs, respectively. The reference to the TLS cipher is omitted
-when Exim is built without TLS support. The use of conditional expansions
-ensures that this works for both locally generated messages and messages
-received from remote hosts, giving header lines such as the following:
+The reference to the TLS cipher is omitted when Exim is built without TLS
+support. The use of conditional expansions ensures that this works for both
+locally generated messages and messages received from remote hosts, giving
+header lines such as the following:
Received: from scrooge.carol.example ([192.168.12.25] ident=root)
by marley.carol.example with esmtp (Exim 4.00)
+ (envelope-from <bob@carol.example>)
id 16IOWa-00019l-00
for chas@dickens.example; Tue, 25 Dec 2001 14:43:44 +0000
Received: by scrooge.carol.example with local (Exim 4.00)
cindex:[host,name in SMTP responses]
cindex:[SMTP,host name in responses]
+cindex:[$primary_hostname$]
This option is provided for multi-homed servers that want to masquerade as
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.
-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.
-
+cindex:[$smtp_active_hostname$]
+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.
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
===
cindex:[ETRN,command to be run]
+cindex:[$domain$]
If this option is set, the given command is run whenever an SMTP ETRN
command is received from a host that is permitted to issue such commands (see
chapter <<CHAPACL>>). The string is split up into separate arguments which are
By using this option to override the compiled-in path, it is possible to run
tests of Exim without using the standard spool.
+oindex:[%sqlite_lock_timeout%]
+`..'=
+%sqlite_lock_timeout%, Use: 'main', Type: 'time', Default: '5s'
+===
+
+[revisionflag="changed"]
+cindex:[sqlite,lock timeout]
+This option controls the timeout that the ^sqlite^ lookup uses when trying to
+access an SQLite database. See section <<SECTsqlite>> for more details.
+
oindex:[%strip_excess_angle_brackets%]
`..'=
%system_filter_directory_transport%, Use: 'main', Type: 'string'!!, Default: 'unset'
===
+cindex:[$address_file$]
This sets the name of the transport driver that is to be used when the
%save% command in a system message filter specifies a path ending in ``/'',
implying delivery of each message into a separate file in some directory.
===
cindex:[^pipe^ transport,for system filter]
+cindex:[$address_pipe$]
This specifies the transport driver that is to be used when a %pipe% command is
used in a system filter. During the delivery, the variable $address_pipe$
contains the pipe command.
oindex:[%trusted_groups%]
`..'=
-%trusted_groups%, Use: 'main', Type: 'string list', Default: 'unset'
+%trusted_groups%, Use: 'main', Type: 'string list'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[trusted group]
cindex:[group,trusted]
-If this option is set, any process that is running in one of the listed groups,
-or which has one of them as a supplementary group, is trusted.
-The groups can be specified numerically or by name.
-See section <<SECTtrustedadmin>> for details of what trusted callers are
-permitted to do. If neither %trusted_groups% nor %trusted_users% is set, only
-root and the Exim user are trusted.
+This option is expanded just once, at the start of Exim's processing. If this
+option is set, any process that is running in one of the listed groups, or
+which has one of them as a supplementary group, is trusted. The groups can be
+specified numerically or by name. See section <<SECTtrustedadmin>> for details
+of what trusted callers are permitted to do. If neither %trusted_groups% nor
+%trusted_users% is set, only root and the Exim user are trusted.
oindex:[%trusted_users%]
`..'=
-%trusted_users%, Use: 'main', Type: 'string list', Default: 'unset'
+%trusted_users%, Use: 'main', Type: 'string list'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[trusted user]
cindex:[user,trusted]
-If this option is set, any process that is running as one of the listed users
-is trusted.
-The users can be specified numerically or by name.
-See section <<SECTtrustedadmin>> for details of what trusted callers are
-permitted to do. If neither %trusted_groups% nor %trusted_users% is set, only
-root and the Exim user are trusted.
+This option is expanded just once, at the start of Exim's processing. If this
+option is set, any process that is running as one of the listed users is
+trusted. The users can be specified numerically or by name. See section
+<<SECTtrustedadmin>> for details of what trusted callers are permitted to do.
+If neither %trusted_groups% nor %trusted_users% is set, only root and the Exim
+user are trusted.
oindex:[%unknown_login%]
`..'=
===
cindex:[uid (user id),unknown caller]
+cindex:[$caller_uid$]
This is a specialized feature for use in unusual configurations. By default, if
the uid of the caller of Exim cannot be looked up using 'getpwuid()', Exim
gives up. The %unknown_login% option can be used to set a login name to be
exim -f '<>' user@domain.example
+cindex:[$sender_ident$]
The %untrusted_set_sender% option allows you to permit untrusted users to set
other envelope sender addresses in a controlled way. When it is set, untrusted
users are allowed to set envelope sender addresses that match any of the
It checks only up to the hours and minutes, and allows for a 2-digit or 4-digit
year in the second case. The first word after ``From'' is matched in the regular
expression by a parenthesized subpattern. The default value for
-%uucp_from_sender% is ``$1'', which therefore just uses this first word (``ph10''
-in the example above) as the message's sender. See also
+%uucp_from_sender% is ``$1'', which therefore just uses this first word
+(``ph10'' in the example above) as the message's sender. See also
%ignore_fromline_hosts%.
%address_data%, Use: 'routers', Type: 'string'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[router,data attached to address]
The string is expanded just before the router is run, that is, after all the
precondition tests have succeeded. If the expansion is forced to fail, the
-router declines. Other expansion failures cause delivery of the address to be
-deferred.
+router declines, the value of %address_data% remains unchanged, and the %more%
+option controls what happens next. Other expansion failures cause delivery of
+the address to be deferred.
+cindex:[$address_data$]
When the expansion succeeds, the value is retained with the address, and can be
accessed using the variable $address_data$ in the current router, subsequent
routers, and the eventual transport.
*Warning*: if the current or any subsequent router is a ^redirect^ router
-that runs a user's filter file, the contents of $address_data$ are
-accessible in the filter. This is not normally a problem, because such data is
-usually either not confidential or it ``belongs'' to the current user, but if you
-do put confidential data into $address_data$ you need to remember this
-point.
+that runs a user's filter file, the contents of $address_data$ are accessible
+in the filter. This is not normally a problem, because such data is usually
+either not confidential or it ``belongs'' to the current user, but if you do
+put confidential data into $address_data$ you need to remember this point.
Even if the router declines or passes, the value of $address_data$ remains
with the address, though it can be changed by another %address_data% setting
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 a recipient address from an
-ACL, it remains available for use in the rest of the ACL statement. After
+cindex:[$sender_address_data$]
+cindex:[$address_data$]
+When $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$.
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.
+cindex:[$local_part$]
+cindex:[$original_local_part$]
+cindex:[$parent_local_part$]
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
cindex:[local user, checking in router]
cindex:[router,checking for local user]
cindex:[_/etc/passwd_]
+cindex:[$home$]
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
===
cindex:[router,restricting to specific domains]
+cindex:[$domain_data$]
If this option is set, the router is skipped unless the current domain matches
the list. If the match is achieved by means of a file lookup, the data that the
lookup returned for the domain is placed in $domain_data$ for use in string
-expansions of the driver's private options.
-See section <<SECTrouprecon>> for a list of the order in which preconditions
-are evaluated.
+expansions of the driver's private options. See section <<SECTrouprecon>> for a
+list of the order in which preconditions are evaluated.
delivery or it may generate child addresses. In both cases, if there is a
delivery problem during later processing, the resulting bounce message is sent
to the address that results from expanding this string, provided that the
-address verifies successfully.
-%errors_to% is expanded before %headers_add%, %headers_remove%, and
-%transport%.
+address verifies successfully. %errors_to% is expanded before %headers_add%,
+%headers_remove%, and %transport%.
If the option is unset, or the expansion is forced to fail, or the result of
the expansion fails to verify, the errors address associated with the incoming
address is delivered to a remote host, the return path is set to `<>`, unless
overridden by the %return_path% option on the transport.
+cindex:[$address_data$]
If for some reason you want to discard local errors, but use a non-empty
MAIL command for remote delivery, you can preserve the original return
path in $address_data$ in the router, and reinstate it in the transport by
%fallback_hosts%, Use: 'routers', Type: 'string list', Default: 'unset'
===
+[revisionflag="changed"]
cindex:[router,fallback hosts]
cindex:[fallback,hosts specified on router]
String expansion is not applied to this option. The argument must be a
-colon-separated list of host names or IP addresses. If a router queues an
-address for a remote transport, this host list is associated with the address,
-and used instead of the transport's fallback host list. If %hosts_randomize%
-is set on the transport, the order of the list is randomized for each use. See
-the %fallback_hosts% option of the ^smtp^ transport for further details.
+colon-separated list of host names or IP addresses. The list separator can be
+changed (see section <<SECTlistconstruct>>), and a port can be specified with
+each name or address. In fact, the format of each item is exactly the same as
+defined for the list of hosts in a ^manualroute^ router (see section
+<<SECTformatonehostitem>>).
+
+If a router queues an address for a remote transport, this host list is
+associated with the address, and used instead of the transport's fallback host
+list. If %hosts_randomize% is set on the transport, the order of the list is
+randomized for each use. See the %fallback_hosts% option of the ^smtp^
+transport for further details.
oindex:[%group%]
%headers_add%, Use: 'routers', Type: 'string'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[header lines,adding]
cindex:[router,adding header lines]
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 add header lines at transport time is described in section
-<<SECTheadersaddrem>>.
+<<SECTheadersaddrem>>. New header lines are not actually added until the
+message is in the process of being transported. This means that references to
+header lines in string expansions in the transport's configuration do not
+``see'' the added header lines.
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.
-*Warning*: The %headers_add% option cannot be used for a ^redirect^
+*Warning 1*: The %headers_add% option cannot be used for a ^redirect^
router that has the %one_time% option set.
+[revisionflag="changed"]
+*Warning 2*: If the %unseen% option is set on the router, all header additions
+are deleted when the address is passed on to subsequent routers.
+
%headers_remove%, Use: 'routers', Type: 'string'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[header lines,removing]
cindex:[router,removing header lines]
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>>.
+section <<SECTheadersaddrem>>. Header lines are not actually removed until the
+message is in the process of being transported. This means that references to
+header lines in string expansions in the transport's configuration still
+``see'' the original header lines.
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^
+*Warning 1*: The %headers_remove% option cannot be used for a ^redirect^
router that has the %one_time% option set.
+[revisionflag="changed"]
+*Warning 2*: If the %unseen% option is set on the router, all header removal
+requests are deleted when the address is passed on to subsequent routers.
is expanded before use as a list, it is possible to make it dependent on the
domain that is being routed.
+cindex:[$host_address$]
During its expansion, $host_address$ is set to the IP address that is being
checked.
cindex:[router,prefix for local part]
cindex:[prefix,for local part; used in router]
-If this option is set, the router is skipped unless the local part
-starts with one of the given strings, or %local_part_prefix_optional% is
-true.
-See section <<SECTrouprecon>> for a list of the order in which preconditions
-are evaluated.
+If this option is set, the router is skipped unless the local part starts with
+one of the given strings, or %local_part_prefix_optional% is true. See section
+<<SECTrouprecon>> for a list of the order in which preconditions are evaluated.
The list is scanned from left to right, and the first prefix that matches is
used. A limited form of wildcard is available; if the prefix begins with an
asterisk, it matches the longest possible sequence of arbitrary characters at
the start of the local part. An asterisk should therefore always be followed by
some character that does not occur in normal local parts.
-
cindex:[multiple mailboxes]
cindex:[mailbox,multiple]
Wildcarding can be used to set up multiple user mailboxes, as described in
section <<SECTmulbox>>.
+[revisionflag="changed"]
+cindex:[$local_part$]
+cindex:[$local_part_prefix$]
During the testing of the %local_parts% option, and while the router is
running, the prefix is removed from the local part, and is available in the
-expansion variable $local_part_prefix$. If the router accepts the address,
-this remains true during subsequent delivery.
-In particular, the local part that is transmitted in the RCPT command
-for LMTP, SMTP, and BSMTP deliveries has the prefix removed by default. This
-behaviour can be overridden by setting %rcpt_include_affixes% true on the
+expansion variable $local_part_prefix$. When a message is being delivered, if
+the router accepts the address, this remains true during subsequent delivery by
+a transport. In particular, the local part that is transmitted in the RCPT
+command for LMTP, SMTP, and BSMTP deliveries has the prefix removed by default.
+This behaviour can be overridden by setting %rcpt_include_affixes% true on the
relevant transport.
+[revisionflag="changed"]
+When an address is being verified, %local_part_prefix% affects only the
+behaviour of the router. If the callout feature of verification is in use, this
+means that the full address, including the prefix, will be used during the
+callout.
+
The prefix facility is commonly used to handle local parts of the form
%owner-something%. Another common use is to support local parts of the form
%real-username% to bypass a user's _.forward_ file -- helpful when trying to
local_parts = dbm;/usr/local/specials/$domain
+cindex:[$local_part_data$]
If the match is achieved by a lookup, the data that the lookup returned
for the local part is placed in the variable $local_part_data$ for use in
expansions of the router's private options. You might use this option, for
fail, the default value for the option (true) is used. Other failures cause
delivery to be deferred.
-If this option is set false, and the router is run, but declines to handle the
-address, no further routers are tried, routing fails, and the address is
-bounced.
-cindex:[%self% option]
-However, if the router explicitly passes an address to the following router by
-means of the setting
+If this option is set false, and the router declines to handle the address, no
+further routers are tried, routing fails, and the address is bounced.
+cindex:[%self% option] However, if the router explicitly passes an address to
+the following router by means of the setting
self = pass
does not affect the behaviour if one of the precondition tests fails. In that
case, the address is always passed to the next router.
+[revisionflag="changed"]
+Note that %address_data% is not considered to be a precondition. If its
+expansion is forced to fail, the router declines, and the value of %more%
+controls what happens next.
+
oindex:[%pass_on_timeout%]
cindex:[router,home directory for]
cindex:[home directory,for router]
+cindex:[$home$]
This option sets a home directory for use while the router is running. (Compare
%transport_home_directory%, which sets a home directory for later
transporting.) In particular, if used on a ^redirect^ router, this option
cindex:[%more% option]
This overrides %no_more%.
+
+cindex:[$self_hostname$]
During subsequent routing and delivery, the variable $self_hostname$ contains
the name of the local host that the router encountered. This can be used to
distinguish between different cases for hosts with multiple names. The
code to support this option is not included in the Exim binary unless
SUPPORT_TRANSLATE_IP_ADDRESS=yes is set in _Local/Makefile_.
+cindex:[$host_address$]
The %translate_ip_address% string is expanded for every IP address generated
by the router, with the generated address set in $host_address$. If the
expansion is forced to fail, no action is taken.
cindex:[router,carrying on after success]
The result of string expansion for this option must be a valid boolean value,
-that is, one of the strings ``yes'', ``no'', ``true'', or ``false''. Any other result
-causes an error, and delivery is deferred. If the expansion is forced to fail,
-the default value for the option (false) is used. Other failures cause delivery
-to be deferred.
+that is, one of the strings ``yes'', ``no'', ``true'', or ``false''. Any other
+result causes an error, and delivery is deferred. If the expansion is forced to
+fail, the default value for the option (false) is used. Other failures cause
+delivery to be deferred.
When this option is set true, routing does not cease if the router accepts the
address. Instead, a copy of the incoming address is passed to the next router,
of %unseen% contains expansion items (and therefore, presumably, is sometimes
true and sometimes false).
+[revisionflag="changed"]
cindex:[copy of message (%unseen% option)]
The %unseen% option can be used to cause copies of messages to be delivered to
some other destination, while also carrying out a normal delivery. In effect,
the current address is made into a ``parent'' that has two children -- one that
is delivered as specified by this router, and a clone that goes on to be routed
-further.
-
-Header lines added to the address (or specified for removal) by this router or
-by previous routers affect the ``unseen'' copy of the message only. The clone
-that continues to be processed by further routers starts with no added headers
-and none specified for removal.
+further. For this reason, %unseen% may not be combined with the %one_time%
+option in a ^redirect^ router.
-However, any data that was set by the %address_data% option in the current or
-previous routers is passed on. Setting this option has a similar effect to the
-%unseen% command qualifier in filter files.
+*Warning*: Header lines added to the address (or specified for removal) by this
+router or by previous routers affect the ``unseen'' copy of the message only.
+The clone that continues to be processed by further routers starts with no
+added headers and none specified for removal. However, any data that was set by
+the %address_data% option in the current or previous routers is passed on.
+Setting the %unseen% option has a similar effect to the %unseen% command
+qualifier in filter files.
and %search_parents% options can cause some widening to be undertaken inside
the DNS resolver.
+[revisionflag="changed"]
+%widen_domains% is not applied to sender addresses when verifying, unless
+%rewrite_headers% is false (not the default).
+
Effect of qualify_single and search_parents
generic %transport% option must specify a transport, unless the router is being
used purely for verification (see %verify_only%).
+cindex:[$host$]
In the case of verification, matching the domain pattern is sufficient for the
router to accept the address. When actually routing an address for delivery,
an address that matches a domain pattern is queued for the associated
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The value of %route_list% is a string consisting of a sequence of routing
rules, separated by semicolons. If a semicolon is needed in a rule, it can be
-entered as two semicolons. Empty rules are ignored. The format of each rule is
+entered as two semicolons. Alternatively, the list separator can be changed as
+described (for colon-separated lists) in section <<SECTlistconstruct>>.
+Empty rules are ignored. The format of each rule is
<domain pattern> <list of hosts> <options>
Format of the list of hosts
~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
A list of hosts, whether obtained via %route_data% or %route_list%, is always
separately expanded before use. If the expansion fails, the router declines.
The result of the expansion must be a colon-separated list of names and/or
-IP addresses. IP addresses are not enclosed in brackets.
+IP addresses, optionally also including ports. The format of each item in the
+list is described in the next section. The list separator can be changed as
+described in section <<SECTlistconstruct>>.
If the list of hosts was obtained from a %route_list% item, the following
variables are set during its expansion:
- cindex:[numerical variables ($1$ $2$ etc),in ^manualroute^ router]
If the domain was matched against a regular expression, the numeric variables
-$1$, $2$, etc. may be set.
+$1$, $2$, etc. may be set. For example:
+
+....
+ route_list = ^domain(\d+) host-$1.text.example
+....
- $0$ is always set to the entire domain.
- cindex:[$value$]
If the pattern that matched the domain was a lookup item, the data that was
-looked up is available in the expansion variable $value$.
+looked up is available in the expansion variable $value$. For example:
+
+....
+ route_list = lsearch;;/some/file.routes $value
+....
+Note the doubling of the semicolon in the pattern that is necessary because
+semicolon is the default route list separator.
+[[SECTformatonehostitem]]
+Format of one host item
+~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+Each item in the list of hosts is either a host name or an IP address,
+optionally with an attached port number. When no port is given, an IP address
+is not enclosed in brackets. When a port is specified, it overrides the port
+specification on the transport. The port is separated from the name or address
+by a colon. This leads to some complications:
+
+[revisionflag="changed"]
+- Because colon is the default separator for the list of hosts, either
+the colon that specifies a port must be doubled, or the list separator must
+be changed. The following two examples have the same effect:
++
+ route_list = * "host1.tld::1225 : host2.tld::1226"
+ route_list = * "<+ host1.tld:1225 + host2.tld:1226"
+
+[revisionflag="changed"]
+- When IPv6 addresses are involved, it gets worse, because they contain
+colons of their own. To make this case easier, it is permitted to
+enclose an IP address (either v4 or v6) in square brackets if a port
+number follows. For example:
++
+ route_list = * "</ [10.1.1.1]:1225 / [::1]:1226"
+
+
+
+[[SECThostshowused]]
How the list of hosts is used
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When an address is routed to an ^smtp^ transport by ^manualroute^, each of
route_list = * x.y.z:p.q.r/MX:e.f.g
+[revisionflag="changed"]
+If this feature is used with a port specifier, the port must come last. For
+example:
+
+ route_list = * dom1.tld/mx::1225
+
If the %hosts_randomize% option is set, the order of the items in the list is
randomized before any lookups are done. Exim then scans the list; for any name
that is not followed by `/MX` it looks up an IP address. If this turns out to
If no IP address for a host can be found, what happens is controlled by the
%host_find_failed% option.
+cindex:[$host$]
When an address is routed to a local transport, IP addresses are not looked up.
The host list is passed to the transport in the $host$ variable.
batch_pipe
....
+
+cindex:[$domain$]
+cindex:[$host$]
The first of these just passes the domain in the $host$ variable, which
doesn't achieve much (since it is also in $domain$), but the second does a
file lookup to find a value to pass, causing the router to decline to handle
^smtp^ transport that does not itself supply a list of hosts.
The format of the list of hosts is the same as for the ^manualroute^ router.
-As well as host names and IP addresses, it may contain names followed by
-`/MX` to specify sublists of hosts that are obtained by looking up MX
-records.
+As well as host names and IP addresses with optional port numbers, as described
+in section <<SECTformatonehostitem>>, it may contain names followed by `/MX` to
+specify sublists of hosts that are obtained by looking up MX records (see
+section <<SECThostshowused>>).
If the lookup type is not specified, Exim behaves as follows when trying to
find an IP address for each host: First, a DNS lookup is done. If this yields
goes on to try a call to 'getipnodebyname()' or 'gethostbyname()', and the
result of the lookup is the result of that call.
+cindex:[$address_data$]
If the DATA field is set, its value is placed in the $address_data$
variable. For example, this return line
If an item is entirely enclosed in double quotes, these are removed. Otherwise
double quotes are retained because some forms of mail address require their use
-(but never to enclose the entire address). In the following description, ``item''
-refers to what remains after any surrounding double quotes have been removed.
+(but never to enclose the entire address). In the following description,
+``item'' refers to what remains after any surrounding double quotes have been
+removed.
+cindex:[$local_part$]
*Warning*: If you use an Exim expansion to construct a redirection address,
and the expansion contains a reference to $local_part$, you should make use
-of the %quote% expansion operator, in case the local part contains special
-characters. For example, to redirect all mail for the domain
+of the %quote_local_part% expansion operator, in case the local part contains
+special characters. For example, to redirect all mail for the domain
'obsolete.example', retaining the existing local part, you could use this
setting:
- data = ${quote:$local_part}@newdomain.example
+ data = ${quote_local_part:$local_part}@newdomain.example
cindex:[EXPN error text, display of]
The text is not included in the response to an EXPN command.
+
+cindex:[$acl_verify_message$]
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
%file_transport%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
===
+cindex:[$address_file$]
A ^redirect^ router sets up a direct delivery to a file when a path name not
ending in a slash is specified as a new ``address''. The transport used is
specified by this option, which, after expansion, must be the name of a
-configured transport.
-This should normally be an ^appendfile^ transport.
-When it is running, the file name is in $address_file$.
+configured transport. This should normally be an ^appendfile^ transport. When
+it is running, the file name is in $address_file$.
oindex:[%forbid_blackhole%]
locks out the Sieve's ``keep'' facility.
+oindex:[%forbid_filter_dlfunc%]
+`..'=
+%forbid_filter_dlfunc%, Use: 'redirect', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+cindex:[filter,locking out certain features]
+If this option is true, string expansions in Exim filters are not allowed to
+make use of the %dlfunc% expansion facility to run dynamically loaded
+functions.
+
+
oindex:[%forbid_filter_existstest%]
`..'=
%forbid_filter_existstest%, Use: 'redirect', Type: 'boolean', Default: 'false'
===
-cindex:[filter,locking out certain features]
+[revisionflag="changed"]
+cindex:[expansion,statting a file]
If this option is true, string expansions in Exim filters are not allowed to
-make use of the %exists% condition.
+make use of the %exists% condition or the %stat% expansion item.
oindex:[%forbid_filter_logwrite%]
%forbid_filter_perl%, Use: 'redirect', Type: 'boolean', Default: 'false'
===
-This option is available only if Exim is built with embedded Perl support. If
+This option has an effect only if Exim is built with embedded Perl support. If
it is true, string expansions in Exim filter files are not allowed to make use
of the embedded Perl support.
cindex:[mailing lists,one-time expansion]
cindex:[address redirection,one-time expansion]
Sometimes the fact that Exim re-evaluates aliases and reprocesses redirection
-files each time it tries to deliver a message causes a problem
-when one or more of the generated addresses fails be delivered at the first
-attempt. The problem is not one of duplicate delivery -- Exim is clever enough
-to handle that -- but of what happens when the redirection list changes during
-the time that the message is on Exim's queue. This is particularly true in the
-case of mailing lists, where new subscribers might receive copies of messages
-that were posted before they subscribed.
-
-If %one_time% is set and any addresses generated by the router fail to
-deliver at the first attempt, the failing addresses are added to the message as
-``top level'' addresses, and the parent address that generated them is marked
-``delivered''. Thus, redirection does not happen again at the next
-delivery attempt.
+files each time it tries to deliver a message causes a problem when one or more
+of the generated addresses fails be delivered at the first attempt. The problem
+is not one of duplicate delivery -- Exim is clever enough to handle that -- but
+of what happens when the redirection list changes during the time that the
+message is on Exim's queue. This is particularly true in the case of mailing
+lists, where new subscribers might receive copies of messages that were posted
+before they subscribed.
+
+If %one_time% is set and any addresses generated by the router fail to deliver
+at the first attempt, the failing addresses are added to the message as ``top
+level'' addresses, and the parent address that generated them is marked
+``delivered''. Thus, redirection does not happen again at the next delivery
+attempt.
-*Warning 1*: This means that any header line addition or removal that is
-specified by this router would be lost if delivery did not succeed at the
-first attempt. For this reason, the %headers_add% and %headers_remove%
-generic options are not permitted when %one_time% is set.
+*Warning 1*: Any header line addition or removal that is specified by this
+router would be lost if delivery did not succeed at the first attempt. For this
+reason, the %headers_add% and %headers_remove% generic options are not
+permitted when %one_time% is set.
*Warning 2*: To ensure that the router generates only addresses (as opposed
to pipe or file deliveries or auto-replies) %forbid_file%, %forbid_pipe%,
and %forbid_filter_reply% are forced to be true when %one_time% is set.
+[revisionflag="changed"]
+*Warning 3*: The %unseen% generic router option may not be set with %one_time%.
+
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
%pipe_transport%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
===
+cindex:[$address_pipe$]
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
used is specified by this option, which, after expansion, must be the name of a
-configured transport.
-This should normally be a ^pipe^ transport.
-When the transport is run, the pipe command is in $address_pipe$.
+configured transport. This should normally be a ^pipe^ transport. When the
+transport is run, the pipe command is in $address_pipe$.
oindex:[%qualify_domain%]
%qualify_domain%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
===
+cindex:[$qualify_recipient$]
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,
and are rewritten according to the global rewriting rules.
+oindex:[%sieve_subaddress%]
+`..'=
+%sieve_subaddress%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
+===
+
+[revisionflag="changed"]
+The value of this option is passed to a Sieve filter to specify the
+:subaddress part of an address.
+
+
+oindex:[%sieve_useraddress%]
+`..'=
+%sieve_useraddress%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
+===
+
+[revisionflag="changed"]
+The value of this option is passed to a Sieve filter to specify the :user part
+of an address. However, if it is unset, the entire original local part
+(including any prefix or suffix) is used for :user.
+
+
oindex:[%sieve_vacation_directory%]
`..'=
%sieve_vacation_directory%, Use: 'redirect', Type: 'string'!!, Default: 'unset'
===
+[revisionflag="changed"]
cindex:[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.
+%reply_transport% option refers to an ^autoreply^ transport. Each user needs
+their own directory; Exim will create it if necessary.
Expansion variables derived from the address
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cindex:[$domain$]
+cindex:[$local_part$]
+cindex:[$original_domain$]
Normally a local delivery is handling a single address, and in that case the
-variables such as $domain$ and $local_part$ are set during local
-deliveries. However, in some circumstances more than one address may be handled
-at once (for example, while writing batch SMTP for onward transmission by some
-other means). In this case, the variables associated with the local part are
-never set, $domain$ is set only if all the addresses have the same
-domain, and $original_domain$ is never set.
+variables such as $domain$ and $local_part$ are set during local deliveries.
+However, in some circumstances more than one address may be handled at once
+(for example, while writing batch SMTP for onward transmission by some other
+means). In this case, the variables associated with the local part are never
+set, $domain$ is set only if all the addresses have the same domain, and
+$original_domain$ is never set.
===
cindex:[transport,home directory for]
+cindex:[$home$]
This option specifies a home directory setting for the transport, overriding
any value that may be set by the router. The home directory is placed in
$home$ while expanding the transport's private options. It is also used as
RCPT TO:<xyz@some.domain>
+[revisionflag="changed"]
+This is also the case when an ACL-time callout is being used to verify a
+recipient address.
+
If %rcpt_include_affixes% is set true, the whole local part is included in
the RCPT command. This option applies to BSMTP deliveries by the
^appendfile^ and ^pipe^ transports as well as to the ^lmtp^ and ^smtp^
only effect is to change the address that is placed in the 'Return-path:'
header line, if one is added to the message (see the next option).
+cindex:[$return_path$]
The expansion can refer to the existing value via $return_path$. This is
either the message's envelope sender, or an address set by the
%errors_to% option on a router. If the expansion is forced to fail, no
individual users or via a system filter.
When the message is about to be written out, the command specified by
-%transport_filter% is started up in a separate process, and the entire
-message, including the header lines, is passed to it on its standard input
-(this in fact is done from a third process, to avoid deadlock).
-The command must be specified as an absolute path.
+%transport_filter% is started up in a separate process, and the entire message,
+including the header lines, is passed to it on its standard input (this in fact
+is done from a third process, to avoid deadlock). The command must be specified
+as an absolute path.
The lines of the message that are written to the transport filter are
-terminated by newline (``\n'').
-
-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.
+terminated by newline (``\n''). 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 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.
+destination. 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 show the possibilities. Exim does not check the result,
+except to test for a final newline when SMTP is in use. All messages
+transmitted over SMTP must end with a newline, so Exim supplies one if it is
+missing.
-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
-show the possibilities. Exim does not check the result, except to test for a
-final newline when SMTP is in use. All messages transmitted over SMTP must end
-with a newline, so Exim supplies one if it is missing.
+[revisionflag="changed"]
+cindex:[content scanning,per user]
+A transport filter can be used to provide content-scanning on a per-user basis
+at delivery time if the only required effect of the scan is to modify the
+message. For example, a content scan could insert a new header line containing
+a spam score. This could be interpreted by a filter in the user's MUA. It is
+not possible to discard a message at this stage.
cindex:[SMTP,SIZE]
A problem might arise if the filter increases the size of a message that is
the %size_addition% option on the ^smtp^ transport, either to allow for
additions to the message, or to disable the use of SIZE altogether.
+cindex:[$pipe_addresses$]
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:
%transport_filter_timeout%, Use: 'transports', Type: 'time', Default: '5m'
===
+[revisionflag="changed"]
cindex:[transport filter, timeout]
When Exim is reading the output of a transport filter, it a applies a timeout
-that can be set by this option. Exceeding the timeout is treated as a
-temporary delivery failure.
+that can be set by this option. Exceeding the timeout is normally treated as a
+temporary delivery failure. However, if a transport filter is used with a
+^pipe^ transport, a timeout in the transport filter is treated in the same way
+as a timeout in the pipe command itself. By default, a timeout is a hard error,
+but if the ^pipe^ transport's %timeout_defer% option is set true, it becomes a
+temporary error.
value greater than one, the addresses are delivered in a batch (that is, in a
single run of the transport), subject to certain conditions:
-- If any of the transport's options contain a reference to $local_part$, no
+- cindex:[$local_part$]
+If any of the transport's options contain a reference to $local_part$, no
batching is possible.
-- If any of the transport's options contain a reference to $domain$, only
+- cindex:[$domain$]
+If any of the transport's options contain a reference to $domain$, only
addresses with the same domain are batched.
- cindex:[customizing,batching condition]
%use_bsmtp% option, because it always delivers using the SMTP protocol.
cindex:[^pipe^ transport,with multiple addresses]
+cindex:[$pipe_addresses$]
If you are not using BSMTP, but are using a ^pipe^ transport, you can include
$pipe_addresses$ as part of the command. This is not a true variable; it is
a bit of magic that causes each of the recipient addresses to be inserted into
the message is created. Only one of these two options can be set, and for
normal deliveries to mailboxes, one of them 'must' be set.
+cindex:[$address_file$]
+cindex:[$local_part$]
However, ^appendfile^ is also used for delivering messages to files or
directories whose names (or parts of names) are obtained from alias,
forwarding, or filtering operations (for example, a %save% command in a user's
===
cindex:[base62]
+cindex:[$inode$]
When %directory% is set, but neither %maildir_format% nor %mailstore_format%
is set, ^appendfile^ delivers each message into a file whose name is obtained
by expanding this string. The default value generates a unique name from the
Nevertheless, it seems best to stick to the 'used' figure, because this is
the obvious value which users understand most easily.
+[revisionflag="changed"]
The value of the option is expanded, and must then be a numerical value
-(decimal point allowed), optionally followed by one of the letters K or M. The
-expansion happens while Exim is running as root, before it changes uid for the
-delivery. This means that files which are inaccessible to the end user can be
-used to hold quota values that are looked up in the expansion. When delivery
-fails because this quota is exceeded, the handling of the error is as for
-system quota failures.
+(decimal point allowed), optionally followed by one of the letters K, M, or G,
+for kilobytes, megabytes, or gigabytes. If Exim is running on a system with
+large file support (Linux and FreeBSD have this), mailboxes larger than 2G can
+be handled.
*Note*: A value of zero is interpreted as ``no quota''.
+The expansion happens while Exim is running as root, before it changes uid for
+the delivery. This means that files that are inaccessible to the end user can
+be used to hold quota values that are looked up in the expansion. When delivery
+fails because this quota is exceeded, the handling of the error is as for
+system quota failures.
+
By default, Exim's quota checking mimics system quotas, and restricts the
mailbox to the specified maximum size, though the value is not accurate to the
last byte, owing to separator lines and additional headers that may get added
maildir_tag = ,S=$message_size
quota_size_regex = ,S=(\d+)
+[revisionflag="changed"]
+An alternative to $message_size$ is $message_linecount$, which contains the
+number of lines in the message.
+
The regular expression should not assume that the length is at the end of the
file name (even though %maildir_tag% puts it there) because maildir MUAs
sometimes add other information onto the ends of message file names.
+
oindex:[%quota_warn_message%]
`..'=
%quota_warn_message%, Use: 'appendfile', Type: 'string'!!, Default: 'see below'
If %quota% is not set, a setting of %quota_warn_threshold% that ends with a
percent sign is ignored.
+[revisionflag="changed"]
The warning message itself is specified by the %quota_warn_message% option,
-and it must start with a 'To:' header line containing the recipient(s). A
-'Subject:' line should also normally be supplied. The %quota% option does not
-have to be set in order to use this option; they are independent of one
-another except when the threshold is specified as a percentage.
+and it must start with a 'To:' header line containing the recipient(s) of the
+warning message. These do not necessarily have to include the recipient(s) of
+the original message. A 'Subject:' line should also normally be supplied. You
+can include any other header lines that you want.
+
+The %quota% option does not have to be set in order to use this option; they
+are independent of one another except when the threshold is specified as a
+percentage.
oindex:[%use_bsmtp%]
name to the point where the test 'stat()' call fails with ENAMETOOLONG,
the tag is dropped and the maildir file is created with no tag.
+cindex:[$message_size$]
Tags can be used to encode the size of files in their names; see
-%quota_size_regex% above for an example. The expansion of %maildir_tag%
-happens after the message has been written. The value of the $message_size$
-variable is set to the number of bytes actually written. If the expansion is
-forced to fail, the tag is ignored, but a non-forced failure causes delivery to
-be deferred. The expanded tag may contain any printing characters except ``/''.
+%quota_size_regex% above for an example. The expansion of %maildir_tag% happens
+after the message has been written. The value of the $message_size$ variable is
+set to the number of bytes actually written. If the expansion is forced to
+fail, the tag is ignored, but a non-forced failure causes delivery to be
+deferred. The expanded tag may contain any printing characters except ``/''.
Non-printing characters in the string are ignored; if the resulting string is
empty, it is ignored. If it starts with an alphanumeric character, a leading
colon is inserted.
in the given directory. A unique base name is constructed from the message id
and the current delivery process, and the files that are written use this base
name plus the suffixes _.env_ and _.msg_. The _.env_ file contains the
-message's envelope, and the _.msg_ file contains the message itself.
+message's envelope, and the _.msg_ file contains the message itself. The base
+name is placed in the variable $mailstore_basename$.
During delivery, the envelope is first written to a file with the suffix
_.tmp_. The _.msg_ file is then written, and when it is complete, the
greater than one. Finally, %mailstore_suffix% is expanded and the result
appended to the file, followed by a newline if it does not end with one.
+[revisionflag="changed"]
If expansion of %mailstore_prefix% or %mailstore_suffix% ends with a forced
failure, it is ignored. Other expansion errors are treated as serious
-configuration errors, and delivery is deferred.
+configuration errors, and delivery is deferred. The variable
+$mailstore_basename$ is available for use during these expansions.
Non-printing characters are not permitted in the header lines generated for the
message that ^autoreply^ creates, with the exception of newlines that are
-immediately followed by whitespace. If any non-printing characters are found,
+immediately followed by white space. If any non-printing characters are found,
the transport defers.
Whether characters with the top bit set count as printing characters or not is
controlled by the %print_topbitchars% global option.
the original message that is included in the generated message when
%return_message% is set. They do not apply to the generated message itself.
+cindex:[$sender_address$]
If the ^autoreply^ transport receives return code 2 from Exim when it submits
the message, indicating that there were no recipients, it does not treat this
as an error. This means that autoreplies sent to $sender_address$ when this
%mode%, Use: 'autoreply', Type: 'octal integer', Default: '0600'
===
-If either the log file or the ``once'' file has to be created, this mode is used.
+If either the log file or the ``once'' file has to be created, this mode is
+used.
oindex:[%never_mail%]
%once%, Use: 'autoreply', Type: 'string'!!, Default: '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.
-*Note*: This does not apply to 'Cc:' or 'Bcc:' recipients.
-If %once_file_size% is not set, a DBM database is used, and it is allowed to
-grow as large as necessary. If a potential recipient is already in the
-database, no message is sent by default. However, if %once_repeat% specifies a
-time greater than zero, the message is sent if that much time has elapsed since
-a message was last sent to this recipient. If %once% is unset, the message is
-always sent.
-
-If %once_file_size% is set greater than zero, it changes the way Exim
-implements the %once% option. Instead of using a DBM file to record every
-recipient it sends to, it uses a regular file, whose size will never get larger
-than the given value. In the file, it keeps a linear list of recipient
-addresses and times at which they were sent messages. If the file is full when
-a new address needs to be added, the oldest address is dropped. If
-%once_repeat% is not set, this means that a given recipient may receive
-multiple messages, but at unpredictable intervals that depend on the rate of
-turnover of addresses in the file. If %once_repeat% is set, it specifies a
-maximum time between repeats.
+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. *Note*: This
+does not apply to 'Cc:' or 'Bcc:' recipients.
+
+If %once% is unset, or is set to an empty string, the message is always sent.
+By default, if %once% is set to a non-empty file name, the message
+is not sent if a potential recipient is already listed in the database.
+However, if the %once_repeat% option specifies a time greater than zero, the
+message is sent if that much time has elapsed since a message was last sent to
+this recipient. A setting of zero time for %once_repeat% (the default) prevents
+a message from being sent a second time -- in this case, zero means infinity.
+
+If %once_file_size% is zero, a DBM database is used to remember recipients, and
+it is allowed to grow as large as necessary. If %once_file_size% is set greater
+than zero, it changes the way Exim implements the %once% option. Instead of
+using a DBM file to record every recipient it sends to, it uses a regular file,
+whose size will never get larger than the given value.
+
+In the file, Exim keeps a linear list of recipient addresses and the times at
+which they were sent messages. If the file is full when a new address needs to
+be added, the oldest address is dropped. If %once_repeat% is not set, this
+means that a given recipient may receive multiple messages, but at
+unpredictable intervals that depend on the rate of turnover of addresses in the
+file. If %once_repeat% is set, it specifies a maximum time between repeats.
oindex:[%once_file_size%]
%command%, Use: 'lmtp', Type: 'string'!!, Default: 'unset'
===
-This option must be set if %socket% is not set.
-The string is a command which is run in a separate process. It is split up into
-a command name and list of arguments, each of which is separately expanded (so
-expansion cannot change the number of arguments). The command is run directly,
-not via a shell. The message is passed to the new process using the standard
-input and output to operate the LMTP protocol.
+This option must be set if %socket% is not set. The string is a command which
+is run in a separate process. It is split up into a command name and list of
+arguments, each of which is separately expanded (so expansion cannot change the
+number of arguments). The command is run directly, not via a shell. The message
+is passed to the new process using the standard input and output to operate the
+LMTP protocol.
+
+oindex:[%ignore_quota%]
+`..'=
+%ignore_quota%, Use: 'lmtp', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+cindex:[LMTP,ignoring quota errors]
+If this option is set true, the string `IGNOREQUOTA` is added to RCPT commands,
+provided that the LMTP server has advertised support for IGNOREQUOTA in its
+response to the LHLO command.
oindex:[%socket%]
automatically process their incoming messages. The ^pipe^ transport can be
used in one of the following ways:
-- 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 local part of the address (as usual), and the command that is run is
-specified by the %command% option on the transport.
+- cindex:[$local_part$]
+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 local part of the address (as usual), and the command that is run
+is specified by the %command% option on the transport.
-- If the %batch_max% option is set greater than 1 (the default), the transport
+- cindex:[$pipe_addresses$]
+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.
-- A router redirects an address directly to a pipe command (for example, from an
+- cindex:[$address_pipe$]
+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
that was redirected, and $address_pipe$ contains the text of the pipe
command itself. The %command% option on the transport is ignored.
implemented by the ^lmtp^ transport.
In the case when ^pipe^ is run as a consequence of an entry in a local user's
-_.forward_ file, the command runs under the uid and gid of that user. In
-other cases, the uid and gid have to be specified explicitly, either on the
-transport or on the router that handles the address. Current and ``home''
-directories are also controllable. See chapter <<CHAPenvironment>> for details of
-the local delivery environment.
+_.forward_ file, the command runs under the uid and gid of that user. In other
+cases, the uid and gid have to be specified explicitly, either on the transport
+or on the router that handles the address. Current and ``home'' directories are
+also controllable. See chapter <<CHAPenvironment>> for details of the local
+delivery environment.
cindex:[transport,filter]
cindex:[filter,transport filter]
+cindex:[$pipe_addresses$]
Special handling takes place when an argument consists of precisely the text
`\$pipe_addresses\}`. This is not a general expansion variable; the only
place this string is recognized is when it appears as an argument for a pipe or
`LOCAL_PART_PREFIX ` see below
`LOCAL_PART_SUFFIX ` see below
`LOGNAME ` see below
-`MESSAGE_ID ` the message's id
+`MESSAGE_ID ` Exim's local ID for the message
`PATH ` as specified by the %path% option below
`QUALIFY_DOMAIN ` the sender qualification domain
`RECIPIENT ` the complete recipient address
If this option is true, the status returned by the subprocess that is set up to
run the command is ignored, and Exim behaves as if zero had been returned.
-Otherwise, a non-zero status
-or termination by signal
-causes an error return from the transport unless the status value is one of
-those listed in %temp_errors%; these cause the delivery to be deferred and
-tried again later.
+Otherwise, a non-zero status or termination by signal causes an error return
+from the transport unless the status value is one of those listed in
+%temp_errors%; these cause the delivery to be deferred and tried again later.
+
+[revisionflag="changed"]
+*Note*: This option does not apply to timeouts, which do not return a status.
+See the %timeout_defer% option for how timeouts are handled.
oindex:[%log_defer_output%]
oindex:[%path%]
`..'=
-%path%, Use: 'pipe', Type: 'string', Default: `/usr/bin`
+%path%, Use: 'pipe', Type: 'string', Default: `/bin:/usr/bin`
===
This option specifies the string that is set up in the PATH environment
===
If the command fails to complete within this time, it is killed. This normally
-causes the delivery to fail. A zero time interval specifies no timeout. In
-order to ensure that any subprocesses created by the command are also killed,
-Exim makes the initial process a process group leader, and kills the whole
-process group on a timeout. However, this can be defeated if one of the
-processes starts a new process group.
+causes the delivery to fail (but see %timeout_defer%). A zero time interval
+specifies no timeout. In order to ensure that any subprocesses created by the
+command are also killed, Exim makes the initial process a process group leader,
+and kills the whole process group on a timeout. However, this can be defeated
+if one of the processes starts a new process group.
+
+oindex:[%timeout_defer%]
+`..'=
+%timeout_defer%, Use: 'pipe', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+A timeout in a ^pipe^ transport, either in the command that the transport runs,
+or in a transport filter that is associated with it, is by default treated as a
+hard error, and the delivery fails. However, if %timeout_defer% is set true,
+both kinds of timeout become temporary errors, causing the delivery to be
+deferred.
oindex:[%umask%]
%use_shell%, Use: 'pipe', Type: 'boolean', Default: 'false'
===
+cindex:[$pipe_addresses$]
If this option is set, it causes the command to be passed to _/bin/sh_
instead of being run directly from the transport, as described in section
<<SECThowcommandrun>>. This is less secure, but is needed in some situations
%fallback_hosts%, Use: 'smtp', Type: 'string list', Default: 'unset'
===
+[revisionflag="changed"]
cindex:[fallback,hosts specified on transport]
String expansion is not applied to this option. The argument must be a
-colon-separated list of host names or IP addresses. Fallback hosts can also be
-specified on routers, which associate them with the addresses they process. As
-for the %hosts% option without %hosts_override%, %fallback_hosts% specified
-on the transport is used only if the address does not have its own associated
-fallback host list. Unlike %hosts%, a setting of %fallback_hosts% on an
-address is not overridden by %hosts_override%. However, %hosts_randomize%
-does apply to fallback host lists.
+colon-separated list of host names or IP addresses, optionally also including
+port numbers, though the separator can be changed, as described in section
+<<SECTlistconstruct>>. Each individual item in the list is the same as an item
+in a %route_list% setting for the ^manualroute^ router, as described in section
+<<SECTformatonehostitem>>.
+
+Fallback hosts can also be specified on routers, which associate them with the
+addresses they process. As for the %hosts% option without %hosts_override%,
+%fallback_hosts% specified on the transport is used only if the address does
+not have its own associated fallback host list. Unlike %hosts%, a setting of
+%fallback_hosts% on an address is not overridden by %hosts_override%. However,
+%hosts_randomize% does apply to fallback host lists.
If Exim is unable to deliver to any of the hosts for a particular address, and
the errors are not permanent rejections, the address is put on a separate
===
Hosts are associated with an address by a router such as ^dnslookup^, which
-finds the hosts by looking up the address domain in the DNS. However, addresses
-can be passed to the ^smtp^ transport by any router, and not all of them can
-provide an associated host list. The %hosts% option specifies a list of hosts
-which are used if the address being processed does not have any hosts
-associated with it. The hosts specified by %hosts% are also used, whether or
-not the address has its own hosts, if %hosts_override% is set.
+finds the hosts by looking up the address domain in the DNS, or by
+^manualroute^, which has lists of hosts in its configuration. However,
+email addresses can be passed to the ^smtp^ transport by any router, and not
+all of them can provide an associated list of hosts.
+
+The %hosts% option specifies a list of hosts to be used if the address being
+processed does not have any hosts associated with it. The hosts specified by
+%hosts% are also used, whether or not the address has its own hosts, if
+%hosts_override% is set.
+[revisionflag="changed"]
The string is first expanded, before being interpreted as a colon-separated
-list of host names or IP addresses. If the expansion fails, delivery is
-deferred. Unless the failure was caused by the inability to complete a lookup,
-the error is logged to the panic log as well as the main log. Host names are
-looked up either by searching directly for address records in the DNS or by
-calling 'gethostbyname()'
-(or 'getipnodebyname()' when available),
-depending on the setting of the %gethostbyname% option. When Exim is compiled
-with IPv6 support, if a host that is looked up in the DNS has both IPv4 and
-IPv6 addresses, both types of address are used.
+list of host names or IP addresses, possibly including port numbers. The
+separator may be changed to something other than colon, as described in section
+<<SECTlistconstruct>>. Each individual item in the list is the same as an item
+in a %route_list% setting for the ^manualroute^ router, as described in section
+<<SECTformatonehostitem>>. However, note that the `/MX` facility of the
+^manualroute^ router is not available here.
+
+If the expansion fails, delivery is deferred. Unless the failure was caused by
+the inability to complete a lookup, the error is logged to the panic log as
+well as the main log. Host names are looked up either by searching directly for
+address records in the DNS or by calling 'gethostbyname()' (or
+'getipnodebyname()' when available), depending on the setting of the
+%gethostbyname% option. When Exim is compiled with IPv6 support, if a host that
+is looked up in the DNS has both IPv4 and IPv6 addresses, both types of address
+are used.
During delivery, the hosts are tried in order, subject to their retry status,
unless %hosts_randomize% is set.
cindex:[bind IP address]
cindex:[IP address,binding]
+cindex:[$host$]
+cindex:[$host_address$]
This option specifies which interface to bind to when making an outgoing SMTP
call. The variables $host$ and $host_address$ refer to the host to which a
connection is about to be made during the expansion of the string. Forced
unreachable hosts.
+oindex:[%lmtp_ignore_quota%]
+`..'=
+%lmtp_ignore_quota%, Use: 'smtp', Type: 'boolean', Default: 'false'
+===
+
+[revisionflag="changed"]
+cindex:[LMTP,ignoring quota errors]
+If this option is set true when the %protocol% option is set to ``lmtp'', the
+string `IGNOREQUOTA` is added to RCPT commands, provided that the LMTP server
+has advertised support for IGNOREQUOTA in its response to the LHLO command.
+
+
oindex:[%max_rcpt%]
`..'=
%max_rcpt%, Use: 'smtp', Type: 'integer', Default: '100'
%multi_domain%, Use: 'smtp', Type: 'boolean', Default: 'true'
===
+cindex:[$domain$]
When this option is set, the ^smtp^ transport can handle a number of addresses
containing a mixture of different domains provided they all resolve to the same
list of hosts. Turning the option off restricts the transport to handling only
cindex:[TLS client certificate, location of]
cindex:[certificate for client, location of]
+cindex:[$host$]
+cindex:[$host_address$]
The value of this option must be the absolute path to a file which contains the
client's certificate, for use when sending a message over an encrypted
connection. The values of $host$ and $host_address$ are set to the name
===
cindex:[TLS client private key, location of]
+cindex:[$host$]
+cindex:[$host_address$]
The value of this option must be the absolute path to a file which contains the
client's private key, for use when sending a message over an encrypted
connection. The values of $host$ and $host_address$ are set to the name
cindex:[TLS,requiring specific ciphers]
cindex:[cipher,requiring specific]
+cindex:[$host$]
+cindex:[$host_address$]
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
cindex:[TLS,server certificate verification]
cindex:[certificate,verification of server]
+cindex:[$host$]
+cindex:[$host_address$]
The value of this option must be the absolute path to a file containing
permitted server certificates, for use when setting up an encrypted connection.
Alternatively, if you are using OpenSSL, you can set
Configured address rewriting can take place at several different stages of a
message's processing.
+cindex:[$sender_address$]
At the start of an ACL for MAIL, the sender address may have been rewritten
by a special SMTP-time rewrite rule (see section <<SECTrewriteS>>), but no
ordinary rewrite rules have yet been applied. If, however, the sender address
RCPT ACL. Otherwise, when the sender address is not verified, it is
rewritten as soon as a message's header lines have been received.
+cindex:[$domain$]
+cindex:[$local_part$]
Similarly, at the start of an ACL for RCPT, the current recipient's address
may have been rewritten by a special SMTP-time rewrite rule, but no ordinary
rewrite rules have yet been applied to it. However, the behaviour is different
has not) already been rewritten. However, a rewrite of 'From:' may assume that
the envelope sender has already been rewritten.
+cindex:[$domain$]
+cindex:[$local_part$]
The variables $local_part$ and $domain$ can be used in the replacement
string to refer to the address that is being rewritten. Note that lookup-driven
rewriting can be done by a rule of the form
The source pattern in a rewriting rule is any item which may appear in an
address list (see section <<SECTaddresslist>>). It is in fact processed as a
single-item address list, which means that it is expanded before being tested
-against the address.
+against the address. As always, if you use a regular expression as a pattern,
+you must take care to escape dollar and backslash characters, or use the `\N`
+facility to suppress string expansion within the regular expression.
Domains in patterns should be given in lower case. Local parts in patterns are
case-sensitive. If you want to do case-insensitive matching of local parts, you
specifies that 'hatta@lookingglass.fict.example' is never to be rewritten in
'From:' headers.
+cindex:[$domain$]
+cindex:[$local_part$]
If the replacement string is not a single asterisk, it is expanded, and must
yield a fully qualified address. Within the expansion, the variables
$local_part$ and $domain$ refer to the address that is being rewritten.
required to be a regular expression, and it is matched against the whole of the
data for the command, including any surrounding angle brackets.
+cindex:[$domain$]
+cindex:[$local_part$]
This form of rewrite rule allows for the handling of addresses that are not
compliant with RFCs 2821 and 2822 (for example, ``bang paths'' in batched SMTP
input). Because the input is not required to be a syntactically valid address,
From: Ford Prefect <prefectf@hitch.fict.example>
+
+cindex:[RFC 2047]
Sometimes there is a need to replace the whole address item, and this can be
done by adding the flag letter ``w'' to a rule. If this is set on a rule that
causes an address in a header line to be rewritten, the entire address is
replaced, not just the working part. The replacement must be a complete RFC
2822 address, including the angle brackets if necessary. If text outside angle
brackets contains a character whose value is greater than 126 or less than 32
-(except for tab), the text is encoded according to RFC 2047.
-The character set is taken from %headers_charset%, which defaults to
-ISO-8859-1.
+(except for tab), the text is encoded according to RFC 2047. The character set
+is taken from %headers_charset%, which defaults to ISO-8859-1.
+
When the ``w'' flag is set on a rule that causes an envelope address to be
rewritten, all but the working part of the replacement address is discarded.
-Choosing which retry rule to use
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Choosing which retry rule to use for address errors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When Exim is looking for a retry rule after a routing attempt has failed (for
example, after a DNS timeout), each line in the retry configuration is tested
against the complete address only if %retry_use_local_part% is set for the
retry rules. The rule that is found is used to create a retry time for the
failing address.
-For a temporary error that is not related to an individual address,
-(for example, a connection timeout), each line in the retry configuration is
-checked twice. First, the name of the remote host is used as a domain name
-(preceded by ``\*@'' when matching a regular expression). If this does not match
-the line, the domain from the email address is tried in a similar fashion. For
-example, suppose the MX records for 'a.b.c.example' are
+
+Choosing which retry rule to use for host errors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For a temporary error that is not related to an individual address (for
+example, a connection timeout), each line in the retry configuration is checked
+twice. First, the name of the remote host is used as a domain name (preceded by
+``\*@'' when matching a regular expression). If this does not match the line,
+the domain from the email address is tried in a similar fashion. For example,
+suppose the MX records for 'a.b.c.example' are
a.b.c.example MX 5 x.y.z.example
MX 6 p.q.r.example
p.q.r.example * F,24h,30m;
a.b.c.example * F,4d,45m;
-and a delivery to the host 'x.y.z.example' fails. The first rule matches
-neither the host nor the domain, so Exim looks at the second rule. This does
-not match the host, but it does match the domain, so it is used to calculate
-the retry time for the host 'x.y.z.example'. Meanwhile, Exim tries to deliver
-to 'p.q.r.example'. If this fails, the first retry rule is used, because it
-matches the host.
+and a delivery to the host 'x.y.z.example' suffers a connection failure. The
+first rule matches neither the host nor the domain, so Exim looks at the second
+rule. This does not match the host, but it does match the domain, so it is used
+to calculate the retry time for the host 'x.y.z.example'. Meanwhile, Exim tries
+to deliver to 'p.q.r.example'. If this also suffers a host error, the first
+retry rule is used, because it matches the host.
-In other words, failures to deliver to host 'p.q.r.example' use the first
-rule to determine retry times, but for all the other hosts for the domain
+In other words, temporary failures to deliver to host 'p.q.r.example' use the
+first rule to determine retry times, but for all the other hosts for the domain
'a.b.c.example', the second rule is used. The second rule is also used if
routing to 'a.b.c.example' suffers a temporary failure.
+[revisionflag="changed"]
+*Note*: the host name is used when matching the patterns, not its IP address.
+However, if a message is routed directly to an IP address without the use of a
+host name, for example, if a ^manualroute^ router contains a setting such as:
+
+ route_list = *.a.example 192.168.34.23
+
+then the ``host name'' that is used when searching for a retry rule is the
+textual form of the IP address.
+
Retry rules for specific errors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The retry timings themselves are then the fourth item. For example:
....
-* * senders=: F,1h,30m
+* rcpt_4xx senders=: F,1h,30m
....
-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:
+matches 4##'xx' errors for bounce messages sent to any host. If the address
+list contains white space, it must be enclosed in quotes. For example:
- a.domain timeout senders="xb.dom : yc.dom" G,8h,10m,1.5
+ a.domain auth_failed senders="xb.dom : yc.dom" G,8h,10m,1.5
+
+[revisionflag="changed"]
+*Warning*: This facility can be unhelpful if it is used for host errors (those
+that do not depend on the recipient). The reason is that the sender is used
+only to match the retry rule. Once the rule has been found for a host error,
+its contents are used to set a retry time for the host, and this will apply to
+all messages, not just those with specific senders.
When testing retry rules using %-brt%, you can supply a sender using the %-f%
command line option, like this:
relevant) was detected, not from the time the message was received.
cindex:[retry,algorithms]
+cindex:[retry,fixed intervals]
+cindex:[retry,increasing intervals]
+cindex:[retry,random intervals]
The available algorithms are:
- 'F': retry at fixed intervals. There is a single time parameter specifying
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.
+[revisionflag="changed"]
+- 'H': retry at randomized intervals. The arguments are as for 'G'. For each
+retry, the previous interval is multiplied by the factor in order to get a
+maximum for the next interval. The mininum interval is the first argument of
+the parameter, and an actual interval is chosen randomly between them. Such a
+rule has been found to be helpful in cluster configurations when all the
+members of the cluster restart at once, and may therefore synchronize their
+queue processing times.
+
When computing the next retry time, the algorithm definitions are scanned in
order until one whose cutoff time has not yet passed is reached. This is then
used to compute a new retry time that is later than the current time. In the
included by setting
AUTH_CRAM_MD5=yes
+ AUTH_CYRUS_SASL=yes
AUTH_PLAINTEXT=yes
AUTH_SPA=yes
in _Local/Makefile_, respectively. The first of these supports the CRAM-MD5
-authentication mechanism (RFC 2195), and the second can be configured to
-support the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism,
-which is not formally documented, but used by several MUAs. The third
-authenticator supports Microsoft's 'Secure Password Authentication'
-mechanism.
+authentication mechanism (RFC 2195), and the second provides an interface to
+the Cyrus SASL authentication library. The third can be configured to support
+the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, which is
+not formally documented, but used by several MUAs. The fourth authenticator
+supports Microsoft's 'Secure Password Authentication' mechanism.
The authenticators are configured using the same syntax as other drivers (see
section <<SECTfordricon>>). If no authenticators are required, no authentication
%server_set_id%, Use: 'authenticators', Type: 'string'!!, Default: 'unset'
===
+cindex:[$authenticated_id$]
When an Exim server successfully authenticates a client, this string is
expanded using data from the authentication, and preserved for any incoming
messages in the variable $authenticated_id$. It is also included in the log
- If the value of the AUTH= parameter is ``<>'', it is ignored.
-- If %acl_smtp_mailauth% is defined, the ACL it specifies is run. While it is
-running, the value of $authenticated_sender$ is set to the value obtained
-from the AUTH= parameter. If the ACL does not yield ``accept'', the value of
-$authenticated_sender$ is deleted. The %acl_smtp_mailauth% ACL may not
-return ``drop'' or ``discard''. If it defers, a temporary error code (451) is given
+- cindex:[$authenticated_sender$]
+If %acl_smtp_mailauth% is defined, the ACL it specifies is run. While it is
+running, the value of $authenticated_sender$ is set to the value obtained from
+the AUTH= parameter. If the ACL does not yield ``accept'', the value of
+$authenticated_sender$ is deleted. The %acl_smtp_mailauth% ACL may not return
+``drop'' or ``discard''. If it defers, a temporary error code (451) is given
for the MAIL command.
- If %acl_smtp_mailauth% is not defined, the value of the AUTH= parameter
$authenticated_id$, which is a string obtained from the authentication
process, and which is not usually a complete email address.
+cindex:[$sender_address$]
Whenever an AUTH= value is ignored, the incident is logged. The ACL for
MAIL, if defined, is run after AUTH= is accepted or ignored. It can
therefore make use of $authenticated_sender$. The converse is not true: the
server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
+cindex:[$tls_cipher$]
If the session is encrypted, $tls_cipher$ is not empty, and so the expansion
yields ``yes'', which allows the advertisement to happen.
fails. If there is no matching advertised mechanism, the AUTH command is
rejected with a 504 error.
+cindex:[$received_protocol$]
+cindex:[$sender_host_authenticated$]
When a message is received from an authenticated host, the value of
-$received_protocol$ is set to ``esmtpa'' 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 ``esmtpa'' or ``esmtpsa'' instead of ``esmtp'' or
+``esmtps'', 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.
authentication mechanisms announced by the server for one whose name
matches the public name of the authenticator.
-- When it finds one that matches, it runs the authenticator's client code.
+- cindex:[$host$]
+cindex:[$host_address$]
+When it finds one that matches, it runs the authenticator's client code.
The variables $host$ and $host_address$ are available for any string
expansions that the client might do. They are set to the server's name and
IP address. If any expansion is forced to fail, the authentication attempt
command, the remaining prompts are used to obtain more data. Each response from
the client may be a list of NUL-separated strings.
-Once a sufficient number of data strings have been received,
-%server_condition% is expanded.
-If the expansion is forced to fail, authentication fails. Any other expansion
-failure causes a temporary error code to be returned.
-If the result of a successful expansion is an empty string, ``0'', ``no'', or
-``false'', authentication fails. If the result of the expansion is ``1'', ``yes'', or
-``true'', authentication succeeds and the generic %server_set_id% option is
-expanded and saved in $authenticated_id$. For any other result, a temporary
-error code is returned, with the expanded string as the error text.
+cindex:[$authenticated_id$]
+Once a sufficient number of data strings have been received, %server_condition%
+is expanded. If the expansion is forced to fail, authentication fails. Any
+other expansion failure causes a temporary error code to be returned. If the
+result of a successful expansion is an empty string, ``0'', ``no'', or
+``false'', authentication fails. If the result of the expansion is ``1'',
+``yes'', or ``true'', authentication succeeds and the generic %server_set_id%
+option is expanded and saved in $authenticated_id$. For any other result, a
+temporary error code is returned, with the expanded string as the error text.
*Warning*: If you use a lookup in the expansion to find the user's
password, be sure to make the authentication fail if the user is unknown.
server_secret = ${if eq{$1}{ph10}{secret}fail}
server_set_id = $1
+cindex:[$authenticated_id$]
If authentication succeeds, the setting of %server_set_id% preserves the user
-name in $authenticated_id$.
-A more tyical configuration might look up the secret string in a file, using
-the user name as the key. For example:
+name in $authenticated_id$. A more tyical configuration might look up the
+secret string in a file, using the user name as the key. For example:
lookup_cram:
driver = cram_md5
expanded and the result used as the secret string when computing the response.
+cindex:[$host$]
+cindex:[$host_address$]
Different user names and secrets can be used for different servers by referring
to $host$ or $host_address$ in the options.
This option is expanded, and the result must be the cleartext password for the
authenticating user, whose name is at this point in $1$. For example:
- spa:
- driver = spa
- public_name = NTLM
- server_password = ${lookup{$1}lsearch{/etc/exim/spa_clearpass}}
+....
+spa:
+ driver = spa
+ public_name = NTLM
+ server_password = ${lookup{$1}lsearch{/etc/exim/spa_clearpass}\
+ {$value}fail}
+....
If the expansion is forced to fail, authentication fails. Any other expansion
failure causes a temporary error code to be returned.
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
+RFC 3207 defines how SMTP connections can make use of encryption. Once a
connection is established, the client issues a STARTTLS command. If the
server accepts this, the client and the server negotiate an encryption
mechanism. If the negotiation succeeds, the data that subsequently passes
facility for varying its Diffie-Hellman parameters. I understand that this has
changed, but Exim has not been updated to provide this facility.
-- GnuTLS uses RSA and D-H parameters that take a substantial amount of
-time to compute. It is unreasonable to re-compute them for every TLS
-session. Therefore, Exim keeps this data in a file in its spool
-directory, called _gnutls-params_. The file is owned by the Exim user and is
-readable only by its owner. Every Exim process that start up GnuTLS reads the
-RSA and D-H parameters from this file. If the file does not exist, the first
-Exim process that needs it computes the data and writes it to a temporary file
-which is renamed once it is complete. It does not matter if several Exim
-processes do this simultaneously (apart from wasting a few resources). Once a
-file is in place, new Exim processes immediately start using it.
-+
-For maximum security, the parameters that are stored in this file should be
-recalculated periodically, the frequency depending on your paranoia level.
-Arranging this is easy; just delete the file when you want new values to be
-computed.
-
-- Distinguished Name (DN) strings reported by the OpenSSL library use a slash for
+- cindex:[$tls_peerdn$]
+Distinguished Name (DN) strings reported by the OpenSSL library use a slash for
separating fields; GnuTLS uses commas, in accordance with RFC 2253. This
affects the value of the $tls_peerdn$ variable.
option).
- The %tls_require_ciphers% options operate differently, as described in the
-following sections.
+sections <<SECTreqciphssl>> and <<SECTreqciphgnu>>.
+
+
+GnuTLS parameter computation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+GnuTLS uses RSA and D-H parameters that take a substantial amount of time to
+compute. It is unreasonable to re-compute them for every TLS session.
+Therefore, Exim keeps this data in a file in its spool directory, called
+_gnutls-params_. The file is owned by the Exim user and is readable only by its
+owner. Every Exim process that start up GnuTLS reads the RSA and D-H parameters
+from this file. If the file does not exist, the first Exim process that needs
+it computes the data and writes it to a temporary file which is renamed once it
+is complete. It does not matter if several Exim processes do this
+simultaneously (apart from wasting a few resources). Once a file is in place,
+new Exim processes immediately start using it.
+
+[revisionflag="changed"]
+For maximum security, the parameters that are stored in this file should be
+recalculated periodically, the frequency depending on your paranoia level.
+Arranging this is easy in principle; just delete the file when you want new
+values to be computed. However, there may be a problem. The calculation of new
+parameters needs random numbers, and these are obtained from _/dev/random_. If
+the system is not very active, _/dev/random_ may delay returning data until
+enough randomness (entropy) is available. This may cause Exim to hang for a
+substantial amount of time, causing timeouts on incoming connections.
+
+[revisionflag="changed"]
+The solution is to generate the parameters externally to Exim. They are stored
+in _gnutls-params_ in PEM format, which means that they can be generated
+externally using the ^certtool^ command that is part of GnuTLS.
+
+[revisionflag="changed"]
+To replace the parameters with new ones, instead of deleting the file
+and letting Exim re-create it, you can generate new parameters using
+^certtool^ and, when this has been done, replace Exim's cache file by
+renaming. The relevant commands are something like this:
+
+[revisionflag="changed"]
+....
+# rm -f new-params
+# touch new-params
+# chown exim:exim new-params
+# chmod 0400 new-params
+# certtool --generate-privkey --bits 512 >new-params
+# echo "" >>new-params
+# certtool --generate-dh-params --bits 1024 >> new-params
+# mv new-params gnutls-params
+....
+
+[revisionflag="changed"]
+If Exim never has to generate the parameters itself, the possibility of
+stalling is removed.
cindex:[cipher,logging]
cindex:[log,TLS cipher]
+cindex:[$tls_cipher$]
The variable $tls_cipher$ is set to the cipher suite that was negotiated for
an incoming TLS connection. It is included in the 'Received:' header of an
incoming message (by default -- you can, of course, change this), and it is
example, you can insist on a certificate before accepting a message for
relaying, but not when the message is destined for local delivery.
+cindex:[$tls_peerdn$]
When a client supplies a certificate (whether it verifies or not), the value of
the Distinguished Name of the certificate is made available in the variable
$tls_peerdn$ during subsequent processing of the message.
the current host is abandoned, and the ^smtp^ transport tries to deliver to
alternative hosts, if any.
+cindex:[$host$]
+cindex:[$host_address$]
All the TLS options in the ^smtp^ transport are expanded before use, with
$host$ and $host_address$ containing the name and address of the server to
which the client is connected. Forced failure of an expansion causes Exim to
The QUIT ACL
~~~~~~~~~~~~
cindex:[QUIT, ACL for]
-The ACL for the SMTP QUIT command is anomalous, in that the
-outcome of the ACL does not affect the response code to QUIT,
-which is always 221. Thus, the ACL does not in fact control any access.
-For this reason, the only verbs that are permitted are %accept% and %warn%.
+The ACL for the SMTP QUIT command is anomalous, in that the outcome of the ACL
+does not affect the response code to QUIT, which is always 221. Thus, the ACL
+does not in fact control any access. For this reason, the only verbs that are
+permitted are %accept% and %warn%.
This ACL can be used for tasks such as custom logging at the end of an SMTP
session. For example, you can use ACL variables in other ACLs to count
messages, recipients, etc., and log the totals at QUIT time using one or
more %logwrite% modifiers on a %warn% verb.
+[revisionflag="changed"]
+*Warning*: only the $acl_c$'x' variables can be used for this, because the
+$acl_m$'x' variables are reset at the end of each incoming message.
+
You do not need to have a final %accept%, but if you do, you can use a
%message% modifier to specify custom text that is sent as part of the 221
response to QUIT.
Data for message ACLs
~~~~~~~~~~~~~~~~~~~~~
cindex:[{ACL},data for message ACL]
-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.
+cindex:[$domain$]
+cindex:[$local_part$]
+cindex:[$sender_address$]
+cindex:[$sender_host_address$]
+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 running, the variables that
contain information about the host are set, but $sender_address$ is not yet
set. Section <<SECTauthparamail>> contains a discussion of this parameter and
how it is used.
+cindex:[$message_size$]
The $message_size$ variable is set to the value of the SIZE parameter on
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 (for
-both the DATA ACLs), $rcpt_count$ contains the total number of RCPT
-commands, and $recipients_count$ contains the total number of accepted
-recipients.
+cindex:[$rcpt_count$]
+cindex:[$recipients_count$]
+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 (for both the DATA ACLs),
+$rcpt_count$ contains the total number of RCPT commands, and $recipients_count$
+contains the total number of accepted recipients.
Data for non-message ACLs
~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[{ACL},data for non-message ACL]
+cindex:[$smtp_command_argument$]
When an ACL is being run for AUTH, EHLO, ETRN, EXPN, HELO, STARTTLS, or VRFY,
the remainder of the SMTP command line is placed in $smtp_command_argument$.
This can be tested using a %condition% condition. For example, here is an ACL
one copy is actually written to the log. If you want to force duplicates to be
written, use the %logwrite% modifier instead.
+
+cindex:[$acl_verify_message$]
When one of the %warn% conditions is an address verification that fails, the
text of the verification failure message is in $acl_verify_message$. If you
want this logged, you must set it up explicitly. For example:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[{ACL},conditions; processing]
cindex:[{ACL},modifiers; processing]
-An exclamation mark preceding a condition negates its result. For example,
+An exclamation mark preceding a condition negates its result. For example:
deny domains = *.dom.example
!verify = recipient
-causes the ACL to return ``deny'' if the recipient domain ends in
-'dom.example' and the recipient address cannot be verified.
+[revisionflag="changed"]
+causes the ACL to return ``deny'' if the recipient domain ends in 'dom.example'
+and the recipient address cannot be verified. Sometimes negation can be used on
+the right-hand side of a condition. For example, these two statements are
+equivalent:
+
+[revisionflag="changed"]
+....
+deny hosts = !192.168.3.4
+deny !hosts = 192.168.3.4
+....
+
+[revisionflag="changed"]
+However, for many conditions (%verify% being a good example), only left-hand
+side negation of the whole condition is possible.
The arguments of conditions and modifiers are expanded. A forced failure
of an expansion causes a condition to be ignored, that is, it behaves as if the
black list lookup succeeds. If the expansion of %log_message% fails, or if the
result is an empty string, the modifier is ignored.
+
+cindex:[$acl_verify_message$]
If you want to use a %warn% statement to log the result of an address
verification, you can use $acl_verify_message$ to include the verification
error message.
newlines, this gives rise to a multi-line SMTP response. Like %log_message%,
the contents of %message% are not expanded until after a condition has failed.
+
+cindex:[$acl_verify_message$]
If %message% is used on a statement that verifies an address, the message
specified overrides any message that is generated by the verification process.
However, the original message is available in the variable
-$acl_verify_message$, so you can incorporate it into your message if you
-wish. In particular, if you want the text from %:fail:% items in ^redirect^
-routers to be passed back as part of the SMTP response, you should either not
-use a %message% modifier, or make use of $acl_verify_message$.
+$acl_verify_message$, so you can incorporate it into your message if you wish.
+In particular, if you want the text from %:fail:% items in ^redirect^ routers
+to be passed back as part of the SMTP response, you should either not use a
+%message% modifier, or make use of $acl_verify_message$.
*set*~<'acl_name'>~=~<'value'>::
cindex:[%set%, ACL modifier]
*control~=~caselower_local_part*::
cindex:[{ACL},case of local part in]
cindex:[case of local parts]
+cindex:[$local_part$]
These two controls are permitted only in the ACL specified by %acl_smtp_rcpt%
(that is, during RCPT processing). By default, the contents of $local_part$ are
lower cased before ACL processing. If ``caseful_local_part'' is specified, any
synchronization checks for badly-behaved hosts that you nevertheless need to
work with.
+
+[revisionflag="changed"]
+*control~=~fakedefer/*<'message'>::
+cindex:[fake defer]
+cindex:[defer,fake]
+This control works in exactly the same way as %fakereject% (described below)
+except that it causes an SMTP 450 response after the message data instead of a
+550 response. You must take care when using %fakedefer% because it causes the
+messages to be duplicated when the sender retries. Therefore, you should not
+use %fakedefer% if the message is to be delivered normally.
+
+
*control~=~fakereject/*<'message'>::
cindex:[fake rejection]
cindex:[rejection, fake]
only to the current message, not to any subsequent ones that may be received in
the same SMTP connection.
+[revisionflag="changed"]
+*control~=~suppress_local_fixups*::
+cindex:[submission fixups,suppressing]
+This control applies to locally submitted (non TCP/IP) messages, and is the
+complement of `control = submission`. It disables the fixups that are normally
+applied to locally-submitted messages. Specifically:
++
+--
+[revisionflag="changed"]
+- Any 'Sender:' header line is left alone (in this respect, it is a
+dynamic version of %local_sender_retain%).
+
+[revisionflag="changed"]
+- No 'Message-ID:', 'From:', or 'Date:' header lines are added.
+
+[revisionflag="changed"]
+- There is no check that 'From:' corresponds to the actual sender.
+--
++
+[revisionflag="changed"]
+This feature may be useful when a remotely-originated message is accepted,
+passed to some scanning program, and then re-submitted for delivery.
+
+[revisionflag="changed"]
+All four possibilities for message fixups can be specified:
+
+[revisionflag="changed"]
+- Locally submitted, fixups applied: the default.
+
+[revisionflag="changed"]
+- Locally submitted, no fixups applied: use `control = suppress_local_fixups`.
+
+[revisionflag="changed"]
+- Remotely submitted, no fixups applied: the default.
+
+[revisionflag="changed"]
+- Remotely submitted, fixups applied: use `control = submission`.
+
+
+
[[SECTaddheadwarn]]
added in an ACL. It does NOT work for header lines that are added in a
system filter or in a router or transport.
+[revisionflag="changed"]
cindex:[header lines,added; visibility of]
-Header lines that are added by an ACL at MAIL or RCPT time are not
-visible in string expansions in ACLs for subsequent RCPT commands or in the
+Header lines that are added by an ACL at MAIL or RCPT time are not visible in
+string expansions in ACLs for subsequent RCPT commands or in the
%acl_smtp_predata% ACL. However, they are visible in string expansions in the
-ACL that is run after DATA is complete (the %acl_smtp_data% ACL). This is
-also true for header lines that are added in the %acl_smtp_predata% ACL.
-If a message is rejected after DATA, all added header lines are included in
-the entry that is written to the reject log.
+ACL that is run after DATA is complete (the %acl_smtp_data% ACL). This is also
+true for header lines that are added in the %acl_smtp_predata% ACL. However,
+header lines that are added in the %acl_smtp_data% itself are not visible
+during that ACL. If a message is rejected after DATA, all added header lines
+are included in the entry that is written to the reject log.
If you want to preserve data between MAIL, RCPT, and the
%acl_smtp_predata% ACLs, you can use ACL variables, as described in section
%acl_smtp_mime%. It causes the current MIME part to be decoded into a file. For
details, see chapter <<CHAPexiscan>>.
+*demime~=~*<'extension~list'>::
+cindex:[%demime%, ACL condition]
+This condition is available only when Exim is compiled with the
+content-scanning extension. Its use is described in section <<SECTdemimecond>>.
+
*dnslists~=~*<'list~of~domain~names~and~other~data'>::
cindex:[%dnslists%, ACL condition]
cindex:[DNS list,in ACL]
cindex:[%domains%, ACL condition]
cindex:[domain,ACL checking]
cindex:[{ACL},testing a recipient domain]
+cindex:[$domain_data$]
This condition is relevant only after a RCPT command. It checks that the domain
of the recipient address is in the domain list. If percent-hack processing is
enabled, it is done before this test is done. If the check succeeds with a
is not in the list, so the first %accept% statement fails. The second statement
can then check the IP address.
+
+cindex:[$host_data$]
If a %hosts% condition is satisfied by means of a lookup, the result
of the lookup is made available in the $host_data$ variable. This
allows you, for example, to set up a statement like this:
cindex:[%local_parts%, ACL condition]
cindex:[local part,ACL checking]
cindex:[{ACL},testing a local part]
+cindex:[$local_part_data$]
This condition is relevant only after a RCPT command. It checks that the local
part of the recipient address is in the list. If percent-hack processing is
enabled, it is done before this test. If the check succeeds with a lookup, the
-result of the lookup is placed in $local_part_data$ until the next
-%local_parts% test.
+result of the lookup is placed in $local_part_data$, which remains set until
+the next %local_parts% test.
*malware~=~*<'option'>::
cindex:[%malware%, ACL condition]
%acl_smtp_mime%. It causes the current MIME part to be scanned for a match with
any of the regular expressions. For details, see chapter <<CHAPexiscan>>.
+[revisionflag="changed"]
+*ratelimit~=~*<'parameters'>::
+cindex:[rate limiting]
+This condition can be used to limit the rate at which a user or host submits
+messages. Details are given in section <<SECTratelimiting>>.
+
*recipients~=~*<'address~list'>::
cindex:[%recipients%, ACL condition]
cindex:[recipient,ACL checking]
cindex:[%regex%, ACL condition]
cindex:[{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
-<<CHAPexiscan>>.
+content-scanning extension, and is available only in the DATA, MIME, and
+non-SMTP ACLs. It causes the incoming message to be scanned for a match with
+any of the regular expressions. For details, see chapter <<CHAPexiscan>>.
*sender_domains~=~*<'domain~list'>::
cindex:[%sender_domains%, ACL condition]
cindex:[sender,ACL checking]
cindex:[{ACL},testing a sender domain]
+cindex:[$domain$]
+cindex:[$sender_address_domain$]
This condition tests the domain of the sender of the message against the given
domain list. *Note*: the domain of the sender address is in
$sender_address_domain$. It is 'not' put in $domain$ during the testing of this
It is done this way so that, if this condition is used in an ACL for a RCPT
command, the recipient's domain (which is in $domain$) can be used to influence
the sender checking.
++
+[revisionflag="changed"]
+*Note*: it is a bad idea to use this condition on its own as a control on
+relaying, because sender addresses are easily, and commonly, forged.
*senders~=~*<'address~list'>::
cindex:[%senders%, ACL condition]
for a bounce message, which has an empty sender, set
senders = :
++
+[revisionflag="changed"]
+*Note*: it is a bad idea to use this condition on its own as a control on
+relaying, because sender addresses are easily, and commonly, forged.
*spam~=~*<'username'>::
cindex:[%spam%, ACL condition]
server requests a certificate only if the client matches %tls_verify_hosts% or
%tls_try_verify_hosts% (see chapter <<CHAPTLS>>).
+[revisionflag="changed"]
+*verify~=~csa*::
+cindex:[CSA verification]
+This condition checks whether the sending host (the client) is authorized to
+send email. Details of how this works are given in section
+<<SECTverifyCSA>>.
+
*verify~=~header_sender/*<'options'>::
cindex:[%verify%, ACL condition]
cindex:[{ACL},verifying sender in the header]
and this condition can be used to reject such messages, though they are not as
common as they used to be.
+[revisionflag="changed"]
*verify~=~helo*::
cindex:[%verify%, ACL condition]
cindex:[{ACL},verifying HELO/EHLO]
cindex:[verifying,EHLO]
cindex:[verifying,HELO]
This condition is true if a HELO or EHLO command has been received from the
-client host, and its contents have been verified. Verification of these
-commands does not happen by default. See the description of the
-%helo_verify_hosts% and %helo_try_verify_hosts% options for details of how to
-request it.
+client host, and its contents have been verified. It there has been no previous
+attempt to verify the the HELO/EHLO contents, it is carried out when this
+condition is encountered. See the description of the %helo_verify_hosts% and
+%helo_try_verify_hosts% options for details of how to request verification
+independently of this condition.
+
+[revisionflag="changed"]
+*verify~=~not_blind*::
+cindex:[verifying,not blind]
+cindex:[bcc recipients,verifying none]
+This condition checks that there are no blind (bcc) recipients in the message.
+Every envelope recipient must appear either in a 'To:' header line or in a
+'Cc:' header line for this condition to be true. Local parts are checked
+case-sensitively; domains are checked case-insensitively. If 'Resent-To:' or
+'Resent-Cc:' header lines exist, they are also checked. This condition can be
+used only in a DATA or non-SMTP ACL.
++
+[revisionflag="changed"]
+There are, of course, many legitimate messages that make use of blind
+(bcc) recipients. This check should not be used on its own for blocking
+messages.
+
+
*verify~=~recipient/*<'options'>::
cindex:[%verify%, ACL condition]
cindex:[{ACL},verifying recipient]
cindex:[recipient,verifying]
cindex:[verifying,recipient]
+cindex:[$address_data$]
This condition is relevant only after a RCPT command. It verifies the current
recipient. Details of address verification are given later, starting at section
<<SECTaddressverification>>. After a recipient has been verified, the value of
message's sender is empty (that is, this is a bounce message), the condition is
true. Otherwise, the sender address is verified.
+
+cindex:[$address_data$]
+cindex:[$sender_address_data$]
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
of the calling host. However, you can specify another IP address by listing it
after the domain name, introduced by a slash. For example:
- deny dnslists = black.list.tls/192.168.1.2
+ deny dnslists = black.list.tld/192.168.1.2
This feature is not very helpful with explicit IP addresses; it is intended for
use with IP addresses that are looked up, for example, the IP addresses of the
Variables set from DNS lists
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[DNS list,variables set from]
+cindex:[$dnslist_domain$]
+cindex:[$dnslist_text$]
+cindex:[$dnslist_value$]
When an entry is found in a DNS list, the variable $dnslist_domain$
contains the name of the domain that matched, $dnslist_value$ contains the
data from the entry, and $dnslist_text$ contains the contents of any
+[[SECTratelimiting]]
+Rate limiting senders
+~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[rate limiting,client sending]
+cindex:[limiting client sending rates]
+oindex:[%smpt_ratelimit_*%]
+The %ratelimit% ACL condition can be used to measure and control the rate at
+which clients can send email. This is more powerful than the %smtp_ratelimit_*%
+options, because those options control the rate of commands in a single SMTP
+session only, whereas the %ratelimit% condition works across all connections
+(concurrent and sequential) from the same client host. There's a script in
+_util/ratelimit.pl_ which extracts sending rates from log files, to assist with
+choosing appropriate settings when deploying the %ratelimit% ACL condition.
+The syntax of the %ratelimit% condition is:
+
+[revisionflag="changed"]
+&&&
+`ratelimit =` <'m'> `/` <'p'> `/` <'options'> `/` <'key'>
+&&&
+
+[revisionflag="changed"]
+If the average client sending rate is less than 'm' messages per time
+period 'p' then the condition is false; otherwise it is true.
+
+[revisionflag="changed"]
+The parameter 'p' is the smoothing time constant, in the form of an Exim
+time interval, for example, `8h` for eight hours. A larger time constant means
+that it takes Exim longer to forget a client's past behaviour. The parameter
+'m' is the maximum number of messages that a client is permitted to send in a
+fast burst. By increasing both 'm' and 'p' but keeping 'm/p' constant, you can
+allow a client to send more messages in a burst without changing its overall
+sending rate limit. Conversely, if 'm' and 'p' are both small, messages must be
+sent at an even rate.
+
+[revisionflag="changed"]
+The key is used to look up the data for calculating the client's average
+sending rate. This data is stored in a database maintained by Exim in its spool
+directory, alongside the retry and other hints databases. You can limit the
+sending rate of each authenticated user, independent of the computer they are
+sending from, by setting the key to $authenticated_id$. The default key is
+$sender_host_address$, which applies the limit to the client host, independent
+of the sender.
+
+[revisionflag="changed"]
+Internally, Exim includes the smoothing constant 'p' and the options in the
+lookup key because they alter the meaning of the stored data. This is not true
+for the limit 'm', so you can alter the configured maximum rate and Exim will
+still remember clients' past behaviour, but if you alter the other ratelimit
+parameters Exim forgets past behaviour.
+
+[revisionflag="changed"]
+Each %ratelimit% condition can have up to two options. The first option
+specifies what Exim measures the rate of, and the second specifies how Exim
+handles excessively fast clients. The options are separated by a slash, like
+the other parameters.
+
+[revisionflag="changed"]
+The %per_conn% option limits the client's connection rate. The %per_mail%
+option limits the client's rate of sending messages. This is the default if
+none of the %per_*% options is specified.
+
+[revisionflag="changed"]
+The %per_byte% option limits the sender's email bandwidth. Note that it is best
+to use this option in the DATA ACL; if it is used in an earlier ACL it relies
+on the SIZE parameter on the MAIL command, which may be inaccurate or
+completely missing. You can follow the limit 'm' in the configuration with K,
+M, or G to specify limits in kilobytes, megabytes, or gigabytes, respectively.
+
+[revisionflag="changed"]
+The %per_cmd% option causes Exim to recompute the rate every time the condition
+is processed. This can be used to limit the SMTP command rate. The alias
+%per_rcpt% is provided for use in the RCPT ACL instead of %per_cmd% to make it
+clear that the effect is to limit the rate at which recipients are accepted.
+Note that in this case the rate limiting engine will see a message with many
+recipients as a large high-speed burst.
+
+[revisionflag="changed"]
+If a client's average rate is greater than the maximum, the rate limiting
+engine can react in two possible ways, depending on the presence of the
+%strict% or %leaky% options. This is independent of the other counter-measures
+(such as rejecting the message) that may be specified by the rest of the ACL.
+The default mode is leaky, which avoids a sender's over-aggressive retry rate
+preventing it from getting any email through.
+
+[revisionflag="changed"]
+The %strict% option means that the client's recorded rate is always updated.
+The effect of this is that Exim measures the client's average rate of attempts
+to send email, which can be much higher than the maximum. If the client is over
+the limit it will be subjected to counter-measures until it slows down below
+the maximum rate. The smoothing period determines the time it takes for a high
+sending rate to decay exponentially to 37% of its peak value, which means that
+you can work out the time (the number of smoothing periods) that a client is
+subjected to counter-measures after an over-limit burst with this formula:
+
+ ln(peakrate/maxrate)
+
+[revisionflag="changed"]
+The %leaky% option means that the client's recorded rate is not updated if it
+is above the limit. The effect of this is that Exim measures the client's
+average rate of successfully sent email, which cannot be greater than the
+maximum. If the client is over the limit it will suffer some counter-measures,
+but it will still be able to send email at the configured maximum rate,
+whatever the rate of its attempts.
+
+[revisionflag="changed"]
+As a side-effect, the %ratelimit% condition sets the expansion variable
+$sender_rate$ to the client's computed rate, $sender_rate_limit$ to the
+configured value of 'm', and $sender_rate_period$ to the configured value of
+'p'.
+
+[revisionflag="changed"]
+Exim's other ACL facilities are used to define what counter-measures are taken
+when the rate limit is exceeded. This might be anything from logging a warning
+(for example, while measuring existing sending rates in order to define
+policy), through time delays to slow down fast senders, up to rejecting the
+message. For example:
+
+[revisionflag="changed"]
+....
+# Log all senders' rates
+warn
+ ratelimit = 0 / 1h / strict
+ log_message = Sender rate $sender_rate / $sender_rate_period
+
+# Slow down fast senders
+warn
+ ratelimit = 100 / 1h / per_rcpt / strict
+ delay = ${eval: $sender_rate - $sender_rate_limit }s
+
+# Keep authenticated users under control
+deny
+ ratelimit = 100 / 1d / strict / $authenticated_id
+
+# System-wide rate limit
+defer
+ message = Sorry, too busy. Try again later.
+ ratelimit = 10 / 1s / $primary_hostname
+
+# Restrict incoming rate from each host, with a default
+# set using a macro and special cases looked up in a table.
+defer
+ message = Sender rate exceeds $sender_rate_limit \
+ messages per $sender_rate_period
+ ratelimit = ${lookup {$sender_host_address} \
+ cdb {DB/ratelimits.cdb} \
+ {$value} {RATELIMIT} }
+....
+
+[revisionflag="changed"]
+*Warning*: if you have a busy server with a lot of %ratelimit% tests,
+especially with the %per_rcpt% option, you may suffer from a performance
+bottleneck caused by locking on the ratelimit hints database. Apart from
+making your ACLs less complicated, you can reduce the problem by using a
+RAM disk for Exim's hints directory (usually _/var/spool/exim/db/_). However
+this means that Exim will lose its hints data after a reboot (including retry
+hints, the callout cache, and ratelimit data).
+
+
[[SECTaddressverification]]
Address verification
the condition is forced to be true instead. Note that this is a main
verification option as well as a suboption for callouts.
-- The %no_details% option is covered in section <<SECTsenaddver>>, which discusses
-the reporting of sender address verification failures.
+- The %no_details% option is covered in section <<SECTsenaddver>>, which
+discusses the reporting of sender address verification failures.
+[revisionflag="changed"]
+- The %success_on_redirect% option causes verification always to succeed
+immediately after a successful redirection. By default, if a redirection
+generates just one address, that address is also verified. See further
+discussion in section <<SECTredirwhilveri>>.
+
+[revisionflag="changed"]
cindex:[verifying address, differentiating failures]
-After an address verification failure, $sender_verify_failure$ or
-$recipient_verify_failure$ (as appropriate) contains one of the following
-words:
+cindex:[$recipient_verify_failure$]
+cindex:[$sender_verify_failure$]
+cindex:[$acl_verify_message$]
+After an address verification failure, $acl_verify_message$ contains the error
+message that is associated with the failure. It can be preserved by coding like
+this:
+
+ warn !verify = sender
+ set acl_m0 = $acl_verify_message
+
+[revisionflag="changed"]
+If you are writing your own custom rejection message or log message when
+denying access, you can use this variable to include information about the
+verification failure.
+
+In addition, $sender_verify_failure$ or $recipient_verify_failure$ (as
+appropriate) contains one of the following words:
- %qualify%: The address was unqualified (no domain), and the message
was neither local nor came from an exempted host.
- %postmaster%: The postmaster check in a callout was rejected.
-
The main use of these variables is expected to be to distinguish between
rejections of MAIL and rejections of RCPT in callouts.
[[SECTcallver]]
Callout verification
~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:[verifying address, by callout]
cindex:[callout,verification]
cindex:[SMTP,callout verification]
For non-local addresses, routing verifies the domain, but is unable to do any
checking of the local part. There are situations where some means of verifying
the local part is desirable. One way this can be done is to make an SMTP
-'callback' to the sending host (for a sender address) or a 'callforward' to
-a subsequent host (for a recipient address), to see if the host accepts the
-address. We use the term 'callout' to cover both cases. This facility should
-be used with care, because it can add a lot of resource usage to the cost of
-verifying an address. However, Exim does cache the results of callouts, which
-helps to reduce the cost. Details of caching are in the next section.
+'callback' to a delivery host for the sender address or a 'callforward' to a
+subsequent host for a recipient address, to see if the host accepts the
+address. We use the term 'callout' to cover both cases. Note that for a sender
+address, the callback is not to the client host that is trying to deliver the
+message, but to one of the hosts that accepts incoming mail for the sender's
+domain.
+
+[revisionflag="changed"]
+Exim does not do callouts by default. If you want them to happen, you must
+request them by setting appropriate options on the %verify% condition, as
+described below. This facility should be used with care, because it can add a
+lot of resource usage to the cost of verifying an address. However, Exim does
+cache the results of callouts, which helps to reduce the cost. Details of
+caching are in section <<SECTcallvercache>>.
Recipient callouts are usually used only between hosts that are controlled by
the same administration. For example, a corporate gateway host could use
-callouts to check for valid recipients on an internal mailserver.
-A successful callout does not guarantee that a real delivery to the address
-would succeed; on the other hand, a failing callout does guarantee that
-a delivery would fail.
+callouts to check for valid recipients on an internal mailserver. A successful
+callout does not guarantee that a real delivery to the address would succeed;
+on the other hand, a failing callout does guarantee that a delivery would fail.
If the %callout% option is present on a condition that verifies an address, a
second stage of verification occurs if the address is successfully routed to
of temporary error, is treated as success by the ACL. However, the cache is not
updated in this circumstance.
+[revisionflag="changed"]
+*fullpostmaster*::
+cindex:[callout,full postmaster check]
+This operates like the %postmaster% option (see below), but if the check for
+'postmaster@domain' fails, it tries just 'postmaster', without a domain, in
+accordance with the specification in RFC 2821. The RFC states that the
+unqualified address 'postmaster' should be accepted.
+
+
+
*mailfrom~=~*<'email~address'>::
cindex:[callout,sender when verifying header]
When verifying addresses in header lines using the %header_sender% verification
cindex:[callout,postmaster; checking]
When this parameter is set, a sucessful callout check is followed by a similar
check for the local part 'postmaster' at the same domain. If this address is
-rejected, the callout fails. The result of the postmaster check is recorded in
-a cache record; if it is a failure, this is used to fail subsequent callouts
-for the domain without a connection being made, until the cache record expires.
+rejected, the callout fails (but see %fullpostmaster% above). The result of the
+postmaster check is recorded in a cache record; if it is a failure, this is
+used to fail subsequent callouts for the domain without a connection being
+made, until the cache record expires.
*postmaster_mailfrom~=~*<'email~address'>::
The postmaster check uses an empty sender in the MAIL command by default.
deny !verify = recipient/callout=use_postmaster
+
-It causes a non-empty postmaster address to be used in the MAIL command
-when performing the callout. The local part of the address is `postmaster`
-and the domain is the contents of $qualify_domain$.
+[revisionflag="changed"]
+cindex:[$qualify_domain$]
+It causes a non-empty postmaster address to be used in the MAIL command when
+performing the callout for the recipient, and also for a ``random'' check if
+that is configured. The local part of the address is `postmaster` and the
+domain is the contents of $qualify_domain$.
*use_sender*::
This option applies to recipient callouts only. For example:
-
+[[SECTredirwhilveri]]
Redirection while verifying
~~~~~~~~~~~~~~~~~~~~~~~~~~~
cindex:[verifying,redirection while]
A dilemma arises when a local address is redirected by aliasing or forwarding
during verification: should the generated addresses themselves be verified,
or should the successful expansion of the original address be enough to verify
-it? Exim takes the following pragmatic approach:
+it? By default, Exim takes the following pragmatic approach:
- When an incoming address is redirected to just one child address, verification
continues with the child address, and if that fails to verify, the original
mailing list, where the existence of the alias itself is sufficient for
verification to succeed.
+[revisionflag="changed"]
+It is possible, however, to change the default behaviour so that all successful
+redirections count as successful verifications, however many new addresses are
+generated. This is specified by the %success_on_redirect% verification option.
+For example:
+
+[revisionflag="changed"]
+ require verify = recipient/success_on_redirect/callout=10s
+
+[revisionflag="changed"]
+In this example, verification succeeds if a router generates a new address, and
+the callout does not occur, because no address was routed to a remote host.
+
+
+
+
+
+[[SECTverifyCSA]]
+Client SMTP authorization (CSA)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[CSA,verifying]
+Client SMTP Authorization is a system that allows a site to advertise
+which machines are and are not permitted to send email. This is done by placing
+special SRV records in the DNS; these are looked up using the client's HELO
+domain. At the time of writing, CSA is still an Internet Draft. Client SMTP
+Authorization checks in Exim are performed by the ACL condition:
+
+ verify = csa
+
+[revisionflag="changed"]
+This fails if the client is not authorized. If there is a DNS problem, or if no
+valid CSA SRV record is found, or if the client is authorized, the condition
+succeeds. These three cases can be distinguished using the expansion variable
+$csa_status$, which can take one of the values ``fail'', ``defer'',
+``unknown'', or ``ok''. The condition does not itself defer because that would
+be likely to cause problems for legitimate email.
+
+[revisionflag="changed"]
+The error messages produced by the CSA code include slightly more
+detail. If $csa_status$ is ``defer'', this may be because of problems
+looking up the CSA SRV record, or problems looking up the CSA target
+address record. There are four reasons for $csa_status$ being ``fail'':
+
+[revisionflag="changed"]
+- The client's host name is explicitly not authorized.
+
+[revisionflag="changed"]
+- The client's IP address does not match any of the CSA target IP addresses.
+
+[revisionflag="changed"]
+- The client's host name is authorized but it has no valid target IP addresses
+(for example, the target's addresses are IPv6 and the client is using IPv4).
+
+[revisionflag="changed"]
+- The client's host name has no CSA SRV record but a parent domain has asserted
+that all subdomains must be explicitly authorized.
+
+[revisionflag="changed"]
+The %csa% verification condition can take an argument which is the domain to
+use for the DNS query. The default is:
+
+ verify = csa/$sender_helo_name
+
+[revisionflag="changed"]
+This implementation includes an extension to CSA. If the query domain
+is an address literal such as [192.0.2.95], or if it is a bare IP
+address, Exim searches for CSA SRV records in the reverse DNS as if
+the HELO domain was (for example) '95.2.0.192.in-addr.arpa'. Therefore it is
+meaningful to say:
+
+ verify = csa/$sender_host_address
+
+[revisionflag="changed"]
+In fact, this is the check that Exim performs if the client does not say HELO.
+This extension can be turned off by setting the main configuration option
+%dns_csa_use_reverse% to be false.
+
+[revisionflag="changed"]
+If a CSA SRV record is not found for the domain itself, a search
+is performed through its parent domains for a record which might be
+making assertions about subdomains. The maximum depth of this search is limited
+using the main configuration option %dns_csa_search_limit%, which is 5 by
+default. Exim does not look for CSA SRV records in a top level domain, so the
+default settings handle HELO domains as long as seven
+('hostname.five.four.three.two.one.com'). This encompasses the vast majority of
+legitimate HELO domains.
+
+[revisionflag="changed"]
+The 'dnsdb' lookup also has support for CSA. Although 'dnsdb' also supports
+direct SRV lookups, this is not sufficient because of the extra parent domain
+search behaviour of CSA, and (as with PTR lookups) 'dnsdb' also turns IP
+addresses into lookups in the reverse DNS space. The result of a successful
+lookup such as:
+
+[revisionflag="changed"]
+....
+${lookup dnsdb {csa=$sender_helo_name}}
+....
+
+[revisionflag="changed"]
+has two space-separated fields: an authorization code and a target host name.
+The authorization code can be ``Y'' for yes, ``N'' for no, ``X'' for explicit
+authorization required but absent, or ``?'' for unknown.
+
+
+
+
+[[SECTverifyPRVS]]
+Bounce address tag validation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
+cindex:[BATV,verifying]
+Bounce address tag validation (BATV) is a scheme whereby the envelope senders
+of outgoing messages have a cryptographic, timestamped ``tag'' added to them.
+Genuine incoming bounce messages should therefore always be addressed to
+recipients that have a valid tag. This scheme is a way of detecting unwanted
+bounce messages caused by sender address forgeries (often called ``collateral
+spam''), because the recipients of such messages will not include valid tags.
+
+[revisionflag="changed"]
+There are two expansion items to help with the implementation of the BATV
+``prvs'' (private signature) scheme in an Exim configuration. This scheme signs
+the original envelope sender address by using a simple shared key to add a hash
+of the address and some time-based randomizing information. The %prvs%
+expansion item creates a signed address, and the %prvscheck% expansion item
+checks one. The syntax of these expansion items is described in section
+<<SECTexpansionitems>>.
+
+[revisionflag="changed"]
+As an example, suppose the secret per-address keys are stored in an MySQL
+database. A query to look up the key for an address could be defined as a macro
+like this:
+
+[revisionflag="changed"]
+....
+PRVSCHECK_SQL = ${lookup mysql{SELECT secret FROM batv_prvs \
+ WHERE sender='${quote_mysql:$prvscheck_address}'\
+ }{$value}}
+....
+
+[revisionflag="changed"]
+Suppose also that the senders who make use of BATV are defined by an address
+list called %batv_senders%. Then, in the ACL for RCPT commands, you could
+use this:
+
+[revisionflag="changed"]
+....
+# Bounces: drop unsigned addresses for BATV senders
+deny message = This address does not send an unsigned reverse path.
+ senders = :
+ recipients = +batv_senders
+
+# Bounces: In case of prvs-signed address, check signature.
+deny message = Invalid reverse path signature.
+ senders = :
+ condition = ${prvscheck {$local_part@$domain}\
+ {PRVSCHECK_SQL}{1}}
+ !condition = $prvscheck_result
+....
+
+[revisionflag="changed"]
+The first statement rejects recipients for bounce messages that are addressed
+to plain BATV sender addresses, because it is known that BATV senders do not
+send out messages with plain sender addresses. The second statement rejects
+recipients that are prvs-signed, but with invalid signatures (either because
+the key is wrong, or the signature has timed out).
+
+[revisionflag="changed"]
+A non-prvs-signed address is not rejected by the second statement, because the
+%prvscheck% expansion yields an empty string if its first argument is not a
+prvs-signed address, thus causing the %condition% condition to be false. If the
+first argument is a syntactically valid prvs-signed address, the yield is the
+third string (in this case ``1''), whether or not the cryptographic and timeout
+checks succeed. The $prvscheck_result$ variable contains the result of the
+checks (empty for failure, ``1'' for success).
+
+[revisionflag="changed"]
+Of course, when you accept a prvs-signed address, you have to ensure that the
+routers accept it and deliver it correctly. The easiest way to handle this is
+to use a ^redirect^ router to remove the signature with a configuration along
+these lines:
+
+[revisionflag="changed"]
+....
+batv_redirect:
+ driver = redirect
+ data = ${prvscheck {$local_part@$domain}{PRVSCHECK_SQL}}
+....
+
+[revisionflag="changed"]
+This works because, if the third argument of %prvscheck% is empty, the result
+of the expansion of a prvs-signed address is the decoded value of the original
+address. This router should probably be the first of your routers that handles
+local addresses.
+
+[revisionflag="changed"]
+To create BATV-signed addresses in the first place, a transport of this form
+can be used:
+
+[revisionflag="changed"]
+....
+external_smtp_batv:
+ driver = smtp
+ return_path = ${prvs {$return_path} \
+ {${lookup mysql{SELECT \
+ secret FROM batv_prvs WHERE \
+ sender='${quote_mysql:$sender_address}'} \
+ {$value}fail}}}
+....
+
+[revisionflag="changed"]
+If no key can be found for the existing return path, no signing takes place.
+
+
[[SECTrelaycontrol]]
delivers it directly to another host as a result of a remote address contained
within it. Redirecting a local address via an alias or forward file and then
passing the message on to another host is not relaying,
-
cindex:[``percent hack'']
but a redirection as a result of the ``percent hack'' is.
////////////////////////////////////////////////////////////////////////////
[[CHAPexiscan]]
-Content scanning
-----------------
-cindex:[content scanning]
-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
+Content scanning at ACL time
+----------------------------
+cindex:[content scanning,at ACL time]
+The extension of Exim to include content scanning at ACL time, 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.
+
+[revisionflag="changed"]
+It is also possible to scan the content of messages at other times. The
+'local_scan()' function (see chapter <<CHAPlocalscan>>) allows for content
+scanning after all the ACLs have run. A transport filter can be used to scan
+messages at delivery time (see the %transport_filter% option, described in
+chapter <<CHAPtransportgeneric>>).
+
+If you want to include the ACL-time content-scanning features when you compile
+Exim, you need to arrange for WITH_CONTENT_SCAN to be defined in your
_Local/Makefile_. When you do that, the Exim binary is built with:
-- An additional ACL (%acl_smtp_mime%) that is run for all MIME parts.
+[revisionflag="changed"]
+- Two additional ACLs (%acl_smtp_mime% and %acl_not_smtp_mime%) that are run for
+all MIME parts for SMTP and non-SMTP messages, respectively.
- Additional ACL conditions and modifiers: %decode%, %malware%, %mime_regex%,
%regex%, and %spam%. These can be used in the ACL that is run at the end of
%clamd%::
cindex:[virus scanners,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/[]*. Some older versions of clamd do not seem to unpack
+MIME containers, so it used to be recommended to unpack MIME attachments in the
+MIME ACL. This no longer believed to be necessary. One option is required:
+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:
av_scanner = clamd:/opt/clamd/socket
av_scanner = clamd:192.168.2.100 1234
cindex:[virus scanners,DrWeb]
The DrWeb daemon scanner (*http://www.sald.com/[]*) interface takes one
argument, either a full path to a UNIX socket, or an IP address and port
-separated by whitespace, as in these examples:
+separated by white space, as in these examples:
av_scanner = drweb:/var/run/drwebd.sock
av_scanner = drweb:192.168.2.20 31337
End of list
///
+[revisionflag="changed"]
When %av_scanner% is correctly set, you can use the %malware% condition in the
-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.
+DATA ACL. *Note*: you cannot use the %malware% condition in the MIME 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
spamd_address = /var/run/spamd_socket
-
You can have multiple %spamd% servers to improve scalability. These can reside
on other hardware reachable over the network. To specify multiple %spamd%
servers, put multiple address/port pairs in the %spamd_address% option,
192.168.2.12 783
....
-Up to 32 %spamd% servers are supported. The servers are
-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%
+Up to 32 %spamd% servers are supported. The servers are 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.
*Warning*: It is not possible to use the UNIX socket connection method with
multiple %spamd% servers.
+
+Calling SpamAssassin from an Exim ACL
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here is a simple example of the use of the %spam% condition in a DATA ACL:
deny message = This message was classified as SPAM
The right-hand side of the %spam% condition specifies the username that
SpamAssassin should scan for. If you do not want to scan for a particular user,
but rather use the SpamAssassin system-wide default profile, you can scan for
-an unknown user, or simply use ``nobody''. However, you must put something on the
-right-hand side.
+an unknown user, or simply use ``nobody''. However, you must put something on
+the right-hand side.
The username allows you to use per-domain or per-user antispam profiles. The
right-hand side is expanded before being used, so you can put lookups or
conditions there. When the right-hand side evaluates to ``0'' or ``false'', no
scanning is done and the condition fails immediately.
+[revisionflag="changed"]
+Scanning with SpamAssassin uses a lot of resources. If you scan every message,
+large ones may cause significant performance degredation. As most spam messages
+are quite small, it is recommended that you do not scan the big ones. For
+example:
+
+[revisionflag="changed"]
+....
+deny message = This message was classified as SPAM
+ condition = ${if < {$message_size}{10K}}
+ spam = nobody
+....
+
The %spam% condition returns true if the threshold specified in the user's
SpamAssassin profile has been matched or exceeded. If you want to use the
%spam% condition for its side effects (see the variables below), you can make
[[SECTscanmimepart]]
Scanning MIME parts
~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:[content scanning,MIME parts]
cindex:[MIME content scanning]
cindex:[%acl_smtp_mime%]
-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.
+The %acl_smtp_mime% global option specifies an ACL that is called once for each
+MIME part of an SMTP message, including multipart types, in the sequence of
+their position in the message. Similarly, the %acl_not_smtp_mime% option
+specifies an ACL that is used for the MIME parts of non-SMTP messages. These
+options may both refer to the same ACL if you want the same processing in both
+cases.
-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.
+[revisionflag="changed"]
+These ACLs are called (possibly many times) just before the %acl_smtp_data% ACL
+in the case of an SMTP message, or just before a non-SMTP message is accepted.
+However, a MIME ACL is called only if the message contains a 'MIME-Version:'
+header line. When a call to a MIME ACL does not yield ``accept'', ACL
+processing is aborted and the appropriate result code is sent to the client. In
+the case of an SMTP message, the %acl_smtp_data% ACL is not called when this
+happens.
+
+[revisionflag="changed"]
+You cannot use the %malware% or %spam% conditions in a MIME ACL; these can only
+be used in the DATA or non-SMTP ACLs. However, you can use the %regex%
+condition to match against the raw MIME part. You can also use the %mime_regex%
+condition to match against the decoded MIME part (see section
+<<SECTscanregex>>).
-At the start of the MIME ACL, a number of variables are set from the header
+At the start of a 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:
+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:
decode = [/<path>/]<filename>
successfully run. It contains the full path and file name of the file
containing the decoded data.
+cindex:[RFC 2047]
$mime_filename$::
This is perhaps the most important of the MIME variables. It contains a
proposed filename for an attachment, if one was found in either the
--
. The outermost MIME part of a message is always a cover letter.
-. If a multipart/alternative or multipart/related MIME part is a cover letter, so
-are all MIME subparts within that multipart.
+. If a multipart/alternative or multipart/related MIME part is a cover letter,
+so are all MIME subparts within that multipart.
. If any other multipart is a cover letter, the first subpart is a cover letter,
and the rest are attachments.
cindex:[content scanning,MIME checking]
cindex:[MIME content scanning]
The %demime% ACL condition provides MIME unpacking, sanity checking and file
-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 _Local/Makefile_ at build time to be
-able to use the %demime% condition.
+extension blocking. It is usable only in the DATA and non-SMTP ACLs. The
+%demime% condition 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 backward compatibility. You must 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
The %demime% condition set the following variables:
$demime_errorlevel$::
+cindex:[$demime_errorlevel$]
When an error is detected in a MIME container, this variable contains the
severity of the error, as an integer number. The higher the value, the more
-severe the error. If this variable is unset or zero, no error occurred.
+severe the error (the current maximum value is 3). If this variable is unset or
+zero, no error occurred.
$demime_reason$::
+cindex:[$demime_reason$]
When $demime_errorlevel$ is greater than zero, this variable contains a
human-readable text string describing the MIME error that occurred.
+cindex:[$found_extension$]
$found_extension$::
When the %demime% condition is true, this variable contains the file extension
it found.
The function must return an %int% value which is one of the following macros:
`LOCAL_SCAN_ACCEPT`::
+cindex:[$local_scan_data$]
The message is accepted. If you pass back a string of text, it is saved with
the message, and made available in the variable $local_scan_data$. No
newlines are permitted (if there are any, they are turned into spaces) and the
The port on which this message was received.
*uschar~\*message_id*::
-This variable contains the message id for the incoming message as a
-zero-terminated string.
+This variable contains Exim's message id for the incoming message (the value of
+$message_exim_id$) as a zero-terminated string.
*uschar~\*received_protocol*::
The name of the protocol by which the message was received.
*BOOL~header_testname(header_line~{star}hdr,~uschar~{star}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
+a string comparison, because white space 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:
lss_match_host(sender_host_name, sender_host_address, ...)
+
-An empty address field matches an empty item in the host list. If the
-host name is NULL, the name corresponding to $sender_host_address$ is
-automatically looked up if a host name is required to match an item in the
-list. The return values are as for 'lss_match_domain()', but in addition,
-'lss_match_host()' returns ERROR in the case when it had to look up a host
-name, but the lookup failed.
+cindex:[$sender_host_address$]
+An empty address field matches an empty item in the host list. If the host name
+is NULL, the name corresponding to $sender_host_address$ is automatically
+looked up if a host name is required to match an item in the list. The return
+values are as for 'lss_match_domain()', but in addition, 'lss_match_host()'
+returns ERROR in the case when it had to look up a host name, but the lookup
+failed.
*void~log_write(unsigned~int~selector,~int~which,~char~{star}format,~...)*::
This function writes to Exim's log files. The first argument should be zero (it
address.
+cindex:[RFC 2047]
*uschar~*rfc2047_decode(uschar~{star}string,~BOOL~lencheck,~uschar~{star}target,~int~zeroval,~int~{star}lenptr,~uschar~{star}{star}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
+these are the contents of header lines. First, each ``encoded word'' is decoded
from the Q or B encoding into a byte-string. Then, if provided with the name of
a charset encoding, and if the 'iconv()' function is available, an attempt is
made to translate the result to the named character set. If this fails, the
encoding, or NULL if no translation is wanted.
+
cindex:[binary zero,in RFC 2047 decoding]
+cindex:[RFC 2047,binary zero in]
If a binary zero is encountered in the decoded string, it is replaced by the
contents of the %zeroval% argument. For use with Exim headers, the value must
not be 0 because header lines are handled as zero-terminated strings.
of the %first_delivery% condition in an %if% command in the filter to prevent
it happening on retries.
+cindex:[$domain$]
+cindex:[$local_part$]
*Warning*: Because the system filter runs just once, variables that are
specific to individual recipient addresses, such as $local_part$ and
$domain$, are not set, and the ``personal'' condition is not meaningful. If you
Additional variable for system filters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+cindex:[$recipients$]
The expansion variable $recipients$, containing a list of all the recipients
of the message (separated by commas and white space), is available in system
filters. It is not available in users' filters for privacy reasons.
[[SECTperaddfil]]
Per-address filtering
~~~~~~~~~~~~~~~~~~~~~
+cindex:[$domain$]
+cindex:[$local_part$]
In contrast to the system filter, which is run just once per message for each
delivery attempt, it is also possible to set up a system-wide filtering
operation that runs once for each recipient address. In this case, variables
[[SECTsubmodnon]]
Submission mode for non-local messages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:[message,submission]
cindex:[submission mode]
-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
+Processing that happens automatically for locally-originated messages (unless
+%suppress_local_fixups% is set) can also be requested for messages that are
+received over TCP/IP. The term ``submission mode'' is used to describe this
+state. Submisssion mode is set by the modifier
control = submission
-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:
+in a MAIL, RCPT, or pre-data ACL for an incoming 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:
warn hosts = 127.0.0.1
control = submission
+cindex:[%sender_retain%]
There are some options that can be used when setting submission mode. A slash
is used to separate options. For example:
'Message-ID:' header lines if they are missing, but makes no attempt to check
sender authenticity in header lines.
-A submission mode setting may also specify a domain to be used when generating
-a 'From:' or 'Sender:' header. For example:
+When %sender_retain% is not set, a submission mode setting may specify a domain
+to be used when generating a 'From:' or 'Sender:' header line. For example:
control = submission/domain=some.domain
+[revisionflag="changed"]
The domain may be empty. How this value is used is described in sections
-<<SECTthefrohea>> and <<SECTthesenhea>>.
+<<SECTthefrohea>> and <<SECTthesenhea>>. There is also a %name% option that
+allows you to specify the user's full name for inclusion in a created
+'Sender:' or 'From:' header line. For example:
+
+[revisionflag="changed"]
+....
+accept authenticated = *
+ control = submission/domain=wonderland.example/\
+ name=${lookup {$authenticated_id} \
+ lsearch {/etc/exim/namelist}}
+....
+
+[revisionflag="changed"]
+Because the name may contain any characters, including slashes, the %name%
+option must be given last. The remainder of the string is used as the name. For
+the example above, if _/etc/exim/namelist_ contains:
+
+[revisionflag="changed"]
+....
+bigegg: Humpty Dumpty
+....
+
+[revisionflag="changed"]
+then when the sender has authenticated as 'bigegg', the generated 'Sender:'
+line would be:
+[revisionflag="changed"]
+....
+Sender: Humpty Dumpty <bigegg@wonderland.example>
+....
+[revisionflag="changed"]
+cindex:[return path,in submission mode]
+By default, submission mode forces the return path to the same address as is
+used to create the 'Sender:' header. However, if %sender_retain% is specified,
+the return path is also left unchanged.
+[revisionflag="changed"]
+*Note*: the changes caused by submission mode take effect after the predata
+ACL. This means that any sender checks performed before the fix-ups use the
+untrusted sender address specified by the user, not the trusted sender address
+specified by submission mode. Although this might be slightly unexpected, it
+does mean that you can configure ACL checks to spot that a user is trying to
+spoof another's address.
[[SECTlineendings]]
The Date: header line
~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:['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.
+If a locally-generated or submission-mode message has no 'Date:' header line,
+Exim adds one, using the current date and time, unless the
+%suppress_local_fixups% control has been specified.
The Delivery-date: header line
- The envelope sender address is not empty (that is, this is not a bounce
message). The added header line copies the envelope sender address.
-- The SMTP session is authenticated and $authenticated_id$ is not empty.
+- cindex:[$authenticated_id$]
+The SMTP session is authenticated and $authenticated_id$ is not empty.
-.. If no domain is specified by the submission control, the local part is
+.. cindex:[$qualify_domain$]
+If no domain is specified by the submission control, the local part is
$authenticated_id$ and the domain is $qualify_domain$.
.. If a non-empty domain is specified by the submission control, the local
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%.
+[revisionflag="changed"]
+If a locally-generated incoming message does not contain a 'From:' header line,
+and the %suppress_local_fixups% control is not set, 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
The Message-ID: header line
~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:['Message-ID:' header line]
cindex:[message,submission]
+cindex:[%message_id_header_text%]
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
+'Message-ID:' or 'Resent-Message-ID:' header line, and the
+%suppress_local_fixups% control is not set, Exim adds a suitable header line 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
-cindex:[%message_id_header_text%]
-%message_id_header_text% and/or %message_id_header_domain% options.
+header line by setting the %message_id_header_text% and/or
+%message_id_header_domain% options.
[[SECTthesenhea]]
The Sender: header line
~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:['Sender:' header line]
cindex:[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.
+actions by setting the %local_sender_retain% option true, the
+%local_from_check% option false, or by using the %suppress_local_fixups%
+control setting.
-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.
+[revisionflag="changed"]
+When a local message is received from an untrusted user and %local_from_check%
+is true (the default), and the %suppress_local_fixups% control has not been
+set, 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
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:
+cindex:[$authenticated_id$]
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:
-- If no domain is specified by the submission control, the local part is
+- cindex:[$qualify_domain$]
+If no domain is specified by the submission control, the local part is
$authenticated_id$ and the domain is $qualify_domain$.
-- 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.
+- 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.
- If an empty domain is specified by the submission control,
$authenticated_id$ is assumed to be the complete address.
added. Prefixes and suffixes for the local part in 'From:' can be permitted by
setting %local_from_prefix% and %local_from_suffix% appropriately.
+[revisionflag="changed"]
+cindex:[return path,created from 'Sender:']
+*Note*: whenever a 'Sender:' header line is created, the return path for the
+message (the envelope sender address) is changed to be the same address, except
+in the case of submission mode when %sender_retain% is specified.
+
[[SECTheadersaddrem]]
Adding and removing header lines in routers and transports
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:[header lines,adding; in router or transport]
cindex:[header lines,removing; in router or transport]
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.
+modifying headers in a system filter. Header lines can also be added in an ACL
+as a message is received (see section <<SECTaddheadwarn>>).
In contrast to what happens in a system filter, header modifications that are
specified on routers and transports apply only to the particular recipient
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.
+[revisionflag="changed"]
+*Note*: in particular, this means that any expansions in the configuration of
+the transport cannot refer to the modified header lines, because such
+expansions all occur before the message is actually transported.
+
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:
%unknown_username% option can be used to specify user names in cases when
there is no password file entry.
+cindex:[RFC 2047]
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.
+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.
max_rcpt = 1
+cindex:[$local_part$]
in the ^smtp^ transport. Otherwise a single copy of a message might be
addressed to several different recipients in the same domain, in which case
$local_part$ is not available (because it is not unique). Of course, if you
smtp_etrn_command = /etc/etrn_command $domain $sender_host_address
+cindex:[$domain$]
The string is split up into arguments which are independently expanded. The
expansion variable $domain$ is set to the argument of the ETRN command,
and no syntax checking is done on the contents of this argument. Exim does not
this is done for BSMTP, messages may contain multiple RCPT commands. See
chapter <<CHAPbatching>> for more details.
+cindex:[$host$]
When one or more addresses are routed to a BSMTP transport by a router that
sets up a host list, the name of the first host on the list is available to the
transport in the variable $host$. Here is an example of such a transport and
logs. If any text item in the file is empty, default text is used for that
item.
+cindex:[$bounce_recipient$]
+cindex:[$bounce_return_size_limit$]
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.
+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
+$bounce_return_size_limit$ contains the value of the %return_size_limit%
+option, rounded to a whole number.
The items must appear in the file in the following order:
------ 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.
+ ------ $bounce_return_size_limit or so are included here.
****
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:
- Subject: Warning: message $message_id delayed $warn_message_delay
+ Subject: Warning: message $message_exim_id delayed $warn_message_delay
****
This message was created automatically by mail delivery software.
}}has not been delivered to all of its recipients after
more than $warn_message_delay on the queue on $primary_hostname.
- The message identifier is: $message_id
+ The message identifier is: $message_exim_id
The subject of the message is: $h_subject
The date of the message is: $h_date
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.
-
++
+cindex:[$warn_message_delay$]
+cindex:[$warn_message_recipients$]
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'>
local_part_suffix_optional
allow_filter
+cindex:[$local_part_suffix$]
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:
the H field is omitted, and the U field contains the login name of the caller
of Exim.
+[revisionflag="changed"]
cindex:[authentication,logging]
cindex:[AUTH,logging]
For all messages, the P field specifies the protocol used to receive the
-message. This is set to ``esmtpa'' 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
+message. This is the value that is stored in $received_protocol$. In the case
+of incoming SMTP messages, the value indicates whether or not any SMTP
+extensions (ESMTP), encryption, or authentication were used. If the SMTP
+session was encrypted, there is an additional X field that records the cipher
+suite that was used.
+
+[revisionflag="changed"]
+The protocol is set to ``esmptsa'' or ``esmtpa'' for messages received from
+hosts that have authenticated themselves using the SMTP AUTH command. The first
+value is used when the SMTP connection was encrypted (``secure''). 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.
+
cindex:[size,of message]
-The size of the received message is given by the S field. When the message is
-delivered, headers may get removed or added, so that the size of delivered
-copies of the message may not correspond with this value (and indeed may be
-different to each other).
+The id field records the existing message id, if present. The size of the
+received message is given by the S field. When the message is delivered,
+headers may be removed or added, so that the size of delivered copies of the
+message may not correspond with this value (and indeed may be different to each
+other).
The %log_selector% option can be used to request the logging of additional
data when a message is received. See section <<SECTlogselector>> below.
If the shadow transport did not succeed, the error message is put in
parentheses afterwards.
+cindex:[asterisk,after IP address]
When more than one address is included in a single delivery (for example, two
-SMTP RCPT commands in one transaction) the second and subsequent
-addresses are flagged with `->` instead of `=>`. When two or more
-messages are delivered down a single SMTP connection, an asterisk follows the
-IP address in the log lines for the second and subsequent messages.
+SMTP RCPT commands in one transaction) the second and subsequent addresses are
+flagged with `->` instead of `=>`. When two or more messages are delivered down
+a single SMTP connection, an asterisk follows the IP address in the log lines
+for the second and subsequent messages.
The generation of a reply message by a filter file gets logged as a ``delivery''
to the addressee, preceded by ``>''.
data when a message is delivered. See section <<SECTlogselector>> below.
-
Discarded deliveries
~~~~~~~~~~~~~~~~~~~~
cindex:[discarded messages]
selection marked by asterisks:
&&&
+`\*acl_warn_skipped ` skipped %warn% statement in ACL
` address_rewrite ` address rewriting
` all_parents ` all parents in => lines
` arguments ` command line arguments
` tls_certificate_verified ` certificate verification status
`\*tls_cipher ` TLS cipher suite on <= and => lines
` tls_peerdn ` TLS peer DN on <= and => lines
+` unknown_in_list ` DNS lookup failed in list match
` all ` all of the above
&&&
More details on each of these items follows:
+[revisionflag="changed"]
+- cindex:[%warn% statement,log when skipping]
+%acl_warn_skipped%: When an ACL %warn% statement is skipped because one of its
+conditions cannot be evaluated, a log line to this effect is written if this
+log selector is set.
+
- cindex:[log,rewriting]
cindex:[rewriting,logging]
%address_rewrite%: This applies both to global rewrites and per-transport
-rewrites,
-but not to rewrites in filters run as an unprivileged user (because such users
-cannot access the log).
+rewrites, but not to rewrites in filters run as an unprivileged user (because
+such users cannot access the log).
- cindex:[log,full parentage]
%all_parents%: Normally only the original and final addresses are logged on
feature, added to make it easier to find out how certain MUAs call
_/usr/sbin/sendmail_. The logging does not happen if Exim has given up root
privilege because it was called with the %-C% or %-D% options. Arguments that
-are empty or that contain whitespace are quoted. Non-printing characters are
+are empty or that contain white space are quoted. Non-printing characters are
shown as escape sequences. This facility cannot log unrecognized arguments,
because the arguments are checked before the configuration file is read. The
only way to log such cases is to interpose a script such as _util/logargs.sh_
- cindex:[log,incoming remote port]
cindex:[port,logging remote]
cindex:[TCP/IP,logging incoming remote port]
+cindex:[$sender_fullhost$]
+cindex:[$sender_rcvhost$]
%incoming_port%: The remote port number from which a message was received is
added to log entries and 'Received:' header lines, following the IP address in
square brackets, and separated from it by a colon. This is implemented by
and a certificate is supplied by the remote host, the peer DN is added to the
log line, preceded by DN=.
+[revisionflag="changed"]
+- cindex:[log,DNS failure in list]
+%unknown_in_list%: This setting causes a log entry to be written when the
+result of a list match is failure because a DNS lookup failed.
Message log
,<<SECTmailboxmaint>>, 'exim_lock' , lock a mailbox file
~~~~~
+[revisionflag="changed"]
+Another utility that might be of use to sites with many MTAs is Tom Kistner's
+'exilog'. It provides log visualizations across multiple Exim servers. See
+(*http://duncanthrax.net/exilog/[]*) for details.
+
+
+
+
[[SECTfinoutwha]]
Finding out what Exim processes are doing (exiwhat)
[[SECTextspeinf]]
Extracting specific information from the log (exigrep)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[revisionflag="changed"]
cindex:['exigrep']
cindex:[log,extracts; grepping for]
The 'exigrep' utility is a Perl script that searches one or more main log
extracts all the log entries for the relevant message, not just those that
match the pattern. Thus, 'exigrep' can extract complete log entries for a
given message, or all mail for a given user, or for a given host, for example.
+The input files can be in Exim log format or syslog format.
If a matching log line is not associated with a specific message, it is always
-included in 'exigrep''s output.
-The usage is:
+included in 'exigrep''s output. The usage is:
exigrep [-l] [-t<n>] <pattern> [<log file>] ...
given on the command line, the standard input is read.
If the location of a 'zcat' command is known from the definition of
-ZCAT_COMMAND in _Local/Makefile_, 'exigrep' automatically passes any
-file whose name ends in COMPRESS_SUFFIX through 'zcat' as it searches
-it.
+ZCAT_COMMAND in _Local/Makefile_, 'exigrep' automatically passes any file whose
+name ends in COMPRESS_SUFFIX through 'zcat' as it searches it.
[[SECTexipick]]
Three utility programs are provided for maintaining the DBM files that Exim
uses to contain its delivery hint information. Each program requires two
arguments. The first specifies the name of Exim's spool directory, and the
-second is the name of the database it is to operate on. These are as
-follows:
+second is the name of the database it is to operate on. These are as follows:
- 'retry': the database of retry information
- 'callout': the callout cache
+[revisionflag="changed"]
+- 'ratelimit': the data for implementing the ratelimit ACL condition
+
- 'misc': other hints data
The 'misc' database is used for
exim_tidydb
~~~~~~~~~~~
+[revisionflag="changed"]
cindex:['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
-that are more than 30 days old. The cutoff date can be altered by means of the
-%-t% option, which must be followed by a time. For example, to remove all
-records older than a week from the retry database:
+The 'exim_tidydb' utility program is used to tidy up the contents of a hints
+database. If run with no options, it removes all records that are more than 30
+days old. The age is calculated from the date and time that the record was last
+updated. Note that, in the case of the retry database, it is 'not' the time
+since the first delivery failure. Information about a host that has been down
+for more than 30 days will remain in the database, provided that the record is
+updated sufficiently often.
+
+The cutoff date can be altered by means of the %-t% option, which must be
+followed by a time. For example, to remove all records older than a week from
+the retry database:
exim_tidydb -t 7d /var/spool/exim retry
[[CHAPeximon]]
The Exim monitor
----------------
-cindex:[monitor]
-cindex:[Exim monitor]
+cindex:[Exim monitor,description]
cindex:[X-windows]
cindex:['eximon']
cindex:[Local/eximon.conf]
Main action buttons
~~~~~~~~~~~~~~~~~~~
cindex:[size,of monitor window]
-cindex:[monitor window size]
+cindex:[Exim monitor,window size]
cindex:[window size]
Below the stripcharts there is an action button for quitting the monitor. Next
to this is another button marked ``Size''. They are placed here so that shrinking
need to be extremely careful if you do this; it is not recommended and you are
on your own if you do it. Here are some of the pitfalls:
-- You must use the 'exim_lock' utility to ensure that Exim does not try to
-deliver the message while you are fiddling with it. The lock is implemented
-by opening the -D file and taking out a write lock on it. If you update the
-file in place, the lock will be retained. If you write a new file and rename
-it, the lock will be lost at the instant of rename.
+[revisionflag="changed"]
+- You must ensure that Exim does not try to deliver the message while you are
+fiddling with it. The safest way is to take out a write lock on the -D file,
+which is what Exim itself does, using ^^fcntl()^^. If you update the file in
+place, the lock will be retained. If you write a new file and rename it, the
+lock will be lost at the instant of rename.
-- If you change the number of lines in the file, the value of
-$body_linecount$, which is stored in the -H file, will be incorrect.
+[revisionflag="changed"]
+- cindex:[$body_linecount$]
+If you change the number of lines in the file, the value of
+$body_linecount$, which is stored in the -H file, will be incorrect. At
+present, this value is not used by Exim, but there is no guarantee that this
+will always be the case.
- If the message is in MIME format, you must take care not to break it.