INITGROUPS(3)          FreeBSD Library Functions Manual          INITGROUPS(3)

NAME

     initgroups - initialize supplementary groups as per the group database

LIBRARY

     Standard C Library (libc, -lc)

SYNOPSIS

     #include <unistd.h>

     int
     initgroups(const char *name, gid_t basegid);

DESCRIPTION

     The initgroups() function initializes the current process' supplementary
     groups as prescribed by its arguments and the system's group database.

     It first uses the getgrouplist() function to compute a list of groups
     containing the passed basegid, which typically is the user's initial
     numerical group ID from the password database, and the supplementary
     groups in the group database for the user named name.  It then installs
     this list as the current process' supplementary groups using setgroups().

RETURN VALUES

     The initgroups() function returns the value 0 if successful; otherwise
     the value -1 is returned and the global variable errno is set to indicate
     the error.

ERRORS

     The initgroups() function may fail and set errno to any of the errors
     specified for the setgroups(2) system call, or to:

     [ENOMEM]           The initgroups() function was unable to allocate
                        temporary storage.

SEE ALSO

     setgroups(2), getgrouplist(3)

HISTORY

     The initgroups() function appeared in 4.2BSD.

     The initgroups() function changed semantics in FreeBSD 15, following that
     of setgroups(2) in the same release.  Before that, it would also set the
     effective group ID to basegid, and would not include the latter in the
     supplementary groups except before FreeBSD 8.  Its current behavior in
     these respects is known to be compatible with that of the following
     systems up to the specified versions that are current at time of this
     writing:
     -  Linux (up to 6.6) with the GNU libc (up to 2.42)
     -  NetBSD 1.1 and greater (up to 10)
     -  OpenBSD (up to 7.7)
     -  Systems based on illumos (up to August 2025 sources)

SECURITY CONSIDERATIONS

     As basegid is typically the user's initial numerical group ID, to which
     the current process' effective group ID is generally initialized,
     processes using functions to change their effective group ID (via
     setgid(2) or similar) or that are spawned from executables with the set-
     group-ID mode bit set will not be able to relinquish the access rights
     deriving from being a member of basegid, as these functions do not change
     the supplementary groups.

     This behavior is generally desirable in order to paper over the
     difference of treatment between the effective group and supplementary
     ones in this situation, as they are all in the end indiscriminately used
     in traditional UNIX discretionary access checks.  It blends well with the
     practice of allocating each user its own private group, as processes
     launched from a set-group-ID executable keep the same user and
     consistently stay also in the same user's group.  Finally, it was also
     chosen for compatibility with other systems (see the HISTORY section).

     This convention of including basegid in the supplementary groups is
     however only enforced by the initgroups() function, and not by the
     setgroups(2) system call, so applications expressly wanting to include in
     the supplementary groups only those specified by the group database can
     themselves call getgrouplist() and then setgroups() on the result with
     the first element skipped (see getgrouplist(3)).

FreeBSD 15.1-STABLE-HBSD        October 9, 2025                  INITGROUPS(3)