]> granicus.if.org Git - sudo/commitdiff
If sudo.conf contains an I/O plugin but no policy plugin, use sudoers
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 9 Aug 2012 18:11:41 +0000 (14:11 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 9 Aug 2012 18:11:41 +0000 (14:11 -0400)
for the policy plugin.  If a policy plugin is specified without an
I/O plugin, only the policy plugin will be loaded.

common/sudo_conf.c
src/load_plugins.c

index 238d21f260f725bd2e4fd401ffc3cc023cf2c9b6..144bbc3b6274c540d723ab875fe1f3232e076968 100644 (file)
@@ -292,7 +292,6 @@ void
 sudo_conf_read(void)
 {
     struct sudo_conf_table *cur;
-    struct plugin_info *info;
     struct stat sb;
     FILE *fp;
     char *cp;
@@ -346,25 +345,6 @@ sudo_conf_read(void)
        }
     }
     fclose(fp);
-
 done:
-    if (tq_empty(&sudo_conf_data.plugins)) {
-       /* 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; */
-       tq_append(&sudo_conf_data.plugins, info);
-
-       /* Default I/O plugin */
-       info = ecalloc(1, sizeof(*info));
-       info->symbol_name = "sudoers_io";
-       info->path = SUDOERS_PLUGIN;
-       /* info->options = NULL; */
-       info->prev = info;
-       /* info->next = NULL; */
-       tq_append(&sudo_conf_data.plugins, info);
-    }
+    return;
 }
index 767f8ee70097d8566032e3fca22f148a28f3dadc..0371e9f5068d9524ddeaf3bb36fbdc022f404ff6 100644 (file)
 #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;
     }
 
@@ -165,8 +213,6 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
        }
     }
 
-    rval = true;
-
 done:
     debug_return_bool(rval);
 }