Kai Schaetzl wrote:
> Kai Schaetzl wrote:
> > /usr/local/bin/milter-greylist: cannot change supplementary groups:
> > Operation not permitted
> >
> > My first chosen user daemon indeed has several secondary groups, so I
> > changed the user to smmsp. Still that error. group smmsp has a password. I
> > changed to user mail, that user's primary group doesn't have a password
> > and it doesn't have secondary groups. Still no go. I donated it a real
> > login shell. Still no go. What's causing this?
>
> I wanted to revisit this problem today and fix it. milter-greylist had been
> running as root for the last days. At least that is what I thought.
>
> from /etc/init.d/greylist:
> user="root"
> daemon --user=$user /usr/local/bin/milter-greylist $OPTIONS
>
> from greylist.conf:
> user="smmsp"
>
> ps says it's indeed running as user smmsp. However, when I change to
> user="smmsp" in the init file I get the supplementary groups error. Also,
> usually the startup parameters take precedence over greylist.conf.
>
> Isn't that weird?
No, it isn't. The init.d script starts milter-greylist as
root (using the daemon tool). Then milter-greylist itself
switches its user ID to smmsp as specified in the .conf
file (which is only possible when it had been started as
root in the first place, of course).
As you might know, initgroups() is not a standard function
(it's not SUSv3 or POSIX), so it's not portable across
platforms. Even if the function exists on a certain plat-
form, it might behave differently from others.
For example, on FreeBSD, initgroups() exists, but it simply
calls getgrouplist() to get a list of supplementary groups,
and then calls setgroups(). None of those functions is
standard. Note that setgroups() can _only_ be called by
root, otherwise you'll get EPERM (which makes sense). That
error is propagated to initgroups(), of course. So if you
call initgroups() as non-root, you'll get EPERM.
I haven't looked at the milter-greylist code in question,
but I suspect that it calls setuid() first and then it
calls initgroups(), which will fail if implemented in the
way described above. It should call initgroups() first
and then setuid(). It requires that milter-greylist is
started as root, of course.
As for the question if initgroups() should be called at
all: Yes, I think it can be useful. For example, there
may be reasons to have a special group which owns the
milter-greylist dump directory or the .conf file, but not
make it the primary group of the smmsp processes for
security reasons. Such a setup requires that milter-
greylist has the access rights of a certain supplementary
group which is not its primary group.
Of course, if the OS doesn't support initgroups() at all,
there's not much of a choice. :-) But at least all BSDs
(both the free and the commercial ones) support the
initgroups function since the days of 4.2BSD (1983), and
Linux probably sto^H^H^H adopted it from there. Solaris
has announced to become "Linux-compatible", so I guess
they implemented it in the meanwhile, too.
Best regards
Oliver
--
Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing
Dienstleistungen mit Schwerpunkt FreeBSD: http://www.secnetix.de/bsd
Any opinions expressed in this message may be personal to the author
and may not necessarily reflect the opinions of secnetix in any way.
"Being really good at C++ is like being really good
at using rocks to sharpen sticks."
-- Thant Tessman