Dovecot Lua Support

Since v2.3.0 dovecot supports Lua scripting. Dovecot supports Lua 5.1 and Lua 5.3.

Removed in version 2.3.15: Lua 5.2 support.

See also:

lib-lua

Dovecot provides a lib-lua internal helper as part of libdovecot.so. It has facilities for loading scripts from various sources, and also helps with reusing scripts by keeping track of which scripts are loaded. Each script has it’s own memory pool, which is guaranteed to be released when script is unloaded.

When script is loaded, script_init() function is called if found. This can return non-zero to indicate that the script has a problem.

When script is being unloaded, script_deinit() is called.

C API

void dlua_dovecot_register(struct dlua_script *script)

Register dovecot variable. This item can also be extended by context specific tables, like authentication database adds dovecot.auth.

void dlua_push_event(struct event *event)

Pushes an Dovecot Event to stack.

Lua API

Warning

Never use os.exit() from a Lua script. This will cause the whole process to exit instead of just the script.

dovecot.i_debug(text)

Log debug level message

Parameters:

text (str) – Message to log

dovecot.i_info(text)

Log info level message

Parameters:

text (str) – Message to log

dovecot.i_warning(text)

Log warning level message

Parameters:

text (str) – Message to log

dovecot.i_error(text)

Log error level message

Parameters:

text (str) – Message to log

dovecot.event()

Generate new event with lua script as parent.

New in version v2.3.4.

dovecot.event(parent)

Generate new event with given parent event.

New in version v2.3.4.

dovecot.restrict_global_variables(toggle)

Enable or disable restricting new global variables. If enabled, the rest of the script won’t be allowed to declare global non-function variables but they can declare local variables and use already defined global variables. If a script needs to define a variable, they must declare them as local i.e. instead of my_var = "some value", do local my_var = "some value". Restrictions will remain in place until the end of the execution of the script or until they are lifted by calling dovecot.restrict_global_variables(false).

Default is permissive mode i.e. same as lua’s default, global variables are not restricted.

Parameters:

toggle (boolean) – Enable or disable defining new global variables

New in version v2.3.17.

dovecot.http.client({timeout=milliseconds, max_attempts=number, debug=boolean})

Create a new http client object that can be used to submit requests to remote servers.

Parameters:
  • debug (bool) – Enable debug logging.

  • no_auto_redirect (bool) – Don’t automatically act upon redirect responses.

  • no_auto_retry (bool) – Never automatically retry requests.

  • connect_backoff_time_msecs (int) – Initial backoff time; doubled at each connection failure. (Default: 100 msec)

  • connect_backoff_max_time_msecs (int) – Maximum backoff time. (Default: 60 000 msec)

  • connect_timeout_msecs (int) – Max time to wait for connect() (and SSL handshake) to finish before retrying (Default: request_timeout_msecs)

  • event_parent (event) – Parent event to use.

  • max_attempts (int) – Maximum number of attempts for a request (Default: 1)

  • max_auto_retry_delay_secs (int) – Maximum acceptable delay in seconds for automatically retrying/redirecting requests. If a server sends a response with a Retry-After header that causes a delay longer than this, the request is not automatically retried and the response is returned.

  • max_connect_attempts (int) – Maximum number of connection attempts to a host before all associated requests fail. If > 1, the maximum will be enforced across all IPs for that host, meaning that IPs may be tried more than once eventually if the number of IPs is smaller than the specified maximum attempts. If the number of IPs is higher than the maximum attempts, not all IPs are tried. If <= 1, all IPs are tried at most once.

  • max_idle_time_msecs (int) – Maximum time a connection will idle before disconnecting. If parallel connections are idle, the duplicates will end earlier based on how many idle connections exist to that same service

  • max_redirects (int) – Maximum number of redirects for a request (Default: 0; redirects refused)

  • proxy_url (string) – Proxy URL to use, can include username and password.

  • request_absolute_timeout_msecs (int) – Max total time to wait for HTTP request to finish, including retries and everything else. (Default: 0; no timeout)

  • request_timeout_msecs (int) – Max time to wait for HTTP response before retrying (Default: 60 000 msec).

  • soft_connect_timeout_msecs (int) – Time to wait for connect() (and SSL handshake) to finish for the first connection before trying the next IP in parallel (Default: 0; wait until current connection attempt finishes)

  • rawlog_dir (string) – Directory for writing raw log data for debugging purposes. Must be writable by the process creating this log.

  • user_agent (string) – User-Agent: header. (Default: none)

Returns:

An http_client object.

New in version 2.3.19.

object http_client

New in version 2.3.19.

http_client.request({url=string, method=string})

Create a new request object. By default, the request has Host, and Date headers with relevant values, as well as Connection: Keep-Alive.

Parameters:
  • url (string) – Full url address. Parameters will be parsed from the string. TLS encryption is implied with use of https.

  • method (string) – HTTP method to use.

Returns:

An http_request object.

object http_request

New in version 2.3.19.

http_request.add_header(name, value)

Add a header to the request.

Parameters:
  • name (string) – Name of the HTTP header.

  • value (string) – Value of the header.

http_request.remove_header(name)

Do a lookup of the header in the request and remove it if found.

Parameters:

name (string) – Name of the HTTP header.

http_request.set_payload(value)

Set payload data to the request.

Parameters:

value (string) – Payload of the request as string data.

http_request.submit()

Connect to the remote server and submit the request. This function blocks until the HTTP response is fully received.

Returns:

An http_response object.

object http_response

New in version 2.3.19.

http_response.status()

Get the status code of the HTTP response. The codes contain error codes as well as HTTP codes e.g. 200 HTTP_OK and error code that denote connection to remote server failed. A human-readable string of the error can then be read using reason() function.

Returns:

Status code of the http response.

http_response.reason()

Returns a human-readable string of HTTP status codes e.g. “OK”, “Bad Request”, “Service Unavailable”, as well as connection errors e.g. “connect(…) failed: Connection refused”

Returns:

String representation of the status.

http_response.header(name)

Get value of a header in the HTTP request. If header is not found from the response, an empty string is returned.

Returns:

Value of the HTTP response header.

http_response.payload()

Get the payload of the HTTP response.

Returns:

Payload of the HTTP response as string.

Example HTTP client code

local json = require "json"
local http_client = dovecot.http.client {
    timeout = 10000;
    max_attempts = 3;
    debug = true;
}

function auth_password_verify(request, password)
  local auth_request = http_client:request {
    url = "https://endpoint/";
    method = "POST";
  }
  local req = {user=request.user, password=password}
  auth_request:set_payload(json.encode(req))
  local auth_response = auth_request:submit()
  local resp_status = auth_response:status()

  if resp_status == 200
  then
    return dovecot.auth.PASSDB_RESULT_OK, ""
  else
    return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, ""
  end
end

object event

Note

object event_passthrough has same API, except the passthrough_event method is not present.

Functions:

event.append_log_prefix(prefix)

set prefix to append into log messages

Parameters:

prefix (str) – Prefix to append

event.replace_log_prefix(prefix)

replace append prefix for messages

Parameters:

prefix (str) – Prefix to append

event.set_name(name)

set name for event

Parameters:

name (str) – Event name

event.add_str(key, value)

Add a key-value pair to event

Parameters:
  • key (str) – Key name

  • value (str) – A value

event.add_int(key, value)

Add a key-value pair to event

Parameters:
  • key (str) – Key name

  • value (int) – Integer value

event.add_timeval(key, seconds)

add a key-value pair to event

Parameters:
  • key (str) – Key name

  • value (int) – Unix timestamp

event.inc_int(key, diff)

increment key-value pair

Parameters:
  • key (str) – Key name

  • diff (int) – Difference to add, can be negative

event.log_debug(message)

Emit debug message

Parameters:

message (str) – Message to log

event.log_info(message)

Emit info message

Parameters:

message (str) – Message to log

event.log_warning(message)

Emit warning message

Parameters:

message (str) – Message to log

event.log_error("message")

Emit error message

Parameters:

message (str) – Message to log

event.passthrough_event()

Returns an passthrough event. A log message must be logged or else a panic will occur.

object dict

Functions:

dict.lookup(key[, username])

Lookup key from dict. If key is found, returns a table with values. If key is not found, returns nil.

Parameters:
  • key (str) – Key to lookup

  • username (str) – Username for private dict keys

dict.iterate(path, flags[, username])

Returns an iteration step function and dict iter userdata. For example:

for key, values in dict:iterate(key_prefix, 0) do
  dovecot.i_debug('key='..key..', first value='..values[1])
end
Parameters:
  • path (str) – Path prefix to iterate

  • flags (int) – Iteration flags. Currently raw numbers must be used for these. See enum dict_iterate_flags in the C code.

  • username (str) – Username for private dict paths

dict.transaction_begin([username])

Returns a new transaction object.

Parameters:

username (str) – Username for private dict keys

object dict.transaction

Functions:

dict.transaction.set(key, value)

Set key=value in the dict transaction.

Parameters:
  • key (str) – Key to set

  • value (str) – Value to set

dict.transaction.unset(key, value)

Unset key in the dict transaction.

Parameters:

key (str) – Key to unset

New in version v2.3.17.

dict.transaction.set_timestamp({tv_sec=seconds, tv_nsec=nanoseconds})

Set timestamp to the dict transaction. This is currently used only with Cassandra.

Parameters:
  • seconds (int) – UNIX timestamp

  • nanoseconds (int) – Nanoseconds part of the timestamp

New in version v2.3.17.

dict.transaction.commit()

Commit the transaction.

dict.transaction.rollback()

Rollback the transaction.

mail-lua

New in version v2.3.4.

mail-lua is a plugin that can be loaded to provide API for mail storage Lua plugins. Mail-lua provides a common script to be used in mail storage instead of per-plugin scripts.

See: mail-lua plugin.

C API

void dlua_register_mail_storage(struct dlua_script *script)

Register storage Lua interface to script context

Parameters:
  • scriptdlua_script to add mail storage

bool mail_lua_plugin_get_script(struct mail_user *user, struct dlua_script **script_r)

Returns script context if available. If FALSE is returned, no Lua script has been loaded, and you should optionally deal this yourself.

Parameters:
  • usermail_user

  • scriptdlua_script

void dlua_push_mail_user(struct dlua_script *script, struct mail_user *user)

Pushes a mail user on top of stack.

Parameters:
  • scriptdlua_script

  • usermail_user

void dlua_push_mailbox(struct dlua_script *script, struct mailbox *box)

Pushes a mailbox on top of stack.

Parameters:
  • scriptdlua_script

  • boxmailbox

void dlua_push_mail(struct dlua_script *script, struct mail *mail)

Pushes a mail on top of stack.

Parameters:
  • scriptdlua_script

  • boxmail

Lua API

When mail user is created, a script is loaded if present as mail_lua_script() and mail_user_created() is called if present in script.

On deinitialization, mail_user_deinit_pre() is called first, if present, followed by mail_user_deinit().

dovecot.storage

Following constants are specified:

enum STATUS_MESSAGES
enum STATUS_RECENT
enum STATUS_UIDNEXT
enum STATUS_UIDVALIDITY
enum STATUS_UNSEEN
enum STATUS_FIRST_UNSEEN_SEQ
enum STATUS_KEYWORDS
enum STATUS_HIGHESTMODSEQ
enum STATUS_PERMANENT_FLAGS
enum STATUS_FIRST_RECENT_UID
enum STATUS_HIGHESTPVTMODSEQ
enum MAILBOX_FLAG_READONLY
enum MAILBOX_FLAG_SAVEONLY
enum MAILBOX_FLAG_DROP_RECENT
enum MAILBOX_FLAG_NO_INDEX_FILES
enum MAILBOX_FLAG_KEEP_LOCKED
enum MAILBOX_FLAG_IGNORE_ACLS
enum MAILBOX_FLAG_AUTO_CREATE
enum MAILBOX_FLAG_AUTO_SUBSCRIBE
enum MAILBOX_SYNC_FLAG_FULL_READ
enum MAILBOX_SYNC_FLAG_FULL_WRITE
enum MAILBOX_SYNC_FLAG_FAST
enum MAILBOX_SYNC_FLAG_NO_EXPUNGES
enum MAILBOX_SYNC_FLAG_FIX_INCONSISTENT
enum MAILBOX_SYNC_FLAG_EXPUNGE
enum MAILBOX_SYNC_FLAG_FORCE_RESYNC
enum MAILBOX_ATTRIBUTE_PREFIX_DOVECOT

String constant vendor/vendor.dovecot/

New in version 2.3.7.

enum MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT

String constant vendor/vendor.dovecot/pvt/

New in version 2.3.7.

enum MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER

String constant vendor/vendor.dovecot/pvt/server/

New in version 2.3.7.

object mail_user

Meta

  • has tostring

  • is comparable (by username)

Functions

mail_user.plugin_getenv(key)

Returns key from user plugin settings or userdb environment

Parameters:

key (str) – Setting name

mail_user.var_expand(template)

Expands mail user variables (see Config Variables)

Parameters:

template (str) – Variable template string

mail_user.mailbox(name, flags)

Allocates a mailbox, flags optional

Parameters:
mail_user.metadata_get(key)

Returns given metadata key for the user.

Parameters:

key (str) – Metadata key, must begin with /private/ or /shared/

New in version 2.3.7.

mail_user.metadata_set(key, value)

Sets user metadata key to value. Setting value to nil unsets value.

Parameters:
  • key (str) – Metadata key, must begin with /private/ or /shared/

  • value (str) – Value to set, nil unsets value

New in version 2.3.7.

mail_user.metadata_unset(key)

Unsets value, same as calling metadata_set() with nil.

Parameters:

key (str) – Metadata key, must begin with /private/ or /shared/

New in version 2.3.7.

mail_user.metadata_list(prefix, prefix, prefix...)

Lists all keys for the user metadata under prefix.

Parameters:

prefix (str) – Metadata prefix, must begin with /private/ or /shared/

New in version 2.3.7.

Variables

mail_user.home

home directory (if available)

mail_user.username

user’s name

mail_user.uid

system uid

mail_user.gid

system gid

mail_user.service

IMAP/POP3/LMTP/LDA/…

mail_user.session_id

Current session ID

mail_user.session_create_time

When session was created

mail_user.nonexistent

If user does not really exist

mail_user.anonymous

If user is anonymous

mail_user.autocreated

If user was automatically created internally for some operation

mail_user.mail_debug

If debugging is turned on

mail_user.dsyncing

If user is being dsync’d

mail_user.session_restored

If this is a restored session

object mailbox

Meta

  • has tostring

  • is comparable (by full mailbox name)

Functions

mailbox.open()

Opens the mailbox

mailbox.close()

Closes the mailbox

mailbox.free()

Releases mailbox (must be done)

mailbox.sync(flags)

Synchronizes the mailbox (should usually be done, flags optional)

Parameters:

flags (int) – See dovecot.storage

mailbox.status(item, item, item...)

Returns requested mailbox status items as table

Parameters:

item (str) – Item name

mailbox.metadata_get(key)

Returns given metadata key for the mailbox.

Parameters:

key (str) – Metadata key, must begin with /private/ or /shared/

New in version 2.3.7.

mailbox.metadata_set(key, value)

Sets mailbox metadata key to value. Setting value to nil unsets value.

Parameters:
  • key (str) – Metadata key, must begin with /private/ or /shared/

  • value (str) – Value to set, nil unsets value

New in version 2.3.7.

mailbox.metadata_unset(key)

Unsets value, same as calling metadata_set() with nil.

Parameters:

key (str) – Metadata key, must begin with /private/ or /shared/

New in version 2.3.7.

mailbox.metadata_list(prefix, prefix, prefix...)

Lists all keys for the mailbox metadata under prefix.

Parameters:

prefix (str) – Metadata prefix, must begin with /private/ or /shared/

New in version 2.3.7.

Variables

mailbox.vname

Full mailbox name

mailbox.name

Mailbox name

table mailbox status

Variables

mailbox_status.mailbox

full name of mailbox

mailbox_status.messages

number of messages

mailbox_status.recent

number of Recent messages

mailbox_status.unseen

number of Unseen messages

mailbox_status.uidvalidity

current UID validity

mailbox_status.uidnext

next UID

mailbox_status.first_unseen_seq

first seqno of unseen mail

mailbox_status.first_recent_uid

first UID of unseen mail

mailbox_status.highest_modseq

highest modification sequence

mailbox_status.highest_pvt_modseq

highest private modification sequence

mailbox_status.permanent_flags

supported permanent flags as a bitmask

mailbox_status.flags

supported flags as a bitmask

mailbox_status.permanent_keywords

if permanent keywords are supported

mailbox_status.allow_new_keywords

if new keywords can be added

mailbox_status.nonpermanent_modseqs

whether non-permanent keywords are allowed

mailbox_status.no_modseq_tracking

no modification sequence tracking

mailbox_status.have_guids

whether GUIDs exist

mailbox_status.have_save_guids

whether GUIDs can be saved

mailbox_status.have_only_guid128

whether GUIDs are 128 bit always

mailbox_status.keywords

table of current keywords

object mail

Meta

  • has tostring

  • is comparable (within same mailbox, by UID)

Functions

None yet

Variables

mailbox_status.mailbox

mailbox object

mailbox_status.seq

Sequence number (can change)

mailbox_status.uid

UID number (immutable)