File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / group_plugin.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:12:54 2014 UTC (10 years, 2 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_10p3_0, v1_8_10p3, HEAD
sudo v 1.8.10p3

    1: /*
    2:  * Copyright (c) 2010-2013 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: #include <sys/types.h>
   20: #include <sys/stat.h>
   21: #include <sys/time.h>
   22: #include <stdio.h>
   23: #ifdef STDC_HEADERS
   24: # include <stdlib.h>
   25: # include <stddef.h>
   26: #else
   27: # ifdef HAVE_STDLIB_H
   28: #  include <stdlib.h>
   29: # endif
   30: #endif /* STDC_HEADERS */
   31: #ifdef HAVE_STRING_H
   32: # include <string.h>
   33: #endif /* HAVE_STRING_H */
   34: #ifdef HAVE_STRINGS_H
   35: # include <strings.h>
   36: #endif /* HAVE_STRINGS_H */
   37: #ifdef HAVE_UNISTD_H
   38: # include <unistd.h>
   39: #endif /* HAVE_UNISTD_H */
   40: #ifdef TIME_WITH_SYS_TIME
   41: # include <time.h>
   42: #endif
   43: #include <ctype.h>
   44: #include <errno.h>
   45: #include <pwd.h>
   46: 
   47: #include "sudoers.h"
   48: #include "sudo_dso.h"
   49: 
   50: #if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
   51: 
   52: static void *group_handle;
   53: static struct sudoers_group_plugin *group_plugin;
   54: 
   55: /*
   56:  * Load the specified plugin and run its init function.
   57:  * Returns -1 if unable to open the plugin, else it returns
   58:  * the value from the plugin's init function.
   59:  */
   60: int
   61: group_plugin_load(char *plugin_info)
   62: {
   63:     struct stat sb;
   64:     char *args, path[PATH_MAX];
   65:     char **argv = NULL;
   66:     int len, rc = -1;
   67:     debug_decl(group_plugin_load, SUDO_DEBUG_UTIL)
   68: 
   69:     /*
   70:      * Fill in .so path and split out args (if any).
   71:      */
   72:     if ((args = strpbrk(plugin_info, " \t")) != NULL) {
   73: 	len = snprintf(path, sizeof(path), "%s%.*s",
   74: 	    (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "",
   75: 	    (int)(args - plugin_info), plugin_info);
   76: 	args++;
   77:     } else {
   78: 	len = snprintf(path, sizeof(path), "%s%s",
   79: 	    (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "", plugin_info);
   80:     }
   81:     if (len <= 0 || (size_t)len >= sizeof(path)) {
   82: 	errno = ENAMETOOLONG;
   83: 	warning("%s%s",
   84: 	    (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "", plugin_info);
   85: 	goto done;
   86:     }
   87: 
   88:     /* Sanity check plugin path. */
   89:     if (stat(path, &sb) != 0) {
   90: 	warning("%s", path);
   91: 	goto done;
   92:     }
   93:     if (sb.st_uid != ROOT_UID) {
   94: 	warningx(U_("%s must be owned by uid %d"), path, ROOT_UID);
   95: 	goto done;
   96:     }
   97:     if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
   98: 	warningx(U_("%s must only be writable by owner"), path);
   99: 	goto done;
  100:     }
  101: 
  102:     /* Open plugin and map in symbol. */
  103:     group_handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
  104:     if (!group_handle) {
  105: 	warningx(U_("unable to load %s: %s"), path, sudo_dso_strerror());
  106: 	goto done;
  107:     }
  108:     group_plugin = sudo_dso_findsym(group_handle, "group_plugin");
  109:     if (group_plugin == NULL) {
  110: 	warningx(U_("unable to find symbol \"group_plugin\" in %s"), path);
  111: 	goto done;
  112:     }
  113: 
  114:     if (GROUP_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
  115: 	warningx(U_("%s: incompatible group plugin major version %d, expected %d"),
  116: 	    path, GROUP_API_VERSION_GET_MAJOR(group_plugin->version),
  117: 	    GROUP_API_VERSION_MAJOR);
  118: 	goto done;
  119:     }
  120: 
  121:     /*
  122:      * Split args into a vector if specified.
  123:      */
  124:     if (args != NULL) {
  125: 	int ac = 0;
  126: 	bool wasblank = true;
  127: 	char *cp;
  128: 
  129:         for (cp = args; *cp != '\0'; cp++) {
  130:             if (isblank((unsigned char)*cp)) {
  131:                 wasblank = true;
  132:             } else if (wasblank) {
  133:                 wasblank = false;
  134:                 ac++;
  135:             }
  136:         }
  137: 	if (ac != 0) 	{
  138: 	    argv = emalloc2(ac, sizeof(char *));
  139: 	    ac = 0;
  140: 	    for ((cp = strtok(args, " \t")); cp; (cp = strtok(NULL, " \t")))
  141: 		argv[ac++] = cp;
  142: 	}
  143:     }
  144: 
  145:     rc = (group_plugin->init)(GROUP_API_VERSION, sudo_printf, argv);
  146: 
  147: done:
  148:     efree(argv);
  149: 
  150:     if (rc != true) {
  151: 	if (group_handle != NULL) {
  152: 	    sudo_dso_unload(group_handle);
  153: 	    group_handle = NULL;
  154: 	    group_plugin = NULL;
  155: 	}
  156:     }
  157: 
  158:     debug_return_bool(rc);
  159: }
  160: 
  161: void
  162: group_plugin_unload(void)
  163: {
  164:     debug_decl(group_plugin_unload, SUDO_DEBUG_UTIL)
  165: 
  166:     if (group_plugin != NULL) {
  167: 	(group_plugin->cleanup)();
  168: 	group_plugin = NULL;
  169:     }
  170:     if (group_handle != NULL) {
  171: 	sudo_dso_unload(group_handle);
  172: 	group_handle = NULL;
  173:     }
  174:     debug_return;
  175: }
  176: 
  177: int
  178: group_plugin_query(const char *user, const char *group,
  179:     const struct passwd *pwd)
  180: {
  181:     debug_decl(group_plugin_query, SUDO_DEBUG_UTIL)
  182: 
  183:     if (group_plugin == NULL)
  184: 	debug_return_bool(false);
  185:     debug_return_bool((group_plugin->query)(user, group, pwd));
  186: }
  187: 
  188: #else /* !HAVE_DLOPEN && !HAVE_SHL_LOAD */
  189: 
  190: /*
  191:  * No loadable shared object support.
  192:  */
  193: 
  194: int
  195: group_plugin_load(char *plugin_info)
  196: {
  197:     debug_decl(group_plugin_load, SUDO_DEBUG_UTIL)
  198:     debug_return_bool(false);
  199: }
  200: 
  201: void
  202: group_plugin_unload(void)
  203: {
  204:     debug_decl(group_plugin_unload, SUDO_DEBUG_UTIL)
  205:     debug_return;
  206: }
  207: 
  208: int
  209: group_plugin_query(const char *user, const char *group,
  210:     const struct passwd *pwd)
  211: {
  212:     debug_decl(group_plugin_query, SUDO_DEBUG_UTIL)
  213:     debug_return_bool(false);
  214: }
  215: 
  216: #endif /* HAVE_DLOPEN || HAVE_SHL_LOAD */

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