[collectd] exec plugin: Setting the group-ID

Peter Holik peter at holik.at
Tue Feb 19 11:16:21 CET 2008


> the exec plugin first calls `setgid' with the default group-id of the user and then
`setegid' with the configured group.
>
> Assuming that the group of the `nobody' user is `nogroup'. Depending on whether
collectd runs as root or not, the executed program has the following GIDs set:
> - collectd is root:
>   * real GID:      nogroup
>   * effective GID: dialout
>   * saved set-GID: nogroup
> - collectd is nobody:
>   * real GID:      <not changed>
>   * effective GID: dialout
>   * saved set-GID: <not changed>
>
> For any other options, such as starting collectd with the set-GID bit set, I recommend
Stevens `APUE'[*].
>
> So, what is the problem you experience? I assume you have some device like /dev/ttyS0
with permissions similar to:
>   crw-rw---- 1 root dialout 4, 64 2008-02-18 12:14 /dev/ttyS0
> Thus the spawned process needs to be in group `dialout' to be able to read from the
device. This should be possible with the effective GID set to `dialout'.

collectd is running as root

crw-rw---- 1 root dialout 4, 64 2008-02-18 12:14 /dev/ttyS0

Exec "nobody:dialout" "/usr/bin/digitemp_DS9097" ...

/etc/passwd:
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh

/etc/group:
dialout:x:20:nobody
nogroup:x:65534:

./configure --prefix=/usr --sysconfdir=/etc --enable-exec --enable-rrdtool
--enable-syslog --enable-debug

/usr/sbin/collectd -f -C /etc/collectd/collectd.conf

syslog:
exec plugin: exec_read_one: buffer = Error, you don't have +rw permission to access
/dev/ttyS0


running exec with Exec "nobody:dialout" "/usr/bin/id"

syslog:
exec plugin: exec_read_one: buffer = uid=65534(nobody) gid=65534(nogroup)
egid=20(dialout) Gruppen=0(root)

/etc/group with dialout:x:20:nobody has no effect

what is wrong here?

only if i set gid to 20(dialout) its working


Now i found the problem:

exec plugin: exec_read_one: buffer = uid=65534(nobody) gid=65534(nogroup)
egid=20(dialout) Gruppen=0(root)

As you see "Gruppen=0(root)" and to set egid to anything that is not in Gruppen (groups)
has no effect.

now if i add "initgroups" before setuid

  status = initgroups(pl->user, gid);
  if (status != 0)
  {
    ERROR ("exec plugin: initgroups (%i) failed: %s",
      gid, sstrerror (errno, errbuf, sizeof (errbuf)));
    exit (-1);
  }

it works

also if i set with egid

  status = initgroups(pl->user, egid);
  if (status != 0)
  {
    ERROR ("exec plugin: initgroups (%i) failed: %s",
      gid, sstrerror (errno, errbuf, sizeof (errbuf)));
    exit (-1);
  }

/etc/group can be without nobody:
dialout:x:20:


cu Peter






More information about the collectd mailing list