xref: /illumos-gate/usr/src/man/man3c/getgrouplist.3c (revision 9164a50bf932130cbb5097a16f6986873ce0e6e5)
1.\"
2.\" This file and its contents are supplied under the terms of the
3.\" Common Development and Distribution License ("CDDL"), version 1.0.
4.\" You may only use this file in accordance with the terms of version
5.\" 1.0 of the CDDL.
6.\"
7.\" A full copy of the text of the CDDL should have accompanied this
8.\" source.  A copy of the CDDL is also available via the Internet at
9.\" http://www.illumos.org/license/CDDL.
10.\"
11.\"
12.\" Copyright 2020 Joyent, Inc.
13.\"
14.Dd December 2, 2023
15.Dt GETGROUPLIST 3C
16.Os
17.Sh NAME
18.Nm getgrouplist
19.Nd calculate group access list
20.Sh SYNOPSIS
21.In grp.h
22.Ft int
23.Fo getgrouplist
24.Fa "const char *user"
25.Fa "gid_t agroup"
26.Fa "gid_t *groups"
27.Fa "int *ngroups"
28.Fc
29.Sh DESCRIPTION
30The
31.Fn getgrouplist
32function queries the group database to obtain the list of groups that
33.Fa user
34belongs to.
35The
36.Fa agroup
37group is always added to the resulting group list.
38This value is typically the primary gid of the user from the
39.Sy passwd
40database.
41.Pp
42When calling
43.Fn getgrouplist ,
44the caller should set the maximum number of groups that
45.Fa groups
46can hold in
47.Fa *ngroups .
48The value of
49.Dv NGROUPS_MAX
50can be used to size
51.Fa groups
52to ensure it can hold any number of groups supported by the system.
53.Pp
54Upon return,
55.Fn getgrouplist
56stores the list of groups that
57.Fa user
58belongs to in
59.Fa groups
60and stores the number of groups
61.Fa user
62belongs to in
63.Fa *ngroups
64.Po
65this may be a smaller than the value passed in when
66calling
67.Fn getgrouplist
68.Pc .
69If
70.Fa groups
71is too small to hold all of the groups
72.Fa user
73belongs to,
74.Fn getgrouplist
75fails and sets
76.Fa *ngroups
77to a value large enough to hold the full result.
78.Sh RETURN VALUES
79On success,
80.Fn getgrouplist
81returns the number of groups
82.Fa user
83belongs to, fills in
84.Fa groups
85with the gids of the groups
86.Fa user
87belongs to, and also sets
88.Fa *ngroups
89to the number of groups
90.Fa user
91belongs to.
92.Pp
93On failure,
94.Fn getgrouplist
95returns -1 and
96.Va errno
97is set.
98.Pp
99The behavior of
100.Fn getgrouplist
101is undefined if the total number of groups a user belongs to exceeds
102.Dv NGROUPS_MAX .
103.Pp
104Note that on
105.Fx ,
106.Fn getgrouplist
107always returns -1 on failure or 0 on success.
108A caller must rely on the value set in
109.Fa *ngroups
110upon return to determine the number of entries in
111.Fa groups .
112.Pp
113On Linux, both glibc and musl return the number of groups
114.Fa user
115belongs to on success and return -1 on failure.
116.Pp
117None of these other implementations document any
118.Va errno
119values on failure, however their implementations show that
120.Va errno
121may be set on failure.
122Software using
123.Fn getgrouplist
124should be aware of these differences when attempting to write portable
125software.
126.Sh EXAMPLES
127.Sy Example 1
128Print all the groups for a user.
129.Bd -literal
130#include <pwd.h>
131#include <grp.h>
132#include <stdlib.h>
133#include <stdio.h>
134#include <limits.h>
135#include <err.h>
136
137void
138printgroups(const char *user)
139{
140    struct passwd *pw;
141    gid_t *groups;
142    int ngroups, ret;
143
144    if ((groups = calloc(NGROUPS_MAX, sizeof (gid_t))) == NULL)
145        err(EXIT_FAILURE, "calloc");
146
147    if ((pw = getpwnam(user)) == NULL)
148        err(EXIT_FAILURE, "getpwnam");
149
150    ngroups = NGROUPS_MAX;
151    ret = getgrouplist(user, pw->pw_gid, groups, &ngroups);
152    if (ret < 0)
153        err(EXIT_FAILURE, "getgrouplist");
154
155    for (int i = 0; i < ret; i++) {
156        struct group *gr = getgrgid(groups[i]);
157
158        (void) printf("%s ", gr->gr_name);
159    }
160    (void) fputc('\en', stdout);
161
162    free(groups);
163}
164.Ed
165.Sh ERRORS
166On failure,
167.Fn getgrouplist
168returns -1, and will set errno to one of the following values:
169.Bl -tag -width Dv
170.It Er ENOMEM
171Not enough memory to complete the request.
172.It Er EINVAL
173One of the parameters is invalid
174.Po
175for example,
176.Fa ngroups
177is
178.Dv NULL
179.Pc .
180.It Dv ERANGE
181The supplied value of
182.Fa *ngroups
183is too small to hold the results.
184.Fa *ngroups
185is set
186.Po
187upon return
188.Pc
189to a value large enough to hold the results, and a partial set of
190results is written to
191.Fa groups .
192The value written to
193.Fa *ngroups
194may be larger than the value returned by a successful call to
195.Fn getgrouplist .
196.El
197.Sh INTERFACE STABILITY
198.Sy Uncommitted
199.Sh MT-LEVEL
200.Sy MT-Safe
201.Sh SEE ALSO
202.Xr groups 1 ,
203.Xr getgroups 2 ,
204.Xr getuid 2 ,
205.Xr getgrnam 3C ,
206.Xr initgroups 3C ,
207.Xr limits.h 3HEAD
208