|
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". |
| */ |
*/ |
| bool | static 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); |