System command filter

This module executes an arbitrary system command during a specified stage of checks execution.

command executable_name arg0 arg1 ... {
    run_on body

    code 1 reject
    code 2 quarantine


The module arguments specify the command to run. If the first argument is not an absolute path, it is looked up in the Libexec Directory (/usr/lib/maddy on Linux) and in $PATH (in that ordering). Note that no additional handling of arguments is done, especially, the command is executed directly, not via the system shell.

There is a set of special strings that are replaced with the corresponding message-specific values:

If value is undefined (e.g. {source_ip} for a message accepted over a Unix socket) or unavailable (the command is executed too early), the placeholder is replaced with an empty string. Note that it can not remove the argument. E.g. -i {source_ip} will not become just -i, it will be -i ""

Undefined placeholders are not replaced.

Command stdout

The command stdout must be either empty or contain a valid RFC 5322 header. If it contains a byte stream that does not look a valid header, the message will be rejected with a temporary error.

The header from stdout will be prepended to the message header.

Configuration directives

run_on conn | sender | rcpt | body

Default: body

When to run the command. This directive also affects the information visible for the message.

code integer ignore
code integer quarantine
code integer reject smtp-code smtp-enhanced-code smtp-message

This directive specifies the mapping from the command exit code integer to the message pipeline action.

Two codes are defined implicitly, exit code 1 causes the message to be rejected with a permanent error, exit code 2 causes the message to be quarantined. Both actions can be overridden using the 'code' directive.