Description: Fix get_groups_for_user() for large number of users get_groups_for_user() used a hard-coded limit for the number of groups before, barring all access to users with a large number of groups. . Dynamically allocate the list instead, potentially resizing it based on what getgroupslist() tells us. Author: Sascha Silbe --- The information above should follow the Patch Tagging Guidelines, please checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here are templates for supplementary fields that you might want to add: Bug-Debian: http://bugs.debian.org/696989 Last-Update: 2012-12-30 --- policykit-1-0.105.orig/src/polkitbackend/polkitbackendlocalauthority.c +++ policykit-1-0.105/src/polkitbackend/polkitbackendlocalauthority.c @@ -749,11 +749,17 @@ get_groups_for_user (PolkitIdentity *use uid_t uid; struct passwd *passwd; GList *result; - gid_t groups[512]; - int num_groups = 512; + int num_groups, groups_size = 512; + gid_t *groups = malloc(groups_size * sizeof(gid_t)); int n; + int error; result = NULL; + if (!groups) + { + g_warning ("Out of memory when looking up groups for uid %d", uid); + goto out; + } /* TODO: it would be, uhm, good to cache this information */ @@ -765,22 +771,34 @@ get_groups_for_user (PolkitIdentity *use goto out; } - /* TODO: should resize etc etc etc */ - - if (getgrouplist (passwd->pw_name, - passwd->pw_gid, - groups, - &num_groups) < 0) + num_groups = groups_size; + error = getgrouplist (passwd->pw_name, passwd->pw_gid, groups, &num_groups); + if ((error < 0) && (num_groups > groups_size)) + { + gid_t *new_groups; + + groups_size = num_groups; + new_groups = realloc(groups, groups_size * sizeof(gid_t)); + if (!new_groups) { - g_warning ("Error looking up groups for uid %d: %s", uid, g_strerror (errno)); + g_warning ("Out of memory when looking up groups for uid %d", uid); goto out; } + groups = new_groups; + error = getgrouplist (passwd->pw_name, passwd->pw_gid, groups, &num_groups); + } + if (error < 0) + { + g_warning ("Error looking up groups for uid %d: getgrouplist() failed", uid); + goto out; + } for (n = 0; n < num_groups; n++) result = g_list_prepend (result, polkit_unix_group_new (groups[n])); out: - + if (groups) + free(groups); return result; }