Dovecot LMTP mixing up users on multi-recipient mail
Hi,
I've upgraded a mailstore from Debian Jessie (aka oldstable) with Dovecot 2.2.13 to Debian Buster (next stable) with Dovecot 2.3.4.1 today. It worked pretty well, except that we're seeing error messages very similar to this old thread
https://dovecot.org/pipermail/dovecot/2015-July/101396.html
It appears to be happening when a mail with multiple recipients on this message store is getting delivered through lmtp.
Jun 27 11:47:36 lxmhs74 dovecot: lmtp(user1)<47683>sGwaD7eQFF1DugAAgkzuhA:18: Error: open(/var/cache/dovecot/index/n/user2n/.INBOX/dovecot.index.cache) failed: Permission denied (euid=3814520(<unknown>) egid=12(man) missing +x perm: /var/cache/dovecot/index/n/user2, dir owned by 3391995:12 mode=0700)
user1 uid is 3814520, user2n uid is 3391995. Dovecot appears to be trying to deliver the message to user1 while using the index directory of user2n.
Further configuration:
- message store is on NFS
- cache directory is on local disk
- users are coming from LDAP, one UID per user user_attrs = cn=user,homeDirectory=home,uidNumber=uid,gidNumber=gid
- index directory is calculated from the username maildir:~/Maildir:INDEX=/var/cache/dovecot/index/%-1.1n/%n
Despite the error messages (which appear dozens of times per delivery attempt) delivery seems to work. Workaround was to set
lmtp_destination_recipient_limit = 1
on the postfix in front of the message store.
Despite the report linked above being quite old, I can't recall having issues with 2.2.13.
=== doveconf -n ===
# OS: Linux 4.19.0-5-amd64 x86_64 Debian 10.0 # Hostname: lxmhs74.srv.lrz.de default_vsz_limit = 512 M deliver_log_format = from=<%e>, size=%p, message-id=<%m>, status=%$ imap_id_log = * imap_id_send = * lda_mailbox_autocreate = yes lda_mailbox_autosubscribe = yes login_greeting = Dovecot ready. login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c session=<%{session}> cipher=<%k> mail_gid = mstore mail_location = maildir:~/Maildir:INDEX=/var/cache/dovecot/index/%-1.1n/%n mail_plugins = quota listescape mail_uid = mstore 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 mmap_disable = yes namespace inbox { inbox = yes location = mailbox Drafts { auto = subscribe special_use = \Drafts } mailbox Junk { auto = subscribe special_use = \Junk } mailbox Sent { auto = subscribe special_use = \Sent } mailbox "Sent Messages" { special_use = \Sent } mailbox Trash { auto = subscribe special_use = \Trash } prefix = INBOX. separator = . type = private } passdb { args = /etc/dovecot/dovecot-ldap.conf driver = ldap } plugin { quota = maildir quota_rule = *:storage=1024M quota_rule2 = INBOX.Trash:ignore quota_status_nouser = DUNNO quota_status_overquota = 452 4.2.2 Mailbox is full quota_status_success = DUNNO quota_warning = storage=95%% quota-warning 95 %u quota_warning2 = storage=90%% quota-warning 90 %u sieve = ~/currently-active-script.sieve sieve_dir = ~/sieve } pop3_uidl_format = %v-%u protocols = imap lmtp sieve pop3 quota_full_tempfail = yes service anvil { client_limit = 3000 unix_listener anvil { group = sudo mode = 0660 } } service auth { client_limit = 3000 unix_listener auth-userdb { group = mstore mode = 0660 user = mstore } } service imap-login { client_limit = 1024 inet_listener imap { port = 143 } inet_listener imaps { port = 993 ssl = yes } process_limit = 2500 process_min_avail = 4 service_count = 0 } service imap { process_limit = 8192 } service lmtp { inet_listener lmtp { port = 24 } } service managesieve-login { inet_listener sieve { port = 4190 } inet_listener sieve_deprecated { port = 2000 } service_count = 1 } service managesieve { process_limit = 1024 } service pop3-login { inet_listener pop3 { port = 110 } inet_listener pop3s { port = 995 ssl = yes } } service quota-status { client_limit = 20 executable = quota-status -p postfix inet_listener { port = 12340 } } service quota-warning { executable = script /etc/dovecot/quotawarnmsg.sh unix_listener quota-warning { group = mstore mode = 0660 user = mstore } user = mstore } service stats { process_limit = 8192 } ssl_cert =
Thanks, Bernhard
On 27 Jun 2019, at 14.21, Bernhard Schmidt via dovecot
Hi,
I've upgraded a mailstore from Debian Jessie (aka oldstable) with Dovecot 2.2.13 to Debian Buster (next stable) with Dovecot 2.3.4.1 today. It worked pretty well, except that we're seeing error messages very similar to this old thread
https://dovecot.org/pipermail/dovecot/2015-July/101396.html
It appears to be happening when a mail with multiple recipients on this message store is getting delivered through lmtp.
Jun 27 11:47:36 lxmhs74 dovecot: lmtp(user1)<47683>sGwaD7eQFF1DugAAgkzuhA:18: Error: open(/var/cache/dovecot/index/n/user2n/.INBOX/dovecot.index.cache) failed: Permission denied (euid=3814520(<unknown>) egid=12(man) missing +x perm: /var/cache/dovecot/index/n/user2, dir owned by 3391995:12 mode=0700)
user1 uid is 3814520, user2n uid is 3391995. Dovecot appears to be trying to deliver the message to user1 while using the index directory of user2n.
When delivering multiple mails with LMTP it first writes the mail to the first recipient. It then leaves this mail open and uses it to copy the mail to the next recipient. This allows the possibility of e.g. using hard links if the filesystem permissions are the same with both recipients, although that won't happen in your case. Anyway, apparently this copying attempts to update the first recipient's dovecot.index.cache for some reason. I'm not sure why exactly this is different in v2.2 and v2.3. I wasn't able to reproduce this easily though, except with some special plugin it happened. This change helped with it: diff --git a/src/lmtp/lmtp-local.c b/src/lmtp/lmtp-local.c index e43f156d3..93848ef27 100644 --- a/src/lmtp/lmtp-local.c +++ b/src/lmtp/lmtp-local.c @@ -669,6 +669,9 @@ lmtp_local_deliver_to_rcpts(struct lmtp_local *local, will be unreferenced later on */ local->rcpt_user = NULL; src_mail = local->first_saved_mail; + struct mail_private *pmail = + (struct mail_private *)src_mail; + pmail->v.set_uid_cache_updates(src_mail, TRUE); first_uid = geteuid(); i_assert(first_uid != 0); }
participants (2)
-
Bernhard Schmidt
-
Timo Sirainen