Skip to content

Instantly share code, notes, and snippets.

@ebassi
Created June 24, 2015 16:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebassi/303884b8fd6b54480852 to your computer and use it in GitHub Desktop.
Save ebassi/303884b8fd6b54480852 to your computer and use it in GitHub Desktop.
getgrouplist is a bad function, written by bad people
static gboolean
user_is_in_admin_group (uid_t user, const char *admin_group)
{
if (user == G_MAXUINT)
return FALSE;
if (admin_group == NULL || *admin_group == '\0')
admin_group = "wheel";
struct passwd *pw = getpwuid (user);
if (pw == NULL)
return FALSE;
int n_groups = 10;
gid_t *groups = g_new0 (gid_t, n_groups);
while (1)
{
int max_n_groups = n_groups;
int ret = getgrouplist (pw->pw_name, pw->pw_gid, groups, &max_n_groups);
if (ret >= 0)
{
n_groups = max_n_groups;
break;
}
/* some systems fail to update n_groups so we just grow it by approximation */
if (n_groups == max_n_groups)
n_groups = 2 * max_n_groups;
else
n_groups = max_n_groups;
groups = g_renew (gid_t, groups, n_groups);
}
gboolean retval = FALSE;
for (int i = 0; i < n_groups; i++)
{
struct group *gr = getgrgid (groups[i]);
if (gr != NULL && strcmp (gr->gr_name, admin_group) == 0)
{
retval = TRUE;
break;
}
}
g_free (groups);
return retval;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment