Annotation of embedaddon/sudo/plugins/sudoers/alias.c, revision 1.1
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: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>