Provided by: opensmtpd_7.7.0p0-1_amd64 bug

NAME

       smtpd-tables — table API for the smtpd daemon

DESCRIPTION

       The  smtpd(8)  daemon  provides  a  Simple  Mail  Transfer  Protocol (SMTPD) implementation, which allows
       ordinary machines to become Mail eXchangers (MX).  Some features that are commonly used by  MX,  such  as
       querying  databases  for  user  credentials,  are  outside of the scope of SMTP and too complex to fit in
       smtpd(8).

       Because an MX may need to provide these features, smtpd(8) provides an API to implement table(5) backends
       with a simple text-based protocol.

DESIGN

       smtpd-tables are programs that run as unique standalone processes, they do  not  share  smtpd(8)  address
       space.   They are executed by smtpd(8) at startup and expected to run in an infinite loop, reading events
       and queries from standard input and writing responses to  standard  output.   They  are  not  allowed  to
       terminate.

       Because  smtpd-tables  are  standalone programs that communicate with smtpd(8), they may run as different
       users than smtpd(8) and may be written in any language.  smtpd-tables must not  use  blocking  I/O,  they
       must support answering asynchronously to smtpd(8).

PROTOCOL

       The protocol consist of human-readable lines exchanged between smtpd-tables and smtpd(8).

       The  protocol  begins with a handshake.  First, smtpd(8) provides smtpd-tables with general configuration
       information in the form of key-value lines, terminated by ‘config|ready’.  For example:

             config|smtpd-version|7.7.0
             config|protocol|0.1
             config|tablename|devs
             config|ready

       Then, smtpd-tables register the supported services, terminating with ‘register|ready’.  For example:

             register|alias
             register|credentials
             register|ready

       Finally, smtpd(8) can start querying the table.  For example:

             table|0.1|1713795082.354255|devs|lookup|alias|b72508d|op

       The “|” character is used to separate the fields and may only appear verbatim in the last  field  of  the
       payload,  in  which case it should be considered a regular character and not a separator.  No other field
       may contain a “|”.

       Each request has a common set of fields, followed by some other fields that are operation-specific.   The
       common  format  consists  of a protocol prefix ‘table’, the protocol version, the timestamp and the table
       name.  For example:

             table|0.1|1713795091.202157|devs

       The protocol is inherently asynchronous, so multiple request may be sent without waiting for the table to
       reply.  All the replies have a common prefix, followed by the operation-specific  response.   The  common
       format  consist  of  a  prefix with the operation name in followed by ‘-result’, and the unique ID of the
       request.  For example:

             lookup-result|b72508d

       The list of operations, operation-specific parameters and responses are as follows:

       update id
               Ask the table to reload its configuration.  The result is either ‘ok’ on success or ‘error’ and a
               message upon a failure to do so.

       check service id query
               Check whether query is present in the table.  The result is ‘found’ if found, ‘not-found’ if not,
               or ‘error’ and a message upon an error.

       lookup service id query
               Look up a value in the table for given the query.  The result is ‘found’ and the value if  found,
               ‘not-found’ if not found, or ‘error’ and a message upon an error.

       fetch service id
               Fetch  the  next  item  from the table, eventually wrapping around.  It is only supported for the
               source and relayhost services.  The result is ‘found’ and the value if found, ‘not-found’ if  the
               table is empty, or ‘error’ and a message upon an error.

       Each  service  has  a specific format for the result.  The exact syntax for the values and eventually the
       keys are described in table(5).  The services and their result format are as follows:

       alias        One or more aliases separated by a comma.
       auth         Only usable for check.  Lookup key is username and cleartext password separated by ‘:’.
       domain       A domain name.
       credentials  The user name, followed by  ‘:’  and  the  encrypted  password  as  per  smtpctl(8)  encrypt
                    subcommand.
       netaddr      IPv4 and IPv6 address or netmask.
       userinfo     The user id, followed by ‘:’ then the group id, then ‘:’ and finally the home directory.
       source       IPv4 and IPv6 address.
       mailaddr     An username, a domain or a full email address.
       addrname     Used to map IP addresses to hostnames.

EXAMPLES

       Assuming the table is called “devs”, here's an example of a failed update transaction:

             table|0.1|1713795097.394049|devs|update|478ff0d2
             update-result|478ff0d2|error|failed to connect to the database

       A check request for the netaddr service for the 192.168.0.7 IPv4 address which is not in the table:

             table|0.1|1713795103.314423|devs|check|netaddr|e5862859|192.168.0.7
             check-result|e5862859|not-found

       A successful lookup request for the userinfo service for the user ‘op’:

             table|0.1|1713795110.354921|devs|lookup|userinfo|f993c74|op
             lookup-result|f993c74|found|1000:1000:/home/op

       A series of fetch requests for the source service that wraps around:

             table|0.1|1713795116.227321|devs|fetch|source|189bd3ee
             lookup-result|189bd3ee|found|192.168.1.7
             table|0.1|1713795120.162438|devs|fetch|source|9e4c56d4
             lookup-result|9e4c56d4|found|10.0.0.8
             table|0.1|1713795122.930928|devs|fetch|source|f2c8b906
             lookup-result|f2c8b906|found|192.168.1.7

SEE ALSO

       smtpd(8)

HISTORY

       smtpd-tables first appeared in OpenBSD 7.6.

Debian                                            April 8, 2025                                  SMTPD-TABLES(7)