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 <sascha-pgp@silbe.org>

---
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;
 }
 
