Re: Dovecot LMTP mixing up users on multi-recipient mail

2019-07-03 Thread Timo Sirainen via dovecot
On 27 Jun 2019, at 14.21, Bernhard Schmidt via dovecot  
wrote:
> 
> 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>: Error: 
> open(/var/cache/dovecot/index/n/user2n/.INBOX/dovecot.index.cache) failed: 
> Permission denied (euid=3814520() 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);
}

Dovecot LMTP mixing up users on multi-recipient mail

2019-06-27 Thread 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>: 
Error: open(/var/cache/dovecot/index/n/user2n/.INBOX/dovecot.index.cache) 
failed: Permission denied (euid=3814520() 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 =