}
/*
- * Take a uid in string form "#123" and return a faked up passwd struct.
+ * Take a user, uid and gid and return a faked up passwd struct.
*/
struct passwd *
-sudo_fakepwnam(const char *user, gid_t gid)
+sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid)
{
struct cache_item *item;
struct passwd *pw;
item = emalloc(len);
zero_bytes(item, sizeof(*item) + sizeof(*pw));
pw = (struct passwd *) ((char *)item + sizeof(*item));
- pw->pw_uid = (uid_t) atoi(user + 1);
+ pw->pw_uid = uid;
pw->pw_gid = gid;
pw->pw_name = (char *)pw + sizeof(struct passwd);
memcpy(pw->pw_name, user, namelen + 1);
return pw;
}
+/*
+ * Take a uid in string form "#123" and return a faked up passwd struct.
+ */
+struct passwd *
+sudo_fakepwnam(const char *user, gid_t gid)
+{
+ uid_t uid;
+
+ uid = (uid_t) atoi(user + 1);
+ return sudo_fakepwnamid(user, uid, gid);
+}
+
void
sudo_setpwent(void)
{
}
#ifdef HAVE_UTMPX_H
-# define GROUPNAME_LEN (sizeof((struct utmpx *)0)->ut_user)
+# define GROUPNAME_LEN (sizeof((struct utmpx *)0)->ut_user + 1)
#else
# ifdef HAVE_STRUCT_UTMP_UT_USER
-# define GROUPNAME_LEN (sizeof((struct utmp *)0)->ut_user)
+# define GROUPNAME_LEN (sizeof((struct utmp *)0)->ut_user + 1)
# else
-# define GROUPNAME_LEN (sizeof((struct utmp *)0)->ut_name)
+# define GROUPNAME_LEN (sizeof((struct utmp *)0)->ut_name + 1)
# endif
#endif /* HAVE_UTMPX_H */
make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids)
{
char *cp;
- size_t i, nsize, ngroups = 0, total, len;
+ size_t i, nsize, ngroups, total, len;
struct cache_item *item;
struct group_list *grlist;
struct group *grp;
+#ifdef HAVE_SETAUTHDB
+ aix_setauthdb((char *) user);
+#endif
+
/* Allocate in one big chunk for easy freeing. */
nsize = strlen(user) + 1;
total = sizeof(struct cache_item) + sizeof(struct group_list) + nsize;
total += sizeof(gid_t *) * ngids;
total += GROUPNAME_LEN * ngids;
+again:
item = emalloc(total);
cp = (char *) item + sizeof(struct cache_item);
/*
* Copy in group list and make pointers relative to space
- * at the end of the buffer. Note that the gids array must come
+ * at the end of the buffer. Note that the groups array must come
* immediately after struct group to guarantee proper alignment.
*/
grlist = (struct group_list *)cp;
zero_bytes(grlist, sizeof(struct group_list));
cp += sizeof(struct group_list);
- grlist->gids = (gid_t *)cp;
- cp += sizeof(gid_t) * ngids;
grlist->groups = (char **)cp;
cp += sizeof(char *) * ngids;
+ grlist->gids = (gid_t *)cp;
+ cp += sizeof(gid_t) * ngids;
/* Set key and datum. */
memcpy(cp, user, nsize);
grlist->gids[i] = gids[i];
grlist->ngids = ngids;
-#ifdef HAVE_SETAUTHDB
- aix_setauthdb((char *) user);
-#endif
/*
- * Resolve group names by ID and store at the end.
+ * Resolve and store group names by ID.
*/
+ ngroups = 0;
for (i = 0; i < ngids; i++) {
if ((grp = sudo_getgrgid(gids[i])) != NULL) {
len = strlen(grp->gr_name) + 1;
- if (cp - (char *)grlist + len > total) {
- void *ptr = erealloc(grlist, total + len + GROUPNAME_LEN);
+ if (cp - (char *)item + len > total) {
total += len + GROUPNAME_LEN;
- cp = (char *)ptr + (cp - (char *)grlist);
- grlist = ptr;
+ efree(item);
+ gr_delref(grp);
+ goto again;
}
memcpy(cp, grp->gr_name, len);
grlist->groups[ngroups++] = cp;