Annotation of embedaddon/sudo/plugins/sudoers/group_plugin.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com>
        !             3:  *
        !             4:  * Permission to use, copy, modify, and distribute this software for any
        !             5:  * purpose with or without fee is hereby granted, provided that the above
        !             6:  * copyright notice and this permission notice appear in all copies.
        !             7:  *
        !             8:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
        !             9:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        !            10:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
        !            11:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        !            12:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        !            13:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        !            14:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        !            15:  */
        !            16: 
        !            17: #include <config.h>
        !            18: 
        !            19: #if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
        !            20: 
        !            21: #include <sys/types.h>
        !            22: #include <sys/param.h>
        !            23: #include <sys/stat.h>
        !            24: #include <sys/time.h>
        !            25: #include <stdio.h>
        !            26: #ifdef STDC_HEADERS
        !            27: # include <stdlib.h>
        !            28: # include <stddef.h>
        !            29: #else
        !            30: # ifdef HAVE_STDLIB_H
        !            31: #  include <stdlib.h>
        !            32: # endif
        !            33: #endif /* STDC_HEADERS */
        !            34: #ifdef HAVE_STRING_H
        !            35: # include <string.h>
        !            36: #endif /* HAVE_STRING_H */
        !            37: #ifdef HAVE_STRINGS_H
        !            38: # include <strings.h>
        !            39: #endif /* HAVE_STRINGS_H */
        !            40: #ifdef HAVE_UNISTD_H
        !            41: # include <unistd.h>
        !            42: #endif /* HAVE_UNISTD_H */
        !            43: #if TIME_WITH_SYS_TIME
        !            44: # include <time.h>
        !            45: #endif
        !            46: #ifdef HAVE_DLOPEN
        !            47: # include <dlfcn.h>
        !            48: #else
        !            49: # include "compat/dlfcn.h"
        !            50: #endif
        !            51: #include <ctype.h>
        !            52: #include <errno.h>
        !            53: #include <pwd.h>
        !            54: 
        !            55: #include "sudoers.h"
        !            56: 
        !            57: #ifndef RTLD_GLOBAL
        !            58: # define RTLD_GLOBAL   0
        !            59: #endif
        !            60: 
        !            61: static void *group_handle;
        !            62: static struct sudoers_group_plugin *group_plugin;
        !            63: 
        !            64: /*
        !            65:  * Load the specified plugin and run its init function.
        !            66:  * Returns -1 if unable to open the plugin, else it returns
        !            67:  * the value from the plugin's init function.
        !            68:  */
        !            69: int
        !            70: group_plugin_load(char *plugin_info)
        !            71: {
        !            72:     struct stat sb;
        !            73:     char *args, path[PATH_MAX];
        !            74:     char **argv = NULL;
        !            75:     int len, rc = -1;
        !            76: 
        !            77:     /*
        !            78:      * Fill in .so path and split out args (if any).
        !            79:      */
        !            80:     if ((args = strpbrk(plugin_info, " \t")) != NULL) {
        !            81:        len = snprintf(path, sizeof(path), "%s%.*s",
        !            82:            (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "",
        !            83:            (int)(args - plugin_info), plugin_info);
        !            84:        args++;
        !            85:     } else {
        !            86:        len = snprintf(path, sizeof(path), "%s%s",
        !            87:            (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "", plugin_info);
        !            88:     }
        !            89:     if (len <= 0 || len >= sizeof(path)) {
        !            90:        warningx(_("%s%s: %s"),
        !            91:            (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "", plugin_info,
        !            92:            strerror(ENAMETOOLONG));
        !            93:        goto done;
        !            94:     }
        !            95: 
        !            96:     /* Sanity check plugin path. */
        !            97:     if (stat(path, &sb) != 0) {
        !            98:        warning("%s", path);
        !            99:        goto done;
        !           100:     }
        !           101:     if (sb.st_uid != ROOT_UID) {
        !           102:        warningx(_("%s must be owned by uid %d"), path, ROOT_UID);
        !           103:        goto done;
        !           104:     }
        !           105:     if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
        !           106:        warningx(_("%s must only be writable by owner"), path);
        !           107:        goto done;
        !           108:     }
        !           109: 
        !           110:     /* Open plugin and map in symbol. */
        !           111:     group_handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
        !           112:     if (!group_handle) {
        !           113:        warningx(_("unable to dlopen %s: %s"), path, dlerror());
        !           114:        goto done;
        !           115:     }
        !           116:     group_plugin = dlsym(group_handle, "group_plugin");
        !           117:     if (group_plugin == NULL) {
        !           118:        warningx(_("unable to find symbol \"group_plugin\" in %s"), path);
        !           119:        goto done;
        !           120:     }
        !           121: 
        !           122:     if (GROUP_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
        !           123:        warningx(_("%s: incompatible group plugin major version %d, expected %d"),
        !           124:            path, GROUP_API_VERSION_GET_MAJOR(group_plugin->version),
        !           125:            GROUP_API_VERSION_MAJOR);
        !           126:        goto done;
        !           127:     }
        !           128: 
        !           129:     /*
        !           130:      * Split args into a vector if specified.
        !           131:      */
        !           132:     if (args != NULL) {
        !           133:        int ac = 0, wasblank = TRUE;
        !           134:        char *cp;
        !           135: 
        !           136:         for (cp = args; *cp != '\0'; cp++) {
        !           137:             if (isblank((unsigned char)*cp)) {
        !           138:                 wasblank = TRUE;
        !           139:             } else if (wasblank) {
        !           140:                 wasblank = FALSE;
        !           141:                 ac++;
        !           142:             }
        !           143:         }
        !           144:        if (ac != 0)    {
        !           145:            argv = emalloc2(ac, sizeof(char *));
        !           146:            ac = 0;
        !           147:            for ((cp = strtok(args, " \t")); cp; (cp = strtok(NULL, " \t")))
        !           148:                argv[ac++] = cp;
        !           149:        }
        !           150:     }
        !           151: 
        !           152:     rc = (group_plugin->init)(GROUP_API_VERSION, sudo_printf, argv);
        !           153: 
        !           154: done:
        !           155:     efree(argv);
        !           156: 
        !           157:     if (rc != TRUE) {
        !           158:        if (group_handle != NULL) {
        !           159:            dlclose(group_handle);
        !           160:            group_handle = NULL;
        !           161:            group_plugin = NULL;
        !           162:        }
        !           163:     }
        !           164: 
        !           165:     return rc;
        !           166: }
        !           167: 
        !           168: void
        !           169: group_plugin_unload(void)
        !           170: {
        !           171:     if (group_plugin != NULL) {
        !           172:        (group_plugin->cleanup)();
        !           173:        group_plugin = NULL;
        !           174:     }
        !           175:     if (group_handle != NULL) {
        !           176:        dlclose(group_handle);
        !           177:        group_handle = NULL;
        !           178:     }
        !           179: }
        !           180: 
        !           181: int
        !           182: group_plugin_query(const char *user, const char *group,
        !           183:     const struct passwd *pwd)
        !           184: {
        !           185:     if (group_plugin == NULL)
        !           186:        return FALSE;
        !           187:     return (group_plugin->query)(user, group, pwd);
        !           188: }
        !           189: 
        !           190: #else /* !HAVE_DLOPEN && !HAVE_SHL_LOAD */
        !           191: 
        !           192: /*
        !           193:  * No loadable shared object support.
        !           194:  */
        !           195: 
        !           196: #ifndef FALSE
        !           197: #define FALSE  0
        !           198: #endif
        !           199: 
        !           200: struct passwd;
        !           201: 
        !           202: int
        !           203: group_plugin_load(char *plugin_info)
        !           204: {
        !           205:     return FALSE;
        !           206: }
        !           207: 
        !           208: void
        !           209: group_plugin_unload(void)
        !           210: {
        !           211:     return;
        !           212: }
        !           213: 
        !           214: int
        !           215: group_plugin_query(const char *user, const char *group,
        !           216:     const struct passwd *pwd)
        !           217: {
        !           218:     return FALSE;
        !           219: }
        !           220: 
        !           221: #endif /* HAVE_DLOPEN || HAVE_SHL_LOAD */

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