2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 01:49:11 +00:00

Ignore duplicate entries in sudo.conf and report the line number

when there is an error.  Warn, don't abort if there is more than
one policy plugin.
This commit is contained in:
Todd C. Miller 2013-01-23 06:33:53 -05:00
parent c00c968010
commit ef8e141248
3 changed files with 67 additions and 23 deletions

View File

@ -88,6 +88,8 @@ static bool set_path(const char *entry);
static bool set_plugin(const char *entry);
static bool set_variable(const char *entry);
static unsigned int lineno;
static struct sudo_conf_table sudo_conf_table[] = {
{ "Debug", sizeof("Debug") - 1, set_debug },
{ "Path", sizeof("Path") - 1, set_path },
@ -249,6 +251,7 @@ set_plugin(const char *entry)
info->options = options;
info->prev = info;
/* info->next = NULL; */
info->lineno = lineno;
tq_append(&sudo_conf_data.plugins, info);
return true;
@ -333,10 +336,11 @@ sudo_conf_read(void)
goto done;
}
lineno = 0;
while ((cp = sudo_parseln(fp)) != NULL) {
/* Skip blank or comment lines */
lineno++;
if (*cp == '\0')
continue;
continue; /* empty line or comment */
for (cur = sudo_conf_table; cur->name != NULL; cur++) {
if (strncasecmp(cp, cur->name, cur->namelen) == 0 &&

View File

@ -25,6 +25,7 @@ struct plugin_info {
const char *path;
const char *symbol_name;
char * const * options;
int lineno;
};
TQ_DECLARE(plugin_info)

View File

@ -70,26 +70,36 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
if (info->path[0] == '/') {
if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) {
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
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(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(_("%s%s: %s"), _PATH_SUDO_PLUGIN_DIR, info->path,
strerror(ENAMETOOLONG));
goto done;
}
}
if (stat(path, &sb) != 0) {
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warning("%s", path);
goto done;
}
if (sb.st_uid != ROOT_UID) {
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(_("%s must be owned by uid %d"), path, ROOT_UID);
goto done;
}
if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) {
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(_("%s must be only be writable by owner"), path);
goto done;
}
@ -97,45 +107,74 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
/* Open plugin and map in symbol */
handle = dlopen(path, RTLD_LAZY|RTLD_GLOBAL);
if (!handle) {
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
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);
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(_("unable to find symbol `%s' in %s"), info->symbol_name, path);
goto done;
}
if (plugin->type != SUDO_POLICY_PLUGIN && plugin->type != SUDO_IO_PLUGIN) {
warningx(_("%s: unknown policy type %d"), path, plugin->type);
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(_("unknown policy type %d found in %s"), plugin->type, path);
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);
warningx(_("error in %s, line %d while loading plugin `%s'"),
_PATH_SUDO_CONF, info->lineno, info->symbol_name);
warningx(_("incompatible plugin major version %d (expected %d) found in %s"),
SUDO_API_VERSION_GET_MAJOR(plugin->version),
SUDO_API_VERSION_MAJOR, path);
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;
/* Ignore duplicate entries. */
if (strcmp(policy_plugin->name, info->symbol_name) != 0) {
warningx(_("ignoring policy plugin `%s' in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
warningx(_("only a single policy plugin may be specified"));
goto done;
}
warningx(_("ignoring duplicate policy plugin `%s' in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
dlclose(handle);
handle = NULL;
}
if (handle != NULL) {
policy_plugin->handle = handle;
policy_plugin->name = info->symbol_name;
policy_plugin->options = info->options;
policy_plugin->u.generic = plugin;
}
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);
/* Check for duplicate entries. */
tq_foreach_fwd(io_plugins, container) {
if (strcmp(container->name, info->symbol_name) == 0) {
warningx(_("ignoring duplicate I/O plugin `%s' in %s, line %d"),
info->symbol_name, _PATH_SUDO_CONF, info->lineno);
dlclose(handle);
handle = NULL;
break;
}
}
if (handle != NULL) {
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);
}
}
rval = true;