&(pgsql)&: The format of the query is an SQL statement that is passed to a
PostgreSQL database. See section &<<SECTsql>>&.
+.next
+.new
+.cindex "Redis lookup type"
+.cindex lookup Redis
+&(redis)&: The format of the query is an SQL statement that is passed to a
+Redis database. See section &<<SECTsql>>&.
+.wen
+
.next
.cindex "sqlite lookup type"
.cindex "lookup" "sqlite"
.cindex "lookup" "Oracle"
.cindex "InterBase lookup type"
.cindex "lookup" "InterBase"
-Exim can support lookups in InterBase, MySQL, Oracle, PostgreSQL, and SQLite
+.cindex "Redis lookup type"
+.cindex lookup Redis
+Exim can support lookups in InterBase, MySQL, Oracle, PostgreSQL, Redis,
+and SQLite
databases. Queries for these databases contain SQL statements, so an example
might be
.code
with a newline between the data for each row.
-.section "More about MySQL, PostgreSQL, Oracle, and InterBase" "SECID72"
+.section "More about MySQL, PostgreSQL, Oracle, InterBase, and Redis" "SECID72"
.cindex "MySQL" "lookup type"
.cindex "PostgreSQL lookup type"
.cindex "lookup" "MySQL"
.cindex "lookup" "Oracle"
.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%&
+.cindex "Redis lookup type"
+.cindex lookup Redis
+If any MySQL, PostgreSQL, Oracle, InterBase or Redis lookups are used, the
+&%mysql_servers%&, &%pgsql_servers%&, &%oracle_servers%&, &%ibase_servers%&,
+or &%redis_servers%&
option (as appropriate) must be set to a colon-separated list of server
information.
-(For MySQL and PostgreSQL only, the global option need not be set if all
+(For MySQL and PostgreSQL, the global option need not be set if all
queries contain their own server information &-- see section
-&<<SECTspeserque>>&.) Each item in the list is a slash-separated list of four
+&<<SECTspeserque>>&.)
+For all but Redis
+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:
found, but that is still a successful query. In other words, the list of
servers provides a backup facility, not a list of different places to look.
+.new
+For Redis the global option need not be specified if all queries contain their
+own server information &-- see section &<<SECTspeserque>>&.
+If specified, the option must be set to a colon-separated list of server
+information.
+Each item in the list is a slash-separated list of three items:
+host, database number, and password.
+.olist
+The host is required and may be either an IPv4 address and optional
+port number (separated by a colon, which needs doubling due to the
+higher-level list), or a Unix socket pathname enclosed in parentheses
+.next
+The database number is optional; if present that number is selected in the backend
+.next
+The password is optional; if present it is used to authenticate to the backend
+.endlist
+.wen
+
.new
The &%quote_mysql%&, &%quote_pgsql%&, and &%quote_oracle%& expansion operators
convert newline, tab, carriage return, and backspace to \n, \t, \r, and \b
respectively, and the characters single-quote, double-quote, and backslash
itself are escaped with backslashes.
+
+The &%quote_redis%& expansion operator
+escapes whitespace and backslash characters with a backslash.
.wen
.section "Specifying the server in the query" "SECTspeserque"
-For MySQL and PostgreSQL lookups (but not currently for Oracle and InterBase),
+For MySQL, PostgreSQL and Redis lookups (but not currently for Oracle and InterBase),
it is possible to specify a list of servers with an individual query. This is
done by starting the query with
.display
Only a single host name may be given, but if looking it up yields more than
one IP address, they are each tried in turn until a connection is made. For
both kinds of socket, Exim makes a connection, writes the request string
-(unless it is an empty string) and reads from the socket until an end-of-file
+unless it is an empty string; and no terminating NUL is ever sent)
+and reads from the socket until an end-of-file
is read. A timeout of 5 seconds is applied. Additional, optional arguments
extend what can be done. Firstly, you can vary the timeout. For example:
.code
identifiers, base-36 digits. The number is converted to decimal and output as a
string.
+.new
+.vitem &*${base64:*&<&'string'&>&*}*&
+.cindex "expansion" "base64 encoding"
+.cindex "base64 encoding" "in string expansion"
+.cindex "&%base64%& expansion item"
+.cindex certificate "base64 of DER"
+This operator converts a string into one that is base64 encoded.
+
+If the string is a single variable of type certificate,
+returns the base64 encoding of the DER form of the certificate.
+
+
+.vitem &*${base64d:*&<&'string'&>&*}*&
+.cindex "expansion" "base64 decoding"
+.cindex "base64 decoding" "in string expansion"
+.cindex "&%base64d%& expansion item"
+This operator converts a base64-encoded string into the un-coded form.
+.wen
+
.vitem &*${domain:*&<&'string'&>&*}*&
.cindex "domain" "extraction"
.vitem &*${md5:*&<&'string'&>&*}*&
.cindex "MD5 hash"
.cindex "expansion" "MD5 hash"
-.cindex "certificate fingerprint"
+.cindex certificate fingerprint
.cindex "&%md5%& expansion item"
The &%md5%& operator computes the MD5 hash value of the string, and returns it
as a 32-digit hexadecimal number, in which any letters are in lower case.
+If the string is a single variable of type certificate,
+returns the MD5 hash fingerprint of the certificate.
+
.vitem &*${nhash_*&<&'n'&>&*_*&<&'m'&>&*:*&<&'string'&>&*}*&
.cindex "expansion" "numeric hash"
.vitem &*${sha1:*&<&'string'&>&*}*&
.cindex "SHA-1 hash"
.cindex "expansion" "SHA-1 hashing"
-.cindex "certificate fingerprint"
+.cindex certificate fingerprint
.cindex "&%sha2%& expansion item"
The &%sha1%& operator computes the SHA-1 hash value of the string, and returns
it as a 40-digit hexadecimal number, in which any letters are in upper case.
+If the string is a single variable of type certificate,
+returns the SHA-1 hash fingerprint of the certificate.
+
.vitem &*${sha256:*&<&'certificate'&>&*}*&
.cindex "SHA-256 hash"
-.cindex "certificate fingerprint"
+.cindex certificate fingerprint
.cindex "expansion" "SHA-256 hashing"
.cindex "&%sha256%& expansion item"
The &%sha256%& operator computes the SHA-256 hash fingerprint of the
systems for files larger than 2GB.
.vitem &*${str2b64:*&<&'string'&>&*}*&
-.cindex "expansion" "base64 encoding"
-.cindex "base64 encoding" "in string expansion"
.cindex "&%str2b64%& expansion item"
-This operator converts a string into one that is base64 encoded.
+.new
+Now deprecated, a synonym for the &%base64%& expansion operator.
+.wen
.vitem "&$auth1$& &-- &$auth3$&"
.vindex "&$auth1$&, &$auth2$&, etc"
These variables are used in SMTP authenticators (see chapters
-&<<CHAPplaintext>>&&--&<<CHAPspa>>&). Elsewhere, they are empty.
+&<<CHAPplaintext>>&&--&<<CHAPtlsauth>>&). Elsewhere, they are empty.
.vitem &$authenticated_id$&
.cindex "authentication" "id"
.vitem &$tls_in_ourcert$&
.vindex "&$tls_in_ourcert$&"
+.cindex certificate veriables
This variable refers to the certificate presented to the peer of an
inbound connection when the message was received.
It is only useful as the argument of a
.vitem &$tls_in_peerdn$&
.vindex "&$tls_in_peerdn$&"
.vindex "&$tls_peerdn$&"
+.cindex certificate "extracting fields"
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
.section "Logging" "SECID99"
.table2
+.row &%event_action%& "custom logging"
.row &%hosts_connection_nolog%& "exemption from connect logging"
.row &%log_file_path%& "override compiled-in value"
.row &%log_selector%& "set/unset optional logging"
.row &%bounce_message_file%& "content of bounce"
.row &%bounce_message_text%& "content of bounce"
.row &%bounce_return_body%& "include body if returning message"
+.row &%bounce_return_linesize_limit%& "limit on returned message line length"
.row &%bounce_return_message%& "include original message in bounce"
.row &%bounce_return_size_limit%& "limit on returned message"
.row &%bounce_sender_authentication%& "send authenticated sender with bounce"
point at which the error was detected are returned.
.cindex "bounce message" "including original"
+.option bounce_return_linesize_limit main integer 998
+.cindex "size" "of bounce lines, limit"
+.cindex "bounce message" "line length limit"
+.cindex "limit" "bounce message line length"
+This option sets a limit in bytes on the line length of messages
+that are returned to senders due to delivery problems,
+when &%bounce_return_message%& is true.
+The default value corresponds to RFC limits.
+If the message being returned has lines longer than this value it is
+treated as if the &%bounce_return_size_limit%& (below) restriction was exceeded.
+
+The option also applies to bounces returned when an error is detected
+during reception of a messsage.
+In this case lines from the original are truncated.
+
+The option does not apply to messages generated by an &(autoreply)& transport.
+
+
.option bounce_return_message main boolean true
If this option is set false, none of the original message is included in
bounce messages generated by Exim. See also &%bounce_return_size_limit%& and
not used.
+.new
+.option event_action main string&!! unset
+.cindex events
+This option declares a string to be expanded for Exim's events mechanism.
+For details see &<<CHAPevents>>&.
+.wen
+
+
.option exim_group main string "compile-time configured"
.cindex "gid (group id)" "Exim's own"
.cindex "Exim group"
.option ldap_ca_cert_dir main string unset
.cindex "LDAP", "TLS CA certificate directory"
+.cindex certificate "directory for LDAP"
This option indicates which directory contains CA certificates for verifying
a TLS certificate presented by an LDAP server.
While Exim does not provide a default value, your SSL library may.
.option ldap_ca_cert_file main string unset
.cindex "LDAP", "TLS CA certificate file"
+.cindex certificate "file for LDAP"
This option indicates which file contains CA certificates for verifying
a TLS certificate presented by an LDAP server.
While Exim does not provide a default value, your SSL library may.
.option ldap_cert_file main string unset
.cindex "LDAP" "TLS client certificate file"
+.cindex certificate "file for LDAP"
This option indicates which file contains an TLS client certificate which
Exim should present to the LDAP server during TLS negotiation.
Should be used together with &%ldap_cert_key%&.
.option ldap_cert_key main string unset
.cindex "LDAP" "TLS client key file"
+.cindex certificate "key for LDAP"
This option indicates which file contains the secret/private key to use
to prove identity to the LDAP server during TLS negotiation.
Should be used together with &%ldap_cert_file%&, which contains the
transport driver.
-.option openssl_options main "string list" "+no_sslv2"
+.option openssl_options main "string list" "+no_sslv2 +single_dh_use"
.cindex "OpenSSL "compatibility options"
This option allows an administrator to adjust the SSL options applied
by OpenSSL to connections. It is given as a space-separated list of items,
resent to other recipients.
+.option event_action transports string&!! unset
+.cindex events
+This option declares a string to be expanded for Exim's events mechanism.
+For details see &<<CHAPevents>>&.
+.wen
+
+
.option group transports string&!! "Exim group"
.cindex "transport" "group; specifying"
This option specifies a gid for running the transport process, overriding any
of the message. Its value must not be zero. See also &%final_timeout%&.
+.option dkim_domain smtp string&!! unset
+.option dkim_selector smtp string&!! unset
+.option dkim_private_key smtp string&!! unset
+.option dkim_canon smtp string&!! unset
+.option dkim_strict smtp string&!! unset
+.option dkim_sign_headers smtp string&!! unset
+DKIM signing options. For details see &<<SECDKIMSIGN>>&.
+
+
.option delay_after_cutoff smtp boolean true
This option controls what happens when all remote IP addresses for a given
domain have been inaccessible for so long that they have passed their retry
} } } }
server_set_id = ${if = {1}{${listcount:$auth1}} {$auth1}{}}
.endd
+This accepts a client certificate that is verifiable against any
+of your configured trust-anchors
+which usually means the full set of public CAs)
+and which has a SAN with a good account name.
+Note that the client cert is on the wire in-clear, including the SAN,
+whereas a plaintext SMTP AUTH done inside TLS is not.
+
+. An alternative might use
+. .code
+. server_param1 = ${sha256:$tls_in_peercert}
+. .endd
+. to require one of a set of specific certs that define a given account
+. (the verification is still required, but mostly irrelevant).
+. This would help for per-device use.
+.
+. However, for the future we really need support for checking a
+. user cert in LDAP - which probably wants a base-64 DER.
+
.ecindex IIDtlsauth1
.ecindex IIDtlsauth2
session, and indeed is required to issue a new EHLO or HELO after successfully
setting up encryption following a STARTTLS command.
+.new
+Note also that a deny neither forces the client to go away nor means that
+mail will be refused on the connection. Consider checking for
+&$sender_helo_name$& being defined in a MAIL or RCPT ACL to do that.
+.wen
+
If the command is accepted by an &%accept%& verb that has a &%message%&
modifier, the message may not contain more than one line (it will be truncated
at the first newline and a panic logged if it does). Such a message cannot
When Exim receives a VRFY or EXPN command on a TCP/IP connection, it
runs the ACL specified by &%acl_smtp_vrfy%& or &%acl_smtp_expn%& (as
appropriate) in order to decide whether the command should be accepted or not.
-If no ACL is defined, the command is rejected.
+.new
.cindex "VRFY" "processing"
+When no ACL is defined for VRFY, or if it rejects without
+setting an explicit response code, the command is accepted
+(with a 252 SMTP response code)
+in order to support awkward clients that do a VRFY before every RCPT.
+.wen
When VRFY is accepted, it runs exactly the same code as when Exim is
-called with the &%-bv%& option.
+called with the &%-bv%& option, and returns 250/451/550
+SMTP response codes.
.cindex "EXPN" "processing"
+If no ACL for EXPN is defined, the command is rejected.
When EXPN is accepted, a single-level expansion of the address is done.
EXPN is treated as an &"address test"& (similar to the &%-bt%& option) rather
than a verification (the &%-bv%& option). If an unqualified local part is given
be tracked on a per-domain basis, rather than merely upon source IP address.
DKIM is documented in RFC 4871.
-Since version 4.70, DKIM support is compiled into Exim by default. It can be
-disabled by setting DISABLE_DKIM=yes in Local/Makefile.
+.new
+DKIM support is compiled into Exim by default if TLS support is present.
+.wen
+It can be disabled by setting DISABLE_DKIM=yes in &_Local/Makefile_&.
Exim's DKIM implementation allows to
.olist
senders).
-.section "Signing outgoing messages" "SECID513"
+.section "Signing outgoing messages" "SECDKIMSIGN"
.cindex "DKIM" "signing"
Signing is implemented by setting private options on the SMTP transport.
MANDATORY:
This sets the key selector string. You can use the &%$dkim_domain%& expansion
variable to look up a matching selector. The result is put in the expansion
-variable &%$dkim_selector%& which should be used in the &%dkim_private_key%&
+variable &%$dkim_selector%& which may be used in the &%dkim_private_key%&
option along with &%$dkim_domain%&.
.option dkim_private_key smtp string&!! unset
require appropriate care. Filenames created, eg. by
the appendfile transport, will have UTF-8 names.
-Helo names sent by the smtp transport will have any UTF-8
+HELO names sent by the smtp transport will have any UTF-8
components expanded to a-label form,
and any certificate name checks will be done using the a-label
form of the name.
. ////////////////////////////////////////////////////////////////////////////
. ////////////////////////////////////////////////////////////////////////////
+.chapter "Events" "CHAPevents" &&&
+ "Events"
+.cindex events
+
+.new
+The events mechanism in Exim can be used to intercept processing at a number
+of points. It was originally invented to giave a way to do customised logging
+actions (for example, to a database) but can also be used to modify some
+processing actions.
+
+Most installations will never need to use Events.
+The support can be left out of a build by defining DISABLE_EVENT=yes
+in &_Local/Makefile_&.
+
+There are two major classes of events: main and transport.
+The main configuration option &%event_action%& controls reception events;
+a transport option &%event_action%& controls delivery events.
+
+Both options are a string which is expanded when the event fires.
+An example might look like:
+.cindex logging custom
+.code
+event_action = ${if eq {msg:delivery}{$event_name} \
+{${lookup pgsql {SELECT * FROM record_Delivery( \
+ '${quote_pgsql:$sender_address_domain}',\
+ '${quote_pgsql:${lc:$sender_address_local_part}}', \
+ '${quote_pgsql:$domain}', \
+ '${quote_pgsql:${lc:$local_part}}', \
+ '${quote_pgsql:$host_address}', \
+ '${quote_pgsql:${lc:$host}}', \
+ '${quote_pgsql:$message_exim_id}')}} \
+} {}}
+.endd
+
+Events have names which correspond to the point in process at which they fire.
+The name is placed in the variable &$event_name$& and the event action
+expansion must check this, as it will be called for every possible event type.
+
+The current list of events is:
+.display
+&`msg:complete after main `& per message
+&`msg:delivery after transport `& per recipient
+&`msg:rcpt:host:defer after transport `& per recipient per host
+&`msg:rcpt:defer after transport `& per recipient
+&`msg:host:defer after transport `& per attempt
+&`msg:fail:delivery after main `& per recipient
+&`msg:fail:internal after main `& per recipient
+&`tcp:connect before transport `& per connection
+&`tcp:close after transport `& per connection
+&`tls:cert before both `& per certificate in verification chain
+&`smtp:connect after transport `& per connection
+.endd
+New event types may be added in future.
+
+The event name is a colon-separated list, defining the type of
+event in a tree of possibilities. It may be used as a list
+or just matched on as a whole. There will be no spaces in the name.
+
+The second column in the table above describes whether the event fires
+before or after the action is associates with. Those which fire before
+can be used to affect that action (more on this below).
+
+An additional variable, &$event_data$&, is filled with information varying
+with the event type:
+.display
+&`msg:delivery `& smtp confirmation mssage
+&`msg:rcpt:host:defer `& error string
+&`msg:rcpt:defer `& error string
+&`msg:host:defer `& error string
+&`tls:cert `& verification chain depth
+&`smtp:connect `& smtp banner
+.endd
+
+The :defer events populate one extra variable: &$event_defer_errno$&.
+
+For complex operations an ACL expansion can be used in &%event_action%&
+however due to the multiple contextx that Exim operates in during
+the course of its processing:
+.ilist
+variables set in transport events will not be visible outside that
+transport call
+.next
+acl_m variables in a server context are lost on a new connection,
+and after smtp helo/ehlo/mail/starttls/rset commands
+.endlist
+Using an ACL expansion with the logwrite modifier can be
+a useful way of writing to the main log.
+
+The expansion of the event_action option should normally
+return an empty string. Should it return anything else the
+following will be forced:
+.display
+&`msg:delivery `& (ignored)
+&`msg:host:defer `& (ignored)
+&`msg:fail:delivery`& (ignored)
+&`tcp:connect `& do not connect
+&`tcp:close `& (ignored)
+&`tls:cert `& refuse verification
+&`smtp:connect `& close connection
+.endd
+No other use is made of the result string.
+
+For a tcp:connect event, if the connection is being made to a proxy
+then the address and port variables will be that of the proxy and not
+the target system.
+
+For tls:cert events, if GnuTLS is in use this will trigger only per
+chain element received on the connection.
+For OpenSSL it will trigger for every chain element including those
+loaded locally.
+.wen
+
+. ////////////////////////////////////////////////////////////////////////////
+. ////////////////////////////////////////////////////////////////////////////
+
.chapter "Adding new drivers or lookup types" "CHID13" &&&
"Adding drivers or lookups"
.cindex "adding drivers"