2 * Copyright (c) 2010-2013 Todd C. Miller <Todd.Miller@sudo.ws>
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.
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.
18 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
19 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22 #include <sys/types.h>
35 #include "sudo_plugin.h"
37 __dso_public int main(int argc, char *argv[]);
40 * Simple driver to test sudoer group plugins.
41 * usage: plugin_test [-p "plugin.so plugin_args ..."] user:group ...
44 static void *group_handle;
45 static struct sudoers_group_plugin *group_plugin;
48 plugin_printf(int msg_type, const char *fmt, ...)
54 case SUDO_CONV_INFO_MSG:
57 case SUDO_CONV_ERROR_MSG:
66 vfprintf(fp, fmt, ap);
73 * Load the specified plugin and run its init function.
74 * Returns -1 if unable to open the plugin, else it returns
75 * the value from the plugin's init function.
78 group_plugin_load(char *plugin_info)
80 char *args, path[PATH_MAX], savedch;
85 * Fill in .so path and split out args (if any).
87 if ((args = strpbrk(plugin_info, " \t")) != NULL) {
91 strncpy(path, plugin_info, sizeof(path) - 1);
92 path[sizeof(path) - 1] = '\0';
96 /* Open plugin and map in symbol. */
97 group_handle = dlopen(path, RTLD_LAZY);
99 fprintf(stderr, "unable to dlopen %s: %s\n", path, dlerror());
102 group_plugin = dlsym(group_handle, "group_plugin");
103 if (group_plugin == NULL) {
104 fprintf(stderr, "unable to find symbol \"group_plugin\" in %s\n", path);
108 if (SUDO_API_VERSION_GET_MAJOR(group_plugin->version) != GROUP_API_VERSION_MAJOR) {
110 "%s: incompatible group plugin major version %d, expected %d\n",
111 path, SUDO_API_VERSION_GET_MAJOR(group_plugin->version),
112 GROUP_API_VERSION_MAJOR);
117 * Split args into a vector if specified.
120 int ac = 0, wasblank = 1;
123 for (cp = args; *cp != '\0'; cp++) {
124 if (isblank((unsigned char)*cp)) {
126 } else if (wasblank) {
134 argv = malloc(ac * sizeof(char *));
140 for ((cp = strtok_r(args, " \t", &last)); cp != NULL; (cp = strtok_r(NULL, " \t", &last)))
145 rc = (group_plugin->init)(GROUP_API_VERSION, plugin_printf, argv);
153 group_plugin_unload(void)
155 (group_plugin->cleanup)();
156 dlclose(group_handle);
161 group_plugin_query(const char *user, const char *group,
162 const struct passwd *pwd)
164 return (group_plugin->query)(user, group, pwd);
171 "usage: plugin_test [-p \"plugin.so plugin_args ...\"] user:group ...\n");
176 main(int argc, char *argv[])
179 char *plugin = "group_file.so";
183 while ((ch = getopt(argc, argv, "p:")) != -1) {
198 if (group_plugin_load(plugin) != 1) {
199 fprintf(stderr, "unable to load plugin: %s\n", plugin);
203 for (i = 0; argv[i] != NULL; i++) {
205 group = strchr(argv[i], ':');
209 pwd = getpwnam(user);
210 found = group_plugin_query(user, group, pwd);
211 printf("user %s %s in group %s\n", user, found ? "is" : "NOT ", group);
213 group_plugin_unload();