IMAP configuration
Yarilo implements IMAP4rev2 (RFC 9051) with backward compatibility to IMAP4rev1 (RFC 3501).
Listeners: services. (implicit TLS, port 993) and services. (STARTTLS, port 143). See Services configuration for listener-level settings (port, ssl_mode, haproxy_protocol, etc.).
protocol.imap
Protocol-level behaviour, shared across both IMAP listeners.
imap_idle_notify_interval
- Default
120- Type
- integer, seconds
- Helm
protocol.imap.imap_idle_notify_interval
Interval between unsolicited EXISTS/RECENT responses during IDLE (RFC 2177 keepalive). 0 disables them.
imap_max_line_length
- Default
65536- Type
- integer, bytes
- Helm
protocol.imap.imap_max_line_length
Maximum IMAP command line length. 0 is unlimited.
imap_id_send
- Default
name *- Type
- string
- Helm
protocol.imap.imap_id_send
Space-separated key-value pairs sent in the ID response (RFC 2971). * means the server's own value. An empty string turns the ID extension off after login.
imap_id_retain
- Default
false- Type
- boolean
- Helm
protocol.imap.imap_id_retain- Added
- 2.4.5
Keep what a client sends in ID before login and pass it to the auth service, where the policy server sees it as device_. The login's own x- keys are left out; at most 30 pairs and 256 bytes are kept.
login_greeting
- Default
- none
- Type
- string
- Helm
protocol.imap.login_greeting
Replaces IMAP server ready in the backend's greeting. Clients behind a login proxy see yarilo-imap-login's own greeting, Yarilo Login ready, which this key does not change. Empty keeps the default.
imap_logout_format
- Default
- none
- Type
- string
- Helm
protocol.imap.imap_logout_format
Format of the line logged at session end; the variables are listed below. Empty logs no stats line.
imap_quota
- Default
true- Type
- boolean
- Helm
protocol.imap.imap_quota
Advertise and serve the QUOTA extension (RFC 9208). Independent of quota enforcement.
imap_special_use_defaults
- Default
Archive: \Archive, Drafts: \Drafts, Junk: \Junk, Sent: \Sent, Trash: \Trash- Type
- map
- Helm
protocol.imap.imap_special_use_defaults
Folder name (case-sensitive) to its RFC 6154 attribute, e.g. Sent: "\\Sent". A user's own CREATE (USE …) wins.
imap_client_workarounds
- Default
[]- Type
- list
- Values
tb-extra-mailbox-septb-lsub-flags- Also accepted as
client_workarounds- Helm
protocol.imap.client_workarounds
Compatibility shims for clients that break the protocol.
imap_logout_format variables
| Variable | Description |
|---|---|
%{deleted} | Number of messages marked \Deleted in the session. |
%{expunged} | Number of messages expunged (removed from disk). |
%{fetch_ | Number of header fetch operations. |
%{fetch_ | Bytes transferred for header fetches. |
%{fetch_ | Number of body fetch operations. |
%{fetch_ | Bytes transferred for body fetches. |
Example:
protocol:
imap:
imap_logout_format: "in=%{fetch_hdr_bytes}+%{fetch_body_bytes} expunged=%{expunged}"Recent messages
A message is \Recent to the first session that selects its folder after the message arrives (RFC 3501). That session sees it in * n RECENT, in FLAGS and in SEARCH RECENT, NEW and OLD. Every later session sees it as old.
SELECTtakes the folder's recent messages. Mail that arrives while the folder is selected is recent to that session.EXAMINEandSTATUS (RECENT)report the recent messages and leave them for the nextSELECT.- A virtual mailbox has recent messages of its own and is taken the same way. A folder its configuration names with
+gives up its recent messages to thatSELECT; see Virtual Mailboxes. - A client cannot set
\Recent:STOREandAPPENDwith it are answeredBAD.
IMAP4rev2 removed \Recent. After ENABLE IMAP4rev2 the session gets no RECENT response and no \Recent flag. Its SELECT still takes the recent messages, so a later IMAP4rev1 session sees them as old.
Each folder's index records which messages are no longer recent. An index written before this record existed reports every message as recent once, to the first SELECT.
Supported IMAP extensions
Feature coverage is the exhaustive list of what the server advertises. This table explains the ones that need it.
IMAP4rev2 also brings ENABLE, SASL-IR, LITERAL+, SEARCHRES and STATUS=SIZE; LIST-EXTENDED, LIST-STATUS, CREATE-SPECIAL-USE and SORT (RFC 5256, without SORT=DISPLAY) are advertised too.
| Extension | RFC | Notes |
|---|---|---|
| IDLE | RFC 2177 | Server-push new-mail notifications. |
| MOVE | RFC 6851 | Atomic move (no COPY + STORE + EXPUNGE round-trip). |
| CONDSTORE | RFC 7162 | MODSEQ flag, conditional STORE. |
| QRESYNC | RFC 7162 | Fast mailbox resync after reconnect. |
| UIDPLUS | RFC 4315 | APPENDUID / COPYUID response codes. |
| UNSELECT | RFC 3691 | Close mailbox without expunge. |
| NAMESPACE | RFC 2342 | Shared / Other Users namespaces. |
| QUOTA | RFC 9208 | Per-user storage quota. Advertised while imap_ is on (the default). |
| ACL | RFC 4314 | Per-mailbox access control lists. Advertised only with acl.. A body FETCH sets \Seen only for a reader holding s; with r alone the body is served and the flag left as it is. SELECT answers [READ-ONLY] when the reader holds none of i, e, w, t, s. |
| BINARY | RFC 3516 | Binary content transfer. |
| THREAD | RFC 5256 | Threading of the searched messages, both algorithms: THREAD=REFERENCES (ancestry from References / In-Reply-To, then joining by base subject) and THREAD=ORDEREDSUBJECT (base subject alone). Computed per command from message headers. |
| ESEARCH | RFC 4731 | Extended SEARCH with MIN/MAX/COUNT. |
| NOTIFY | RFC 5465 | Event-based notifications. NOTIFY SET/NONE parsed with all mailbox filters; the selected mailbox honours SELECTED / SELECTED-DELAYED (MessageNew / MessageExpunge / FlagChange), suppressing the unsolicited responses the client did not request (RFC 5465 §5). Non-selected mailbox filters (PERSONAL / INBOXES / SUBSCRIBED / SUBTREE / MAILBOXES) are watched via the pkg/ event bus and their MessageNew / MessageExpunge / FlagChange activity is reported as untagged * STATUS (RFC 5465 §6), delivered during IDLE and before the next command's tagged response. The watched set is re-evaluated dynamically: mailboxes created, renamed or subscribed after NOTIFY SET join or leave the set live (via the per-user mlist: event key). Mailbox-level events - MailboxName (create / delete / rename, the last with OLDNAME) and SubscriptionChange (subscribe / unsubscribe) - are reported as untagged * LIST responses (RFC 5465 §5) when requested. AnnotationChange / metadata events are not yet reported. |
| SPECIAL-USE | RFC 6154 | \Sent, \Drafts, \Trash folder flags. |
| ID | RFC 2971 | Server identity advertisement. Always offered before login; after login only while imap_ is non-empty. |
| OBJECTID | RFC 8474 | Stable object identifiers: MAILBOXID (SELECT/EXAMINE response code + STATUS item, from the folder GUID), EMAILID (FETCH, from the message GUID), THREADID (FETCH, the conversation a message belongs to; NIL for accounts whose threading data has not been built yet). IDs are 32 lowercase hex chars of the 128-bit GUID; they survive RENAME. |
| METADATA | RFC 5464 | Advertised only when a metadata dict is configured. Server and per-mailbox annotations (GETMETADATA / SETMETADATA). State lives in cfg. (pkg/). Keys: priv/ and shared/; server-scope entries live under INBOX's GUID with a vendor/ prefix so they cannot collide with INBOX mailbox attributes. |