Fix memory management vs. acl-as-conditional
[users/jgh/exim.git] / doc / doc-txt / experimental-spec.txt
index 7fd2bd8ecf015d1383b2bb8362f4dfd76f24688c..b33612f43d319c7ffe2b760c7377e626a8c8bce7 100644 (file)
@@ -712,7 +712,7 @@ use standard conditions such as hosts, senders, etc, to decide that
 DMARC verification should *not* be performed for them and disable
 DMARC with a control setting:
 
 DMARC verification should *not* be performed for them and disable
 DMARC with a control setting:
 
-  control = dmarc_verify_disable
+  control = dmarc_disable_verify
 
 A DMARC record can also specify a "forensic address", which gives
 exim an email address to submit reports about failed alignment.
 
 A DMARC record can also specify a "forensic address", which gives
 exim an email address to submit reports about failed alignment.
@@ -755,11 +755,13 @@ mean, refer to the DMARC website above.  Valid strings are:
                 rejecting the email.
   o quarantine  The DMARC check failed and the library recommends
                 keeping it for further inspection.
                 rejecting the email.
   o quarantine  The DMARC check failed and the library recommends
                 keeping it for further inspection.
+  o none        The DMARC check passed and the library recommends
+                no specific action, neutral.
   o norecord    No policy section in the DMARC record for this
                 sender domain.
   o nofrom      Unable to determine the domain of the sender.
   o norecord    No policy section in the DMARC record for this
                 sender domain.
   o nofrom      Unable to determine the domain of the sender.
-  o none        There is no DMARC record for this sender domain.
-  o error       Library error or dns error.
+  o temperror   Library error or dns error.
+  o off         The DMARC check was disabled for this email.
 
 You can prefix each string with an exclamation mark to invert its
 meaning, for example "!accept" will match all results but
 
 You can prefix each string with an exclamation mark to invert its
 meaning, for example "!accept" will match all results but
@@ -818,7 +820,7 @@ b. Configure, somewhere before the DATA ACL, the control option to
 (RCPT ACL)
   warn    domains        = +local_domains
           hosts          = +local_hosts
 (RCPT ACL)
   warn    domains        = +local_domains
           hosts          = +local_hosts
-          control        = dmarc_verify_disable
+          control        = dmarc_disable_verify
 
   warn    !domains       = +screwed_up_dmarc_records
           control        = dmarc_enable_forensic
 
   warn    !domains       = +screwed_up_dmarc_records
           control        = dmarc_enable_forensic
@@ -844,6 +846,175 @@ b. Configure, somewhere before the DATA ACL, the control option to
 
 
 
 
 
 
+Transport post-delivery actions
+--------------------------------------------------------------
+
+An arbitrary per-transport string can be expanded on successful delivery,
+and (for SMTP transports) a second string on deferrals caused by a host error.
+This feature may be used, for example, to write exim internal log information
+(not available otherwise) into a database.
+
+In order to use the feature, you must set
+
+EXPERIMENTAL_TPDA=yes
+
+in your Local/Makefile
+
+and define the expandable strings in the runtime config file, to
+be executed at end of delivery.
+
+Additionally, there are 6 more variables, available at end of
+delivery:
+
+tpda_delivery_ip             IP of host, which has accepted delivery
+tpda_delivery_port           Port of remote host which has accepted delivery
+tpda_delivery_fqdn           FQDN of host, which has accepted delivery
+tpda_delivery_local_part     local part of address being delivered
+tpda_delivery_domain         domain part of address being delivered
+tpda_delivery_confirmation   SMTP confirmation message
+
+In case of a deferral caused by a host-error:
+tpda_defer_errno             Error number
+tpda_defer_errstr            Error string possibly containing more details
+
+The $router_name and $transport_name variables are also usable.
+
+
+To take action after successful deliveries, set the following option
+on any transport of interest.
+
+tpda_delivery_action
+
+An example might look like:
+
+tpda_delivery_action = \
+${lookup pgsql {SELECT * FROM record_Delivery( \
+    '${quote_pgsql:$sender_address_domain}',\
+    '${quote_pgsql:${lc:$sender_address_local_part}}', \
+    '${quote_pgsql:$tpda_delivery_domain}', \
+    '${quote_pgsql:${lc:$tpda_delivery_local_part}}', \
+    '${quote_pgsql:$tpda_delivery_ip}', \
+    '${quote_pgsql:${lc:$tpda_delivery_fqdn}}', \
+    '${quote_pgsql:$message_exim_id}')}}
+
+The string is expanded after the delivery completes and any
+side-effects will happen.  The result is then discarded.
+Note that for complex operations an ACL expansion can be used.
+
+
+In order to log host deferrals, add the following option to an SMTP
+transport:
+
+tpda_host_defer_action
+
+This is a private option of the SMTP transport. It is intended to
+log failures of remote hosts. It is executed only when exim has
+attempted to deliver a message to a remote host and failed due to
+an error which doesn't seem to be related to the individual
+message, sender, or recipient address.
+See section 47.2 of the exim documentation for more details on how
+this is determined.
+
+Example:
+
+tpda_host_defer_action = \
+${lookup mysql {insert into delivlog set \
+    msgid = '${quote_mysql:$message_exim_id}', \
+    senderlp = '${quote_mysql:${lc:$sender_address_local_part}}', \
+    senderdom = '${quote_mysql:$sender_address_domain}', \
+    delivlp = '${quote_mysql:${lc:$tpda_delivery_local_part}}', \
+    delivdom = '${quote_mysql:$tpda_delivery_domain}', \
+    delivip = '${quote_mysql:$tpda_delivery_ip}', \
+    delivport = '${quote_mysql:$tpda_delivery_port}', \
+    delivfqdn = '${quote_mysql:$tpda_delivery_fqdn}', \
+    deliverrno = '${quote_mysql:$tpda_defer_errno}', \
+    deliverrstr = '${quote_mysql:$tpda_defer_errstr}' \
+    }}
+
+
+Redis Lookup
+--------------------------------------------------------------
+
+Redis is open source advanced key-value data store. This document
+does not explain the fundamentals, you should read and understand how
+it works by visiting the website at http://www.redis.io/.
+
+Redis lookup support is added via the hiredis library.  Visit:
+
+  https://github.com/redis/hiredis
+
+to obtain a copy, or find it in your operating systems package repository.
+If building from source, this description assumes that headers will be in
+/usr/local/include, and that the libraries are in /usr/local/lib.
+
+1. In order to build exim with Redis lookup support add
+
+EXPERIMENTAL_REDIS=yes
+
+to your Local/Makefile. (Re-)build/install exim. exim -d should show
+Experimental_Redis in the line "Support for:".
+
+EXPERIMENTAL_REDIS=yes
+LDFLAGS += -lhiredis
+# CFLAGS += -I/usr/local/include
+# LDFLAGS += -L/usr/local/lib
+
+The first line sets the feature to include the correct code, and
+the second line says to link the hiredis libraries into the
+exim binary.  The commented out lines should be uncommented if you
+built hiredis from source and installed in the default location.
+Adjust the paths if you installed them elsewhere, but you do not
+need to uncomment them if an rpm (or you) installed them in the
+package controlled locations (/usr/include and /usr/lib).
+
+
+2. Use the following global settings to configure Redis lookup support:
+
+Required:
+redis_servers       This option provides a list of Redis servers
+                    and associated connection data, to be used in
+                    conjunction with redis lookups. The option is
+                    only available if Exim is configured with Redis
+                    support.
+
+For example:
+
+redis_servers = 127.0.0.1/10/ - using database 10 with no password
+redis_servers = 127.0.0.1//password - to make use of the default database of 0 with a password
+redis_servers = 127.0.0.1// - for default database of 0 with no password
+
+3. Once you have the Redis servers defined you can then make use of the
+experimental Redis lookup by specifying ${lookup redis{}} in a lookup query.
+
+4. Example usage:
+
+(Host List)
+hostlist relay_from_ips = <\n ${lookup redis{SMEMBERS relay_from_ips}}
+
+Where relay_from_ips is a Redis set which contains entries such as "192.168.0.0/24" "10.0.0.0/8" and so on.
+The result set is returned as
+192.168.0.0/24
+10.0.0.0/8
+..
+.
+
+(Domain list)
+domainlist virtual_domains = ${lookup redis {HGET $domain domain}}
+
+Where $domain is a hash which includes the key 'domain' and the value '$domain'.
+
+(Adding or updating an existing key)
+set acl_c_spammer = ${if eq{${lookup redis{SPAMMER_SET}}}{OK}}
+
+Where SPAMMER_SET is a macro and it is defined as
+
+"SET SPAMMER <some_value>"
+
+(Getting a value from Redis)
+
+set acl_c_spam_host = ${lookup redis{GET...}}
+
+
 
 --------------------------------------------------------------
 End of file
 
 --------------------------------------------------------------
 End of file