summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Reed <ranger@befunk.com>2009-07-13 11:21:08 -0400
committerColin Walters <walters@verbum.org>2009-07-14 15:41:33 -0400
commit8420a5bb5733f30d591ef6bbba8446fc9f42d3a1 (patch)
tree8c542dc84229ee71ff37fb13438d4aed8cbe10a3
parent93023eb6a447bdb640f3435002e65c81a75912d4 (diff)
Bug 14259 - Work around broken getgrouplist on MacOS X
We don't get the number of groups, so allocate an arbitrary larger array. Signed-off-by: Colin Walters <walters@space-ghost.verbum.org> (cherry picked from commit c71403ddde230378e3beffee21a3d1fe6edc9bce)
-rw-r--r--dbus/dbus-sysdeps-unix.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index f1504b79..456d4d5f 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -1591,8 +1591,10 @@ fill_user_info (DBusUserInfo *info,
gid_t *buf;
int buf_count;
int i;
-
- buf_count = 17;
+ int initial_buf_count;
+
+ initial_buf_count = 17;
+ buf_count = initial_buf_count;
buf = dbus_new (gid_t, buf_count);
if (buf == NULL)
{
@@ -1604,7 +1606,25 @@ fill_user_info (DBusUserInfo *info,
info->primary_gid,
buf, &buf_count) < 0)
{
- gid_t *new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
+ gid_t *new;
+ /* Presumed cause of negative return code: buf has insufficient
+ entries to hold the entire group list. The Linux behavior in this
+ case is to pass back the actual number of groups in buf_count, but
+ on Mac OS X 10.5, buf_count is unhelpfully left alone.
+ So as a hack, try to help out a bit by guessing a larger
+ number of groups, within reason.. might still fail, of course,
+ but we can at least print a more informative message. I looked up
+ the "right way" to do this by downloading Apple's own source code
+ for the "id" command, and it turns out that they use an
+ undocumented library function getgrouplist_2 (!) which is not
+ declared in any header in /usr/include (!!). That did not seem
+ like the way to go here.
+ */
+ if (buf_count == initial_buf_count)
+ {
+ buf_count *= 16; /* Retry with an arbitrarily scaled-up array */
+ }
+ new = dbus_realloc (buf, buf_count * sizeof (buf[0]));
if (new == NULL)
{
dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -1617,14 +1637,22 @@ fill_user_info (DBusUserInfo *info,
errno = 0;
if (getgrouplist (username_c, info->primary_gid, buf, &buf_count) < 0)
{
- dbus_set_error (error,
- _dbus_error_from_errno (errno),
- "Failed to get groups for username \"%s\" primary GID "
- DBUS_GID_FORMAT ": %s\n",
- username_c, info->primary_gid,
- _dbus_strerror (errno));
- dbus_free (buf);
- goto failed;
+ if (errno == 0)
+ {
+ _dbus_warn ("It appears that username \"%s\" is in more than %d groups.\nProceeding with just the first %d groups.",
+ username_c, buf_count, buf_count);
+ }
+ else
+ {
+ dbus_set_error (error,
+ _dbus_error_from_errno (errno),
+ "Failed to get groups for username \"%s\" primary GID "
+ DBUS_GID_FORMAT ": %s\n",
+ username_c, info->primary_gid,
+ _dbus_strerror (errno));
+ dbus_free (buf);
+ goto failed;
+ }
}
}