'id' command does give me all the supplementary groups, but the following code is just returning the primary groups for which the use belongs:
gid_size = getgroups(0, NULL); //1 is getting returned here
grouplist = malloc(gid_size * sizeof(gid_t));
getgroups(gid_size, grouplist); //Even with gid_size>1, only primary groups is returned.
My question is, whether there's any other alternative way to get all the supplementary groups on macOS.
You should be able to get up to 16 more groups by invoking initgroups()
first, but even this is not ideal.
From the initgroups(3)
man page:
Processes should not use the group ID numbers from
getgroups(2)
to determine a user's group membership. The list obtained fromgetgroups()
may only be a partial list of a user's group membership. Membership checks should use thembr_gid_to_uuid(3)
,mbr_uid_to_uuid(3)
, andmbr_check_membership(3)
functions.
So if you're trying to check if the user is a member of a specific group, the mbr_*()
functions are the way to go.
Note that the source code of the id
command is available and based on a very quick inspection it looks like it uses the undocumented getgrouplist_2()
.
It looks like this is a variant of the getgrouplist()
function, but without the 16-group limitation.
I don't think this function is declared in any public headers, id.c
uses the prototype
int32_t getgrouplist_2(const char *, gid_t, gid_t **);