2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-09-03 15:55:40 +00:00

Fix calling sudo_conf_read() multiple times with different conf_types.

The change to reinitialize the configuration data when sudo_conf_read()
is called again didn't take into account that sudo calls sudo_conf_read()
twice--once for the debug info and once for everything else.
This commit is contained in:
Todd C. Miller
2020-11-18 09:36:05 -07:00
parent 7d0b19d2a0
commit 4a6ca4ba22

View File

@@ -64,6 +64,15 @@ struct sudo_conf_path_table {
char *pval; char *pval;
}; };
struct sudo_conf_settings {
bool updated;
bool developer_mode;
bool disable_coredump;
bool probe_interfaces;
int group_source;
int max_groups;
};
static int parse_debug(const char *entry, const char *conf_file, unsigned int lineno); static int parse_debug(const char *entry, const char *conf_file, unsigned int lineno);
static int parse_path(const char *entry, const char *conf_file, unsigned int lineno); static int parse_path(const char *entry, const char *conf_file, unsigned int lineno);
static int parse_plugin(const char *entry, const char *conf_file, unsigned int lineno); static int parse_plugin(const char *entry, const char *conf_file, unsigned int lineno);
@@ -99,36 +108,35 @@ static struct sudo_conf_table sudo_conf_var_table[] = {
#define SUDO_CONF_PATH_PLUGIN_DIR 3 #define SUDO_CONF_PATH_PLUGIN_DIR 3
#define SUDO_CONF_PATH_DEVSEARCH 4 #define SUDO_CONF_PATH_DEVSEARCH 4
#define SUDO_CONF_DATA_INITIALIZER { \ #define SUDO_CONF_PATH_INITIALIZER { \
false, \ { "askpass", sizeof("askpass") - 1, false, _PATH_SUDO_ASKPASS }, \
false, \ { "sesh", sizeof("sesh") - 1, false, _PATH_SUDO_SESH }, \
true, \ { "noexec", sizeof("noexec") - 1, false, _PATH_SUDO_NOEXEC }, \
true, \ { "plugin_dir", sizeof("plugin_dir") - 1, false, _PATH_SUDO_PLUGIN_DIR }, \
GROUP_SOURCE_ADAPTIVE, \ { "devsearch", sizeof("devsearch") - 1, false, _PATH_SUDO_DEVSEARCH }, \
-1, \ { NULL } \
TAILQ_HEAD_INITIALIZER(sudo_conf_data.debugging), \ }
TAILQ_HEAD_INITIALIZER(sudo_conf_data.plugins), \
{ \ #define SUDO_CONF_SETTINGS_INITIALIZER { \
{ "askpass", sizeof("askpass") - 1, false, _PATH_SUDO_ASKPASS }, \ false, /* updated */ \
{ "sesh", sizeof("sesh") - 1, false, _PATH_SUDO_SESH }, \ false, /* developer_mode */ \
{ "noexec", sizeof("noexec") - 1, false, _PATH_SUDO_NOEXEC }, \ true, /* disable_coredump */ \
{ "plugin_dir", sizeof("plugin_dir") - 1, false, _PATH_SUDO_PLUGIN_DIR }, \ true, /* probe_interfaces */ \
{ "devsearch", sizeof("devsearch") - 1, false, _PATH_SUDO_DEVSEARCH }, \ GROUP_SOURCE_ADAPTIVE, /* group_source */ \
{ NULL } \ -1 /* max_groups */ \
} \
} }
static struct sudo_conf_data { static struct sudo_conf_data {
bool updated; struct sudo_conf_settings settings;
bool developer_mode;
bool disable_coredump;
bool probe_interfaces;
int group_source;
int max_groups;
struct sudo_conf_debug_list debugging; struct sudo_conf_debug_list debugging;
struct plugin_info_list plugins; struct plugin_info_list plugins;
struct sudo_conf_path_table path_table[6]; struct sudo_conf_path_table path_table[6];
} sudo_conf_data = SUDO_CONF_DATA_INITIALIZER; } sudo_conf_data = {
SUDO_CONF_SETTINGS_INITIALIZER,
TAILQ_HEAD_INITIALIZER(sudo_conf_data.debugging),
TAILQ_HEAD_INITIALIZER(sudo_conf_data.plugins),
SUDO_CONF_PATH_INITIALIZER
};
/* /*
* "Set variable_name value" * "Set variable_name value"
@@ -376,7 +384,7 @@ set_var_developer_mode(const char *strval, const char *conf_file,
"developer_mode", strval, conf_file, lineno); "developer_mode", strval, conf_file, lineno);
debug_return_bool(false); debug_return_bool(false);
} }
sudo_conf_data.developer_mode = val; sudo_conf_data.settings.developer_mode = val;
debug_return_bool(true); debug_return_bool(true);
} }
@@ -392,7 +400,7 @@ set_var_disable_coredump(const char *strval, const char *conf_file,
"disable_coredump", strval, conf_file, lineno); "disable_coredump", strval, conf_file, lineno);
debug_return_bool(false); debug_return_bool(false);
} }
sudo_conf_data.disable_coredump = val; sudo_conf_data.settings.disable_coredump = val;
debug_return_bool(true); debug_return_bool(true);
} }
@@ -403,11 +411,11 @@ set_var_group_source(const char *strval, const char *conf_file,
debug_decl(set_var_group_source, SUDO_DEBUG_UTIL); debug_decl(set_var_group_source, SUDO_DEBUG_UTIL);
if (strcasecmp(strval, "adaptive") == 0) { if (strcasecmp(strval, "adaptive") == 0) {
sudo_conf_data.group_source = GROUP_SOURCE_ADAPTIVE; sudo_conf_data.settings.group_source = GROUP_SOURCE_ADAPTIVE;
} else if (strcasecmp(strval, "static") == 0) { } else if (strcasecmp(strval, "static") == 0) {
sudo_conf_data.group_source = GROUP_SOURCE_STATIC; sudo_conf_data.settings.group_source = GROUP_SOURCE_STATIC;
} else if (strcasecmp(strval, "dynamic") == 0) { } else if (strcasecmp(strval, "dynamic") == 0) {
sudo_conf_data.group_source = GROUP_SOURCE_DYNAMIC; sudo_conf_data.settings.group_source = GROUP_SOURCE_DYNAMIC;
} else { } else {
sudo_warnx(U_("unsupported group source \"%s\" in %s, line %u"), strval, sudo_warnx(U_("unsupported group source \"%s\" in %s, line %u"), strval,
conf_file, lineno); conf_file, lineno);
@@ -429,7 +437,7 @@ set_var_max_groups(const char *strval, const char *conf_file,
conf_file, lineno); conf_file, lineno);
debug_return_bool(false); debug_return_bool(false);
} }
sudo_conf_data.max_groups = max_groups; sudo_conf_data.settings.max_groups = max_groups;
debug_return_bool(true); debug_return_bool(true);
} }
@@ -445,7 +453,7 @@ set_var_probe_interfaces(const char *strval, const char *conf_file,
"probe_interfaces", strval, conf_file, lineno); "probe_interfaces", strval, conf_file, lineno);
debug_return_bool(false); debug_return_bool(false);
} }
sudo_conf_data.probe_interfaces = val; sudo_conf_data.settings.probe_interfaces = val;
debug_return_bool(true); debug_return_bool(true);
} }
@@ -482,13 +490,13 @@ sudo_conf_devsearch_path_v1(void)
int int
sudo_conf_group_source_v1(void) sudo_conf_group_source_v1(void)
{ {
return sudo_conf_data.group_source; return sudo_conf_data.settings.group_source;
} }
int int
sudo_conf_max_groups_v1(void) sudo_conf_max_groups_v1(void)
{ {
return sudo_conf_data.max_groups; return sudo_conf_data.settings.max_groups;
} }
struct plugin_info_list * struct plugin_info_list *
@@ -542,19 +550,19 @@ sudo_conf_debug_files_v1(const char *progname)
bool bool
sudo_conf_developer_mode_v1(void) sudo_conf_developer_mode_v1(void)
{ {
return sudo_conf_data.developer_mode; return sudo_conf_data.settings.developer_mode;
} }
bool bool
sudo_conf_disable_coredump_v1(void) sudo_conf_disable_coredump_v1(void)
{ {
return sudo_conf_data.disable_coredump; return sudo_conf_data.settings.disable_coredump;
} }
bool bool
sudo_conf_probe_interfaces_v1(void) sudo_conf_probe_interfaces_v1(void)
{ {
return sudo_conf_data.probe_interfaces; return sudo_conf_data.settings.probe_interfaces;
} }
/* /*
@@ -562,46 +570,57 @@ sudo_conf_probe_interfaces_v1(void)
* reset to initial values. * reset to initial values.
*/ */
static void static void
sudo_conf_init(void) sudo_conf_init(int conf_types)
{ {
struct sudo_conf_data sudo_conf_initial = SUDO_CONF_DATA_INITIALIZER;
struct sudo_conf_debug *debug_spec; struct sudo_conf_debug *debug_spec;
struct sudo_debug_file *debug_file; struct sudo_debug_file *debug_file;
struct plugin_info *plugin_info; struct plugin_info *plugin_info;
int i; int i;
debug_decl(sudo_conf_init, SUDO_DEBUG_UTIL); debug_decl(sudo_conf_init, SUDO_DEBUG_UTIL);
/* Free paths. */ /* Free and reset paths. */
sudo_conf_clear_paths(); if (ISSET(conf_types, SUDO_CONF_PATHS)) {
const struct sudo_conf_path_table path_table[] = SUDO_CONF_PATH_INITIALIZER;
/* Free debug settings. */ sudo_conf_clear_paths();
while ((debug_spec = TAILQ_FIRST(&sudo_conf_data.debugging))) { memcpy(sudo_conf_data.path_table, path_table,
TAILQ_REMOVE(&sudo_conf_data.debugging, debug_spec, entries); sizeof(sudo_conf_data.path_table));
free(debug_spec->progname);
while ((debug_file = TAILQ_FIRST(&debug_spec->debug_files))) {
TAILQ_REMOVE(&debug_spec->debug_files, debug_file, entries);
free(debug_file->debug_file);
free(debug_file->debug_flags);
free(debug_file);
}
free(debug_spec);
} }
/* Free plugins. */ /* Free and reset debug settings. */
while ((plugin_info = TAILQ_FIRST(&sudo_conf_data.plugins))) { if (ISSET(conf_types, SUDO_CONF_DEBUG)) {
TAILQ_REMOVE(&sudo_conf_data.plugins, plugin_info, entries); while ((debug_spec = TAILQ_FIRST(&sudo_conf_data.debugging))) {
free(plugin_info->symbol_name); TAILQ_REMOVE(&sudo_conf_data.debugging, debug_spec, entries);
free(plugin_info->path); free(debug_spec->progname);
if (plugin_info->options != NULL) { while ((debug_file = TAILQ_FIRST(&debug_spec->debug_files))) {
for (i = 0; plugin_info->options[i] != NULL; i++) TAILQ_REMOVE(&debug_spec->debug_files, debug_file, entries);
free(plugin_info->options[i]); free(debug_file->debug_file);
free(plugin_info->options); free(debug_file->debug_flags);
free(debug_file);
}
free(debug_spec);
} }
free(plugin_info);
} }
/* Set to initial values. */ /* Free and reset plugins. */
sudo_conf_data = sudo_conf_initial; if (ISSET(conf_types, SUDO_CONF_PLUGINS)) {
while ((plugin_info = TAILQ_FIRST(&sudo_conf_data.plugins))) {
TAILQ_REMOVE(&sudo_conf_data.plugins, plugin_info, entries);
free(plugin_info->symbol_name);
free(plugin_info->path);
if (plugin_info->options != NULL) {
for (i = 0; plugin_info->options[i] != NULL; i++)
free(plugin_info->options[i]);
free(plugin_info->options);
}
free(plugin_info);
}
}
/* Set initial values. */
if (ISSET(conf_types, SUDO_CONF_SETTINGS)) {
const struct sudo_conf_settings settings = SUDO_CONF_SETTINGS_INITIALIZER;
sudo_conf_data.settings = settings;
}
debug_return; debug_return;
} }
@@ -669,8 +688,8 @@ sudo_conf_read_v1(const char *conf_file, int conf_types)
} }
/* Reset to initial values if necessary. */ /* Reset to initial values if necessary. */
if (sudo_conf_data.updated) if (sudo_conf_data.settings.updated)
sudo_conf_init(); sudo_conf_init(conf_types);
while (sudo_parseln(&line, &linesize, &conf_lineno, fp, 0) != -1) { while (sudo_parseln(&line, &linesize, &conf_lineno, fp, 0) != -1) {
struct sudo_conf_table *cur; struct sudo_conf_table *cur;
@@ -690,7 +709,7 @@ sudo_conf_read_v1(const char *conf_file, int conf_types)
ret = cur->parser(cp, conf_file, conf_lineno); ret = cur->parser(cp, conf_file, conf_lineno);
switch (ret) { switch (ret) {
case true: case true:
sudo_conf_data.updated = true; sudo_conf_data.settings.updated = true;
break; break;
case false: case false:
break; break;