Diff for /embedaddon/sudo/src/load_plugins.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/05/29 12:26:49 version 1.1.1.3, 2012/10/09 09:29:52
Line 55 Line 55
 #endif  #endif
   
 /*  /*
 * Load the plugins listed in sudo.conf. * Load the plugin specified by "info".
  */   */
boolstatic bool
sudo_load_plugins(struct plugin_container *policy_plugin,sudo_load_plugin(struct plugin_container *policy_plugin,
    struct plugin_container_list *io_plugins)    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_container *container;
    struct plugin_info *info;    struct generic_plugin *plugin;
     struct stat sb;      struct stat sb;
     void *handle;      void *handle;
     char path[PATH_MAX];      char path[PATH_MAX];
     bool rval = false;      bool rval = false;
    debug_decl(sudo_load_plugins, SUDO_DEBUG_PLUGIN)    debug_decl(sudo_load_plugin, SUDO_DEBUG_PLUGIN)
   
    /* Walk plugin list. */    if (info->path[0] == '/') {
    plugins = sudo_conf_plugins();        if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) {
    tq_foreach_fwd(plugins, info) {            warningx(_("%s: %s"), info->path, strerror(ENAMETOOLONG));
        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;              goto done;
         }          }
        if (sb.st_uid != ROOT_UID) {    } else {
            warningx(_("%s must be owned by uid %d"), path, ROOT_UID);        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;              goto done;
         }          }
        if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {    }
            warningx(_("%s must be only be writable by owner"), path);    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);
         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;              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);
       }
   
        /* Open plugin and map in symbol */    rval = true;
        handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);done:
        if (!handle) {    debug_return_bool(rval);
            warningx(_("unable to dlopen %s: %s"), path, dlerror());}
 
 /*
  * 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;              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);     * 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;              goto done;
        }
        if (SUDO_API_VERSION_GET_MAJOR(plugin->version) != SUDO_API_VERSION_MAJOR) {        /* Default I/O plugin */
            warningx(_("%s: incompatible policy major version %d, expected %d"),        if (tq_empty(io_plugins)) {
                path, SUDO_API_VERSION_GET_MAJOR(plugin->version),            info = ecalloc(1, sizeof(*info));
                SUDO_API_VERSION_MAJOR);            info->symbol_name = "sudoers_io";
            goto done;            info->path = SUDOERS_PLUGIN;
        }            /* info->options = NULL; */
        if (plugin->type == SUDO_POLICY_PLUGIN) {            info->prev = info;
            if (policy_plugin->handle) {            /* info->next = NULL; */
                warningx(_("%s: only a single policy plugin may be loaded"),            rval = sudo_load_plugin(policy_plugin, io_plugins, info);
                    _PATH_SUDO_CONF);            efree(info);
             if (!rval)
                 goto done;                  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) {      if (policy_plugin->u.policy->check_policy == NULL) {
         warningx(_("policy plugin %s does not include a check_policy method"),          warningx(_("policy plugin %s does not include a check_policy method"),
             policy_plugin->name);              policy_plugin->name);
           rval = false;
         goto done;          goto done;
     }      }
   
Line 159  sudo_load_plugins(struct plugin_container *policy_plug Line 207  sudo_load_plugins(struct plugin_container *policy_plug
     if (policy_plugin->u.policy->version >= SUDO_API_MKVERSION(1, 2)) {      if (policy_plugin->u.policy->version >= SUDO_API_MKVERSION(1, 2)) {
         if (policy_plugin->u.policy->register_hooks != NULL)          if (policy_plugin->u.policy->register_hooks != NULL)
             policy_plugin->u.policy->register_hooks(SUDO_HOOK_VERSION, register_hook);              policy_plugin->u.policy->register_hooks(SUDO_HOOK_VERSION, register_hook);
        tq_foreach_fwd(io_plugins, container) {    }
     tq_foreach_fwd(io_plugins, container) {
         if (container->u.io->version >= SUDO_API_MKVERSION(1, 2)) {
             if (container->u.io->register_hooks != NULL)              if (container->u.io->register_hooks != NULL)
                 container->u.io->register_hooks(SUDO_HOOK_VERSION, register_hook);                  container->u.io->register_hooks(SUDO_HOOK_VERSION, register_hook);
         }          }
     }      }
   
     rval = true;  
   
 done:  done:
     debug_return_bool(rval);      debug_return_bool(rval);

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


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