---
name: "filter_api"
section: "3"
platform: "linux"
package: "opensmtpd-extras"
version: "5.7.1-4+b2"
release: "Debian 10 (Buster)"
platforms: ["linux"]
url: "https://new.carta.tech/filter_api"
---

# filter\_api(3)

filter API for smtpd

## NAME

**filter\_api\_loop**, **filter\_api\_accept**, **filter\_api\_reject**, **filter\_api\_reject\_code**, **filter\_api\_writeln**, **filter\_api\_on\_connect**, **filter\_api\_on\_helo**, **filter\_api\_on\_mail**, **filter\_api\_on\_rcpt**, **filter\_api\_on\_data**, **filter\_api\_on\_dataline**, **filter\_api\_on\_eom**, **filter\_api\_on\_reset**, **filter\_api\_on\_disconnect**, **filter\_api\_on\_commit**, **filter\_api\_on\_rollback**, **filter\_api\_setugid**, **filter\_api\_set\_chroot**, **filter\_api\_no\_chroot**, **filter\_api\_set\_udata**, **filter\_api\_get\_udata**, **filter\_api\_sockaddr\_to\_text**, **filter\_api\_mailaddr\_to\_text** – filter API for smtpd

## SYNOPSIS

**#include \<smtpd-defines.h\>**

**#include \<smtpd-api.h\>**

*void*\

**filter\_api\_loop**(*void*);

*int*\

**filter\_api\_accept**(*uint64\_t id*);

*int*\

**filter\_api\_reject**(*uint64\_t id*, *enum filter\_status status*);

*int*\

**filter\_api\_reject\_code**(*uint64\_t id*, *enum filter\_status status*, *uint32\_t code*, *const char \*line*);

*void*\

**filter\_api\_writeln**(*uint64\_t id*, *const char \* line*);

*void*\

**filter\_api\_on\_connect**(*int(\*cb)(uint64\_t, struct filter\_connect \*)*);

*void*\

**filter\_api\_on\_helo**(*int(\*cb)(uint64\_t, const char \*)*);

*void*\

**filter\_api\_on\_mail**(*int(\*cb)(uint64\_t, struct mailaddr \*)*);

*void*\

**filter\_api\_on\_rcpt**(*int(\*cb)(uint64\_t, struct mailaddr \*)*);

*void*\

**filter\_api\_on\_data**(*int(\*cb)(uint64\_t)*);

*void*\

**filter\_api\_on\_dataline**(*void(\*cb)(uint64\_t, const char \*)*);

*void*\

**filter\_api\_on\_eom**(*int(\*cb)(uint64\_t, size\_t)*);

*void*\

**filter\_api\_on\_reset**(*void(\*cb)(uint64\_t)*);

*void*\

**filter\_api\_on\_disconnect**(*void(\*cb)(uint64\_t)*);

*void*\

**filter\_api\_on\_commit**(*void(\*cb)(uint64\_t)*);

*void*\

**filter\_api\_on\_rollback**(*void(\*cb)(uint64\_t)*);

*void*\

**filter\_api\_setugid**(*uid\_t uid*, *gid\_t gid*);

*void*\

**filter\_api\_set\_chroot**(*const char \*rootpath*);

*void*\

**filter\_api\_no\_chroot**(*void*);

*void*\

**filter\_api\_set\_udata**(*uint64\_t id*, *void \*data*);

*void* *\**\

**filter\_api\_get\_udata**(*uint64\_t id*);

*const* *char* *\**\

**filter\_api\_sockaddr\_to\_text**(*const struct sockaddr \*sa*);

*const* *char* *\**\

**filter\_api\_mailaddr\_to\_text**(*const struct mailaddr \*maddr*);

## DESCRIPTION

**filter\_api** is an interface intended to provide filter capabilities for the [smtpd(8)](/smtpd/8.md) daemon. **filter\_api** is used in standalone filter programs, which setup callback functions to hook into the SMTP dialog. For example, each SMTP command can be intercepted with callback functions.

The function **filter\_api\_loop**() is used to enter the filter loop, waiting for callback functions to be called.

The function **filter\_api\_accept**() can be called to accept the current message with the given *id* from within a callback function.

The functions **filter\_api\_reject**() and **filter\_api\_reject\_code**() can be called to reject the current message with the given *id* from within a callback function. Both expect the *status* to be specified which should be one of the following values.

- FILTER\_FAIL

  The filter failed and the message should not be accpeted.

- FILTER\_CLOSE

  The filter is done and the message should not be accepted.

Morover, with the function **filter\_api\_reject\_code**() a *code* and *line* can be specified, to reject the current message with a custom SMTP reply code and error message.

The function **filter\_api\_writeln**() is intended to write (received) SMTP DATA command lines (back) from within a callback function. This might be used by a filter to add or modifiy DATA lines.

## CALLBACK FUNCTIONS

The function **filter\_api\_on\_connect**() is called on new SMTP connections. The callback can be used to accept or reject messages based on the given connection information.

The function **filter\_api\_on\_helo**() is called on SMTP HELO command. The callback can be used to accept or reject messages based on the given HELO string.

The function **filter\_api\_on\_mail**() is called on SMTP MAIL FROM command. The callback can be used to accept or reject messages based on the given MAIL FROM address.

The function **filter\_api\_on\_rcpt**() is called on SMTP RCPT TO command. The callback can be used to accept or reject messages based on the given RCPT TO address.

The function **filter\_api\_on\_data**() is called on SMTP DATA command. The callback might be used to setup data structures for filtering the upcoming DATA lines.

The function **filter\_api\_on\_dataline**() is called on each SMTP DATA line. The callback can be used to accept or reject messaged based on the (header or body) content of the current message.

The function **filter\_api\_on\_eom**() is called on the end (of DATA command) of the current message. The callback might be used to cleanup data structures and finalize the decision of accepting or rejecting the message.

The function **filter\_api\_on\_reset**() is called on SMTP RSET command. The callback might be used to reset the current filter state.

The function **filter\_api\_on\_disconnect**() is called on closed SMTP connections. The callback might be used to cleanup earlier setup data structures.

The function **filter\_api\_on\_commit**() is called on commit of the current message.

The function **filter\_api\_on\_rollback**() is called on rollback of the SMTP session. The callback might be used to cleanup earlier setup data structures.

## HELPER FUNCTIONS

The function **filter\_api\_setugid**() can be called using *uid* and *gid* to set the running user and group of the filter.

The function **filter\_api\_set\_chroot**() can be called using *rootpath* to set the chroot path of the filter.

The function **filter\_api\_no\_chroot**() can be called to disable chroot for the filter.

The function **filter\_api\_set\_udata**() can be called for the current message with the given *id* to set a user data pointer *data* from within a callback function.

The function **filter\_api\_get\_udata**() can be called to get the user data pointer for the current message with the given *id* from within a callback function.

The function **filter\_api\_sockaddr\_to\_text**() can be called to convert a socket address *sa* to a string.

The function **filter\_api\_mailaddr\_to\_text**() can be called to convert a mail address *maddr* to a string.

## RETURN VALUES

The functions **filter\_api\_accept**(), **filter\_api\_reject**(), and **filter\_api\_reject\_code**(), return 1, intended to be used in a return statement of a callback function.

The function **filter\_api\_get\_udata**() returns a pointer to the user data set for the current message.

The functions **filter\_api\_sockaddr\_to\_text**() and **filter\_api\_mailaddr\_to\_text**() return a pointer to a static buffer containing the string representation. The buffer remains valid until the next call to the conversion functions. In case of error, the function **filter\_api\_sockaddr\_to\_text**() returns the static string “(unknown)” and the function **filter\_api\_mailaddr\_to\_text**() returns NULL.

## ERRORS

The function **filter\_api\_sockaddr\_to\_text**() may fail for any of the errors specified for the routine [getnameinfo(3)](/getnameinfo/3.md) and listed in [gai\_strerror(3)](/gai_strerror/3.md).

## EXAMPLES

filter-stub(8) which ships with OpenSMTPD-extras is intended to provide an example code template.

## SEE ALSO

[smtpd.conf(5)](/smtpd.conf/5.md), [smtpd(8)](/smtpd/8.md), filter-stub(8)
