Return to alias.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers |
1.1 ! misho 1: /* ! 2: * Copyright (c) 2004-2005, 2007-2011 ! 3: * Todd C. Miller <Todd.Miller@courtesan.com> ! 4: * ! 5: * Permission to use, copy, modify, and distribute this software for any ! 6: * purpose with or without fee is hereby granted, provided that the above ! 7: * copyright notice and this permission notice appear in all copies. ! 8: * ! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ! 10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! 11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ! 12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! 13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! 14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! 15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ! 16: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ! 17: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! 18: */ ! 19: ! 20: #include <config.h> ! 21: ! 22: #include <sys/types.h> ! 23: #include <sys/param.h> ! 24: #include <stdio.h> ! 25: #ifdef STDC_HEADERS ! 26: # include <stdlib.h> ! 27: # include <stddef.h> ! 28: #else ! 29: # ifdef HAVE_STDLIB_H ! 30: # include <stdlib.h> ! 31: # endif ! 32: #endif /* STDC_HEADERS */ ! 33: #ifdef HAVE_STRING_H ! 34: # include <string.h> ! 35: #endif /* HAVE_STRING_H */ ! 36: #ifdef HAVE_STRINGS_H ! 37: # include <strings.h> ! 38: #endif /* HAVE_STRING_H */ ! 39: #ifdef HAVE_UNISTD_H ! 40: # include <unistd.h> ! 41: #endif /* HAVE_UNISTD_H */ ! 42: #include <errno.h> ! 43: ! 44: #include "sudoers.h" ! 45: #include "parse.h" ! 46: #include "redblack.h" ! 47: #include <gram.h> ! 48: ! 49: /* ! 50: * Globals ! 51: */ ! 52: struct rbtree *aliases; ! 53: unsigned int alias_seqno; ! 54: ! 55: /* ! 56: * Comparison function for the red-black tree. ! 57: * Aliases are sorted by name with the type used as a tie-breaker. ! 58: */ ! 59: int ! 60: alias_compare(const void *v1, const void *v2) ! 61: { ! 62: const struct alias *a1 = (const struct alias *)v1; ! 63: const struct alias *a2 = (const struct alias *)v2; ! 64: int res; ! 65: ! 66: if (v1 == NULL) ! 67: res = -1; ! 68: else if (v2 == NULL) ! 69: res = 1; ! 70: else if ((res = strcmp(a1->name, a2->name)) == 0) ! 71: res = a1->type - a2->type; ! 72: return res; ! 73: } ! 74: ! 75: /* ! 76: * Search the tree for an alias with the specified name and type. ! 77: * Returns a pointer to the alias structure or NULL if not found. ! 78: */ ! 79: struct alias * ! 80: alias_find(char *name, int type) ! 81: { ! 82: struct alias key; ! 83: struct rbnode *node; ! 84: struct alias *a = NULL; ! 85: ! 86: key.name = name; ! 87: key.type = type; ! 88: if ((node = rbfind(aliases, &key)) != NULL) { ! 89: /* ! 90: * Compare the global sequence number with the one stored ! 91: * in the alias. If they match then we've seen this alias ! 92: * before and found a loop. ! 93: */ ! 94: a = node->data; ! 95: if (a->seqno == alias_seqno) { ! 96: errno = ELOOP; ! 97: return NULL; ! 98: } ! 99: a->seqno = alias_seqno; ! 100: } else { ! 101: errno = ENOENT; ! 102: } ! 103: return a; ! 104: } ! 105: ! 106: /* ! 107: * Add an alias to the aliases redblack tree. ! 108: * Returns NULL on success and an error string on failure. ! 109: */ ! 110: char * ! 111: alias_add(char *name, int type, struct member *members) ! 112: { ! 113: static char errbuf[512]; ! 114: struct alias *a; ! 115: ! 116: a = emalloc(sizeof(*a)); ! 117: a->name = name; ! 118: a->type = type; ! 119: a->seqno = 0; ! 120: list2tq(&a->members, members); ! 121: if (rbinsert(aliases, a)) { ! 122: snprintf(errbuf, sizeof(errbuf), _("Alias `%s' already defined"), name); ! 123: alias_free(a); ! 124: return errbuf; ! 125: } ! 126: return NULL; ! 127: } ! 128: ! 129: /* ! 130: * Apply a function to each alias entry and pass in a cookie. ! 131: */ ! 132: void ! 133: alias_apply(int (*func)(void *, void *), void *cookie) ! 134: { ! 135: rbapply(aliases, func, cookie, inorder); ! 136: } ! 137: ! 138: /* ! 139: * Returns TRUE if there are no aliases, else FALSE. ! 140: */ ! 141: int ! 142: no_aliases(void) ! 143: { ! 144: return rbisempty(aliases); ! 145: } ! 146: ! 147: /* ! 148: * Free memory used by an alias struct and its members. ! 149: */ ! 150: void ! 151: alias_free(void *v) ! 152: { ! 153: struct alias *a = (struct alias *)v; ! 154: struct member *m; ! 155: struct sudo_command *c; ! 156: void *next; ! 157: ! 158: efree(a->name); ! 159: for (m = a->members.first; m != NULL; m = next) { ! 160: next = m->next; ! 161: if (m->type == COMMAND) { ! 162: c = (struct sudo_command *) m->name; ! 163: efree(c->cmnd); ! 164: efree(c->args); ! 165: } ! 166: efree(m->name); ! 167: efree(m); ! 168: } ! 169: efree(a); ! 170: } ! 171: ! 172: /* ! 173: * Find the named alias, remove it from the tree and return it. ! 174: */ ! 175: struct alias * ! 176: alias_remove(char *name, int type) ! 177: { ! 178: struct rbnode *node; ! 179: struct alias key; ! 180: ! 181: key.name = name; ! 182: key.type = type; ! 183: if ((node = rbfind(aliases, &key)) == NULL) { ! 184: errno = ENOENT; ! 185: return NULL; ! 186: } ! 187: return rbdelete(aliases, node); ! 188: } ! 189: ! 190: void ! 191: init_aliases(void) ! 192: { ! 193: if (aliases != NULL) ! 194: rbdestroy(aliases, alias_free); ! 195: aliases = rbcreate(alias_compare); ! 196: }