- sizeof("/") /* pw_dir */ + sizeof(_PATH_BSHELL));
- zero_bytes(pw, sizeof(struct passwd));
- pw->pw_uid = (uid_t) atoi(user + 1);
- pw->pw_gid = gid;
- pw->pw_name = (char *)pw + sizeof(struct passwd);
- memcpy(pw->pw_name, user, len + 1);
- pw->pw_passwd = pw->pw_name + len + 1;
- memcpy(pw->pw_passwd, "*", 2);
- pw->pw_gecos = pw->pw_passwd + 2;
- pw->pw_gecos[0] = '\0';
- pw->pw_dir = pw->pw_gecos + 1;
- memcpy(pw->pw_dir, "/", 2);
- pw->pw_shell = pw->pw_dir + 2;
- memcpy(pw->pw_shell, _PATH_BSHELL, sizeof(_PATH_BSHELL));
-
- /* Store by uid and by name, overwriting cached version. */
- if ((node = rbinsert(pwcache_byuid, pw)) != NULL) {
- efree(node->data);
- node->data = (void *) pw;
- }
- if ((node = rbinsert(pwcache_byname, pw)) != NULL) {
- efree(node->data);
- node->data = (void *) pw;
- }
- return(pw);
-}
-
-/*
- * Take a gid in string form "#123" and return a faked up group struct.
- */
-struct group *
-sudo_fakegrnam(group)
- const char *group;
-{
- struct group *gr;
- struct rbnode *node;
- size_t len;
-
- len = strlen(group);
- gr = emalloc(sizeof(struct group) + len + 1);
- zero_bytes(gr, sizeof(struct group));
- gr->gr_gid = (gid_t) atoi(group + 1);
- gr->gr_name = (char *)gr + sizeof(struct group);
- strlcpy(gr->gr_name, group, len + 1);
-
- /* Store by gid and by name, overwriting cached version. */
- if ((node = rbinsert(grcache_bygid, gr)) != NULL) {
- efree(node->data);
- node->data = (void *) gr;
- }
- if ((node = rbinsert(grcache_byname, gr)) != NULL) {
- efree(node->data);
- node->data = (void *) gr;
+ sizeof("/") /* pw_dir */ + sizeof(_PATH_BSHELL);
+
+ for (i = 0; i < 2; i++) {
+ 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_gid = gid;
+ pw->pw_name = (char *)pw + sizeof(struct passwd);
+ memcpy(pw->pw_name, user, namelen + 1);
+ pw->pw_passwd = pw->pw_name + namelen + 1;
+ memcpy(pw->pw_passwd, "*", 2);
+ pw->pw_gecos = pw->pw_passwd + 2;
+ pw->pw_gecos[0] = '\0';
+ pw->pw_dir = pw->pw_gecos + 1;
+ memcpy(pw->pw_dir, "/", 2);
+ pw->pw_shell = pw->pw_dir + 2;
+ memcpy(pw->pw_shell, _PATH_BSHELL, sizeof(_PATH_BSHELL));
+
+ item->refcnt = 1;
+ item->d.pw = pw;
+ if (i == 0) {
+ /* Store by uid, overwriting cached version. */
+ item->k.uid = pw->pw_uid;
+ if ((node = rbinsert(pwcache_byuid, item)) != NULL) {
+ pw_delref_item(node->data);
+ node->data = item;
+ }
+ } else {
+ /* Store by name, overwriting cached version. */
+ item->k.name = pw->pw_name;
+ if ((node = rbinsert(pwcache_byname, item)) != NULL) {
+ pw_delref_item(node->data);
+ node->data = item;
+ }
+ }