Annotation of embedaddon/sudo/plugins/sudoers/alias.c, revision 1.1.1.4

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.1.4 ! misho     134:     HLTQ_TO_TAILQ(&a->members, members, entries);
1.1       misho     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);
1.1.1.4 ! misho     179:     TAILQ_FOREACH_SAFE(m, &a->members, entries, next) {
1.1       misho     180:        if (m->type == COMMAND) {
                    181:                c = (struct sudo_command *) m->name;
                    182:                efree(c->cmnd);
                    183:                efree(c->args);
                    184:        }
                    185:        efree(m->name);
                    186:        efree(m);
                    187:     }
                    188:     efree(a);
1.1.1.2   misho     189: 
                    190:     debug_return;
1.1       misho     191: }
                    192: 
                    193: /*
                    194:  * Find the named alias, remove it from the tree and return it.
                    195:  */
                    196: struct alias *
                    197: alias_remove(char *name, int type)
                    198: {
                    199:     struct rbnode *node;
                    200:     struct alias key;
1.1.1.2   misho     201:     debug_decl(alias_remove, SUDO_DEBUG_ALIAS)
1.1       misho     202: 
                    203:     key.name = name;
                    204:     key.type = type;
                    205:     if ((node = rbfind(aliases, &key)) == NULL) {
                    206:        errno = ENOENT;
                    207:        return NULL;
                    208:     }
1.1.1.2   misho     209:     debug_return_ptr(rbdelete(aliases, node));
1.1       misho     210: }
                    211: 
                    212: void
                    213: init_aliases(void)
                    214: {
1.1.1.2   misho     215:     debug_decl(init_aliases, SUDO_DEBUG_ALIAS)
                    216: 
1.1       misho     217:     if (aliases != NULL)
                    218:        rbdestroy(aliases, alias_free);
                    219:     aliases = rbcreate(alias_compare);
1.1.1.2   misho     220: 
                    221:     debug_return;
1.1       misho     222: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>