Previous   Next   Contents       (Exim 4.40 Specification)

38. Access control lists

Access Control Lists (ACLs) are defined in a separate section of the run time configuration file, headed by “begin acl”. Each ACL definition starts with a name, terminated by a colon. Here is a complete ACL section which contains just one very small ACL:

  begin acl
  
  small_acl:
    accept   hosts = one.host.only

You can have as many lists as you like in the ACL section, and the order in which they appear does not matter. The lists are self-terminating.

The majority of ACLs are used to control Exim's behaviour when it receives certain SMTP commands. This applies both to incoming TCP/IP connections, and when a local process submits a message over a pipe (using the -bs option). The most common use is for controlling which recipients are accepted in incoming messages. In addition, you can also define an ACL that is used to check local non-SMTP messages. The default configuration file contains an example of a realistic ACL for checking RCPT commands. This is discussed in chapter 7.

38.1. Testing ACLs

The -bh command line option provides a way of testing your ACL configuration locally by running a fake SMTP session with which you interact. The host relay-test.mail-abuse.org provides a service for checking your relaying configuration (see section 38.27 for more details).

38.2. Specifying when ACLs are used

In order to cause an ACL to be used, you have to name it in one of the relevant options in the main part of the configuration. These options are:

  acl_not_smtp  ACL for non-SMTP messages
  acl_smtp_auth  ACL for AUTH
  acl_smtp_connect  ACL for start of SMTP connection
  acl_smtp_data  ACL after DATA
  acl_smtp_etrn  ACL for ETRN
  acl_smtp_expn  ACL for EXPN
  acl_smtp_helo  ACL for HELO or EHLO
  acl_smtp_mail  ACL for MAIL
  acl_smtp_mailauth  ACL for the AUTH parameter of MAIL
  acl_smtp_rcpt  ACL for RCPT
  acl_smtp_starttls  ACL for STARTTLS
  acl_smtp_vrfy  ACL for VRFY

For example, if you set

  acl_smtp_rcpt = small_acl

the little ACL defined above is used whenever Exim receives a RCPT command in an SMTP dialogue. The majority of policy tests on incoming messages can be done when RCPT commands arrive. A rejection of RCPT should cause the sending MTA to give up on the recipient address contained in the Exim 4.40 Specification Concepts

Concepts

 A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P  Q  R  S  T  U  V  W  X  Z  



$1, $2, etc. see numerical variables
$bheader_
$header_
$host  [2]
$host_address  [2]
$rheader_
$value  [2]  [3]
*@ with single-key lookup  [2]
+caseful  [2]
+defer_unknown
+exclude_unknown
+ignore_unknown
+include_unknown  [2]
-be option  [2]
-bF option
-bf option
-bh option  [2]
-bi option
-bp option
-bt option
-bv option  [2]
-C option
-D option
-f option
-f option:for address testing
-f option:for filter testing
-f option:overriding “From” line
-M option  [2]
-os option
-q option  [2]
-R option
-t option
.ifdef
.include in configuration file
.include_if_exists in configuration file
/dev/null
/etc/aliases
/etc/mail/mailer.conf
/etc/userdbshadow.dat
8-bit characters  [2]  [3]
8BITMIME
@ in a domain list  [2]
@ in a host list
@@ with single-key lookup
@[] in a domain list
@[] in a host list
@mx_any
@mx_primary
@mx_secondary

A
abandoning mail  [2]
accept router
ACL:certificate verification
ACL:conditions, list of
ACL:conditions, processing
ACL:customized test
ACL:data for message ACL
ACL:data for non-message ACL
ACL:default configuration
ACL:description
ACL:for non-SMTP messages
ACL:format of
ACL:indirect
ACL:introduction
ACL:modifiers, list of
ACL:modifiers, processing
ACL:nested
ACL:on SMTP connection 
ACL:options for specifying
ACL:relay control
ACL:return codes
ACL:rewriting addresses in
ACL:setting up for SMTP commands
ACL:specifying which to use
ACL:testing a DNS list  [2]
ACL:testing a local part
ACL:testing a recipient
ACL:testing a recipient domain
ACL:testing a sender
ACL:testing a sender domain
ACL:testing for authentication
ACL:testing for encryption
ACL:testing the client host
ACL:unset options
ACL:variables
ACL:verbs, definition of
ACL:verifying header syntax
ACL:verifying HELO/EHLO
ACL:verifying host reverse lookup
ACL:verifying recipient
ACL:verifying sender
ACL:verifying sender in the header
adding drivers
additional groups  [2]
address list:@@ lookup type
address list:case forcing
address list:empty item
address list:in a rewriting pattern
address list:in expansion condition
address list:local part starting with !
address list:lookup for complete address
address list:patterns
address list:regular expression in
address list:split local part and domain
address redirection:broken files
address redirection:disabling rewriting
address redirection:domain, preserving
address redirection:errors
address redirection:included external list
address redirection:local part without domain
address redirection:non-filter list items
address redirection:one-time expansion
address redirection:redirect router
address redirection:repeated for each delivery attempt
address redirection:to black hole
address redirection:to file
address redirection:to local mailbox
address redirection:to pipe
address redirection:while verifying  [2]
address:constructed
address:copying routing  [2]
address:duplicate, discarding  [2]
address:qualification  [2]
address:qualification, suppressing
address:sender
address:source-routed
address:testing  [2]
address:verification
address:without domain
address||rewriting see rewriting
admin user  [2]  [3]
admin user:definition of
alias file:backslash in
alias file:broken
alias file:building  [2]
alias file:exception to default
alias file:in a redirect router
alias file:one-time expansion
alias file:ownership
alias file:per-domain default
alias for host
alternate configuration file
angle brackets, excess
appendfile transport
appending to a file
asterisk:after IP address
asterisk:in address list
asterisk:in domain list
asterisk:in host list  [2]
asterisk:in lookup type
asterisk:in search type
Athena
AUTH:ACL for  [2]
AUTH:advertising
AUTH:advertising when encrypted
AUTH:argument
AUTH:configuration  [2]
AUTH:description of
AUTH:in plaintext authenticator
AUTH:logging
AUTH:on bounce message
AUTH:on MAIL command  [2]  [3]  [4]
AUTH:testing a server
AUTH:with PAM
authentication
authentication:ACL checking
authentication:advertising
authentication:bounce message
authentication:CRAM-MD5 mechanism
authentication:failure
authentication:generic options
authentication:id
authentication:id, specifying for local message
authentication:logging
authentication:LOGIN mechanism
authentication:Microsoft Secure Password
authentication:name, specifying for local message
authentication:NTLM
authentication:on an Exim client
authentication:on an Exim server
authentication:optional in client
authentication:PLAIN mechanism
authentication:required by client
authentication:sender
authentication:sender, authenticated
authentication:sender, specifying for local message
authentication:testing a server
authenticators:cram_md5
authenticators:plaintext
authenticators:spa
auto_thaw
autoreply transport
autoreply transport:for system filter

B
background delivery
backlog of connections
backslash in alias file
bang paths:not handled by Exim
bang paths:rewriting
banner for SMTP
base36
base62  [2]  [3]  [4]
base64 encoding:conversion from hex
base64 encoding:creating authentication test data
base64 encoding:functions for local_scan() use
base64 encoding:in encrypted password
base64 encoding:in header lines
base64 encoding:in plaintext authenticator
batch_id
batch_max
batched local delivery
batched SMTP input  [2]
batched SMTP output
batched SMTP output example
Bcc: header line  [2]
Berkeley DB library
Berkeley DB library:file format
BIN_DIRECTORY
binary zero:in authentication data
binary zero:in header line
binary zero:in lookup key  [2]  [3]  [4]  [5]
binary zero:in message body  [2]
binary zero:in plaintext authenticator  [2]
binary zero:in RFC 2047 decoding
bind IP address
black hole
black list (DNS)  [2]  [3]  [4]
body of message:binary zero count
body of message:definition of
body of message:expansion variable  [2]
body of message:line count
body of message:size
body of message:transporting
body of message:visible size
books about Exim
boolean configuration values
bounce message:copy to other address
bounce message:customizing  [2]
bounce message:definition of
bounce message:discarding
bounce message:failure to deliver
bounce message:generating
bounce message:including body
bounce message:including original
bounce message:recipient of
bounce message:redirection details, suppressing
bounce message:Reply-to: in
bounce message:sender authentication
bounce message:size limit
bounce message:when generated
broken alias or forward files
BSD, DBM library for
bug reports
build directory
build-time options, overriding
building alias file
building DBM files
building Exim
building Exim:architecture type
building Exim:multiple OS/architectures
building Exim:operating system type
building Exim:OS-specific C header files
building Exim:overriding default settings
building Exim:pre-building configuration
building Eximon:overriding default options

C
caching:callout
caching:callout, suppressing
caching:callout, timeouts
caching:lookup data
caching:named lists
callout:cache, suppressing
callout:caching
callout:caching timeouts
callout:defer, action on
callout:postmaster, checking
callout:sender for recipient check
callout:timeout, specifying
callout:verification
callout:“random” check
carriage return  [2]  [3]  [4]  [5]
case forcing in address lists
case forcing in strings  [2]
case of local parts  [2]  [3]  [4]
Cc: header line
cdb:acknowledgement
cdb:description of
cdb:including support for
certificate:for client, location of
certificate:for server, location of
certificate:references to discussion
certificate:revocation list
certificate:revocation list for client
certificate:revocation list for server
certificate:self-signed
certificate:verification of client  [2]  [3]  [4]  [5]
certificate:verification of server
change log
checking access
checking disk space  [2]
CIDR notation
CIDR notation 
cipher:logging  [2]
cipher:requiring specific  [2]
command line:addresses with -t
command line:options
common option syntax
configuration file:alternate  [2]
configuration file:common option syntax
configuration file:conditional skips
configuration file:default, “walk through”
configuration file:editing
configuration file:errors in
configuration file:format of
configuration file:general description
configuration file:including other files
configuration file:macros
configuration file:main section
configuration file:ownership
configuration file:retry section
configuration for building Exim
configuration options, extracting
CONFIGURE_FILE  [2]  [3]
connection backlog
constructed address
contributed material
control of incoming mail
copy of bounce message
copy of message (unseen option)
Courier
CR character see carriage return
CRAM-MD5 authentication mechanism
cram_md5 authenticator
creating directories
CRL see certificate revocation list
crypt()
crypt16()
current directory for local transport  [2]
customizing: Received: header
customizing:ACL condition
customizing:ACL failure message
customizing:batching condition
customizing:bounce message  [2]
customizing:failure message
customizing:input scan using C function
customizing:precondition
customizing:SMTP banner
customizing:warning message  [2]
customizing:“cannot route” message
cycling logs  [2]
Cygwin
Cyrus  [2]  [3]  [4]  [5]  [6]

D
daemon  [2]
daemon:listening IP addresses
daemon:pid file path
daemon:process id (pid)  [2]  [3]
daemon:starting
daemon:TCP_NODELAY on sockets
Darwin
DATA, ACL for  [2]
database lookups
Date: header line
DBM:building dbm files
DBM:libraries, configuration for building  [2]
DBM:libraries, discussion of
DBM:lookup type
debugging:-bh option
debugging:-d option
debugging:-N option
debugging:from embedded Perl
debugging:list of selectors
debugging:suppressing delivery
default:ACLs
default:configuration file “walk through”
default:in single-key lookups
default:retry rule
default:routers
default:transports
defer in system filter
deferred delivery, forcing
delay warning, specifying
delay_after_cutoff
delay_warning_condition
delayed delivery, logging
Delivery-date: header line  [2]  [3]
delivery:abandoning further attempts
delivery:by external agent
delivery:cancelling all
delivery:cancelling by address
delivery:deferral
delivery:delaying certain domains
delivery:discarded, logging
delivery:failure, logging
delivery:failure, long-term
delivery:fake, logging
delivery:first
delivery:forcing attempt
delivery:forcing deferral
delivery:forcing failure  [2]
delivery:forcing in queue run
delivery:from given sender
delivery:in detail
delivery:in the background
delivery:in the foreground
delivery:log line format
delivery:manually started, not forced
delivery:maximum number of
delivery:parallelism for remote
delivery:permanent failure
delivery:problems with
delivery:procmail
delivery:retry in remote transports
delivery:retry mechanism
delivery:sorting remote
Exim Filter Specification chapter 3 Previous   Contents       (Exim Filter Specification)


3. Exim filter files

This chapter contains a full description of the contents of Exim filter files.

3.1 Format of Exim filter files

Apart from leading white space, the first text in a filter file must be

  # Exim filter

This is what distinguishes it from a conventional .forward file or a Sieve filter file. If the file does not have this initial line (or the equivalent for a Sieve filter), it is treated as a conventional .forward file, both when delivering mail and when using the -bf testing mechanism. The white space in the line is optional, and any capitalization may be used. Further text on the same line is treated as a comment. For example, you could have

  #   Exim filter   <<== do not edit or remove this line!

The remainder of the file is a sequence of filtering commands, which consist of keywords and data values. For example, in the command

  deliver gulliver@lilliput.fict.example

the keyword is deliver and the data value is gulliver@lilliput.fict.example. White space or line breaks separate the components of a command, except in the case of conditions for the if command, where round brackets (parentheses) also act as separators. Complete commands are separated from each other by white space or line breaks; there are no special terminators. Thus, several commands may appear on one line, or one command may be spread over a number of lines.

If the character # follows a separator anywhere in a command, everything from # up to the next newline is ignored. This provides a way of including comments in a filter file.

3.2 Data values in filter commands

There are two ways in which a data value can be input:

In addition to the escape character processing that occurs when strings are enclosed in quotes, most data values are also subject to string expansion (as described in the next section), in which case the characters $ and \ are also significant. This means that if a single backslash is actually required in such a string, and the string is also quoted, \\\\ has to be entered.

The maximum permitted length of a data string, before expansion, is 1024 characters.

3.3 String expansion

Most data values are expanded before use. Expansion consists of replacing substrings beginning with $ with other text. The full expansion facilities available in Exim are extensive. If you want to know everything that Exim can do with strings, you should consult the chapter on string expansion in the Exim documentation.

In filter files, by far the most common use of string expansion is the substitution of the contents of a variable. For example, the substring

  $reply_address

is replaced by the address to which replies to the message should be sent. If such a variable name is followed by a letter or digit or underscore, it must be enclosed in curly brackets (braces), for example,

  ${reply_address}

If a $ character is actually required in an expanded string, it must be escaped with a backslash, and because backslash is also an escape character in quoted input strings, it must be doubled in that case. The following two examples illustrate two different ways of testing for a $ character in a message:

  if $message_body contains \$ then ...
  if $message_body contains "\\$" then ...

You can prevent part of a string from being expanded by enclosing it between two occurrences of \N. For example,

  if $message_body contains \N$$$$\N then ...

tests for a run of four dollar characters.

3.4 Some useful general variables

A complete list of the available variables is given in the Exim documentation. This shortened list contains the ones that are most likely to be useful in personal filter files:

$body_linecount: The number of lines in the body of the message.

$body_zerocount: The number of binary zero characters in the body of the message.

$home: In conventional configurations, this variable normally contains the user's home directory. The system administrator can, however, change this.

$local_part: The part of the email address that precedes the @ sign – normally the user's login name. If support for multiple personal mailboxes is enabled (see section 3.31 below) and a prefix or suffix for the local part was recognized, it is removed from the string in this variable.

$local_part_prefix: If support for multiple personal mailboxes is enabled (see section 3.31 below), and a local part prefix was recognized, this variable contains the prefix. Otherwise it contains an empty string.

$local_part_suffix: If support for multiple personal mailboxes is enabled (see section 3.31 below), and a local part suffix was recognized, this variable contains the suffix. Otherwise it contains an empty string.

$message_body: The initial portion of the body of the message. By default, up to 500 characters are read into this variable, but the system administrator can configure this to some other value. Newlines in the body are converted into single spaces.

$message_body_end: The final portion of the body of the message, formatted and limited in the same way as $message_body.

$message_body_size: The size of the body of the message, in bytes.

$message_headers: The header lines of the message, concatenated into a single string, with newline characters between them.

$message_id: The message's local identification string, which is unique for each message handled by a single host.

$message_size: The size of the entire message, in bytes.

$original_local_part: When an address that arrived with the message is being processed, this contains the same value as the variable $local_part. However, if an address generated by an alias, forward, or filter file is being processed, this variable contains the local part of the original address.

$reply_address: The contents of the Reply-to: header, if the message has one; otherwise the contents of the From: header. It is the address to which normal replies to the message should be sent.

$return_path: The return path – that is, the sender field that will be transmitted as part of the message's envelope if the message is sent to another host. This is the address to which delivery errors are sent. In many cases, this variable has the same value as $sender_address, but if, for example, an incoming message to a mailing list has been expanded, $return_path may have been changed to contain the address of the list maintainer.

$sender_address: The sender address that was received in the envelope of the message. This is not necessarily the same as the contents of the From: or Sender: header lines. For delivery error messages (“bounce messages”) there is no sender address, and this variable is empty.

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

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

$tod_zone: The local timezone offset, for example: +0100.

3.5 Header variables

There is a special set of expansion variables containing the header lines of the message being processed. These variables have names beginning with $header_ followed by the name of the header line, terminated by a colon. For example,

  $header_from:
  $header_subject:

The whole item, including the terminating colon, is replaced by the contents of the message header line. If there is more than one header line with the same name, their contents are concatenated. For header lines whose data consists of a list of addresses (for example, From: and To:), a comma and newline is inserted between each set of data. For all other header lines, just a newline is used.

Leading and trailing white space is removed from header line data, and if there are any MIME “words” that are encoded as defined by RFC 2047 (because they contain non-ASCII characters), they are decoded and translated, if possible, to a local character set. Translation is attempted only on operating systems that have the iconv() function. This makes the header line look the same as it would when displayed by an MUA. The default character set is ISO-8859-1, but this can be changed by means of the headers command (see below).

If you want to see the actual characters that make up a header line, you can specify $rheader_ instead of $header_. This inserts the “raw” header line, unmodified.

There is also an intermediate form, requested by $bheader_, which removes leading and trailing space and decodes MIME “words”, but does not do any character translation. If an attempt to decode what looks superficially like a MIME “word” fails, the raw string is returned. If decoding produces a binary zero character, it is replaced by a question mark.

The capitalization of the name following $header_ is not significant. Because any printing character except colon may appear in the name of a message's header (this is a requirement of RFC 2822, the document that describes the format of a mail message) curly brackets must not be used in this case, as they will be taken as part of the header name. Two shortcuts are allowed in naming header variables:

If the message does not contain a header of the given name, an empty string is substituted. Thus it is important to spell the names of headers correctly. Do not use $header_Reply_to when you really mean $header_Reply-to.

3.6 User variables

There are ten user variables with names $n0$n9 that can be incremented by the add command (see section 3.10). These can be used for “scoring” messages in various ways. If Exim is configured to run a “system filter” on every message, the values left in these variables are copied into the variables $sn0$sn9 at the end of the system filter, thus making them available to users' filter files. How these values are used is entirely up to the individual installation.

3.7 Current directory

The contents of your filter file should not make any assumptions about the current directory. It is best to use absolute paths for file names; you can normally make use of the $home variable to refer to your home directory. The save command automatically inserts $home at the start of non-absolute paths.

3.8 Significant deliveries

When in the course of delivery a message is processed by a filter file, what happens next, that is, after the filter file has been processed, depends on whether or not the filter sets up any significant deliveries. If at least one significant delivery is set up, the filter is considered to have handled the entire delivery arrangements for the current address, and no further processing of the address takes place. If, however, no significant deliveries are set up, Exim continues processing the current address as if there were no filter file, and typically sets up a delivery of a copy of the message into a local mailbox. In particular, this happens in the special case of a filter file containing only comments.

The delivery commands deliver, save, and pipe are by default significant. However, if such a command is preceded by the word unseen, its delivery is not considered to be significant. In contrast, other commands such as mail and vacation do not set up significant deliveries unless preceded by the word seen.

The following example commands set up significant deliveries:

  deliver jack@beanstalk.example
  pipe $home/bin/mymailscript
  seen mail subject "message discarded"
  seen finish

The following example commands do not set up significant deliveries:

  unseen deliver jack@beanstalk.example
  unseen pipe $home/bin/mymailscript
  mail subject "message discarded"
  finish

3.9 Filter commands

The filter commands that are described in subsequent sections are listed below, with the section in which they are described in brackets:

  add  increment a user variable (section 3.10)
  deliver  deliver to an email address (section 3.11)
  fail  force delivery failure (sysadmin use) (section 3.18)
  finish  end processing (section 3.16)
  freeze  freeze message (sysadmin use) (section 3.19)
  headers  set the header character set (section 3.20)
  if  test condition(s) (section 3.21)
  logfile  define log file (section 3.15)
  logwrite  write to log file (section 3.15)
  mail  send a reply message (section 3.14)
  pipe  pipe to a command (section 3.13)
  save  save to a file (section 3.12)
  testprint  print while testing (section 3.17)
  vacation  tailored form of mail (section 3.14)

The headers command has additional parameters that can be used only in a system filter. The fail and freeze commands are available only when Exim's filtering facilities are being used as a system filter, and are therefore usable only by the system administrator and not by ordinary users. They are mentioned only briefly in this document; for more information, see the main Exim specification.

3.10 The add command

   add <number> to <user variable>
  e.g. add 2 to n3

There are 10 user variables of this type, with names n0n9. Their values can be obtained by the normal expansion syntax (for example $n3) in other commands. At the start of filtering, these variables all contain zero. Both arguments of the add command are expanded before use, making it possible to add variables to each other. Subtraction can be obtained by adding negative numbers.

3.11 The deliver command

   deliver <mail address>
  e.g. deliver "Dr Livingstone <David@somewhere.africa.example>"

This command provides a forwarding operation. The delivery that it sets up is significant unless the command is preceded by unseen (see section 3.8). The message is sent on to the given address, exactly as happens if the address had appeared in a traditional .forward file. If you want to deliver the message to a number of different addresses, you can use more than one deliver command (each one may have only one address). However, duplicate addresses are discarded.

To deliver a copy of the message to your normal mailbox, your login name can be given as the address. Once an address has been processed by the filtering mechanism, an identical generated address will not be so processed again, so doing this does not cause a loop.

However, if you have a mail alias, you should not refer to it here. For example, if the mail address L.Gulliver is aliased to lg303 then all references in Gulliver's .forward file should be to lg303. A reference to the alias will not work for messages that are addressed to that alias, since, like .forward file processing, aliasing is performed only once on an address, in order to avoid looping.

Following the new address, an optional second address, preceded by errors_to may appear. This changes the address to which delivery errors on the forwarded message will be sent. Instead of going to the message's original sender, they go to this new address. For ordinary users, the only value that is permitted for this address is the user whose filter file is being processed. For example, the user lg303 whose mailbox is in the domain lilliput.example could have a filter file that contains

       deliver jon@elsewhere.example errors_to lg303@lilliput.example

Clearly, using this feature makes sense only in situations where not all messages are being forwarded. In particular, bounce messages must not be forwarded in this way, as this is likely to create a mail loop if something goes wrong.

3.12 The save command

   save <file name>
  e.g. save $home/mail/bookfolder

This command specifies that a copy of the message is to be appended to the given file (that is, the file is to be used as a mail folder). The delivery that save sets up is significant unless the command is preceded by unseen (see section 3.8). More than one save command may be obeyed; each one causes a copy of the message to be written to its argument file, provided they are different (duplicate save commands are ignored).

If the file name does not start with a / character, the contents of the $home variable are prepended, unless it is empty. In conventional configurations, this variable is normally set in a user filter to the user's home directory, but the system administrator may set it to some other path. In some configurations, $home may be unset, in which case a non-absolute path name may be generated. Such configurations convert this to an absolute path when the delivery takes place. In a system filter, $home is never set.

The user must of course have permission to write to the file, and the writing of the file takes place in a process that is running as the user, under the user's primary group. Any secondary groups to which the user may belong are not normally taken into account, though the system administrator can configure Exim to set them up. In addition, the ability to use this command at all is controlled by the system administrator – it may be forbidden on some systems.

An optional mode value may be given after the file name. The value for the mode is interpreted as an octal number, even if it does not begin with a zero. For example:

   save /some/folder 640

This makes it possible for users to override the system-wide mode setting for file deliveries, which is normally 600. If an existing file does not have the correct mode, it is changed.

An alternative form of delivery may be enabled on your system, in which each message is delivered into a new file in a given directory. If this is the case, this functionality can be requested by giving the directory name terminated by a slash after the save command, for example

   save separated/messages/

There are several different formats for such deliveries; check with your system administrator or local documentation to find out which (if any) are available on your system. If this functionality is not enabled, the use of a path name ending in a slash causes an error.

3.13 The pipe command

   pipe <command>
  e.g. pipe "$home/bin/countmail $sender_address"

This command specifies that the message is to be delivered to the specified command using a pipe. The delivery that it sets up is significant unless the command is preceded by unseen (see section 3.8). Remember, however, that no deliveries are done while the filter is being processed. All deliveries happen later on. Therefore, the result of running the pipe is not available to the filter.

When the deliveries are done, a separate process is run, and a copy of the message is passed on its standard input. The process runs as the user, under the user's primary group. Any secondary groups to which the user may belong are not normally taken into account, though the system administrator can configure Exim to set them up. More than one pipe command may appear; each one causes a copy of the message to be written to its argument pipe, provided they are different (duplicate pipe commands are ignored).

When the time comes to transport the message, the command supplied to pipe is split up by Exim into a command name and a number of arguments. These are delimited by white space except for arguments enclosed in double quotes, in which case backslash is interpreted as an escape, or in single quotes, in which case no escaping is recognized. Note that as the whole command is normally supplied in double quotes, a second level of quoting is required for internal double quotes. For example:

       pipe "$home/myscript \"size is $message_size\""

String expansion is performed on the separate components after the line has been split up, and the command is then run directly by Exim; it is not run under a shell. Therefore, substitution cannot change the number of arguments, nor can quotes, backslashes or other shell metacharacters in variables cause confusion.

Documentation for some programs that are normally run via this kind of pipe often suggest that the command should start with

  IFS=" "

This is a shell command, and should not be present in Exim filter files, since it does not normally run the command under a shell.

However, there is an option that the administrator can set to cause a shell to be used. In this case, the entire command is expanded as a single string and passed to the shell for interpretation. It is recommended that this be avoided if at all possible, since it can lead to problems when inserted variables contain shell metacharacters.

The default PATH set up for the command is determined by the system administrator, usually containing at least /usr/bin so that common commands are available without having to specify an absolute file name. However, it is possible for the system administrator to restrict the pipe facility so that the command name must not contain any / characters, and must be found in one of the directories in the configured PATH. It is also possible for the system administrator to lock out the use of the pipe command altogether.

When the command is run, a number of environment variables are set up. The complete list for pipe deliveries may be found in the Exim reference manual. Those that may be useful for pipe deliveries from user filter files are:

  DOMAIN  the domain of the address
  HOME  your home directory
  LOCAL_PART  see below
  LOCAL_PART_PREFIX  see below
  LOCAL_PART_SUFFIX  see below
  LOGNAME  your login name
  MESSAGE_ID  the message's unique id
  PATH  the command search path
  RECIPIENT  the complete recipient address
  SENDER  the sender of the message
  SHELL  /bin/sh
  USER  see below

LOCAL_PART, LOGNAME, and USER are all set to the same value, namely, your login id. LOCAL_PART_PREFIX and LOCAL_PART_SUFFIX may be set if Exim is configured to recognize prefixes or suffixes in the local parts of addresses. For example, a message addressed to pat-suf2@domain.example may cause user pat's filter file to be run. If this sets up a pipe delivery, LOCAL_PART_SUFFIX is -suf2 when the pipe command runs. The system administrator has to configure Exim specially for this feature to be available.

If you run a command that is a shell script, be very careful in your use of data from the incoming message in the commands in your script. RFC 2822 is very generous in the characters that are legally permitted to appear in mail addresses, and in particular, an address may begin with a vertical bar or a slash. For this reason you should always use quotes round any arguments that involve data from the message, like this:

  /some/command '$SENDER'

so that inserted shell meta-characters do not cause unwanted effects.

Remember that, as was explained earlier, the pipe command is not run at the time the filter file is interpreted. The filter just defines what deliveries are required for one particular addressee of a message. The deliveries themselves happen later, once Exim has decided everything that needs to be done for the message.

A consequence of this is that you cannot inspect the return code from the pipe command from within the filter. Nevertheless, the code returned by the command is important, because Exim uses it to decide whether the delivery has succeeded or failed.

The command should return a zero completion code if all has gone well. Most non-zero codes are treated by Exim as indicating a failure of the pipe. This is treated as a delivery failure, causing the message to be returned to its sender. However, there are some completion codes that are treated as temporary errors. The message remains on Exim's spool disk, and the delivery is tried again later, though it will ultimately time out if the delivery failures go on too long. The completion codes to which this applies can be specified by the system administrator; the default values are 73 and 75.

The pipe command should not normally write anything to its standard output or standard error file descriptors. If it does, whatever is written is normally returned to the sender of the message as a delivery error, though this action can be varied by the system administrator.

3.14 Mail commands

There are two commands that cause the creation of a new mail message, neither of which count as a significant delivery unless the command is preceded by the word seen (see section 3.8). This is a powerful facility, but it should be used with care, because of the danger of creating infinite sequences of messages. The system administrator can forbid the use of these commands altogether.

To help prevent runaway message sequences, these commands have no effect when the incoming message is a bounce (delivery error) message, and messages sent by this means are treated as if they were reporting delivery errors. Thus, they should never themselves cause a bounce message to be returned. The basic mail-sending command is

   mail [to <address-list>]
   [cc <address-list>]
   [bcc <address-list>]
   [from <address>]
   [reply_to <address>]
   [subject <text>]
   [extra_headers <text>]
   [text <text>]
   [[expand] file <filename>]
   [return message]
   [log <log file name>]
   [once <note file name>]
   [once_repeat <time interval>]

  e.g. mail text "Your message about $h_subject: has been received"

Each <address-list> can contain a number of addresses, separated by commas, in the format of a To: or Cc: header line. In fact, the text you supply here is copied exactly into the appropriate header line. It may contain additional information as well as email addresses. For example:

  mail to "Julius Caesar <jc@rome.example>, \
           <ma@rome.example> (Mark A.)"

Similarly, the texts supplied for from and reply_to are copied into their respective header lines.

As a convenience for use in one common case, there is also a command called vacation. It behaves in the same way as mail, except that the defaults for the subject, file, log, once, and once_repeat options are

  subject "On vacation"
  expand file .vacation.msg
  log .vacation.log
  once .vacation
  once_repeat 7d

respectively. These are the same file names and repeat period used by the traditional Unix vacation command. The defaults can be overridden by explicit settings, but if a file name is given its contents are expanded only if explicitly requested.

Warning: The vacation command should always be used conditionally, subject to at least the personal condition (see section 3.27 below) so as not to send automatic replies to non-personal messages from mailing lists or elsewhere. Sending an automatic response to a mailing list or a mailing list manager is an Internet Sin.

For both commands, the key/value argument pairs can appear in any order. At least one of text or file must appear (except with vacation, where there is a default for file); if both are present, the text string appears first in the message. If expand precedes file, each line of the file is subject to string expansion before it is included in the message.

Several lines of text can be supplied to text by including the escape sequence “\n” in the string wherever a newline is required. If the command is output during filter file testing, newlines in the text are shown as “\n”.

Note that the keyword for creating a Reply-To: header is reply_to, because Exim keywords may contain underscores, but not hyphens. If the from keyword is present and the given address does not match the user who owns the forward file, Exim normally adds a Sender: header to the message, though it can be configured not to do this.

The extra_headers keyword allows you to add custom header lines to the message. The text supplied must be one or more syntactically valid RFC 2882 header lines. You can use “\n” within quoted text to specify newlines between headers, and also to define continued header lines. For example:

  extra_headers "h1: first\nh2: second\n continued\nh3: third"

No newline should appear at the end of the final header line.

If no to argument appears, the message is sent to the address in the $reply_address variable (see section 3.3 above). An In-Reply-To: header is automatically included in the created message, giving a reference to the message identification of the incoming message.

If return message is specified, the incoming message that caused the filter file to be run is added to the end of the message, subject to a maximum size limitation.

If a log file is specified, a line is added to it for each message sent.

If a once file is specified, it is used to hold a database for remembering who has received a message, and no more than one message is ever sent to any particular address, unless once_repeat is set. This specifies a time interval after which another copy of the message is sent. The interval is specified as a sequence of numbers, each followed by the initial letter of one of “seconds”, “minutes”, “hours”, “days”, or “weeks”. For example,

  once_repeat 5d4h

causes a new message to be sent if 5 days and 4 hours have elapsed since the last one was sent. There must be no white space in a time interval.

Commonly, the file name specified for once is used as the base name for direct-access (DBM) file operations. There are a number of different DBM libraries in existence. Some operating systems provide one as a default, but even in this case a different one may have been used when building Exim. With some DBM libraries, specifying once results in two files being created, with the suffixes .dir and .pag being added to the given name. With some others a single file with the suffix .db is used, or the name is used unchanged.

Using a DBM file for implementing the once feature means that the file grows as large as necessary. This is not usually a problem, but some system administrators want to put a limit on it. The facility can be configured not to use a DBM file, but instead, to use a regular file with a maximum size. The data in such a file is searched sequentially, and if the file fills up, the oldest entry is deleted to make way for a new one. This means that some correspondents may receive a second copy of the message after an unpredictable interval. Consult your local information to see if your system is configured this way.

More than one mail or vacation command may be obeyed in a single filter run; they are all honoured, even when they are to the same recipient.

3.15 Logging commands

A log can be kept of actions taken by a filter file. This facility is normally available in conventional configurations, but there are some situations where it might not be. Also, the system administrator may choose to disable it. Check your local information if in doubt.

Logging takes place while the filter file is being interpreted. It does not queue up for later like the delivery commands. The reason for this is so that a log file need be opened only once for several write operations. There are two commands, neither of which constitutes a significant delivery. The first defines a file to which logging output is subsequently written:

   logfile <file name>
  e.g. logfile $home/filter.log

The file name must be fully qualified. You can use $home, as in this example, to refer to your home directory. The file name