[Dovecot] 2.2.4 - quota-status changing the user it is running as
Hello,
I'm currently experimenting with this quota-status service configuration:
service quota-status {
client_limit = 1
executable = quota-status -p postfix
# Let's make the default explicit.
user = root
unix_listener /var/spool/postfix/private/quota-policyd {
user = postfix
}
}
The idea is to run the service as root during the preliminary tests (at worst, since the service is going to be used as a policy daemon by Postfix only, it shouldn't be very problematic to have it running as root anyway).
A user, with address john.doe@example.com and identified as john.doe, is known to be over-quota. A "doveadm quota get" returns:
$ sudo doveadm quota get -u john.doe
Password:
Quota name Type Value Limit %
Quota utilisateur STORAGE 5 5 100
Quota utilisateur MESSAGE 9 - 0
and messages for that user are correctly rejected by lmtp:
dovecot[4989]: lmtp(5069, john.doe@example.com): QWSWLgrP4lF7FAAA5Q0ykw: msgid=<20130714161643.9085DF176F2@ALMba.local>: save failed to INBOX: Quota exceeded (mailbox for user is full)
Let's now simulate a connection from Postfix:
$ sudo -u postfix telnet /_ROOT/var/spool/postfix/private/quota-policyd
Trying /_ROOT/var/spool/postfix/private/quota-policyd...
Connected to (null).
Escape character is '^]'.
A look at the output of top (excerpt) confirms that quota-status is running as root:
PID COMMAND UID
5100 quota-status 0
Going on with our telnet session:
recipient=john.doe@example.com
size=10000
action=OK
Hmmm... OK, this may be a config problem of mine which may require further investigation.
Anyway, looking at top's output:
PID COMMAND UID
5100 quota-status 999
it appears that quota-status is now running as the mail_uid/mail_gid user; the switch happens immediately after having entered the empty line in the telnet session.
Let's then try to go further within the telnet session:
recipient=john.doe@example.com
size=10000
action=DEFER_IF_PERMIT Internal error occurred. Refer to server log for more information.
^]
telnet> quit
Connection closed.
and a look at the log indeed reveals that quota-status doesn't have sufficient privileges anymore:
dovecot[4989]: quota-status(john.doe@example.com): Error: user john.doe@example.com: Error reading configuration: net_connect_unix(/_ROOT/var/run/dovecot/config) failed: Permission denied
Is this the expected behavior, to have quota-status switch to another user?
TIA, Axel
Le 14 juil. 2013 à 18:54, Axel Luttgens a écrit :
[...]
Is this the expected behavior, to have quota-status switch to another user?
I should have added: "And to have it indefinitely running as that user?".
Notwithstanding the permission problems that come with that behavior (see my previous post), this doesn't seem to be fully right for a service intended to be a policy server for Postfix.
For example, let's consider the case of separate uid (or even uid/gid) for mail users. Suppose that the initial connection to quota-status happens for checking quota of user with uid 10001; if quota-status is configured to start as root, we know it will switch to user 10001 and stay running under that uid. Later, a query comes from Postfix for the quota of user with uid 100002. Unless quota-status hasn't fully dropped its root privileges but has just switched to user 10001 while still having the capability to switch to user 10002, I guess there could be a problem...
How exactly is quota-status supposed to behave in such a case?
TIA, Axel
On 14.7.2013, at 19.54, Axel Luttgens AxelLuttgens@swing.be wrote:
and messages for that user are correctly rejected by lmtp:
dovecot[4989]: lmtp(5069, john.doe@example.com): QWSWLgrP4lF7FAAA5Q0ykw: msgid=20130714161643.9085DF176F2@ALMba.local: save failed to INBOX: Quota exceeded (mailbox for user is full)
Going on with our telnet session:
recipient=john.doe@example.com size=10000
action=OK
Hmmm... OK, this may be a config problem of mine which may require further investigation.
Did you solve this?
and a look at the log indeed reveals that quota-status doesn't have sufficient privileges anymore:
dovecot[4989]: quota-status(john.doe@example.com): Error: user john.doe@example.com: Error reading configuration: net_connect_unix(/_ROOT/var/run/dovecot/config) failed: Permission denied
Is this the expected behavior, to have quota-status switch to another user?
Either one of these fixes would be sufficient:
http://hg.dovecot.org/dovecot-2.2/rev/2470bb9106b0 http://hg.dovecot.org/dovecot-2.2/rev/51b8020b29f6
Yet another possibility would be to use service { service_count=1 } to recreate the process every time.
Le 30 juil. 2013 à 12:28, Timo Sirainen a écrit :
On 14.7.2013, at 19.54, Axel Luttgens wrote:
[...]
Going on with our telnet session:
recipient=john.doe@example.com size=10000
action=OK
Hmmm... OK, this may be a config problem of mine which may require further investigation.
Did you solve this?
Hello Timo,
Nice to read from you.
Unfortunately, no; I'm still stuck with that problem, as described in: http://www.dovecot.org/list/dovecot/2013-July/091462.html
[...]
Is this the expected behavior, to have quota-status switch to another user?
Either one of these fixes would be sufficient:
http://hg.dovecot.org/dovecot-2.2/rev/2470bb9106b0 http://hg.dovecot.org/dovecot-2.2/rev/51b8020b29f6
Thanks! Do you really mean "either", not "both"? I ask, because those patches seem to intervene at quite different levels (but I guess I'll have, one day or another, to get more acquainted with Dovecot's coding, so as not to come with such silly questions...).
Yet another possibility would be to use service { service_count=1 } to recreate the process every time.
Yes, but I fear some inefficiencies with such an extreme setting; in fact, I hoped to rely on Postfix for managing the service's life cycle.
Best Regards, Axel
Le 30 juil. 2013 à 20:36, Axel Luttgens a écrit :
[...] Do you really mean "either", not "both"? I ask, because those patches seem to intervene at quite different levels (but I guess I'll have, one day or another, to get more acquainted with Dovecot's coding, so as not to come with such silly questions...). [...]
So, even if I could only test a unique mail uid/gid (i.e. dovemailer/dovemailer) kind of setup, I've applied both patches so as to verify they don't enter in conflict.
Seems to be fine now with my initial attempt:
service quota-status {
client_limit = 1
executable = quota-status -p postfix
unix_listener /var/spool/postfix/private/quota-policyd {
user = postfix
}
}
as far as the switch from root to dovemailer is concerned: the service doesn't complain anymore about not being able to access the config.
On the other hand, trying to run the service as another user:
service quota-status {
client_limit = 1
executable = quota-status -p postfix
user = dovemailer
group = dovemailer
unix_listener /var/spool/postfix/private/quota-policyd {
user = postfix
}
}
unfortunately still requires to relax the permissions on the config unix socket:
service config {
unix_listener config {
group = dovemailer
mode = 0660
}
}
so as to avoid such immediate failures:
quota-status: Fatal: Error reading configuration: net_connect_unix(/_ROOT/var/run/dovecot/config) failed: Permission denied
master: Error: service(quota-status): command startup failed, throttling for 2 secs
But now a failure, very likely related to patch 2470bb9106b0, occurs at the first query:
quota-status: Fatal: seteuid(0) failed: Operation not permitted
Perhaps am I missing some needed setting in the case of that second config?
Axel
On 1.8.2013, at 13.11, Axel Luttgens AxelLuttgens@swing.be wrote:
Le 30 juil. 2013 à 20:36, Axel Luttgens a écrit :
[...] Do you really mean "either", not "both"? I ask, because those patches seem to intervene at quite different levels (but I guess I'll have, one day or another, to get more acquainted with Dovecot's coding, so as not to come with such silly questions...). […]
I meant "either".
So, even if I could only test a unique mail uid/gid (i.e. dovemailer/dovemailer) kind of setup, I've applied both patches so as to verify they don't enter in conflict. On the other hand, trying to run the service as another user:
service quota-status { client_limit = 1 executable = quota-status -p postfix user = dovemailer group = dovemailer unix_listener /var/spool/postfix/private/quota-policyd { user = postfix } }
unfortunately still requires to relax the permissions on the config unix socket:
service config { unix_listener config { group = dovemailer mode = 0660 } }
so as to avoid such immediate failures:
quota-status: Fatal: Error reading configuration: net_connect_unix(/_ROOT/var/run/dovecot/config) failed: Permission denied master: Error: service(quota-status): command startup failed, throttling for 2 secs
Yeah. Hmm. I guess this is a good idea to fix too: http://hg.dovecot.org/dovecot-2.2/rev/eb63eca74471
Although now if the config process crashes, this error comes back and Dovecot can't fix it automatically. That's in my TODO as well. Config process never crashes though :)
But now a failure, very likely related to patch 2470bb9106b0, occurs at the first query:
quota-status: Fatal: seteuid(0) failed: Operation not permitted
Le 1 août 2013 à 12:44, Timo Sirainen a écrit :
On 1.8.2013, at 13.11, Axel Luttgens wrote:
[...] unfortunately still requires to relax the permissions on the config unix socket: [...]
Yeah. Hmm. I guess this is a good idea to fix too: http://hg.dovecot.org/dovecot-2.2/rev/eb63eca74471
Fine! Seems to do the job here; and I guess this is a more wide change that may prove helpful for other cases as well.
Although now if the config process crashes, this error comes back and Dovecot can't fix it automatically. That's in my TODO as well.
Haven't you already begun to work on that (just had a quick look at the hg)?
Config process never crashes though :)
Indeed. Never saw such an ugly event happen up to now. ;-)
But now a failure, very likely related to patch 2470bb9106b0, occurs at the first query:
quota-status: Fatal: seteuid(0) failed: Operation not permitted
As a summary, with:
http://hg.dovecot.org/dovecot-2.2/rev/2470bb9106b0
http://hg.dovecot.org/dovecot-2.2/rev/51b8020b29f6
http://hg.dovecot.org/dovecot-2.2/rev/eb63eca74471
http://hg.dovecot.org/dovecot-2.2/rev/43488e1044c9
it seems that either:
service quota-status {
client_limit = 1
executable = quota-status -p postfix
unix_listener /var/spool/postfix/private/quota-policyd {
user = postfix
}
}
or:
service quota-status {
client_limit = 1
executable = quota-status -p postfix
user = dovemailer
unix_listener /var/spool/postfix/private/quota-policyd {
user = postfix
}
}
are now functional, without any additional settings needed.
Many thanks, Timo. Axel
PS - I may now focus on why the hell I always get "action=OK"...
On Thu, Aug 01, 2013 at 02:31:31PM +0200, Axel Luttgens wrote:
http://hg.dovecot.org/dovecot-2.2/rev/2470bb9106b0 http://hg.dovecot.org/dovecot-2.2/rev/51b8020b29f6 http://hg.dovecot.org/dovecot-2.2/rev/eb63eca74471 http://hg.dovecot.org/dovecot-2.2/rev/43488e1044c9
Is there any chance to get these backported to 2.1 as well? After all, it has the same issues without these patches.
The individual patches seem to apply just fine to current 2.1 tip without any code changes:
$ patch -p1 < p/2470bb9106b0 patching file src/lib-storage/mail-storage-service.c Hunk #1 succeeded at 946 (offset -21 lines). Hunk #2 succeeded at 966 (offset -21 lines). $ patch -p1 < p/51b8020b29f6 patching file src/plugins/quota/quota-status.c Hunk #1 succeeded at 218 (offset 3 lines). $ patch -p1 < p/eb63eca74471 patching file src/lib-master/master-service-settings.c Hunk #1 succeeded at 323 (offset -13 lines). patching file src/lib-master/master-service-settings.h Hunk #1 succeeded at 53 (offset -3 lines). patching file src/lib-master/master-service.c Hunk #1 succeeded at 229 (offset -7 lines). patching file src/lib-master/master-service.h Hunk #1 succeeded at 12 (offset -3 lines). $ patch -p1 < p/43488e1044c9 patching file src/lib-storage/mail-storage-service.c Hunk #1 succeeded at 728 with fuzz 2 (offset -20 lines).
After that, everything works just fine and as expected, as Axel described for 2.2:
- Running under non-root user is possible
- Querying for more than one user under the same connection is possible
$ printf "recipient=m.mustermann@example.net\nsize=1234\n\nrecipient=m.mustermann@example.net\nsize=12340000\n\nrecipient=test@example.net\nsize=12340000\n\n" | nc 127.0.0.1 12340 action=OK
action=REJECT Over quota
action=REJECT Over quota
So it seems to me that I can apply them well enough on my own. I'd just like them to come with the default source, so I cannot forget them when upgrading. :-)
Ulrich
On Thu, 2013-08-01 at 16:27 +0200, Ulrich Zehl wrote:
On Thu, Aug 01, 2013 at 02:31:31PM +0200, Axel Luttgens wrote:
http://hg.dovecot.org/dovecot-2.2/rev/2470bb9106b0 http://hg.dovecot.org/dovecot-2.2/rev/51b8020b29f6 http://hg.dovecot.org/dovecot-2.2/rev/eb63eca74471 http://hg.dovecot.org/dovecot-2.2/rev/43488e1044c9
Is there any chance to get these backported to 2.1 as well? After all, it has the same issues without these patches.
Added http://hg.dovecot.org/dovecot-2.1/rev/b986ac5e1d98 which is good enough and definitely won't cause any problems.
participants (3)
-
Axel Luttgens
-
Timo Sirainen
-
Ulrich Zehl