I have configured a shared private namespace in dovecot so that, via ACLs, users can access other users' mailboxes.
I set up a quota for each user and this also works well. The quota is monitored and new messages are denied if the quota is exceeded.
There is one problem though: apparently dovecot treats shared mailboxes in relation to the current user's quota, it does not consider (as would be appropriate) the shared mailbox owner's quota.
I will try to explain better with a couple of examples.
==============
Consider the following case:
user1 has a quota of 1MB, totally available
user2 has a quota of 10MB, totally available
user1 shares the "Sales" mailbox with user2
user2 copies a 500KB message to the shared "Sales" mailbox
user1's quota will be correctly deducted by 500KB, thus resulting in 0.5MB available
At this point, however, let's try another operation:
user2 copies an 800KB message to the shared "Sales" mailbox.
The server should return error because this way user1 exceeds the allocated quota of 1MB (500KB + 800KB), but instead the copy operation succeeds.
This happens because at the time of the copy operation, dovecot considers the quota limit of user2 instead of considering the quota limit of user1.
==============
Let us consider another case, performing the same operations but where the user quota limits are reversed (user1 has a larger quota than user2):
user1 has a quota of 10MB, totally available
user2 has a quota of 1MB, totally available
user1 shares the "Sales" mailbox with user2
user2 copies a 500KB message to the shared mailbox "Sales"
The operation fails by overquota, because again dovecot considers user2's quota limit instead of considering user1's quota limit. Therefore, it is as if user2, with a 1MB limit, tries to write to a "larger" area (10MB).
As a counterevidence, setting user1 and user2 with the same quota limit, the operation succeeds perfectly.
==============
Can anyone help me solve the problem? Is this a problem that is related to my configuration? Below I attach the output of dovecot -n
===============
# 2.3.19.1 (9b53102964): /etc/dovecot/dovecot.conf # Pigeonhole version 0.5.19 (4eae2f79) # OS: Linux 6.1.0-16-cloud-arm64 aarch64 Debian 12.4
auth_master_user_separator = * auth_mechanisms = PLAIN LOGIN default_client_limit = 7168 default_process_limit = 1024 deliver_log_format = from=%{from}, envelope_sender=%{from_envelope}, subject=%{subject}, msgid=%m, size=%{size}, delivery_time=%{delivery_time}ms, %$ dict { acl = mysql:/etc/dovecot/dovecot-dict-acl-sql.conf.ext } first_valid_uid = 2000 last_valid_uid = 2000 listen = * [::] login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c %k session=<%{session}> mail_gid = 2000 mail_location = maildir:%Lh:INDEX=%Lh mail_plugins = quota mailbox_alias acl mail_log notify mail_uid = 2000 managesieve_notify_capability = mailto managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext editheader metric { filter = event=imap_command_finished metric_name = imap_command } namespace { inbox = yes location = mailbox { auto = no special_use = \Archive name = Archive } mailbox { auto = no special_use = \Archive name = Archives } mailbox { auto = no special_use = \Trash name = Deleted Messages } mailbox { auto = subscribe special_use = \Drafts name = Drafts } mailbox { auto = subscribe special_use = \Junk name = Junk } mailbox { auto = no special_use = \Junk name = Junk E-mail } mailbox { auto = subscribe special_use = \Sent name = Sent } mailbox { auto = no special_use = \Sent name = Sent Items } mailbox { auto = no special_use = \Sent name = Sent Messages } mailbox { auto = no special_use = \Junk name = Spam } mailbox { auto = subscribe special_use = \Trash name = Trash } prefix = separator = / type = private name = } namespace { list = children location = maildir:%%Lh:INDEXPVT=%%Lh/Shared/%{auth_user} prefix = Shared/%%u/ separator = / subscriptions = yes type = shared name = } passdb { args = /etc/dovecot/dovecot-sql.conf.ext driver = sql } passdb { args = /etc/dovecot/master-users driver = passwd-file master = yes result_success = continue } plugin { acl = vfile:/etc/dovecot/dovecot-acl acl_shared_dict = proxy::acl mail_log_events = delete undelete expunge copy mailbox_create mailbox_delete mailbox_rename mail_log_fields = uid box msgid size from subject flags quota = maildir:User quota quota_rule = *:storage=1G quota_rule2 = Trash:storage=+100M quota_status_nouser = DUNNO quota_status_overquota = 552 5.2.2 Mailbox is full quota_status_success = DUNNO quota_warning = storage=95%% quota-warning 95 %u quota_warning2 = storage=80%% quota-warning 80 %u sieve = file:/home/vmail/%d/sieve/%n/;active=/home/vmail/%d/sieve/%n/.dovecot.sieve sieve_before = /home/vmail/sieve/sievebefore1 sieve_editheader_forbid_add = X-Verified sieve_editheader_forbid_delete = X-Verified X-Seen sieve_editheader_max_header_size = 1k sieve_extensions = +editheader sieve_global_dir = /home/vmail/sieve sieve_max_redirects = 30 sieve_vacation_default_period = 1d sieve_vacation_min_period = 0 sieve_vacation_send_from_recipient = yes } protocols = pop3 imap sieve lmtp service replication-notify-fifo { name = aggregator } service anvil-auth-penalty { name = anvil } service auth-worker { name = auth-worker } service { unix_listener { group = postfix mode = 0666 user = postfix path = /var/spool/postfix/private/auth } unix_listener { group = vmail mode = 0660 user = vmail path = auth-userdb } name = auth } service config { name = config } service dict-async { name = dict-async } service { unix_listener { group = vmail mode = 0660 user = vmail path = dict } name = dict } service login/proxy-notify { name = director } service dns-client { name = dns-client } service doveadm-server { name = doveadm } service imap-hibernate { name = imap-hibernate } service imap { process_min_avail = 8 service_count = 0 vsz_limit = 1 G name = imap-login } service imap-urlauth { name = imap-urlauth-login } service imap-urlauth-worker { name = imap-urlauth-worker } service token-login/imap-urlauth { name = imap-urlauth } service { process_limit = 2048 name = imap } service indexer-worker { name = indexer-worker } service indexer { name = indexer } service ipc { name = ipc } service { unix_listener { group = postfix mode = 0666 user = postfix path = /var/spool/postfix/private/dovecot-lmtp } name = lmtp } service log-errors { name = log } service { inet_listener { port = 4190 name = sieve } name = managesieve-login } service login/sieve { name = managesieve } service old-stats-mail { name = old-stats } service pop3 { service_count = 0 name = pop3-login } service login/pop3 { name = pop3 } service { executable = script /opt/scripts/dovecot/quota-warning.sh unix_listener { group = vmail mode = 0660 user = vmail path = quota-warning } name = quota-warning } service replicator-doveadm { name = replicator } service login/stats-writer { unix_listener { group = vmail mode = 0660 user = vmail path = stats-reader } unix_listener { group = vmail mode = 0660 user = vmail path = stats-writer } name = stats } service submission { name = submission-login } service login/submission { name = submission } ssl = required ssl_cert = </etc/letsencrypt/live/mydomain.com/fullchain.pem ssl_cipher_list = EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH ssl_dh = # hidden, use -P to show it ssl_key = # hidden, use -P to show it ssl_prefer_server_ciphers = yes userdb { args = /etc/dovecot/dovecot-sql.conf.ext driver = sql } protocol lda { lda_mailbox_autocreate = yes lda_mailbox_autosubscribe = yes mail_plugins = quota mailbox_alias acl mail_log notify sieve service replication-notify-fifo { name = aggregator } service anvil-auth-penalty { name = anvil } service auth-worker { name = auth-worker } service auth-client { name = auth } service config { name = config } service dict-async { name = dict-async } service dict { name = dict } service login/proxy-notify { name = director } service dns-client { name = dns-client } service doveadm-server { name = doveadm } service imap-hibernate { name = imap-hibernate } service imap { name = imap-login } service imap-urlauth { name = imap-urlauth-login } service imap-urlauth-worker { name = imap-urlauth-worker } service token-login/imap-urlauth { name = imap-urlauth } service imap-master { name = imap } service indexer-worker { name = indexer-worker } service indexer { name = indexer } service ipc { name = ipc } service lmtp { name = lmtp } service log-errors { name = log } service sieve { name = managesieve-login } service login/sieve { name = managesieve } service old-stats-mail { name = old-stats } service pop3 { name = pop3-login } service login/pop3 { name = pop3 } service replicator-doveadm { name = replicator } service login/stats-writer { name = stats } service submission { name = submission-login } service login/submission { name = submission } } protocol lmtp { mail_plugins = quota mailbox_alias acl mail_log notify sieve postmaster_address = postmaster@mydomain.com recipient_delimiter = + service replication-notify-fifo { name = aggregator } service anvil-auth-penalty { name = anvil } service auth-worker { name = auth-worker } service auth-client { name = auth } service config { name = config } service dict-async { name = dict-async } service dict { name = dict } service login/proxy-notify { name = director } service dns-client { name = dns-client } service doveadm-server { name = doveadm } service imap-hibernate { name = imap-hibernate } service imap { name = imap-login } service imap-urlauth { name = imap-urlauth-login } service imap-urlauth-worker { name = imap-urlauth-worker } service token-login/imap-urlauth { name = imap-urlauth } service imap-master { name = imap } service indexer-worker { name = indexer-worker } service indexer { name = indexer } service ipc { name = ipc } service lmtp { name = lmtp } service log-errors { name = log } service sieve { name = managesieve-login } service login/sieve { name = managesieve } service old-stats-mail { name = old-stats } service pop3 { name = pop3-login } service login/pop3 { name = pop3 } service replicator-doveadm { name = replicator } service login/stats-writer { name = stats } service submission { name = submission-login } service login/submission { name = submission } } protocol imap { imap_client_workarounds = tb-extra-mailbox-sep mail_max_userip_connections = 256 mail_plugins = quota mailbox_alias acl mail_log notify imap_quota imap_acl service replication-notify-fifo { name = aggregator } service anvil-auth-penalty { name = anvil } service auth-worker { name = auth-worker } service auth-client { name = auth } service config { name = config } service dict-async { name = dict-async } service dict { name = dict } service login/proxy-notify { name = director } service dns-client { name = dns-client } service doveadm-server { name = doveadm } service imap-hibernate { name = imap-hibernate } service imap { name = imap-login } service imap-urlauth { name = imap-urlauth-login } service imap-urlauth-worker { name = imap-urlauth-worker } service token-login/imap-urlauth { name = imap-urlauth } service imap-master { name = imap } service indexer-worker { name = indexer-worker } service indexer { name = indexer } service ipc { name = ipc } service lmtp { name = lmtp } service log-errors { name = log } service sieve { name = managesieve-login } service login/sieve { name = managesieve } service old-stats-mail { name = old-stats } service pop3 { name = pop3-login } service login/pop3 { name = pop3 } service replicator-doveadm { name = replicator } service login/stats-writer { name = stats } service submission { name = submission-login } service login/submission { name = submission } } protocol pop3 { mail_max_userip_connections = 30 mail_plugins = quota mailbox_alias acl mail_log notify pop3_client_workarounds = outlook-no-nuls oe-ns-eoh pop3_uidl_format = %08Xu%08Xv service replication-notify-fifo { name = aggregator } service anvil-auth-penalty { name = anvil } service auth-worker { name = auth-worker } service auth-client { name = auth } service config { name = config } service dict-async { name = dict-async } service dict { name = dict } service login/proxy-notify { name = director } service dns-client { name = dns-client } service doveadm-server { name = doveadm } service imap-hibernate { name = imap-hibernate } service imap { name = imap-login } service imap-urlauth { name = imap-urlauth-login } service imap-urlauth-worker { name = imap-urlauth-worker } service token-login/imap-urlauth { name = imap-urlauth } service imap-master { name = imap } service indexer-worker { name = indexer-worker } service indexer { name = indexer } service ipc { name = ipc } service lmtp { name = lmtp } service log-errors { name = log } service sieve { name = managesieve-login } service login/sieve { name = managesieve } service old-stats-mail { name = old-stats } service pop3 { name = pop3-login } service login/pop3 { name = pop3 } service replicator-doveadm { name = replicator } service login/stats-writer { name = stats } service submission { name = submission-login } service login/submission { name = submission } }