Use non-exiting allocators in the redblack tree and fix the fallout.
Also switch to non-exiting allocators in affected code blocks.
This commit is contained in:
@@ -139,16 +139,29 @@ sudo_getpwuid(uid_t uid)
|
||||
#endif
|
||||
item = sudo_make_pwitem(uid, NULL);
|
||||
if (item == NULL) {
|
||||
item = sudo_ecalloc(1, sizeof(*item));
|
||||
item = calloc(1, sizeof(*item));
|
||||
if (item == NULL) {
|
||||
sudo_warnx(U_("unable to cache uid %u, out of memory"),
|
||||
(unsigned int) uid);
|
||||
debug_return_ptr(NULL);
|
||||
}
|
||||
item->refcnt = 1;
|
||||
item->k.uid = uid;
|
||||
/* item->d.pw = NULL; */
|
||||
}
|
||||
if (rbinsert(pwcache_byuid, item) != NULL) {
|
||||
switch (rbinsert(pwcache_byuid, item, NULL)) {
|
||||
case 1:
|
||||
/* should not happen */
|
||||
sudo_warnx(U_("unable to cache uid %u, already exists"),
|
||||
(unsigned int) uid);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache uid %u, out of memory"),
|
||||
(unsigned int) uid);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_SETAUTHDB
|
||||
aix_restoreauthdb();
|
||||
@@ -183,16 +196,27 @@ sudo_getpwnam(const char *name)
|
||||
item = sudo_make_pwitem((uid_t)-1, name);
|
||||
if (item == NULL) {
|
||||
len = strlen(name) + 1;
|
||||
item = sudo_ecalloc(1, sizeof(*item) + len);
|
||||
item = calloc(1, sizeof(*item) + len);
|
||||
if (item == NULL) {
|
||||
sudo_warnx(U_("unable to cache user %s, out of memory"), name);
|
||||
debug_return_ptr(NULL);
|
||||
}
|
||||
item->refcnt = 1;
|
||||
item->k.name = (char *) item + sizeof(*item);
|
||||
memcpy(item->k.name, name, len);
|
||||
/* item->d.pw = NULL; */
|
||||
}
|
||||
if (rbinsert(pwcache_byname, item) != NULL) {
|
||||
switch (rbinsert(pwcache_byname, item, NULL)) {
|
||||
case 1:
|
||||
/* should not happen */
|
||||
sudo_warnx(U_("unable to cache user %s, already exists"), name);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache user %s, out of memory"), name);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
#ifdef HAVE_SETAUTHDB
|
||||
aix_restoreauthdb();
|
||||
@@ -253,15 +277,16 @@ sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home,
|
||||
item->refcnt = 1;
|
||||
item->d.pw = pw;
|
||||
if (i == 0) {
|
||||
/* Store by uid if it doesn't already exist. */
|
||||
/* Store by uid. */
|
||||
item->k.uid = pw->pw_uid;
|
||||
pwcache = pwcache_byuid;
|
||||
} else {
|
||||
/* Store by name if it doesn't already exist. */
|
||||
/* Store by name. */
|
||||
item->k.name = pw->pw_name;
|
||||
pwcache = pwcache_byname;
|
||||
}
|
||||
if ((node = rbinsert(pwcache, item)) != NULL) {
|
||||
switch (rbinsert(pwcache, item, &node)) {
|
||||
case 1:
|
||||
/* Already exists. */
|
||||
item = node->data;
|
||||
if (item->d.pw == NULL) {
|
||||
@@ -272,6 +297,12 @@ sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home,
|
||||
/* Good entry, discard our fake one. */
|
||||
sudo_efree(pwitem);
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache user %s, out of memory"), user);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
item->refcnt++;
|
||||
@@ -297,18 +328,21 @@ sudo_fakepwnam(const char *user, gid_t gid)
|
||||
debug_return_ptr(sudo_mkpwent(user, uid, gid, NULL, NULL));
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
sudo_setpwent(void)
|
||||
{
|
||||
debug_decl(sudo_setpwent, SUDOERS_DEBUG_NSS)
|
||||
|
||||
setpwent();
|
||||
if (pwcache_byuid == NULL)
|
||||
pwcache_byuid = rbcreate(cmp_pwuid);
|
||||
if (pwcache_byname == NULL)
|
||||
pwcache_byname = rbcreate(cmp_pwnam);
|
||||
if (pwcache_byuid == NULL || pwcache_byname == NULL)
|
||||
debug_return_int(-1);
|
||||
|
||||
debug_return;
|
||||
setpwent();
|
||||
|
||||
debug_return_int(0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -403,11 +437,19 @@ sudo_getgrgid(gid_t gid)
|
||||
item->k.gid = gid;
|
||||
/* item->d.gr = NULL; */
|
||||
}
|
||||
if (rbinsert(grcache_bygid, item) != NULL) {
|
||||
switch (rbinsert(grcache_bygid, item, NULL)) {
|
||||
case 1:
|
||||
/* should not happen */
|
||||
sudo_warnx(U_("unable to cache gid %u, already exists"),
|
||||
(unsigned int) gid);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache gid %u, out of memory"),
|
||||
(unsigned int) gid);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
done:
|
||||
item->refcnt++;
|
||||
@@ -442,10 +484,17 @@ sudo_getgrnam(const char *name)
|
||||
memcpy(item->k.name, name, len);
|
||||
/* item->d.gr = NULL; */
|
||||
}
|
||||
if (rbinsert(grcache_byname, item) != NULL) {
|
||||
switch (rbinsert(grcache_byname, item, NULL)) {
|
||||
case 1:
|
||||
/* should not happen */
|
||||
sudo_warnx(U_("unable to cache group %s, already exists"), name);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache group %s, out of memory"), name);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
done:
|
||||
item->refcnt++;
|
||||
@@ -497,7 +546,8 @@ sudo_fakegrnam(const char *group)
|
||||
gritem->cache.k.name = gr->gr_name;
|
||||
grcache = grcache_byname;
|
||||
}
|
||||
if ((node = rbinsert(grcache, item)) != NULL) {
|
||||
switch (rbinsert(grcache, item, &node)) {
|
||||
case 1:
|
||||
/* Already exists. */
|
||||
item = node->data;
|
||||
if (item->d.gr == NULL) {
|
||||
@@ -508,6 +558,12 @@ sudo_fakegrnam(const char *group)
|
||||
/* Good entry, discard our fake one. */
|
||||
sudo_efree(gritem);
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache group %s, out of memory"), group);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
item->refcnt++;
|
||||
@@ -542,20 +598,23 @@ sudo_grlist_delref(struct group_list *grlist)
|
||||
debug_return;
|
||||
}
|
||||
|
||||
void
|
||||
int
|
||||
sudo_setgrent(void)
|
||||
{
|
||||
debug_decl(sudo_setgrent, SUDOERS_DEBUG_NSS)
|
||||
|
||||
setgrent();
|
||||
if (grcache_bygid == NULL)
|
||||
grcache_bygid = rbcreate(cmp_grgid);
|
||||
if (grcache_byname == NULL)
|
||||
grcache_byname = rbcreate(cmp_grnam);
|
||||
if (grlist_cache == NULL)
|
||||
grlist_cache = rbcreate(cmp_grnam);
|
||||
if (grcache_bygid == NULL || grcache_byname == NULL || grlist_cache == NULL)
|
||||
debug_return_int(-1);
|
||||
|
||||
debug_return;
|
||||
setgrent();
|
||||
|
||||
debug_return_int(0);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -616,11 +675,19 @@ sudo_get_grlist(const struct passwd *pw)
|
||||
memcpy(item->k.name, pw->pw_name, len);
|
||||
/* item->d.grlist = NULL; */
|
||||
}
|
||||
if (rbinsert(grlist_cache, item) != NULL) {
|
||||
switch (rbinsert(grlist_cache, item, NULL)) {
|
||||
case 1:
|
||||
/* should not happen */
|
||||
sudo_warnx(U_("unable to cache group list for %s, already exists"),
|
||||
pw->pw_name);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
case -1:
|
||||
/* can't cache item, just return it */
|
||||
sudo_warnx(U_("unable to cache group list for %s, out of memory"),
|
||||
pw->pw_name);
|
||||
item->refcnt = 0;
|
||||
break;
|
||||
}
|
||||
done:
|
||||
item->refcnt++;
|
||||
@@ -643,10 +710,17 @@ sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids)
|
||||
sudo_warnx(U_("unable to parse groups for %s"), pw->pw_name);
|
||||
debug_return_int(-1);
|
||||
}
|
||||
if (rbinsert(grlist_cache, item) != NULL) {
|
||||
switch (rbinsert(grlist_cache, item, NULL)) {
|
||||
case 1:
|
||||
sudo_warnx(U_("unable to cache group list for %s, already exists"),
|
||||
pw->pw_name);
|
||||
sudo_grlist_delref_item(item);
|
||||
break;
|
||||
case -1:
|
||||
sudo_warnx(U_("unable to cache group list for %s, out of memory"),
|
||||
pw->pw_name);
|
||||
sudo_grlist_delref_item(item);
|
||||
debug_return_int(-1);
|
||||
}
|
||||
}
|
||||
debug_return_int(0);
|
||||
|
Reference in New Issue
Block a user