42. pepsi-stage-relay-to-lmtp¶
Deliver locally over LMTP to an MDA (Dovecot) that runs Sieve.
42.1. Role¶
pepsi-stage-relay-to-lmtp is a local-delivery stage that hands each message
to a Mail Delivery Agent — typically Dovecot — over LMTP (RFC 2033). The
MDA files the message and, in doing so, runs the recipient’s Sieve (RFC 5228)
script, so server-side filtering is delegated to the MDA instead of being
implemented in Pepsi. It is an alternative to pepsi-stage-relay-to-maildir:
LMTP gains Sieve and a clean per-recipient delivery status, and needs no
setuid helper (the MDA performs the per-user delivery), at the cost of running a
local IMAP/LMTP server.
42.2. LMTP-native delivery, deliver-and-route¶
All envelope recipients are offered in one LMTP transaction; the MDA returns one
reply per recipient after end-of-DATA (RFC 2033 §4.2). The stage never builds a
delivery-status notification itself — it delivers, and otherwise routes each
recipient onward by reason, recording why under state.bounce for a downstream
pepsi-stage-bounce (or a relay) to act on:
2xx— delivered; aNOTIFY=SUCCESSnotification (andDELAYwarnings) is routed to the optionalNOTIFY_STAGE;a permanent reject is routed by its RFC 3463 enhanced status — a bad mailbox (
x.1.x,x.2.xother thanx.2.2, and a bare550with no enhanced status at all) toNEXT_STAGE, over-quota (x.2.2) toQUOTA_LIMIT_STAGE(elseNEXT_STAGE), a Sieve / policy reject (x.7.x) toSIEVE_REJECT_STAGE(elseNEXT_STAGE), anything else toNEXT_STAGE;4xx— transient: retry that recipient (exponential backoff) untilMAX_LIFETIME, then route by the same classification.
Delivered, routed and still-deferred recipients are reconciled in one fan-out:
the delivered recipients leave the row, each routed recipient becomes a sibling
pending row sliced to itself (so a relay target never re-delivers to the
others) at its target stage, and the row is reduced to the deferred recipients
for the next retry. A failure of the whole session (connect, STARTTLS,
authentication, data transfer) retries the whole message, or — when permanent or
past MAX_LIFETIME — routes every recipient to NEXT_STAGE.
Because the MDA is the authority on which addresses are local, the stage does no
locality check of its own — place it after alias expansion so only intended-local
recipients reach it. NEXT_STAGE is mandatory (set it to a
pepsi-stage-bounce to bounce, or to a relay stage to forward off-site); a
message reaching the stage without one is marked failed before the MDA is
contacted, so nothing is delivered.
42.3. Transport¶
The target is either a UNIX-domain socket (SOCKET, the common Dovecot layout:
no TLS, no credentials) or TCP (HOST/PORT, PORT default 24) with optional
TLS = off|starttls|tls and AUTH = none|plain|login|external.
Authentication is refused over cleartext, so any AUTH other than none
requires TLS. The shared LMTP client reuses the SMTP client’s transport, TLS and
SASL machinery (pepsi_common::smtp::deliver_lmtp).
42.4. Configuration¶
[stage-<name>]: PROGRAM = pepsi-stage-relay-to-lmtp, NEXT_STAGE
(mandatory), the optional reason targets QUOTA_LIMIT_STAGE /
SIEVE_REJECT_STAGE / NOTIFY_STAGE, the target (SOCKET, or
HOST/PORT with TLS, TLS_VERIFY, TLS_CA, TLS_CLIENT_CERT,
TLS_CLIENT_KEY, AUTH and its USERNAME/PASSWORD), SERVER_NAME
(the LHLO name; defaults to [pepsi-ingress] HOSTNAME), the timeouts
(CONNECT_TIMEOUT/COMMAND_TIMEOUT/DATA_TIMEOUT) and the retry policy
(RETRY_INITIAL/RETRY_MAX_INTERVAL/RETRY_FACTOR/MAX_LIFETIME/
DELAY_DSN_AFTER).
pepsi-setup requires NEXT_STAGE and checks that each of the three
reason targets names a real stage. This stage has no BOUNCE_STAGE: it
never builds a DSN itself.
42.5. State¶
Inputs:
state.dsn(per-recipientNOTIFY/ORCPT) and the retry bookkeeping it wrote on an earlier pass.Outputs:
state.bounceon each routed sibling row (recording why the MDA refused, or that the delivery succeeded for aSUCCESS/DELAYnotification), andattempts/last_error(plusdelay_sentonce a delay warning was routed) on the deferred row.state.dsn.rcptis sliced in lockstep with every row’s recipients.
42.6. See also¶
pepsi-stage-relay-to-maildir, pepsi-stage-aliases, pepsi-stage-bounce, pepsi-quota, Supported Features, pepsi-stage-relay-to-lmtp(1), pepsi.conf(5).