# Exim Internet Mailer

<-previous next->

## Chapter 61 - Events

The events mechanism in Exim can be used to intercept processing at a number of points. It was originally invented to give 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:

    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}')}} \
    } {}}

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:

auth:fail | after | both | per driver per authentication attempt
dane:fail | after | transport | per connection
dns:fail | after | both | per lookup
msg:complete | after | main | per message
msg:defer | after | transport | per message per delivery try
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 host per delivery try; host errors
msg:fail:delivery | after | transport | 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
tls:fail:connect | after | main | per connection
smtp:connect | after | transport | per connection
smtp:ehlo | after | transport | per connection

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

The third column in the table above says what section of the configuration should define the event action.

An additional variable, $event_data, is filled with information varying with the event type:

auth:fail | smtp response
dane:fail | failure reason
dns:fail | failure reason, key and lookup-type
msg:defer | error string
msg:delivery | smtp confirmation message
msg:fail:internal | failure reason
msg:fail:delivery | smtp error message
msg:host:defer | error string
msg:rcpt:host:defer | error string
msg:rcpt:defer | error string
tls:cert | verification chain depth
tls:fail:connect | error string
smtp:connect | smtp banner
smtp:ehlo | smtp ehlo response

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 contexts that Exim operates in during the course of its processing:

- variables set in transport events will not be visible outside that transport call

- acl_m variables in a server context are lost on a new connection, and after smtp helo/ehlo/mail/starttls/rset commands

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:

auth:fail | log information to write
tcp:connect | do not connect
tls:cert | refuse verification
smtp:connect | close connection

All other message types ignore the result string, and no other use is made of it.

For a tcp:connect event, if the connection is being made to a proxy then the $host_address and $host_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.

For dns:fail events from dnsdb lookups, a “defer_never” option does not affect the reporting of DNS_AGAIN.

<-previous Table of Contents next->