Annotation of embedaddon/sudo/plugins/sudoers/alias.c, revision 1.1.1.3
1.1 misho 1: /*
1.1.1.3 ! misho 2: * Copyright (c) 2004-2005, 2007-2013
1.1 misho 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 <stdio.h>
24: #ifdef STDC_HEADERS
25: # include <stdlib.h>
26: # include <stddef.h>
27: #else
28: # ifdef HAVE_STDLIB_H
29: # include <stdlib.h>
30: # endif
31: #endif /* STDC_HEADERS */
32: #ifdef HAVE_STRING_H
33: # include <string.h>
34: #endif /* HAVE_STRING_H */
35: #ifdef HAVE_STRINGS_H
36: # include <strings.h>
37: #endif /* HAVE_STRING_H */
38: #ifdef HAVE_UNISTD_H
39: # include <unistd.h>
40: #endif /* HAVE_UNISTD_H */
41: #include <errno.h>
42:
43: #include "sudoers.h"
44: #include "parse.h"
45: #include "redblack.h"
46: #include <gram.h>
47:
48: /*
49: * Globals
50: */
51: struct rbtree *aliases;
52:
53: /*
54: * Comparison function for the red-black tree.
55: * Aliases are sorted by name with the type used as a tie-breaker.
56: */
57: int
58: alias_compare(const void *v1, const void *v2)
59: {
60: const struct alias *a1 = (const struct alias *)v1;
61: const struct alias *a2 = (const struct alias *)v2;
62: int res;
1.1.1.2 misho 63: debug_decl(alias_compare, SUDO_DEBUG_ALIAS)
1.1 misho 64:
65: if (v1 == NULL)
66: res = -1;
67: else if (v2 == NULL)
68: res = 1;
69: else if ((res = strcmp(a1->name, a2->name)) == 0)
70: res = a1->type - a2->type;
1.1.1.2 misho 71: debug_return_int(res);
1.1 misho 72: }
73:
74: /*
75: * Search the tree for an alias with the specified name and type.
76: * Returns a pointer to the alias structure or NULL if not found.
1.1.1.3 ! misho 77: * Caller is responsible for calling alias_put() on the returned
! 78: * alias to mark it as unused.
1.1 misho 79: */
80: struct alias *
1.1.1.3 ! misho 81: alias_get(char *name, int type)
1.1 misho 82: {
83: struct alias key;
84: struct rbnode *node;
85: struct alias *a = NULL;
1.1.1.3 ! misho 86: debug_decl(alias_get, SUDO_DEBUG_ALIAS)
1.1 misho 87:
88: key.name = name;
89: key.type = type;
90: if ((node = rbfind(aliases, &key)) != NULL) {
91: /*
1.1.1.3 ! misho 92: * Check whether this alias is already in use.
! 93: * If so, we've detected a loop. If not, set the flag,
! 94: * which the caller should clear with a call to alias_put().
1.1 misho 95: */
96: a = node->data;
1.1.1.3 ! misho 97: if (a->used) {
1.1 misho 98: errno = ELOOP;
1.1.1.2 misho 99: debug_return_ptr(NULL);
1.1 misho 100: }
1.1.1.3 ! misho 101: a->used = true;
1.1 misho 102: } else {
103: errno = ENOENT;
104: }
1.1.1.2 misho 105: debug_return_ptr(a);
1.1 misho 106: }
107:
108: /*
1.1.1.3 ! misho 109: * Clear the "used" flag in an alias once the caller is done with it.
! 110: */
! 111: void
! 112: alias_put(struct alias *a)
! 113: {
! 114: debug_decl(alias_put, SUDO_DEBUG_ALIAS)
! 115: a->used = false;
! 116: debug_return;
! 117: }
! 118:
! 119: /*
1.1 misho 120: * Add an alias to the aliases redblack tree.
121: * Returns NULL on success and an error string on failure.
122: */
123: char *
124: alias_add(char *name, int type, struct member *members)
125: {
126: static char errbuf[512];
127: struct alias *a;
1.1.1.2 misho 128: debug_decl(alias_add, SUDO_DEBUG_ALIAS)
1.1 misho 129:
1.1.1.2 misho 130: a = ecalloc(1, sizeof(*a));
1.1 misho 131: a->name = name;
132: a->type = type;
1.1.1.3 ! misho 133: /* a->used = false; */
1.1 misho 134: list2tq(&a->members, members);
135: if (rbinsert(aliases, a)) {
1.1.1.3 ! misho 136: snprintf(errbuf, sizeof(errbuf), N_("Alias `%s' already defined"), name);
1.1 misho 137: alias_free(a);
1.1.1.2 misho 138: debug_return_str(errbuf);
1.1 misho 139: }
1.1.1.2 misho 140: debug_return_str(NULL);
1.1 misho 141: }
142:
143: /*
144: * Apply a function to each alias entry and pass in a cookie.
145: */
146: void
147: alias_apply(int (*func)(void *, void *), void *cookie)
148: {
1.1.1.2 misho 149: debug_decl(alias_apply, SUDO_DEBUG_ALIAS)
150:
1.1 misho 151: rbapply(aliases, func, cookie, inorder);
1.1.1.2 misho 152:
153: debug_return;
1.1 misho 154: }
155:
156: /*
1.1.1.2 misho 157: * Returns true if there are no aliases, else false.
1.1 misho 158: */
1.1.1.2 misho 159: bool
1.1 misho 160: no_aliases(void)
161: {
1.1.1.2 misho 162: debug_decl(no_aliases, SUDO_DEBUG_ALIAS)
163: debug_return_bool(rbisempty(aliases));
1.1 misho 164: }
165:
166: /*
167: * Free memory used by an alias struct and its members.
168: */
169: void
170: alias_free(void *v)
171: {
172: struct alias *a = (struct alias *)v;
173: struct member *m;
174: struct sudo_command *c;
175: void *next;
1.1.1.2 misho 176: debug_decl(alias_free, SUDO_DEBUG_ALIAS)
1.1 misho 177:
178: efree(a->name);
179: for (m = a->members.first; m != NULL; m = next) {
180: next = m->next;
181: if (m->type == COMMAND) {
182: c = (struct sudo_command *) m->name;
183: efree(c->cmnd);
184: efree(c->args);
185: }
186: efree(m->name);
187: efree(m);
188: }
189: efree(a);
1.1.1.2 misho 190:
191: debug_return;
1.1 misho 192: }
193:
194: /*
195: * Find the named alias, remove it from the tree and return it.
196: */
197: struct alias *
198: alias_remove(char *name, int type)
199: {
200: struct rbnode *node;
201: struct alias key;
1.1.1.2 misho 202: debug_decl(alias_remove, SUDO_DEBUG_ALIAS)
1.1 misho 203:
204: key.name = name;
205: key.type = type;
206: if ((node = rbfind(aliases, &key)) == NULL) {
207: errno = ENOENT;
208: return NULL;
209: }
1.1.1.2 misho 210: debug_return_ptr(rbdelete(aliases, node));
1.1 misho 211: }
212:
213: void
214: init_aliases(void)
215: {
1.1.1.2 misho 216: debug_decl(init_aliases, SUDO_DEBUG_ALIAS)
217:
1.1 misho 218: if (aliases != NULL)
219: rbdestroy(aliases, alias_free);
220: aliases = rbcreate(alias_compare);
1.1.1.2 misho 221:
222: debug_return;
1.1 misho 223: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>