Supplemental Groups
Linux uses the security mechanism of users and groups originally
developed for Unix. Under this model, each user has a user id (uid) and
a group id (gid). uids and gids are integer values that are mapped to
symbolic names in /etc/passwd and /etc/group, respectively. Originally,
Unix systems associated a single gid to a user. This restriction turned
out to be problematic when users working in different projects needed to
access files of different groups. They were forced to change their gid
explicitly every time they accessed a file of a different group. To
solve this problem, BSD 4.3 introduced supplemental groups. Under this
model, each process still has a primary gid (which is used when the user
creates a file, for example). However, it may belong to a set of
supplemental groups, too. Security checks that ensure that a process
belongs to a certain group now grant access to a file as long as that
file's group is included in the user's list of supplemental groups.
Manipulating Supplemental Groups
The <sys/param.h> defines the constant NGROUPS_MAX, which specifies how
many groups a process may belong to. To set a list of groups for a
process, use the setgroups() syscall, which has the following prototype:
int setgroups(size_t num, const gid_t * list);
Only users running as root may call this function. The argument num is
the number of groups contained in the array list. A setgroups() call
assigns the gids listed in list to the process's supplemental groups.
To obtain a process's list of supplemental groups, use the getgroups()
syscall, which has the following prototype:
int getgroups(size_t num, gid_t * list);
The list argument points to an array of gid_t. The getgroups() function
fills that array with up to num supplemental gids. A return value of -1
indicates an error. Typically, such an error occurs when list isn't
large enough to contain the entire set of supplemental groups. On
success, getgroups() returns the number of supplemental groups. As a
special case, a num value of 0 causes getgroups() to return the total
number of supplemental groups without writing them to list.