.. This file is part of PEPSI. Copyright (C) 2026 GNUnet e.V. PEPSI is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. =========== pepsi-quota =========== *Manage and reconcile per-account mailbox quotas.* Role ==== ``pepsi-quota`` is the operator interface to the ``pepsi.mailbox_quota`` table: the per-account mailbox limits that :doc:`pepsi-stage-relay-to-maildir` enforces, and the usage accounting that both it and :doc:`pepsi-ingress` work from. It is **not** a stage. Every row is keyed on the passwd **login**, not on an e-mail address and not on a uid. A login is what :doc:`pepsi-ingress` can compare an envelope recipient against at ``RCPT`` time without resolving aliases — which it must not do, and cannot, since the alias map and the passwd database belong to the delivery stage — and it stays one row when several addresses reach one mailbox. Reference: :manpage:`pepsi-quota(1)`. Subcommands =========== * **set** *LOGIN SIZE* [``--messages`` *N*] — give one account its own limit (``2G``, ``500M``, a byte count, or ``none`` for explicitly unlimited, which is how a single account is exempted from a site-wide quota). * **unset** *LOGIN* — drop the account's own limit, so it inherits the site default again. (Not the same as ``set … none``.) * **show** *LOGIN* / **list** [``--full``] — one account's limits and usage, or every accounted-for account oldest measurement first (``--full`` restricts the listing to those at or over their limit). * **measure** *LOGIN* — re-measure one mailbox now. * **reconcile** [``--all``] — re-measure the accounts at or over their limit; ``--all`` also re-measures those whose measurement is merely stale. * **remove** *LOGIN* — forget the account's limits *and* its accounting; the next delivery re-creates the row. Three layers ============ Policy ``[pepsi] MAILBOX_QUOTA`` is the site default (absent means unlimited), overridden per account by ``pepsi-quota set``, and tightened further by the kernel's own limit where the filesystem enforces one. Measurement Only :manpage:`pepsi-helper-maildir-writer(1)` can take one: it is the single process that becomes the user, and a ``Maildir`` is mode ``0700``. ``measure`` and ``reconcile`` run it; nothing else here touches a mailbox. Estimate The ``used_* + since_*`` counters. Pepsi's own deliveries add to them and **nothing ever subtracts**, because nothing tells Pepsi when a user deletes mail over IMAP. The estimate is therefore an upper bound on real usage, which is what makes it safe as a *trigger* — "could this account be near its limit? then measure" — and unsafe as a *verdict*. Hence the rule: **nothing refuses a message on an estimate, only on a measurement**. Why reconcile exists ==================== An account at its limit is refused at ``RCPT`` by :doc:`pepsi-ingress`. Suppose its owner then empties the mailbox over IMAP. Nothing tells Pepsi — and because every message is being refused, no delivery ever runs to take a fresh measurement. The mailbox would stay shut for ever. Two things prevent that, and both are needed. :doc:`pepsi-ingress` refuses only on a measurement younger than ``[pepsi] MAILBOX_QUOTA_MAX_AGE`` (15 minutes by default), so a stale figure lets the message through and the delivery path looks again. And ``pepsi-quota reconcile`` re-measures the accounts that are *at* their limit — a cheap sweep precisely because it is only those. The package runs it from ``pepsi-quota-reconcile.timer`` (every ten minutes, ``Wants=``\ ed by ``pepsi.target``); do not add a cron job beside it. On a source install without systemd the equivalent is:: */10 * * * * pepsi pepsi-quota -c /etc/pepsi/pepsi.conf reconcile Privileges ========== Installed set-group-id to ``pepsi-maildir`` (mode ``2550``, owner ``pepsi:pepsi-maildir`` — owner-execute, so no other local user reaches the setgid bit), for the same reason :doc:`pepsi-stage-relay-to-maildir` is: ``measure``/``reconcile`` run the ``4750 root:pepsi-maildir`` helper, and the ``pepsi`` service account is deliberately not a member of that group. Run as ``root`` it drops to ``pepsi`` before connecting to the database, keeping that one group across the drop — so the tool behaves the same by hand as it does from its timer, where the setgid bit supplies the group and no drop happens. See also ======== :doc:`pepsi-stage-relay-to-maildir`, :doc:`pepsi-ingress`, :doc:`pepsi-status`, :manpage:`pepsi-quota(1)`, :manpage:`pepsi-helper-maildir-writer(1)`, :manpage:`pepsi.conf(5)`.