don't. */
#undef HAVE_DECL_GETDOMAINNAME
+/* Define to 1 if you have the declaration of `getgrouplist_2', and to 0 if
+ you don't. */
+#undef HAVE_DECL_GETGROUPLIST_2
+
/* Define to 1 if you have the declaration of `getresuid', and to 0 if you
don't. */
#undef HAVE_DECL_GETRESUID
/* Define to 1 if you have the `getgrouplist' function. */
#undef HAVE_GETGROUPLIST
+/* Define to 1 if you have the `getgrouplist_2' function. */
+#undef HAVE_GETGROUPLIST_2
+
/* Define to 1 if your system has a working `getgroups' function. */
#undef HAVE_GETGROUPS
fi
RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
+ # Undocumented API that dynamically allocates the groups.
+ AC_CHECK_FUNCS([getgrouplist_2], [AC_CHECK_DECLS([getgrouplist_2])])
+
# We need to force a flat namespace to make libc
# symbol hooking work like it does on ELF.
AX_CHECK_LINK_FLAG([-Wl,-force_flat_namespace], [AX_APPEND_FLAG([-Wl,-force_flat_namespace], [SUDO_LDFLAGS])])
# undef getgrouplist
# define getgrouplist(_a, _b, _c, _d) sudo_getgrouplist((_a), (_b), (_c), (_d))
#endif /* GETGROUPLIST */
+#if defined(HAVE_GETGROUPLIST_2) && !defined(HAVE_DECL_GETGROUPLIST_2)
+int getgrouplist_2(const char *name, gid_t basegid, gid_t **groups);
+#endif /* HAVE_GETGROUPLIST_2 && !HAVE_DECL_GETGROUPLIST_2 */
#ifndef HAVE_GETLINE
__dso_public ssize_t sudo_getline(char **bufp, size_t *bufsizep, FILE *fp);
# undef getline
}
(void)getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids);
} else {
+#ifdef HAVE_GETGROUPLIST_2
+ ngids = getgrouplist_2(pw->pw_name, pw->pw_gid, &gids);
+ if (ngids == -1) {
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "unable to allocate memory");
+ debug_return_ptr(NULL);
+ }
+#else
ngids = (int)sysconf(_SC_NGROUPS_MAX) * 2;
if (ngids < 0)
ngids = NGROUPS_MAX * 2;
if (getgrouplist(pw->pw_name, pw->pw_gid, gids, &ngids) == -1)
ngids = -1;
}
+#endif /* HAVE_GETGROUPLIST_2 */
}
}
if (ngids <= 0) {
/*
* Allocate space for groups and fill in using getgrouplist()
* for when we cannot (or don't want to) use getgroups().
+ * Returns 0 on success and -1 on failure.
*/
static int
fill_group_list(struct user_details *ud, int system_maxgroups)
(void)getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
ret = 0;
} else {
+#ifdef HAVE_GETGROUPLIST_2
+ ud->groups = NULL;
+ ud->ngroups = getgrouplist_2(ud->username, ud->gid, &ud->groups);
+ if (ud->ngroups != -1)
+ ret = 0;
+#else
/*
* It is possible to belong to more groups in the group database
* than NGROUPS_MAX. We start off with NGROUPS_MAX * 4 entries
}
ret = getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups);
}
+#endif /* HAVE_GETGROUPLIST_2 */
}
done:
debug_return_int(ret);