initgroup()
, the libc function that is typically called by login applications to set supplementary group list of the process it runs in your name does add the primary group id to that list.
If it didn't, that would be a security issue, as that would give you a way to relinquish access to that group by creating a setgid executable with one of your other groups, and execute that to lose your primary gid (that executable would have to call setgid()
for the real gid to also change), which would give you access to resources that have been explicitly denied access to your primary group for instance.
Example:
$ ls -l file
-rw----r-- 1 root chazelas 7 Dec 12 15:33 file
Access has been denied to my primary gid:
$ cat file
cat: file: Permission denied
Now, let's start a shell as me where the supplementary group ids doesn't include that group to see what we could do if login
didn't add that group to our supplementary group id list:
$ sudo perl -le '$( = $) = "1000 2"; $< = $> = 1000; exec zsh'
$ ps -o rgroup,egroup,supgrp -p $$
RGROUP EGROUP SUPGRP
chazelas chazelas bin
$ id -a
uid=1000(chazelas) gid=1000(chazelas) groups=1000(chazelas),2(bin)
1000 is in gid, egid, but not the supplementary group list. As I'm also a member of bin
, I can create a setgid bin
executable:
$ cp -f /usr/bin/env .
$ chgrp bin env
$ chmod g+s env
$ ./env perl -U -le '$( = $); exec qw(/usr/bin/id -a)'
uid=1000(chazelas) gid=2(bin) groups=2(bin)
I'm using perl
to call setgid()
($( = $)
). And then I've lost membership of the chazelas
group. So:
$ ./env perl -U -le '$( = $); exec qw(cat file)'
secret
By adding the group to the supplementary list, login
makes sure you can't get out of it (as only root can change that list and it's not affected by the execution of setgid executables).
Best Answer
You mix two different distinctions here:
The first distinction refers to how processes are being run. Normally, when you run a command/program, it is run with the privileges of your user. It has the real group id same as your user's primary group. This can be changed by a process in order to perform some tasks as a member of another special group. To do that, programs use the
setgid
function that changes their effective group id.The second distinction refers to users. Each user has his/her primary group. There is only one per user and is referred to as gid in the output of the
id
command. Apart from that, each user can belong to a number of supplementary groups - and these are listed at the end ofid
output.[Edit] :
I agree that the manpage for
id
is somewhat misleading here. It is probably because it is a stripped-down version of the description provided by the info document. To see it more clearly, runinfo coreutils "id invocation"
(as suggested at the end of theid
manual).