GETGROUPLIST(3C) Standard C Library Functions GETGROUPLIST(3C)
getgrouplist - calculate group access list
#include <grp.h>
int
getgrouplist(const char *user, gid_t agroup, gid_t *groups,
int *ngroups);
The getgrouplist() function queries the group database to obtain the
list of groups that user belongs to. The agroup group is always added
to the resulting group list. This value is typically the primary gid
of the user from the passwd database.
When calling getgrouplist(), the caller should set the maximum number
of groups that groups can hold in *ngroups. The value of NGROUPS_MAX
can be used to size groups to ensure it can hold any number of groups
supported by the system.
Upon return, getgrouplist() stores the list of groups that user belongs
to in groups and stores the number of groups user belongs to in
*ngroups (this may be a smaller than the value passed in when calling
getgrouplist()). If groups is too small to hold all of the groups user
belongs to, getgrouplist() fails and sets *ngroups to a value large
enough to hold the full result.
On success, getgrouplist() returns the number of groups user belongs
to, fills in groups with the gids of the groups user belongs to, and
also sets *ngroups to the number of groups user belongs to.
On failure, getgrouplist() returns -1 and errno is set.
The behavior of getgrouplist() is undefined if the total number of
groups a user belongs to exceeds NGROUPS_MAX.
Note that on FreeBSD, getgrouplist() always returns -1 on failure or 0
on success. A caller must rely on the value set in *ngroups upon
return to determine the number of entries in groups.
On Linux, both glibc and musl return the number of groups user belongs
to on success and return -1 on failure.
None of these other implementations document any errno values on
failure, however their implementations show that errno may be set on
failure. Software using getgrouplist() should be aware of these
differences when attempting to write portable software.
Example 1 Print all the groups for a user.
#include <pwd.h>
#include <grp.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <err.h>
void
printgroups(const char *user)
{
struct passwd *pw;
gid_t *groups;
int ngroups, ret;
if ((groups = calloc(NGROUPS_MAX, sizeof (gid_t))) == NULL)
err(EXIT_FAILURE, "calloc");
if ((pw = getpwnam(user)) == NULL)
err(EXIT_FAILURE, "getpwnam");
ngroups = NGROUPS_MAX;
ret = getgrouplist(user, pw->pw_gid, groups, &ngroups);
if (ret < 0)
err(EXIT_FAILURE, "getgrouplist");
for (int i = 0; i < ret; i++) {
struct group *gr = getgrgid(groups[i]);
(void) printf("%s ", gr->gr_name);
}
(void) fputc('\n', stdout);
free(groups);
}
On failure, getgrouplist() returns -1, and will set errno to one of the
following values:
ENOMEM Not enough memory to complete the request.
EINVAL One of the parameters is invalid (for example, ngroups is
NULL).
ERANGE The supplied value of *ngroups is too small to hold the
results. *ngroups is set (upon return) to a value large
enough to hold the results, and a partial set of results
is written to groups. The value written to *ngroups may
be larger than the value returned by a successful call to
getgrouplist().
Uncommitted
MT-LEVEL
MT-Safe
groups(1), getgroups(2), getuid(2), getgrnam(3C), initgroups(3C),
limits.h(3HEAD)
illumos December 2, 2023 illumos
NAME
getgrouplist - calculate group access list
SYNOPSIS
#include <grp.h>
int
getgrouplist(const char *user, gid_t agroup, gid_t *groups,
int *ngroups);
DESCRIPTION
The getgrouplist() function queries the group database to obtain the
list of groups that user belongs to. The agroup group is always added
to the resulting group list. This value is typically the primary gid
of the user from the passwd database.
When calling getgrouplist(), the caller should set the maximum number
of groups that groups can hold in *ngroups. The value of NGROUPS_MAX
can be used to size groups to ensure it can hold any number of groups
supported by the system.
Upon return, getgrouplist() stores the list of groups that user belongs
to in groups and stores the number of groups user belongs to in
*ngroups (this may be a smaller than the value passed in when calling
getgrouplist()). If groups is too small to hold all of the groups user
belongs to, getgrouplist() fails and sets *ngroups to a value large
enough to hold the full result.
RETURN VALUES
On success, getgrouplist() returns the number of groups user belongs
to, fills in groups with the gids of the groups user belongs to, and
also sets *ngroups to the number of groups user belongs to.
On failure, getgrouplist() returns -1 and errno is set.
The behavior of getgrouplist() is undefined if the total number of
groups a user belongs to exceeds NGROUPS_MAX.
Note that on FreeBSD, getgrouplist() always returns -1 on failure or 0
on success. A caller must rely on the value set in *ngroups upon
return to determine the number of entries in groups.
On Linux, both glibc and musl return the number of groups user belongs
to on success and return -1 on failure.
None of these other implementations document any errno values on
failure, however their implementations show that errno may be set on
failure. Software using getgrouplist() should be aware of these
differences when attempting to write portable software.
EXAMPLES
Example 1 Print all the groups for a user.
#include <pwd.h>
#include <grp.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <err.h>
void
printgroups(const char *user)
{
struct passwd *pw;
gid_t *groups;
int ngroups, ret;
if ((groups = calloc(NGROUPS_MAX, sizeof (gid_t))) == NULL)
err(EXIT_FAILURE, "calloc");
if ((pw = getpwnam(user)) == NULL)
err(EXIT_FAILURE, "getpwnam");
ngroups = NGROUPS_MAX;
ret = getgrouplist(user, pw->pw_gid, groups, &ngroups);
if (ret < 0)
err(EXIT_FAILURE, "getgrouplist");
for (int i = 0; i < ret; i++) {
struct group *gr = getgrgid(groups[i]);
(void) printf("%s ", gr->gr_name);
}
(void) fputc('\n', stdout);
free(groups);
}
ERRORS
On failure, getgrouplist() returns -1, and will set errno to one of the
following values:
ENOMEM Not enough memory to complete the request.
EINVAL One of the parameters is invalid (for example, ngroups is
NULL).
ERANGE The supplied value of *ngroups is too small to hold the
results. *ngroups is set (upon return) to a value large
enough to hold the results, and a partial set of results
is written to groups. The value written to *ngroups may
be larger than the value returned by a successful call to
getgrouplist().
INTERFACE STABILITY
Uncommitted
MT-LEVEL
MT-Safe
SEE ALSO
groups(1), getgroups(2), getuid(2), getgrnam(3C), initgroups(3C),
limits.h(3HEAD)
illumos December 2, 2023 illumos