Created
June 24, 2015 16:47
-
-
Save ebassi/303884b8fd6b54480852 to your computer and use it in GitHub Desktop.
getgrouplist is a bad function, written by bad people
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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