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:
@@ -132,10 +132,15 @@ alias_add(char *name, int type, struct member *members)
|
|||||||
a->type = type;
|
a->type = type;
|
||||||
/* a->used = false; */
|
/* a->used = false; */
|
||||||
HLTQ_TO_TAILQ(&a->members, members, entries);
|
HLTQ_TO_TAILQ(&a->members, members, entries);
|
||||||
if (rbinsert(aliases, a)) {
|
switch (rbinsert(aliases, a, NULL)) {
|
||||||
|
case 1:
|
||||||
snprintf(errbuf, sizeof(errbuf), N_("Alias `%s' already defined"), name);
|
snprintf(errbuf, sizeof(errbuf), N_("Alias `%s' already defined"), name);
|
||||||
alias_free(a);
|
alias_free(a);
|
||||||
debug_return_str(errbuf);
|
debug_return_str(errbuf);
|
||||||
|
case -1:
|
||||||
|
strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf));
|
||||||
|
alias_free(a);
|
||||||
|
debug_return_str(errbuf);
|
||||||
}
|
}
|
||||||
debug_return_str(NULL);
|
debug_return_str(NULL);
|
||||||
}
|
}
|
||||||
@@ -209,7 +214,7 @@ alias_remove(char *name, int type)
|
|||||||
debug_return_ptr(rbdelete(aliases, node));
|
debug_return_ptr(rbdelete(aliases, node));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
init_aliases(void)
|
init_aliases(void)
|
||||||
{
|
{
|
||||||
debug_decl(init_aliases, SUDOERS_DEBUG_ALIAS)
|
debug_decl(init_aliases, SUDOERS_DEBUG_ALIAS)
|
||||||
@@ -218,5 +223,5 @@ init_aliases(void)
|
|||||||
rbdestroy(aliases, alias_free);
|
rbdestroy(aliases, alias_free);
|
||||||
aliases = rbcreate(alias_compare);
|
aliases = rbcreate(alias_compare);
|
||||||
|
|
||||||
debug_return;
|
debug_return_bool(aliases != NULL);
|
||||||
}
|
}
|
||||||
|
@@ -844,12 +844,13 @@ add_userspec(struct member *members, struct privilege *privs)
|
|||||||
* Free up space used by data structures from a previous parser run and sets
|
* Free up space used by data structures from a previous parser run and sets
|
||||||
* the current sudoers file to path.
|
* the current sudoers file to path.
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
init_parser(const char *path, bool quiet)
|
init_parser(const char *path, bool quiet)
|
||||||
{
|
{
|
||||||
struct member_list *binding;
|
struct member_list *binding;
|
||||||
struct defaults *d, *d_next;
|
struct defaults *d, *d_next;
|
||||||
struct userspec *us, *us_next;
|
struct userspec *us, *us_next;
|
||||||
|
bool rval = true;
|
||||||
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
|
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) {
|
TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) {
|
||||||
@@ -954,21 +955,31 @@ init_parser(const char *path, bool quiet)
|
|||||||
}
|
}
|
||||||
TAILQ_INIT(&defaults);
|
TAILQ_INIT(&defaults);
|
||||||
|
|
||||||
init_aliases();
|
|
||||||
|
|
||||||
init_lexer();
|
init_lexer();
|
||||||
|
|
||||||
sudo_efree(sudoers);
|
if (!init_aliases()) {
|
||||||
sudoers = path ? sudo_estrdup(path) : NULL;
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
rval = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sudoers);
|
||||||
|
if (path != NULL) {
|
||||||
|
if ((sudoers = strdup(path)) == NULL) {
|
||||||
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
rval = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sudoers = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
parse_error = false;
|
parse_error = false;
|
||||||
errorlineno = -1;
|
errorlineno = -1;
|
||||||
errorfile = sudoers;
|
errorfile = sudoers;
|
||||||
sudoers_warnings = !quiet;
|
sudoers_warnings = !quiet;
|
||||||
|
|
||||||
debug_return;
|
debug_return_bool(rval);
|
||||||
}
|
}
|
||||||
#line 919 "gram.c"
|
#line 930 "gram.c"
|
||||||
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
|
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
|
||||||
#if defined(__cplusplus) || defined(__STDC__)
|
#if defined(__cplusplus) || defined(__STDC__)
|
||||||
static int yygrowstack(void)
|
static int yygrowstack(void)
|
||||||
@@ -1877,7 +1888,7 @@ case 113:
|
|||||||
yyval.member = new_member(yyvsp[0].string, WORD);
|
yyval.member = new_member(yyvsp[0].string, WORD);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#line 1828 "gram.c"
|
#line 1839 "gram.c"
|
||||||
}
|
}
|
||||||
yyssp -= yym;
|
yyssp -= yym;
|
||||||
yystate = *yyssp;
|
yystate = *yyssp;
|
||||||
|
@@ -818,12 +818,13 @@ add_userspec(struct member *members, struct privilege *privs)
|
|||||||
* Free up space used by data structures from a previous parser run and sets
|
* Free up space used by data structures from a previous parser run and sets
|
||||||
* the current sudoers file to path.
|
* the current sudoers file to path.
|
||||||
*/
|
*/
|
||||||
void
|
bool
|
||||||
init_parser(const char *path, bool quiet)
|
init_parser(const char *path, bool quiet)
|
||||||
{
|
{
|
||||||
struct member_list *binding;
|
struct member_list *binding;
|
||||||
struct defaults *d, *d_next;
|
struct defaults *d, *d_next;
|
||||||
struct userspec *us, *us_next;
|
struct userspec *us, *us_next;
|
||||||
|
bool rval = true;
|
||||||
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
|
debug_decl(init_parser, SUDOERS_DEBUG_PARSER)
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) {
|
TAILQ_FOREACH_SAFE(us, &userspecs, entries, us_next) {
|
||||||
@@ -928,17 +929,27 @@ init_parser(const char *path, bool quiet)
|
|||||||
}
|
}
|
||||||
TAILQ_INIT(&defaults);
|
TAILQ_INIT(&defaults);
|
||||||
|
|
||||||
init_aliases();
|
|
||||||
|
|
||||||
init_lexer();
|
init_lexer();
|
||||||
|
|
||||||
sudo_efree(sudoers);
|
if (!init_aliases()) {
|
||||||
sudoers = path ? sudo_estrdup(path) : NULL;
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
rval = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(sudoers);
|
||||||
|
if (path != NULL) {
|
||||||
|
if ((sudoers = strdup(path)) == NULL) {
|
||||||
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
rval = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sudoers = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
parse_error = false;
|
parse_error = false;
|
||||||
errorlineno = -1;
|
errorlineno = -1;
|
||||||
errorfile = sudoers;
|
errorfile = sudoers;
|
||||||
sudoers_warnings = !quiet;
|
sudoers_warnings = !quiet;
|
||||||
|
|
||||||
debug_return;
|
debug_return_bool(rval);
|
||||||
}
|
}
|
||||||
|
@@ -587,8 +587,10 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
|||||||
|
|
||||||
bindtextdomain("sudoers", LOCALEDIR);
|
bindtextdomain("sudoers", LOCALEDIR);
|
||||||
|
|
||||||
sudo_setpwent();
|
if (sudo_setpwent() == -1 || sudo_setgrent() == -1) {
|
||||||
sudo_setgrent();
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
debug_return_int(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the debug subsystem. */
|
/* Initialize the debug subsystem. */
|
||||||
for (cur = settings; *cur != NULL; cur++) {
|
for (cur = settings; *cur != NULL; cur++) {
|
||||||
|
@@ -192,10 +192,10 @@ struct alias *alias_remove(char *name, int type);
|
|||||||
void alias_apply(int (*func)(void *, void *), void *cookie);
|
void alias_apply(int (*func)(void *, void *), void *cookie);
|
||||||
void alias_free(void *a);
|
void alias_free(void *a);
|
||||||
void alias_put(struct alias *a);
|
void alias_put(struct alias *a);
|
||||||
void init_aliases(void);
|
bool init_aliases(void);
|
||||||
|
|
||||||
/* gram.c */
|
/* gram.c */
|
||||||
void init_parser(const char *, bool);
|
bool init_parser(const char *, bool);
|
||||||
|
|
||||||
/* match_addr.c */
|
/* match_addr.c */
|
||||||
bool addr_matches(char *n);
|
bool addr_matches(char *n);
|
||||||
|
@@ -139,16 +139,29 @@ sudo_getpwuid(uid_t uid)
|
|||||||
#endif
|
#endif
|
||||||
item = sudo_make_pwitem(uid, NULL);
|
item = sudo_make_pwitem(uid, NULL);
|
||||||
if (item == 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->refcnt = 1;
|
||||||
item->k.uid = uid;
|
item->k.uid = uid;
|
||||||
/* item->d.pw = NULL; */
|
/* item->d.pw = NULL; */
|
||||||
}
|
}
|
||||||
if (rbinsert(pwcache_byuid, item) != NULL) {
|
switch (rbinsert(pwcache_byuid, item, NULL)) {
|
||||||
|
case 1:
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
sudo_warnx(U_("unable to cache uid %u, already exists"),
|
sudo_warnx(U_("unable to cache uid %u, already exists"),
|
||||||
(unsigned int) uid);
|
(unsigned int) uid);
|
||||||
item->refcnt = 0;
|
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
|
#ifdef HAVE_SETAUTHDB
|
||||||
aix_restoreauthdb();
|
aix_restoreauthdb();
|
||||||
@@ -183,16 +196,27 @@ sudo_getpwnam(const char *name)
|
|||||||
item = sudo_make_pwitem((uid_t)-1, name);
|
item = sudo_make_pwitem((uid_t)-1, name);
|
||||||
if (item == NULL) {
|
if (item == NULL) {
|
||||||
len = strlen(name) + 1;
|
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->refcnt = 1;
|
||||||
item->k.name = (char *) item + sizeof(*item);
|
item->k.name = (char *) item + sizeof(*item);
|
||||||
memcpy(item->k.name, name, len);
|
memcpy(item->k.name, name, len);
|
||||||
/* item->d.pw = NULL; */
|
/* item->d.pw = NULL; */
|
||||||
}
|
}
|
||||||
if (rbinsert(pwcache_byname, item) != NULL) {
|
switch (rbinsert(pwcache_byname, item, NULL)) {
|
||||||
|
case 1:
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
sudo_warnx(U_("unable to cache user %s, already exists"), name);
|
sudo_warnx(U_("unable to cache user %s, already exists"), name);
|
||||||
item->refcnt = 0;
|
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
|
#ifdef HAVE_SETAUTHDB
|
||||||
aix_restoreauthdb();
|
aix_restoreauthdb();
|
||||||
@@ -253,15 +277,16 @@ sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home,
|
|||||||
item->refcnt = 1;
|
item->refcnt = 1;
|
||||||
item->d.pw = pw;
|
item->d.pw = pw;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
/* Store by uid if it doesn't already exist. */
|
/* Store by uid. */
|
||||||
item->k.uid = pw->pw_uid;
|
item->k.uid = pw->pw_uid;
|
||||||
pwcache = pwcache_byuid;
|
pwcache = pwcache_byuid;
|
||||||
} else {
|
} else {
|
||||||
/* Store by name if it doesn't already exist. */
|
/* Store by name. */
|
||||||
item->k.name = pw->pw_name;
|
item->k.name = pw->pw_name;
|
||||||
pwcache = pwcache_byname;
|
pwcache = pwcache_byname;
|
||||||
}
|
}
|
||||||
if ((node = rbinsert(pwcache, item)) != NULL) {
|
switch (rbinsert(pwcache, item, &node)) {
|
||||||
|
case 1:
|
||||||
/* Already exists. */
|
/* Already exists. */
|
||||||
item = node->data;
|
item = node->data;
|
||||||
if (item->d.pw == NULL) {
|
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. */
|
/* Good entry, discard our fake one. */
|
||||||
sudo_efree(pwitem);
|
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++;
|
item->refcnt++;
|
||||||
@@ -297,18 +328,21 @@ sudo_fakepwnam(const char *user, gid_t gid)
|
|||||||
debug_return_ptr(sudo_mkpwent(user, uid, gid, NULL, NULL));
|
debug_return_ptr(sudo_mkpwent(user, uid, gid, NULL, NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
sudo_setpwent(void)
|
sudo_setpwent(void)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_setpwent, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_setpwent, SUDOERS_DEBUG_NSS)
|
||||||
|
|
||||||
setpwent();
|
|
||||||
if (pwcache_byuid == NULL)
|
if (pwcache_byuid == NULL)
|
||||||
pwcache_byuid = rbcreate(cmp_pwuid);
|
pwcache_byuid = rbcreate(cmp_pwuid);
|
||||||
if (pwcache_byname == NULL)
|
if (pwcache_byname == NULL)
|
||||||
pwcache_byname = rbcreate(cmp_pwnam);
|
pwcache_byname = rbcreate(cmp_pwnam);
|
||||||
|
if (pwcache_byuid == NULL || pwcache_byname == NULL)
|
||||||
|
debug_return_int(-1);
|
||||||
|
|
||||||
debug_return;
|
setpwent();
|
||||||
|
|
||||||
|
debug_return_int(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -403,11 +437,19 @@ sudo_getgrgid(gid_t gid)
|
|||||||
item->k.gid = gid;
|
item->k.gid = gid;
|
||||||
/* item->d.gr = NULL; */
|
/* item->d.gr = NULL; */
|
||||||
}
|
}
|
||||||
if (rbinsert(grcache_bygid, item) != NULL) {
|
switch (rbinsert(grcache_bygid, item, NULL)) {
|
||||||
|
case 1:
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
sudo_warnx(U_("unable to cache gid %u, already exists"),
|
sudo_warnx(U_("unable to cache gid %u, already exists"),
|
||||||
(unsigned int) gid);
|
(unsigned int) gid);
|
||||||
item->refcnt = 0;
|
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:
|
done:
|
||||||
item->refcnt++;
|
item->refcnt++;
|
||||||
@@ -442,10 +484,17 @@ sudo_getgrnam(const char *name)
|
|||||||
memcpy(item->k.name, name, len);
|
memcpy(item->k.name, name, len);
|
||||||
/* item->d.gr = NULL; */
|
/* item->d.gr = NULL; */
|
||||||
}
|
}
|
||||||
if (rbinsert(grcache_byname, item) != NULL) {
|
switch (rbinsert(grcache_byname, item, NULL)) {
|
||||||
|
case 1:
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
sudo_warnx(U_("unable to cache group %s, already exists"), name);
|
sudo_warnx(U_("unable to cache group %s, already exists"), name);
|
||||||
item->refcnt = 0;
|
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:
|
done:
|
||||||
item->refcnt++;
|
item->refcnt++;
|
||||||
@@ -497,7 +546,8 @@ sudo_fakegrnam(const char *group)
|
|||||||
gritem->cache.k.name = gr->gr_name;
|
gritem->cache.k.name = gr->gr_name;
|
||||||
grcache = grcache_byname;
|
grcache = grcache_byname;
|
||||||
}
|
}
|
||||||
if ((node = rbinsert(grcache, item)) != NULL) {
|
switch (rbinsert(grcache, item, &node)) {
|
||||||
|
case 1:
|
||||||
/* Already exists. */
|
/* Already exists. */
|
||||||
item = node->data;
|
item = node->data;
|
||||||
if (item->d.gr == NULL) {
|
if (item->d.gr == NULL) {
|
||||||
@@ -508,6 +558,12 @@ sudo_fakegrnam(const char *group)
|
|||||||
/* Good entry, discard our fake one. */
|
/* Good entry, discard our fake one. */
|
||||||
sudo_efree(gritem);
|
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++;
|
item->refcnt++;
|
||||||
@@ -542,20 +598,23 @@ sudo_grlist_delref(struct group_list *grlist)
|
|||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
sudo_setgrent(void)
|
sudo_setgrent(void)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_setgrent, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_setgrent, SUDOERS_DEBUG_NSS)
|
||||||
|
|
||||||
setgrent();
|
|
||||||
if (grcache_bygid == NULL)
|
if (grcache_bygid == NULL)
|
||||||
grcache_bygid = rbcreate(cmp_grgid);
|
grcache_bygid = rbcreate(cmp_grgid);
|
||||||
if (grcache_byname == NULL)
|
if (grcache_byname == NULL)
|
||||||
grcache_byname = rbcreate(cmp_grnam);
|
grcache_byname = rbcreate(cmp_grnam);
|
||||||
if (grlist_cache == NULL)
|
if (grlist_cache == NULL)
|
||||||
grlist_cache = rbcreate(cmp_grnam);
|
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
|
void
|
||||||
@@ -616,11 +675,19 @@ sudo_get_grlist(const struct passwd *pw)
|
|||||||
memcpy(item->k.name, pw->pw_name, len);
|
memcpy(item->k.name, pw->pw_name, len);
|
||||||
/* item->d.grlist = NULL; */
|
/* item->d.grlist = NULL; */
|
||||||
}
|
}
|
||||||
if (rbinsert(grlist_cache, item) != NULL) {
|
switch (rbinsert(grlist_cache, item, NULL)) {
|
||||||
|
case 1:
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
sudo_warnx(U_("unable to cache group list for %s, already exists"),
|
sudo_warnx(U_("unable to cache group list for %s, already exists"),
|
||||||
pw->pw_name);
|
pw->pw_name);
|
||||||
item->refcnt = 0;
|
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:
|
done:
|
||||||
item->refcnt++;
|
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);
|
sudo_warnx(U_("unable to parse groups for %s"), pw->pw_name);
|
||||||
debug_return_int(-1);
|
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"),
|
sudo_warnx(U_("unable to cache group list for %s, already exists"),
|
||||||
pw->pw_name);
|
pw->pw_name);
|
||||||
sudo_grlist_delref_item(item);
|
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);
|
debug_return_int(0);
|
||||||
|
@@ -82,7 +82,8 @@ static void rbdestroy_int(struct rbtree *, struct rbnode *, void (*)(void *));
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a red black tree struct using the specified compare routine.
|
* Create a red black tree struct using the specified compare routine.
|
||||||
* Allocates and returns the initialized (empty) tree.
|
* Allocates and returns the initialized (empty) tree or NULL if
|
||||||
|
* memory cannot be allocated.
|
||||||
*/
|
*/
|
||||||
struct rbtree *
|
struct rbtree *
|
||||||
rbcreate(int (*compar)(const void *, const void*))
|
rbcreate(int (*compar)(const void *, const void*))
|
||||||
@@ -90,24 +91,25 @@ rbcreate(int (*compar)(const void *, const void*))
|
|||||||
struct rbtree *tree;
|
struct rbtree *tree;
|
||||||
debug_decl(rbcreate, SUDOERS_DEBUG_RBTREE)
|
debug_decl(rbcreate, SUDOERS_DEBUG_RBTREE)
|
||||||
|
|
||||||
tree = sudo_emalloc(sizeof(*tree));
|
if ((tree = malloc(sizeof(*tree))) != NULL) {
|
||||||
tree->compar = compar;
|
tree->compar = compar;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We use a self-referencing sentinel node called nil to simplify the
|
* We use a self-referencing sentinel node called nil to simplify the
|
||||||
* code by avoiding the need to check for NULL pointers.
|
* code by avoiding the need to check for NULL pointers.
|
||||||
*/
|
*/
|
||||||
tree->nil.left = tree->nil.right = tree->nil.parent = &tree->nil;
|
tree->nil.left = tree->nil.right = tree->nil.parent = &tree->nil;
|
||||||
tree->nil.color = black;
|
tree->nil.color = black;
|
||||||
tree->nil.data = NULL;
|
tree->nil.data = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Similarly, the fake root node keeps us from having to worry
|
* Similarly, the fake root node keeps us from having to worry
|
||||||
* about splitting the root.
|
* about splitting the root.
|
||||||
*/
|
*/
|
||||||
tree->root.left = tree->root.right = tree->root.parent = &tree->nil;
|
tree->root.left = tree->root.right = tree->root.parent = &tree->nil;
|
||||||
tree->root.color = black;
|
tree->root.color = black;
|
||||||
tree->root.data = NULL;
|
tree->root.data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
debug_return_ptr(tree);
|
debug_return_ptr(tree);
|
||||||
}
|
}
|
||||||
@@ -166,11 +168,11 @@ rotate_right(struct rbtree *tree, struct rbnode *node)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert data pointer into a redblack tree.
|
* Insert data pointer into a redblack tree.
|
||||||
* Returns a NULL pointer on success. If a node matching "data"
|
* Returns a 0 on success, 1 if a node matching "data" already exists
|
||||||
* already exists, a pointer to the existant node is returned.
|
* (filling in "existing" if not NULL), or -1 on malloc() failure.
|
||||||
*/
|
*/
|
||||||
struct rbnode *
|
int
|
||||||
rbinsert(struct rbtree *tree, void *data)
|
rbinsert(struct rbtree *tree, void *data, struct rbnode **existing)
|
||||||
{
|
{
|
||||||
struct rbnode *node = rbfirst(tree);
|
struct rbnode *node = rbfirst(tree);
|
||||||
struct rbnode *parent = rbroot(tree);
|
struct rbnode *parent = rbroot(tree);
|
||||||
@@ -180,12 +182,17 @@ rbinsert(struct rbtree *tree, void *data)
|
|||||||
/* Find correct insertion point. */
|
/* Find correct insertion point. */
|
||||||
while (node != rbnil(tree)) {
|
while (node != rbnil(tree)) {
|
||||||
parent = node;
|
parent = node;
|
||||||
if ((res = tree->compar(data, node->data)) == 0)
|
if ((res = tree->compar(data, node->data)) == 0) {
|
||||||
debug_return_ptr(node);
|
if (existing != NULL)
|
||||||
|
*existing = node;
|
||||||
|
debug_return_int(1);
|
||||||
|
}
|
||||||
node = res < 0 ? node->left : node->right;
|
node = res < 0 ? node->left : node->right;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = sudo_emalloc(sizeof(*node));
|
node = malloc(sizeof(*node));
|
||||||
|
if (node == NULL)
|
||||||
|
debug_return_int(-1);
|
||||||
node->data = data;
|
node->data = data;
|
||||||
node->left = node->right = rbnil(tree);
|
node->left = node->right = rbnil(tree);
|
||||||
node->parent = parent;
|
node->parent = parent;
|
||||||
@@ -255,7 +262,7 @@ rbinsert(struct rbtree *tree, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
rbfirst(tree)->color = black; /* first node is always black */
|
rbfirst(tree)->color = black; /* first node is always black */
|
||||||
debug_return_ptr(NULL);
|
debug_return_int(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -341,13 +348,13 @@ rbdestroy_int(struct rbtree *tree, struct rbnode *node, void (*destroy)(void *))
|
|||||||
rbdestroy_int(tree, node->right, destroy);
|
rbdestroy_int(tree, node->right, destroy);
|
||||||
if (destroy != NULL)
|
if (destroy != NULL)
|
||||||
destroy(node->data);
|
destroy(node->data);
|
||||||
sudo_efree(node);
|
free(node);
|
||||||
}
|
}
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Destroy the specified tree, calling the destructor destroy
|
* Destroy the specified tree, calling the destructor "destroy"
|
||||||
* for each node and then freeing the tree itself.
|
* for each node and then freeing the tree itself.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@@ -355,7 +362,7 @@ rbdestroy(struct rbtree *tree, void (*destroy)(void *))
|
|||||||
{
|
{
|
||||||
debug_decl(rbdestroy, SUDOERS_DEBUG_RBTREE)
|
debug_decl(rbdestroy, SUDOERS_DEBUG_RBTREE)
|
||||||
rbdestroy_int(tree, rbfirst(tree), destroy);
|
rbdestroy_int(tree, rbfirst(tree), destroy);
|
||||||
sudo_efree(tree);
|
free(tree);
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,7 +51,7 @@ void *rbdelete(struct rbtree *, struct rbnode *);
|
|||||||
int rbapply_node(struct rbtree *, struct rbnode *,
|
int rbapply_node(struct rbtree *, struct rbnode *,
|
||||||
int (*)(void *, void *), void *, enum rbtraversal);
|
int (*)(void *, void *), void *, enum rbtraversal);
|
||||||
struct rbnode *rbfind(struct rbtree *, void *);
|
struct rbnode *rbfind(struct rbtree *, void *);
|
||||||
struct rbnode *rbinsert(struct rbtree *, void *);
|
int rbinsert(struct rbtree *, void *, struct rbnode **);
|
||||||
struct rbtree *rbcreate(int (*)(const void *, const void *));
|
struct rbtree *rbcreate(int (*)(const void *, const void *));
|
||||||
void rbdestroy(struct rbtree *, void (*)(void *));
|
void rbdestroy(struct rbtree *, void (*)(void *));
|
||||||
|
|
||||||
|
@@ -124,8 +124,10 @@ sudoers_policy_init(void *info, char * const envp[])
|
|||||||
|
|
||||||
bindtextdomain("sudoers", LOCALEDIR);
|
bindtextdomain("sudoers", LOCALEDIR);
|
||||||
|
|
||||||
sudo_setpwent();
|
if (sudo_setpwent() == -1 || sudo_setgrent() == -1) {
|
||||||
sudo_setgrent();
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
debug_return_int(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Register fatal/fatalx callback. */
|
/* Register fatal/fatalx callback. */
|
||||||
sudo_fatal_callback_register(sudoers_cleanup);
|
sudo_fatal_callback_register(sudoers_cleanup);
|
||||||
|
@@ -303,8 +303,8 @@ void sudo_grlist_delref(struct group_list *);
|
|||||||
void sudo_pw_addref(struct passwd *);
|
void sudo_pw_addref(struct passwd *);
|
||||||
void sudo_pw_delref(struct passwd *);
|
void sudo_pw_delref(struct passwd *);
|
||||||
int sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids);
|
int sudo_set_grlist(struct passwd *pw, char * const *groups, char * const *gids);
|
||||||
void sudo_setgrent(void);
|
int sudo_setgrent(void);
|
||||||
void sudo_setpwent(void);
|
int sudo_setpwent(void);
|
||||||
void sudo_setspent(void);
|
void sudo_setspent(void);
|
||||||
|
|
||||||
/* timestr.c */
|
/* timestr.c */
|
||||||
|
@@ -193,8 +193,8 @@ main(int argc, char *argv[])
|
|||||||
setgrfile(grfile);
|
setgrfile(grfile);
|
||||||
if (pwfile)
|
if (pwfile)
|
||||||
setpwfile(pwfile);
|
setpwfile(pwfile);
|
||||||
sudo_setpwent();
|
if (sudo_setpwent() == -1 || sudo_setgrent() == -1)
|
||||||
sudo_setgrent();
|
sudo_fatalx(U_("unable to allocate memory"));
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
if (!dflag)
|
if (!dflag)
|
||||||
|
@@ -222,8 +222,8 @@ main(int argc, char *argv[])
|
|||||||
if (argc - optind != 0)
|
if (argc - optind != 0)
|
||||||
usage(1);
|
usage(1);
|
||||||
|
|
||||||
sudo_setpwent();
|
if (sudo_setpwent() == -1 || sudo_setgrent() == -1)
|
||||||
sudo_setgrent();
|
sudo_fatalx(U_("unable to allocate memory"));
|
||||||
|
|
||||||
/* Mock up a fake sudo_user struct. */
|
/* Mock up a fake sudo_user struct. */
|
||||||
user_cmnd = user_base = "";
|
user_cmnd = user_base = "";
|
||||||
@@ -1106,7 +1106,8 @@ alias_remove_recursive(char *name, int type)
|
|||||||
rval = false;
|
rval = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rbinsert(alias_freelist, a);
|
if (rbinsert(alias_freelist, a, NULL) != 0)
|
||||||
|
rval = false;
|
||||||
}
|
}
|
||||||
debug_return_bool(rval);
|
debug_return_bool(rval);
|
||||||
}
|
}
|
||||||
@@ -1172,6 +1173,10 @@ check_aliases(bool strict, bool quiet)
|
|||||||
debug_decl(check_aliases, SUDOERS_DEBUG_ALIAS)
|
debug_decl(check_aliases, SUDOERS_DEBUG_ALIAS)
|
||||||
|
|
||||||
alias_freelist = rbcreate(alias_compare);
|
alias_freelist = rbcreate(alias_compare);
|
||||||
|
if (alias_freelist == NULL) {
|
||||||
|
sudo_warnx(U_("unable to allocate memory"));
|
||||||
|
debug_return_int(-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Forward check. */
|
/* Forward check. */
|
||||||
TAILQ_FOREACH(us, &userspecs, entries) {
|
TAILQ_FOREACH(us, &userspecs, entries) {
|
||||||
|
Reference in New Issue
Block a user