Fix handling of duplicate policy and I/O plugins.

The warning message said the later I/O plugin was ignored but it
actually overwrote the existing one instead.
The first registered plugin of the same name now is used, as was intended.
Specifying more than one policy plugin is no longer a fatal error;
this allows the admin to fix the situation.
This commit is contained in:
Todd C. Miller
2020-01-14 13:53:52 -07:00
parent c592470dbd
commit 9c5c79194d

View File

@@ -171,11 +171,12 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
struct generic_plugin *plugin;
char path[PATH_MAX];
void *handle = NULL;
bool ret = false;
debug_decl(sudo_load_plugin, SUDO_DEBUG_PLUGIN);
/* Sanity check plugin and fill in path */
if (!sudo_check_plugin(info, path, sizeof(path)))
goto bad;
goto done;
/* Open plugin and map in symbol */
handle = sudo_dso_load(path, SUDO_DSO_LAZY|SUDO_DSO_GLOBAL);
@@ -185,21 +186,21 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unable to load %s: %s"), path,
errstr ? errstr : "unknown error");
goto bad;
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);
goto bad;
goto done;
}
if (plugin->type != SUDO_POLICY_PLUGIN && plugin->type != SUDO_IO_PLUGIN) {
sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
sudo_warnx(U_("unknown policy type %d found in %s"), plugin->type, path);
goto bad;
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\""),
@@ -207,26 +208,28 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
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 bad;
goto done;
}
if (plugin->type == SUDO_POLICY_PLUGIN) {
if (policy_plugin->handle != NULL) {
/* Ignore duplicate entries. */
if (strcmp(policy_plugin->name, info->symbol_name) != 0) {
if (strcmp(policy_plugin->name, info->symbol_name) == 0) {
sudo_warnx(U_("ignoring duplicate policy 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"));
goto bad;
goto done;
}
sudo_warnx(U_("ignoring duplicate policy plugin \"%s\" in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
goto bad;
ret = true;
goto done;
}
policy_plugin->handle = handle;
policy_plugin->path = strdup(path);
if (policy_plugin->path == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto bad;
goto done;
}
policy_plugin->name = info->symbol_name;
policy_plugin->options = info->options;
@@ -239,15 +242,15 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
if (strcmp(container->name, info->symbol_name) == 0) {
sudo_warnx(U_("ignoring duplicate I/O plugin \"%s\" in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
sudo_dso_unload(handle);
handle = NULL;
break;
ret = true;
goto done;
}
}
container = calloc(1, sizeof(*container));
if (container == NULL || (container->path = strdup(path)) == NULL) {
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
goto bad;
free(container);
goto done;
}
container->handle = handle;
container->name = info->symbol_name;
@@ -261,13 +264,14 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
/* Zero out info strings that we now own (see above). */
info->symbol_name = NULL;
info->options = NULL;
handle = NULL;
debug_return_bool(true);
bad:
free(container);
ret = true;
done:
if (handle != NULL)
sudo_dso_unload(handle);
debug_return_bool(false);
debug_return_bool(ret);
}
static void