Load the sudoers module as an audit plugin if loaded as a policy plugin.

Now that logging of successful commands is performed by sudoers as an
audit plugin we need to load sudoers_audit if sudoers_policy is also
loaded.  Otherwise, accpted commands will not be logged.
This commit is contained in:
Todd C. Miller
2020-06-02 14:54:04 -06:00
parent b519481912
commit 253e041d3b
3 changed files with 157 additions and 72 deletions

View File

@@ -198,13 +198,13 @@ bad:
}
static bool
plugin_exists(struct plugin_container_list *plugins, struct plugin_info *info)
plugin_exists(struct plugin_container_list *plugins, const char *symbol_name)
{
struct plugin_container *container;
debug_decl(find_plugin, SUDO_DEBUG_PLUGIN);
TAILQ_FOREACH(container, plugins, entries) {
if (strcmp(container->name, info->symbol_name) == 0)
if (strcmp(container->name, symbol_name) == 0)
debug_return_bool(true);
}
debug_return_bool(false);
@@ -241,7 +241,7 @@ sudo_insert_plugin(struct plugin_container_list *plugin_list, void *handle,
struct plugin_container *container;
debug_decl(sudo_insert_plugin, SUDO_DEBUG_PLUGIN);
if (plugin_exists(plugin_list, info)) {
if (plugin_exists(plugin_list, info->symbol_name)) {
plugin = sudo_plugin_try_to_clone(handle, info->symbol_name);
if (plugin == NULL) {
sudo_warnx(U_("ignoring duplicate plugin \"%s\" in %s, line %d"),
@@ -267,7 +267,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
struct plugin_container_list *io_plugins,
struct plugin_container_list *audit_plugins,
struct plugin_container_list *approval_plugins,
struct plugin_info *info)
struct plugin_info *info, bool quiet)
{
struct generic_plugin *plugin;
char path[PATH_MAX];
@@ -282,27 +282,34 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
/* Open plugin and map in symbol */
handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
if (!handle) {
const char *errstr = sudo_dso_strerror();
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unable to load %s: %s"), path,
errstr ? errstr : "unknown error");
if (!quiet) {
const char *errstr = sudo_dso_strerror();
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unable to load %s: %s"), path,
errstr ? errstr : "unknown error");
}
goto done;
}
plugin = sudo_dso_findsym(handle, info->symbol_name);
if (!plugin) {
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unable to find symbol \"%s\" in %s"), info->symbol_name, path);
if (!quiet) {
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unable to find symbol \"%s\" in %s"),
info->symbol_name, path);
}
goto done;
}
if (SUDO_API_VERSION_GET_MAJOR(plugin->version) != SUDO_API_VERSION_MAJOR) {
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("incompatible plugin major version %d (expected %d) found in %s"),
SUDO_API_VERSION_GET_MAJOR(plugin->version),
SUDO_API_VERSION_MAJOR, path);
if (!quiet) {
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("incompatible plugin major version %d (expected %d) found in %s"),
SUDO_API_VERSION_GET_MAJOR(plugin->version),
SUDO_API_VERSION_MAJOR, path);
}
goto done;
}
@@ -311,12 +318,16 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
if (policy_plugin->handle != NULL) {
/* Ignore duplicate entries. */
if (strcmp(policy_plugin->name, info->symbol_name) == 0) {
sudo_warnx(U_("ignoring duplicate plugin \"%s\" in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
if (!quiet) {
sudo_warnx(U_("ignoring duplicate plugin \"%s\" in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
}
} else {
sudo_warnx(U_("ignoring policy plugin \"%s\" in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
sudo_warnx(U_("only a single policy plugin may be specified"));
if (!quiet) {
sudo_warnx(U_("ignoring policy plugin \"%s\" in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
sudo_warnx(U_("only a single policy plugin may be specified"));
}
goto done;
}
ret = true;
@@ -338,9 +349,11 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
goto done;
break;
default:
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unknown plugin type %d found in %s"), plugin->type, path);
if (!quiet) {
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unknown plugin type %d found in %s"), plugin->type, path);
}
goto done;
}
@@ -427,6 +440,44 @@ sudo_init_event_alloc(struct plugin_container *policy_plugin,
debug_return;
}
/*
* Load the specified symbol from the sudoers plugin.
* Used to provide a default plugin when none are specified in sudo.conf.
*/
bool
sudo_load_sudoers_plugin(const char *symbol_name,
struct plugin_container *policy_plugin,
struct plugin_container_list *io_plugins,
struct plugin_container_list *audit_plugins,
struct plugin_container_list *approval_plugins,
bool optional)
{
struct plugin_info *info;
bool ret = false;
debug_decl(sudo_load_sudoers_plugin, SUDO_DEBUG_PLUGIN);
/* Default policy plugin */
info = calloc(1, sizeof(*info));
if (info == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
info->symbol_name = strdup(symbol_name);
info->path = strdup(SUDOERS_PLUGIN);
if (info->symbol_name == NULL || info->path == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
free_plugin_info(info);
goto done;
}
/* info->options = NULL; */
ret = sudo_load_plugin(policy_plugin, io_plugins, audit_plugins,
approval_plugins, info, optional);
free_plugin_info(info);
done:
debug_return_bool(ret);
}
/*
* Load the plugins listed in sudo.conf.
*/
@@ -445,7 +496,7 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
plugins = sudo_conf_plugins();
TAILQ_FOREACH_SAFE(info, plugins, entries, next) {
ret = sudo_load_plugin(policy_plugin, io_plugins, audit_plugins,
approval_plugins, info);
approval_plugins, info, false);
if (!ret)
goto done;
free_plugin_info(info);
@@ -458,47 +509,33 @@ sudo_load_plugins(struct plugin_container *policy_plugin,
*/
if (policy_plugin->handle == NULL) {
/* Default policy plugin */
info = calloc(1, sizeof(*info));
if (info == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
info->symbol_name = strdup("sudoers_policy");
info->path = strdup(SUDOERS_PLUGIN);
if (info->symbol_name == NULL || info->path == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
free_plugin_info(info);
goto done;
}
/* info->options = NULL; */
ret = sudo_load_plugin(policy_plugin, io_plugins, audit_plugins,
approval_plugins, info);
free_plugin_info(info);
ret = sudo_load_sudoers_plugin("sudoers_policy", policy_plugin,
io_plugins, audit_plugins, approval_plugins, false);
if (!ret)
goto done;
/* Default audit plugin, optional (sudoers < 1.9.1 lack this) */
(void)sudo_load_sudoers_plugin("sudoers_audit", policy_plugin,
io_plugins, audit_plugins, approval_plugins, true);
/* Default I/O plugin */
if (TAILQ_EMPTY(io_plugins)) {
info = calloc(1, sizeof(*info));
if (info == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto done;
}
info->symbol_name = strdup("sudoers_io");
info->path = strdup(SUDOERS_PLUGIN);
if (info->symbol_name == NULL || info->path == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
free_plugin_info(info);
goto done;
}
/* info->options = NULL; */
ret = sudo_load_plugin(policy_plugin, io_plugins, audit_plugins,
approval_plugins, info);
free_plugin_info(info);
ret = sudo_load_sudoers_plugin("sudoers_io", policy_plugin,
io_plugins, audit_plugins, approval_plugins, false);
if (!ret)
goto done;
}
} else if (strcmp(policy_plugin->name, "sudoers_policy") == 0) {
/*
* If policy plugin is sudoers_policy but there is no sudoers_audit
* loaded, load it too, if possible.
*/
if (!plugin_exists(audit_plugins, "sudoers_audit")) {
(void)sudo_load_sudoers_plugin("sudoers_audit", policy_plugin,
io_plugins, audit_plugins, approval_plugins, true);
}
}
/* TODO: check all plugins for open function too */
if (policy_plugin->u.policy->check_policy == NULL) {
sudo_warnx(U_("policy plugin %s does not include a check_policy method"),