summaryrefslogtreecommitdiffstats
path: root/dbus/dbus-sysdeps-unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'dbus/dbus-sysdeps-unix.c')
-rw-r--r--dbus/dbus-sysdeps-unix.c65
1 files changed, 50 insertions, 15 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 64d925d9..c96499a6 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -1487,28 +1487,60 @@ fill_user_info (DBusUserInfo *info,
{
struct passwd *p;
int result;
- char buf[1024];
+ size_t buflen;
+ char *buf;
struct passwd p_str;
- p = NULL;
+ /* retrieve maximum needed size for buf */
+ buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
+
+ if (buflen <= 0)
+ buflen = 1024;
+
+ result = -1;
+ while (1)
+ {
+ buf = dbus_malloc (buflen);
+ if (buf == NULL)
+ {
+ dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+ return FALSE;
+ }
+
+ p = NULL;
#ifdef HAVE_POSIX_GETPWNAM_R
- if (uid != DBUS_UID_UNSET)
- result = getpwuid_r (uid, &p_str, buf, sizeof (buf),
- &p);
- else
- result = getpwnam_r (username_c, &p_str, buf, sizeof (buf),
- &p);
+ if (uid != DBUS_UID_UNSET)
+ result = getpwuid_r (uid, &p_str, buf, buflen,
+ &p);
+ else
+ result = getpwnam_r (username_c, &p_str, buf, buflen,
+ &p);
#else
- if (uid != DBUS_UID_UNSET)
- p = getpwuid_r (uid, &p_str, buf, sizeof (buf));
- else
- p = getpwnam_r (username_c, &p_str, buf, sizeof (buf));
- result = 0;
+ if (uid != DBUS_UID_UNSET)
+ p = getpwuid_r (uid, &p_str, buf, buflen);
+ else
+ p = getpwnam_r (username_c, &p_str, buf, buflen);
+ result = 0;
#endif /* !HAVE_POSIX_GETPWNAM_R */
+ //Try a bigger buffer if ERANGE was returned
+ if (result == ERANGE && buflen < 512 * 1024)
+ {
+ dbus_free (buf);
+ buflen *= 2;
+ }
+ else
+ {
+ break;
+ }
+ }
if (result == 0 && p == &p_str)
{
if (!fill_user_info_from_passwd (p, info, error))
- return FALSE;
+ {
+ dbus_free (buf);
+ return FALSE;
+ }
+ dbus_free (buf);
}
else
{
@@ -1516,6 +1548,7 @@ fill_user_info (DBusUserInfo *info,
"User \"%s\" unknown or no memory to allocate password entry\n",
username_c ? username_c : "???");
_dbus_verbose ("User %s unknown\n", username_c ? username_c : "???");
+ dbus_free (buf);
return FALSE;
}
}
@@ -1532,7 +1565,9 @@ fill_user_info (DBusUserInfo *info,
if (p != NULL)
{
if (!fill_user_info_from_passwd (p, info, error))
- return FALSE;
+ {
+ return FALSE;
+ }
}
else
{