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