"sieve: failed to store into mailbox 'Junk': Read-only mbox" over root_squashed NFS, lmtp : euid/egid set and access() don't mix together for me
Ludovic POUZENC
ludovic.pouzenc at mines-albi.fr
Thu Feb 7 13:09:12 EET 2019
Hi,
I try to migrate an old fashioned mailsystem to Debian 9.7 / dovecot
2.2.7. I "have" to cope with mbox for now. I try to get rid of Sun OS
5.9 sendmail before mbox to mdbox migration (I'm fine if you laugh
loudly ^^). Intended setup : 2 VM with exim (smtp in, smtp out roughly),
3 VM with dovecot (mbox, maildir, testbed), 1 VM with IMAP proxy and
LMTP proxy.
doveconf -n is at end of this mail. My test case is :
root at wagram:~# swaks --to tstifi04 --server imap --protocol lmtp --header-X-Spam-Status yes
root at wagram:~#
(imap VM LMTP proxies to telegraphe5 VM in this test)
mbox folders are in users homedir, no generic "vmail" unix account. Real
posixAccounts in LDAP, NFS root_squashed.
sieve "fileinto "Junk" call goes wrong :
> Feb 6 17:56:03 telegraphe5 dovecot: lmtp(tstifi04): Error:
> PytSHqIRW1x2dgAA+Fldtw: sieve: msgid=unspecified: failed to store into
> mailbox 'Junk': Read-only mbox
straced : https://pastebin.com/A53hDYnS
I may miss some configuration options... but I get stuck. I get to IRC
and it seems that there is no simple things to circumvent. I tried to
read some code path too.
https://wiki.dovecot.org/LMTP states :
>
> Security
>
> Unfortunately LMTP process currently needs to run as root, and only
> temporarily drop privileges to users. Otherwise it couldn't handle
> mail deliveries to more than a single user with different UID. If
> you're using only a single global UID/GID, you can improve security by
> running lmtp processes as that user:
> service lmtp {
> user = vmail
> }
lmtp run as root, drop temporarily privileges. The point, IHMO, is lmtp
calls sieve code paths, that call some mbox saving function, that calls
libc/syscall access(). And this explicitly not consider effective uid/gid.
From strace (more in pastebin) :
> [pid 30326] geteuid() = 0
> [pid 30326] setresuid(-1, 20609, -1) = 0
> [pid 30326] geteuid() = 20609
> [pid 30326] access("/home/tstifi04/mail-imap/Junk", R_OK|W_OK) = -1
> EACCES (Permission denied)
From man access
> The check is done using the calling process's real UID and GID,
> rather than the effective IDs as is done when actually
> attempting an operation (e.g., open(2)) on the file.
> Similarly, for the root user, the check uses the set of permitted
> capabilities rather than the set of effective capabilities; and
> for non-root users, the check uses an empty set of capa-
> bilities.
I think that the process has effectively sufficient permissions to write
into the root_squashed file, and infortunately access() check another thing.
In dovecot sources, src/lib/eacces-error.c is aware of those "problems"
with access(), but I think that mbox and maybe other storage backends
don't use this for main codepath (like save a mail), but "only" for
smart log messages in some cases.
I may gone wrong while seeking about it. Do you see a configuration that
can use root squashed mboxes and LMTP ?
Should test_access() variant could be used as access() replacement ?
There is eaccess() and euidaccess() too but may be not portable enough
(_GNU_SOURCE only).
Regards,
Ludovic
telegraphe5:/dev/shm# mount | grep tstifi04
cifs1:/homeeleves/tstifi/tstifi04 on /home/tstifi04 type nfs (rw,nosuid,nodev,relatime,vers=3,rsize=65536,wsize=65536,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,mountaddr=172.16.2.29,mountvers=3,mountport=635,mountproto=udp,local_lock=none,addr=172.16.2.29)
telegraphe5:/dev/shm# dovecot -n
# 2.2.27 (c0f36b0): /etc/dovecot/dovecot.conf
# Pigeonhole version 0.4.16 (fed8554)
# OS: Linux 4.9.0-8-amd64 x86_64 Debian 9.7
auth_debug = yes
auth_verbose = yes
default_client_limit = 10240
default_process_limit = 2048
lda_mailbox_autocreate = yes
lda_mailbox_autosubscribe = yes
mail_debug = yes
mail_fsync = always
mail_location = mbox:~/mail-imap:INBOX=/var/mail/mailbox/%u:INDEX=/var/dovecot-indexes/%u
mail_nfs_storage = yes
mail_plugins = quota
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
mbox_write_locks = fcntl
mmap_disable = yes
namespace inbox {
inbox = yes
location =
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
mailbox Trash {
special_use = \Trash
}
prefix =
}
passdb {
args = /etc/dovecot/dovecot-ldap.conf.ext
driver = ldap
}
plugin {
mail_log_events = delete undelete expunge copy mailbox_delete mailbox_rename
mail_log_fields = uid box msgid size
quota = count:Quota mail global
quota_rule = *:storage=100M
quota_rule2 = Trash:storage=+100M
quota_vsizes = yes
quota_warning = storage=95%% quota-warning 95 %u
quota_warning2 = storage=80%% quota-warning 80 %u
sieve = file:/var/mail/mailconf/%1u/%u/sieve;active=/var/mail/mailconf/%1u/%u/.dovecot.sieve
sieve_after = /var/mail/mailconf/global/sieve/after.d/
sieve_before = /var/mail/mailconf/global/sieve/before.d/
sieve_global = /var/mail/mailconf/global/sieve
sieve_vacation_dont_check_recipient = yes
}
protocols = " imap lmtp sieve sieve"
service anvil {
unix_listener anvil-auth-penalty {
mode = 00
}
}
service imap-login {
inet_listener imap {
port = 0
}
}
service lmtp {
inet_listener lmtp {
port = 24
}
}
service managesieve {
process_limit = 16
}
service quota-warning {
executable = script /usr/local/bin/quota-warning.sh
unix_listener quota-warning {
mode = 0666
}
user = root
}
ssl = required
ssl_cert = </etc/ssl/local_certs/telegraphe5_cert.pem
ssl_key = # hidden, use -P to show it
syslog_facility = local0
userdb {
args = /etc/dovecot/dovecot-ldap.conf.ext
driver = ldap
}
verbose_proctitle = yes
protocol lmtp {
mail_plugins = quota sieve
}
protocol imap {
mail_max_userip_connections = 20
mail_plugins = quota imap_quota
}
telegraphe5:/dev/shm# grep -vE '^(#|$)' /etc/dovecot/dovecot-ldap.conf.ext
uris = ldaps://ldap-test.mines-albi.fr
tls_require_cert = hard
auth_bind = yes
base = ou=People,dc=enstimac,dc=fr
user_attrs = homeDirectory=home,uidNumber=uid,gidNumber=gid,\
dcMailQuota=quota_rule=*:bytes=%{ldap:dcMailQuota}M
user_filter = (&(objectClass=posixAccount)(|(uid=%n)(mail=%n at mines-albi.fr)))
iterate_attrs = uid=user
iterate_filter = (objectClass=posixAccount)
telegraphe5:/dev/shm# ls -l /var/mail/mailconf/global/sieve/before.d/
total 0
telegraphe5:/dev/shm# ls -al /var/mail/mailconf/t/tstifi04/
total 44
drwx------ 3 tstifi04 ifie2012 4096 févr. 5 10:46 .
drwxrwxrwt 169 root root 16384 janv. 5 18:48 ..
lrwxrwxrwx 1 tstifi04 ifie2012 25 janv. 31 17:50 .dovecot.sieve -> sieve/rainloop.user.sieve
-rw------- 1 tstifi04 ifie2012 1520 févr. 5 13:22 .dovecot.sieve.log
-rw------- 1 tstifi04 ifie2012 10336 févr. 5 10:46 .dovecot.sieve.log.0
-rw------- 1 tstifi04 ifie2012 172 janv. 31 17:56 .dovecot.svbin
drwx------ 3 tstifi04 ifie2012 4096 janv. 31 17:50 sieve
telegraphe5:/dev/shm# ls -al /var/mail/mailconf/t/tstifi04/sieve/rainloop.user.sieve
-rw------- 1 tstifi04 ifie2012 102 janv. 31 17:50 /var/mail/mailconf/t/tstifi04/sieve/rainloop.user.sieve
telegraphe5:/dev/shm# cat /var/mail/mailconf/t/tstifi04/sieve/rainloop.user.sieve
# This is RainLoop Webmail sieve script.
# Please don't change anything here.
# RAINLOOP:SIEVE
telegraphe5:/dev/shm#
telegraphe5:/dev/shm# cat /var/mail/mailconf/global/sieve/after.d/spam-into-junk.sieve
require ["fileinto"];
if header :is "X-Spam-Status" "Yes" {
fileinto "Junk";
stop;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://dovecot.org/pipermail/dovecot/attachments/20190207/dd00858d/attachment.html>
More information about the dovecot
mailing list