user-util: add getgrouplist_malloc and initgroups_wrapper

This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-07-02 17:19:18 +02:00
parent bbeef4b948
commit 5c2bd19f40
2 changed files with 47 additions and 0 deletions
+44
View File
@@ -1445,6 +1445,50 @@ ssize_t lookup_groups_in_files(
return n_arr;
}
int getgrouplist_malloc(const char *user, gid_t gid, gid_t **ret) {
#if BUILD_STATIC
return lookup_groups_in_files(GROUP_FILES, user, gid, ret);
#else
int ngroups_max = sysconf_ngroups_max();
if (ngroups_max < 0)
return ngroups_max;
_cleanup_free_ gid_t *gids = new(gid_t, ngroups_max);
if (!gids)
return -ENOMEM;
int k = ngroups_max;
if (getgrouplist(user, gid, gids, &k) < 0)
return -EIO; /* getgrouplist does not set errno */
if (ret)
*ret = TAKE_PTR(gids);
return k;
#endif
}
int initgroups_wrapper(const char *user, gid_t gid) {
#if BUILD_STATIC
_cleanup_free_ gid_t *groups = NULL;
int r, n_groups;
n_groups = getgrouplist_malloc(user, gid, &groups);
if (n_groups <= 0)
return n_groups;
/* Try to set the maximum number of groups the kernel can handle. This is what glibc does. */
for (; n_groups > 0; n_groups--) {
r = RET_NERRNO(setgroups(n_groups, groups));
if (r != -EINVAL)
break;
}
return r;
#else
return RET_NERRNO(initgroups(user, gid));
#endif
}
#if !BUILD_STATIC
static size_t getgr_buffer_size(void) {
+3
View File
@@ -189,11 +189,14 @@ int lookup_grent_in_files(
const char *name,
gid_t gid,
struct group **ret);
ssize_t lookup_groups_in_files(
char * const *files,
const char *name,
gid_t gid,
gid_t **ret);
int getgrouplist_malloc(const char *user, gid_t gid, gid_t **ret);
int initgroups_wrapper(const char *user, gid_t gid);
int getpwuid_malloc(uid_t uid, struct passwd **ret);
int getpwnam_malloc(const char *name, struct passwd **ret);