#endif
/*
- * Load the plugins listed in sudo.conf.
+ * Load the plugin specified by "info".
*/
-bool
-sudo_load_plugins(struct plugin_container *policy_plugin,
- struct plugin_container_list *io_plugins)
+static bool
+sudo_load_plugin(struct plugin_container *policy_plugin,
+ struct plugin_container_list *io_plugins, struct plugin_info *info)
{
- struct plugin_info_list *plugins;
- struct generic_plugin *plugin;
struct plugin_container *container;
- struct plugin_info *info;
+ struct generic_plugin *plugin;
struct stat sb;
void *handle;
char path[PATH_MAX];
bool rval = false;
- debug_decl(sudo_load_plugins, SUDO_DEBUG_PLUGIN)
+ debug_decl(sudo_load_plugin, SUDO_DEBUG_PLUGIN)
- /* Walk plugin list. */
- plugins = sudo_conf_plugins();
- tq_foreach_fwd(plugins, info) {
- if (info->path[0] == '/') {
- if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) {
- warningx(_("%s: %s"), info->path, strerror(ENAMETOOLONG));
- goto done;
- }
- } else {
- if (snprintf(path, sizeof(path), "%s%s", _PATH_SUDO_PLUGIN_DIR,
- info->path) >= sizeof(path)) {
- warningx(_("%s%s: %s"), _PATH_SUDO_PLUGIN_DIR, info->path,
- strerror(ENAMETOOLONG));
- goto done;
- }
- }
- if (stat(path, &sb) != 0) {
- warning("%s", path);
- goto done;
- }
- if (sb.st_uid != ROOT_UID) {
- warningx(_("%s must be owned by uid %d"), path, ROOT_UID);
+ if (info->path[0] == '/') {
+ if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) {
+ warningx(_("%s: %s"), info->path, strerror(ENAMETOOLONG));
goto done;
}
- if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
- warningx(_("%s must be only be writable by owner"), path);
+ } else {
+ if (snprintf(path, sizeof(path), "%s%s", _PATH_SUDO_PLUGIN_DIR,
+ info->path) >= sizeof(path)) {
+ warningx(_("%s%s: %s"), _PATH_SUDO_PLUGIN_DIR, info->path,
+ strerror(ENAMETOOLONG));
goto done;
}
+ }
+ if (stat(path, &sb) != 0) {
+ warning("%s", path);
+ goto done;
+ }
+ if (sb.st_uid != ROOT_UID) {
+ warningx(_("%s must be owned by uid %d"), path, ROOT_UID);
+ goto done;
+ }
+ if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
+ warningx(_("%s must be only be writable by owner"), path);
+ goto done;
+ }
- /* Open plugin and map in symbol */
- handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
- if (!handle) {
- warningx(_("unable to dlopen %s: %s"), path, dlerror());
- goto done;
- }
- plugin = dlsym(handle, info->symbol_name);
- if (!plugin) {
- warningx(_("%s: unable to find symbol %s"), path,
- info->symbol_name);
+ /* Open plugin and map in symbol */
+ handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
+ if (!handle) {
+ warningx(_("unable to dlopen %s: %s"), path, dlerror());
+ goto done;
+ }
+ plugin = dlsym(handle, info->symbol_name);
+ if (!plugin) {
+ warningx(_("%s: unable to find symbol %s"), path,
+ info->symbol_name);
+ goto done;
+ }
+
+ if (plugin->type != SUDO_POLICY_PLUGIN && plugin->type != SUDO_IO_PLUGIN) {
+ warningx(_("%s: unknown policy type %d"), path, plugin->type);
+ goto done;
+ }
+ if (SUDO_API_VERSION_GET_MAJOR(plugin->version) != SUDO_API_VERSION_MAJOR) {
+ warningx(_("%s: incompatible policy major version %d, expected %d"),
+ path, SUDO_API_VERSION_GET_MAJOR(plugin->version),
+ SUDO_API_VERSION_MAJOR);
+ goto done;
+ }
+ if (plugin->type == SUDO_POLICY_PLUGIN) {
+ if (policy_plugin->handle) {
+ warningx(_("%s: only a single policy plugin may be loaded"),
+ _PATH_SUDO_CONF);
goto done;
}
+ policy_plugin->handle = handle;
+ policy_plugin->name = info->symbol_name;
+ policy_plugin->options = info->options;
+ policy_plugin->u.generic = plugin;
+ } else if (plugin->type == SUDO_IO_PLUGIN) {
+ container = ecalloc(1, sizeof(*container));
+ container->prev = container;
+ /* container->next = NULL; */
+ container->handle = handle;
+ container->name = info->symbol_name;
+ container->options = info->options;
+ container->u.generic = plugin;
+ tq_append(io_plugins, container);
+ }
- if (plugin->type != SUDO_POLICY_PLUGIN && plugin->type != SUDO_IO_PLUGIN) {
- warningx(_("%s: unknown policy type %d"), path, plugin->type);
+ rval = true;
+done:
+ debug_return_bool(rval);
+}
+
+/*
+ * Load the plugins listed in sudo.conf.
+ */
+bool
+sudo_load_plugins(struct plugin_container *policy_plugin,
+ struct plugin_container_list *io_plugins)
+{
+ struct plugin_container *container;
+ struct plugin_info_list *plugins;
+ struct plugin_info *info;
+ bool rval = false;
+ debug_decl(sudo_load_plugins, SUDO_DEBUG_PLUGIN)
+
+ /* Walk the plugin list from sudo.conf, if any. */
+ plugins = sudo_conf_plugins();
+ tq_foreach_fwd(plugins, info) {
+ rval = sudo_load_plugin(policy_plugin, io_plugins, info);
+ if (!rval)
goto done;
- }
- if (SUDO_API_VERSION_GET_MAJOR(plugin->version) != SUDO_API_VERSION_MAJOR) {
- warningx(_("%s: incompatible policy major version %d, expected %d"),
- path, SUDO_API_VERSION_GET_MAJOR(plugin->version),
- SUDO_API_VERSION_MAJOR);
+ }
+
+ /*
+ * If no policy plugin, fall back to the default (sudoers).
+ * If there is also no I/O log plugin, sudoers for that too.
+ */
+ if (policy_plugin->handle == NULL) {
+ /* Default policy plugin */
+ info = ecalloc(1, sizeof(*info));
+ info->symbol_name = "sudoers_policy";
+ info->path = SUDOERS_PLUGIN;
+ /* info->options = NULL; */
+ info->prev = info;
+ /* info->next = NULL; */
+ rval = sudo_load_plugin(policy_plugin, io_plugins, info);
+ efree(info);
+ if (!rval)
goto done;
- }
- if (plugin->type == SUDO_POLICY_PLUGIN) {
- if (policy_plugin->handle) {
- warningx(_("%s: only a single policy plugin may be loaded"),
- _PATH_SUDO_CONF);
+
+ /* Default I/O plugin */
+ if (tq_empty(io_plugins)) {
+ info = ecalloc(1, sizeof(*info));
+ info->symbol_name = "sudoers_io";
+ info->path = SUDOERS_PLUGIN;
+ /* info->options = NULL; */
+ info->prev = info;
+ /* info->next = NULL; */
+ rval = sudo_load_plugin(policy_plugin, io_plugins, info);
+ efree(info);
+ if (!rval)
goto done;
- }
- policy_plugin->handle = handle;
- policy_plugin->name = info->symbol_name;
- policy_plugin->options = info->options;
- policy_plugin->u.generic = plugin;
- } else if (plugin->type == SUDO_IO_PLUGIN) {
- container = ecalloc(1, sizeof(*container));
- container->prev = container;
- /* container->next = NULL; */
- container->handle = handle;
- container->name = info->symbol_name;
- container->options = info->options;
- container->u.generic = plugin;
- tq_append(io_plugins, container);
}
}
- if (policy_plugin->handle == NULL) {
- warningx(_("%s: at least one policy plugin must be specified"),
- _PATH_SUDO_CONF);
- goto done;
- }
if (policy_plugin->u.policy->check_policy == NULL) {
warningx(_("policy plugin %s does not include a check_policy method"),
policy_plugin->name);
+ rval = false;
goto done;
}
}
}
- rval = true;
-
done:
debug_return_bool(rval);
}