--- embedaddon/sudo/plugins/sudoers/alias.c 2012/02/21 16:23:02 1.1.1.1 +++ embedaddon/sudo/plugins/sudoers/alias.c 2014/06/15 16:12:54 1.1.1.4 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005, 2007-2011 + * Copyright (c) 2004-2005, 2007-2013 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -20,7 +20,6 @@ #include #include -#include #include #ifdef STDC_HEADERS # include @@ -50,7 +49,6 @@ * Globals */ struct rbtree *aliases; -unsigned int alias_seqno; /* * Comparison function for the red-black tree. @@ -62,6 +60,7 @@ alias_compare(const void *v1, const void *v2) const struct alias *a1 = (const struct alias *)v1; const struct alias *a2 = (const struct alias *)v2; int res; + debug_decl(alias_compare, SUDO_DEBUG_ALIAS) if (v1 == NULL) res = -1; @@ -69,41 +68,55 @@ alias_compare(const void *v1, const void *v2) res = 1; else if ((res = strcmp(a1->name, a2->name)) == 0) res = a1->type - a2->type; - return res; + debug_return_int(res); } /* * Search the tree for an alias with the specified name and type. * Returns a pointer to the alias structure or NULL if not found. + * Caller is responsible for calling alias_put() on the returned + * alias to mark it as unused. */ struct alias * -alias_find(char *name, int type) +alias_get(char *name, int type) { struct alias key; struct rbnode *node; struct alias *a = NULL; + debug_decl(alias_get, SUDO_DEBUG_ALIAS) key.name = name; key.type = type; if ((node = rbfind(aliases, &key)) != NULL) { /* - * Compare the global sequence number with the one stored - * in the alias. If they match then we've seen this alias - * before and found a loop. + * Check whether this alias is already in use. + * If so, we've detected a loop. If not, set the flag, + * which the caller should clear with a call to alias_put(). */ a = node->data; - if (a->seqno == alias_seqno) { + if (a->used) { errno = ELOOP; - return NULL; + debug_return_ptr(NULL); } - a->seqno = alias_seqno; + a->used = true; } else { errno = ENOENT; } - return a; + debug_return_ptr(a); } /* + * Clear the "used" flag in an alias once the caller is done with it. + */ +void +alias_put(struct alias *a) +{ + debug_decl(alias_put, SUDO_DEBUG_ALIAS) + a->used = false; + debug_return; +} + +/* * Add an alias to the aliases redblack tree. * Returns NULL on success and an error string on failure. */ @@ -112,18 +125,19 @@ alias_add(char *name, int type, struct member *members { static char errbuf[512]; struct alias *a; + debug_decl(alias_add, SUDO_DEBUG_ALIAS) - a = emalloc(sizeof(*a)); + a = ecalloc(1, sizeof(*a)); a->name = name; a->type = type; - a->seqno = 0; - list2tq(&a->members, members); + /* a->used = false; */ + HLTQ_TO_TAILQ(&a->members, members, entries); if (rbinsert(aliases, a)) { - snprintf(errbuf, sizeof(errbuf), _("Alias `%s' already defined"), name); + snprintf(errbuf, sizeof(errbuf), N_("Alias `%s' already defined"), name); alias_free(a); - return errbuf; + debug_return_str(errbuf); } - return NULL; + debug_return_str(NULL); } /* @@ -132,16 +146,21 @@ alias_add(char *name, int type, struct member *members void alias_apply(int (*func)(void *, void *), void *cookie) { + debug_decl(alias_apply, SUDO_DEBUG_ALIAS) + rbapply(aliases, func, cookie, inorder); + + debug_return; } /* - * Returns TRUE if there are no aliases, else FALSE. + * Returns true if there are no aliases, else false. */ -int +bool no_aliases(void) { - return rbisempty(aliases); + debug_decl(no_aliases, SUDO_DEBUG_ALIAS) + debug_return_bool(rbisempty(aliases)); } /* @@ -154,10 +173,10 @@ alias_free(void *v) struct member *m; struct sudo_command *c; void *next; + debug_decl(alias_free, SUDO_DEBUG_ALIAS) efree(a->name); - for (m = a->members.first; m != NULL; m = next) { - next = m->next; + TAILQ_FOREACH_SAFE(m, &a->members, entries, next) { if (m->type == COMMAND) { c = (struct sudo_command *) m->name; efree(c->cmnd); @@ -167,6 +186,8 @@ alias_free(void *v) efree(m); } efree(a); + + debug_return; } /* @@ -177,6 +198,7 @@ alias_remove(char *name, int type) { struct rbnode *node; struct alias key; + debug_decl(alias_remove, SUDO_DEBUG_ALIAS) key.name = name; key.type = type; @@ -184,13 +206,17 @@ alias_remove(char *name, int type) errno = ENOENT; return NULL; } - return rbdelete(aliases, node); + debug_return_ptr(rbdelete(aliases, node)); } void init_aliases(void) { + debug_decl(init_aliases, SUDO_DEBUG_ALIAS) + if (aliases != NULL) rbdestroy(aliases, alias_free); aliases = rbcreate(alias_compare); + + debug_return; }