On 25.2.2013, at 13.28, Dimos Alevizos dalevizo@otenet.gr wrote:
we've been using dovecot for pop3 and imap for some time now and we're in the middle of deploying lmtp as well, however we're run into a problem we can't solve. Specifically for some reason it seems that dovecot tries to write to the wrong index file during some, but not all, lmtp deliveries. If lmtp tries to deliver to person user_a@domain, sometimes it'll try to write to index directory user_b@domain using user_a euid. We haven't found and pattern in the problem. A user may receive multiple mails with only 1 in 20 or more deliveries having problems. The only things that we know is that user_b (the wrong one) is always from the same domain as the correct user and always (so far) also a recipient in the same mail.
Feb 25 09:07:01 pop02 dovecot: lmtp(20931, sub1ika@ika.gr): Error: stat(/indexes/2/b/0/diefecon.log@ika.gr/.imap/INBOX/dovecot.index.log) failed: Permission denied (euid=10054601(<unknown>) egid=165(<unknown>) missing +x perm: /indexes/2/b/0/diefecon.log@ika.gr, dir owned by 10107819:165 mode=0700) Feb 25 09:07:01 pop02 dovecot: lmtp(20931, sub1ika@ika.gr): Error: nfs_flush_chown_uid: stat(/indexes/2/b/0/diefecon.log@ika.gr/.imap/INBOX) failed: Permission denied .. Our current setup is 3 directors (dovecot 2.1.12) proxying pop3/imap and lmtp to a farm of 8 dovecot servers (all of them 2.1.15). All of our mailboxes are stored in NFS.
Since you're using directors, you can use mail_nfs_index=no and mail_nfs_storage=no. The performance will be better.
mail_location = mbox:INDEX=/var/index/dovecot/%1Mu/%2.1Mu/%3.1Mu/%u
This isn't a valid mail_location. Better to remove it entirely so it won't be accidentally used, except..:
user_attrs = folderPath=home,mailQuota=quota_rule=*:storage=%$M,uidNumber=uid,gidNumber=gid,mailPath=mail=mbox:~/:INBOX=%$:INDEX=/indexes/%1Mu/%2.1Mu/%3.1Mu/%u user_filter = (&(|(objectClass=otenetMailAccount)(objectClass=otenetservices))(|(uid=%u)(mail=%u)(mailAlternateAddress=%u))) pass_attrs = mail=user,userpassword=password pass_filter = (&(|(objectClass=otenetMailAccount)(objectClass=otenetservices))(|(uid=%u)(mail=%u)(mailAlternateAddress=%u)))
The main problem here is that you create indexes using %u, but there are 3 different valid %us: uid, mail and mailAlternateAddress. So you're most likely hitting problems for users whose mails are being delivered using mailAlternateAddress. Those alias expansions should normally be handled by your MTA.
With the above config you should be able to solve this by not using %u but the LDAP's mail field. So something like (with cleaning up the whole config):
user_attrs =
=user=%{ldap:mail},
=home=%{ldap:folderPath},
=quota_rule=*:storage=%{ldap:mailQuota}M,
=uid=%{ldap:uidNumber},
=gid=%{ldap:gidNumber},
=mail=mbox:~/:INBOX=%{ldap:mailPath}:INDEX=/indexes/%1M{ldap:mail}/%2.1M{ldap:mail}/%3.1M{ldap:mail}/%{ldap:mail}
Easier of course would be if you could determine mailPath using a static template, then you could just use the global mail_location and %u directly, because the %u gets normalized to same as "mail" field.