Annotation of embedaddon/sudo/plugins/sudoers/group_plugin.c, revision 1.1.1.2
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: #include <sys/types.h>
20: #include <sys/param.h>
21: #include <sys/stat.h>
22: #include <sys/time.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_STRINGS_H */
38: #ifdef HAVE_UNISTD_H
39: # include <unistd.h>
40: #endif /* HAVE_UNISTD_H */
41: #if TIME_WITH_SYS_TIME
42: # include <time.h>
43: #endif
44: #ifdef HAVE_DLOPEN
45: # include <dlfcn.h>
46: #else
47: # include "compat/dlfcn.h"
48: #endif
49: #include <ctype.h>
50: #include <errno.h>
51: #include <pwd.h>
52:
53: #include "sudoers.h"
54:
55: #ifndef RTLD_GLOBAL
56: # define RTLD_GLOBAL 0
57: #endif
58:
1.1.1.2 ! misho 59: #if defined(HAVE_DLOPEN) || defined(HAVE_SHL_LOAD)
! 60:
1.1 misho 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;
1.1.1.2 ! misho 76: debug_decl(group_plugin_load, SUDO_DEBUG_UTIL)
1.1 misho 77:
78: /*
79: * Fill in .so path and split out args (if any).
80: */
81: if ((args = strpbrk(plugin_info, " \t")) != NULL) {
82: len = snprintf(path, sizeof(path), "%s%.*s",
83: (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "",
84: (int)(args - plugin_info), plugin_info);
85: args++;
86: } else {
87: len = snprintf(path, sizeof(path), "%s%s",
88: (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "", plugin_info);
89: }
90: if (len <= 0 || len >= sizeof(path)) {
91: warningx(_("%s%s: %s"),
92: (*plugin_info != '/') ? _PATH_SUDO_PLUGIN_DIR : "", plugin_info,
93: strerror(ENAMETOOLONG));
94: goto done;
95: }
96:
97: /* Sanity check plugin path. */
98: if (stat(path, &sb) != 0) {
99: warning("%s", path);
100: goto done;
101: }
102: if (sb.st_uid != ROOT_UID) {
103: warningx(_("%s must be owned by uid %d"), path, ROOT_UID);
104: goto done;
105: }
106: if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
107: warningx(_("%s must only be writable by owner"), path);
108: goto done;
109: }
110:
111: /* Open plugin and map in symbol. */
112: group_handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
113: if (!group_handle) {
114: warningx(_("unable to dlopen %s: %s"), path, dlerror());
115: goto done;
116: }
117: group_plugin = dlsym(group_handle, "group_plugin");
118: if (group_plugin == NULL) {
119: warningx(_("unable to find symbol \"group_plugin\" in %s"), path);
120: goto done;
121: }
122:
123: if (GROUP_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
124: warningx(_("%s: incompatible group plugin major version %d, expected %d"),
125: path, GROUP_API_VERSION_GET_MAJOR(group_plugin->version),
126: GROUP_API_VERSION_MAJOR);
127: goto done;
128: }
129:
130: /*
131: * Split args into a vector if specified.
132: */
133: if (args != NULL) {
1.1.1.2 ! misho 134: int ac = 0;
! 135: bool wasblank = true;
1.1 misho 136: char *cp;
137:
138: for (cp = args; *cp != '\0'; cp++) {
139: if (isblank((unsigned char)*cp)) {
1.1.1.2 ! misho 140: wasblank = true;
1.1 misho 141: } else if (wasblank) {
1.1.1.2 ! misho 142: wasblank = false;
1.1 misho 143: ac++;
144: }
145: }
146: if (ac != 0) {
147: argv = emalloc2(ac, sizeof(char *));
148: ac = 0;
149: for ((cp = strtok(args, " \t")); cp; (cp = strtok(NULL, " \t")))
150: argv[ac++] = cp;
151: }
152: }
153:
154: rc = (group_plugin->init)(GROUP_API_VERSION, sudo_printf, argv);
155:
156: done:
157: efree(argv);
158:
1.1.1.2 ! misho 159: if (rc != true) {
1.1 misho 160: if (group_handle != NULL) {
161: dlclose(group_handle);
162: group_handle = NULL;
163: group_plugin = NULL;
164: }
165: }
166:
1.1.1.2 ! misho 167: debug_return_bool(rc);
1.1 misho 168: }
169:
170: void
171: group_plugin_unload(void)
172: {
1.1.1.2 ! misho 173: debug_decl(group_plugin_unload, SUDO_DEBUG_UTIL)
! 174:
1.1 misho 175: if (group_plugin != NULL) {
176: (group_plugin->cleanup)();
177: group_plugin = NULL;
178: }
179: if (group_handle != NULL) {
180: dlclose(group_handle);
181: group_handle = NULL;
182: }
1.1.1.2 ! misho 183: debug_return;
1.1 misho 184: }
185:
186: int
187: group_plugin_query(const char *user, const char *group,
188: const struct passwd *pwd)
189: {
1.1.1.2 ! misho 190: debug_decl(group_plugin_query, SUDO_DEBUG_UTIL)
! 191:
1.1 misho 192: if (group_plugin == NULL)
1.1.1.2 ! misho 193: debug_return_bool(false);
! 194: debug_return_bool((group_plugin->query)(user, group, pwd));
1.1 misho 195: }
196:
197: #else /* !HAVE_DLOPEN && !HAVE_SHL_LOAD */
198:
199: /*
200: * No loadable shared object support.
201: */
202:
203: int
204: group_plugin_load(char *plugin_info)
205: {
1.1.1.2 ! misho 206: debug_decl(group_plugin_load, SUDO_DEBUG_UTIL)
! 207: debug_return_bool(false);
1.1 misho 208: }
209:
210: void
211: group_plugin_unload(void)
212: {
1.1.1.2 ! misho 213: debug_decl(group_plugin_unload, SUDO_DEBUG_UTIL)
! 214: debug_return;
1.1 misho 215: }
216:
217: int
218: group_plugin_query(const char *user, const char *group,
219: const struct passwd *pwd)
220: {
1.1.1.2 ! misho 221: debug_decl(group_plugin_query, SUDO_DEBUG_UTIL)
! 222: debug_return_bool(false);
1.1 misho 223: }
224:
225: #endif /* HAVE_DLOPEN || HAVE_SHL_LOAD */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>