Add a flag argument to sudo_conf_read() so we can decide which

bits get parsed.  This lets us parse Debug statements first and
init the debug subsystem early.
This commit is contained in:
Todd C. Miller
2014-10-26 08:33:08 -06:00
parent f8bd2af4da
commit 6b1b734ffa
11 changed files with 102 additions and 103 deletions

View File

@@ -19,6 +19,14 @@
#include "sudo_queue.h" #include "sudo_queue.h"
/* Flags for sudo_conf_read() */
#define SUDO_CONF_DEBUG 0x01
#define SUDO_CONF_PATHS 0x02
#define SUDO_CONF_PLUGINS 0x04
#define SUDO_CONF_SETTINGS 0x08
#define SUDO_CONF_ALL 0x0f
/* Values of sudo_conf_group_source() */
#define GROUP_SOURCE_ADAPTIVE 0 #define GROUP_SOURCE_ADAPTIVE 0
#define GROUP_SOURCE_STATIC 1 #define GROUP_SOURCE_STATIC 1
#define GROUP_SOURCE_DYNAMIC 2 #define GROUP_SOURCE_DYNAMIC 2
@@ -28,7 +36,6 @@ TAILQ_HEAD(sudo_conf_debug_file_list, sudo_debug_file);
struct plugin_info { struct plugin_info {
TAILQ_ENTRY(plugin_info) entries; TAILQ_ENTRY(plugin_info) entries;
struct sudo_conf_debug_file_list debug_files;
const char *path; const char *path;
const char *symbol_name; const char *symbol_name;
char * const * options; char * const * options;
@@ -44,8 +51,8 @@ struct sudo_conf_debug {
TAILQ_HEAD(sudo_conf_debug_list, sudo_conf_debug); TAILQ_HEAD(sudo_conf_debug_list, sudo_conf_debug);
/* Read main sudo.conf file. */ /* Read main sudo.conf file. */
__dso_public void sudo_conf_read_v1(const char *conf_file); __dso_public void sudo_conf_read_v1(const char *conf_file, int conf_types);
#define sudo_conf_read(_a) sudo_conf_read_v1((_a)) #define sudo_conf_read(_a, _b) sudo_conf_read_v1((_a), (_b))
/* Accessor functions. */ /* Accessor functions. */
__dso_public const char *sudo_conf_askpass_path_v1(void); __dso_public const char *sudo_conf_askpass_path_v1(void);
@@ -53,6 +60,7 @@ __dso_public const char *sudo_conf_sesh_path_v1(void);
__dso_public const char *sudo_conf_noexec_path_v1(void); __dso_public const char *sudo_conf_noexec_path_v1(void);
__dso_public const char *sudo_conf_plugin_dir_path_v1(void); __dso_public const char *sudo_conf_plugin_dir_path_v1(void);
__dso_public struct sudo_conf_debug_list *sudo_conf_debugging_v1(void); __dso_public struct sudo_conf_debug_list *sudo_conf_debugging_v1(void);
__dso_public struct sudo_conf_debug_file_list *sudo_conf_debug_files_v1(const char *progname);
__dso_public struct plugin_info_list *sudo_conf_plugins_v1(void); __dso_public struct plugin_info_list *sudo_conf_plugins_v1(void);
__dso_public bool sudo_conf_disable_coredump_v1(void); __dso_public bool sudo_conf_disable_coredump_v1(void);
__dso_public bool sudo_conf_probe_interfaces_v1(void); __dso_public bool sudo_conf_probe_interfaces_v1(void);
@@ -63,6 +71,7 @@ __dso_public int sudo_conf_max_groups_v1(void);
#define sudo_conf_noexec_path() sudo_conf_noexec_path_v1() #define sudo_conf_noexec_path() sudo_conf_noexec_path_v1()
#define sudo_conf_plugin_dir_path() sudo_conf_plugin_dir_path_v1() #define sudo_conf_plugin_dir_path() sudo_conf_plugin_dir_path_v1()
#define sudo_conf_debugging() sudo_conf_debugging_v1() #define sudo_conf_debugging() sudo_conf_debugging_v1()
#define sudo_conf_debug_files(_a) sudo_conf_debug_files_v1((_a))
#define sudo_conf_plugins() sudo_conf_plugins_v1() #define sudo_conf_plugins() sudo_conf_plugins_v1()
#define sudo_conf_disable_coredump() sudo_conf_disable_coredump_v1() #define sudo_conf_disable_coredump() sudo_conf_disable_coredump_v1()
#define sudo_conf_probe_interfaces() sudo_conf_probe_interfaces_v1() #define sudo_conf_probe_interfaces() sudo_conf_probe_interfaces_v1()

View File

@@ -63,7 +63,7 @@ main(int argc, char *argv[])
fprintf(stderr, "usage: %s conf_file\n", getprogname()); fprintf(stderr, "usage: %s conf_file\n", getprogname());
exit(1); exit(1);
} }
sudo_conf_read(argv[1]); sudo_conf_read(argv[1], SUDO_CONF_ALL);
sudo_conf_dump(); sudo_conf_dump();
exit(0); exit(0);

View File

@@ -323,58 +323,9 @@ store_plugin(const char *cp, unsigned int lineno)
info->path = sudo_estrndup(path, pathlen); info->path = sudo_estrndup(path, pathlen);
info->options = options; info->options = options;
info->lineno = lineno; info->lineno = lineno;
TAILQ_INIT(&info->debug_files);
TAILQ_INSERT_TAIL(&sudo_conf_data.plugins, info, entries); TAILQ_INSERT_TAIL(&sudo_conf_data.plugins, info, entries);
} }
/*
* Initialize debugging subsystem for the running program.
* Also stores plugin-specific debug info in sudo_conf_data.plugins.
*/
static void
set_debugging(const char *conf_file)
{
struct sudo_conf_debug *debug_spec;
struct plugin_info *plugin_info;
const char *progname;
size_t prognamelen;
debug_decl(main, SUDO_DEBUG_UTIL, SUDO_DEBUG_INSTANCE_DEFAULT)
progname = getprogname();
prognamelen = strlen(progname);
if (prognamelen > 4 && strcmp(progname + 4, "edit") == 0)
prognamelen -= 4;
TAILQ_FOREACH(debug_spec, &sudo_conf_data.debugging, entries) {
if (strncmp(debug_spec->progname, progname, prognamelen) == 0 &&
debug_spec->progname[prognamelen] == '\0') {
/*
* Register debug instance for the main program, making it
* the default instance if one is not already set.
*/
sudo_debug_register(progname, NULL, NULL, &debug_spec->debug_files);
sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys);
continue;
}
/* Move debug_files to plugin if it matches. */
TAILQ_FOREACH(plugin_info, &sudo_conf_data.plugins, entries) {
const char *plugin_name = plugin_info->path;
if (debug_spec->progname[0] != '/') {
/* Match basename(path). */
plugin_name = strrchr(plugin_info->path, '/');
if (plugin_name++ == NULL)
plugin_name = plugin_info->path;
}
if (strcmp(debug_spec->progname, plugin_name) == 0) {
/* Move debug_files into plugin_info. */
TAILQ_SWAP(&plugin_info->debug_files, &debug_spec->debug_files,
sudo_debug_file, entries);
break;
}
}
/* XXX - free up remaining structs */
}
}
/* /*
* Update path settings. * Update path settings.
*/ */
@@ -558,6 +509,42 @@ sudo_conf_debugging_v1(void)
return &sudo_conf_data.debugging; return &sudo_conf_data.debugging;
} }
/* Return the debug files list for a program, or NULL if none. */
struct sudo_conf_debug_file_list *
sudo_conf_debug_files_v1(const char *progname)
{
struct sudo_conf_debug *debug_spec;
size_t prognamelen, progbaselen;
const char *progbase = progname;
debug_decl(sudo_conf_debug_files, SUDO_DEBUG_UTIL, SUDO_DEBUG_INSTANCE_DEFAULT)
/* Determine basename if program is fully qualified (like for plugins). */
prognamelen = progbaselen = strlen(progname);
if (*progname == '/') {
progbase = strrchr(progname, '/');
progbaselen = strlen(++progbase);
}
/* Convert sudoedit -> sudo. */
if (progbaselen > 4 && strcmp(progbase + 4, "edit") == 0) {
progbaselen -= 4;
}
TAILQ_FOREACH(debug_spec, &sudo_conf_data.debugging, entries) {
const char *prog = progbase;
size_t len = progbaselen;
if (debug_spec->progname[0] == '/') {
/* Match fully-qualified name, if possible. */
prog = progname;
len = prognamelen;
}
if (strncmp(debug_spec->progname, prog, len) == 0 &&
debug_spec->progname[len] == '\0') {
debug_return_ptr(&debug_spec->debug_files);
}
}
debug_return_ptr(NULL);
}
bool bool
sudo_conf_disable_coredump_v1(void) sudo_conf_disable_coredump_v1(void)
{ {
@@ -574,12 +561,11 @@ sudo_conf_probe_interfaces_v1(void)
* Reads in /etc/sudo.conf and populates sudo_conf_data. * Reads in /etc/sudo.conf and populates sudo_conf_data.
*/ */
void void
sudo_conf_read_v1(const char *conf_file) sudo_conf_read_v1(const char *conf_file, int conf_types)
{ {
struct sudo_conf_table *cur;
struct stat sb; struct stat sb;
FILE *fp; FILE *fp;
char *cp, *line = NULL; char *line = NULL;
char *prev_locale = sudo_estrdup(setlocale(LC_ALL, NULL)); char *prev_locale = sudo_estrdup(setlocale(LC_ALL, NULL));
unsigned int conf_lineno = 0; unsigned int conf_lineno = 0;
size_t linesize = 0; size_t linesize = 0;
@@ -624,10 +610,16 @@ sudo_conf_read_v1(const char *conf_file)
} }
while (sudo_parseln(&line, &linesize, &conf_lineno, fp) != -1) { while (sudo_parseln(&line, &linesize, &conf_lineno, fp) != -1) {
struct sudo_conf_table *cur;
unsigned int i;
char *cp;
if (*(cp = line) == '\0') if (*(cp = line) == '\0')
continue; /* empty line or comment */ continue; /* empty line or comment */
for (cur = sudo_conf_table; cur->name != NULL; cur++) { for (i = 0, cur = sudo_conf_table; cur->name != NULL; i++, cur++) {
if (!ISSET(conf_types, (1 << i)))
continue;
if (strncasecmp(cp, cur->name, cur->namelen) == 0 && if (strncasecmp(cp, cur->name, cur->namelen) == 0 &&
isblank((unsigned char)cp[cur->namelen])) { isblank((unsigned char)cp[cur->namelen])) {
cp += cur->namelen; cp += cur->namelen;
@@ -641,12 +633,11 @@ sudo_conf_read_v1(const char *conf_file)
fclose(fp); fclose(fp);
free(line); free(line);
/* First, init the debug system. */ /* Parse paths and variables as needed. */
set_debugging(conf_file); if (ISSET(conf_types, SUDO_CONF_PATHS))
set_paths(conf_file);
/* Then set paths and variables. */ if (ISSET(conf_types, SUDO_CONF_SETTINGS))
set_paths(conf_file); set_variables(conf_file);
set_variables(conf_file);
done: done:
/* Restore locale if needed. */ /* Restore locale if needed. */

View File

@@ -1,5 +1,6 @@
@COMPAT_EXP@initprogname @COMPAT_EXP@initprogname
sudo_conf_askpass_path_v1 sudo_conf_askpass_path_v1
sudo_conf_debug_files_v1
sudo_conf_debugging_v1 sudo_conf_debugging_v1
sudo_conf_disable_coredump_v1 sudo_conf_disable_coredump_v1
sudo_conf_group_source_v1 sudo_conf_group_source_v1

View File

@@ -106,19 +106,19 @@ sudoers_debug_parse_flags(struct sudo_conf_debug_file_list *debug_files,
} }
/* /*
* Register the specified debug files and plugin_path with the * Register the specified debug files and program with the
* debug subsystem. * debug subsystem, freeing the debug list when done.
*/ */
void void
sudoers_debug_register(struct sudo_conf_debug_file_list *debug_files, sudoers_debug_register(struct sudo_conf_debug_file_list *debug_files,
const char *plugin_path) const char *program)
{ {
struct sudo_debug_file *debug_file, *debug_next; struct sudo_debug_file *debug_file, *debug_next;
/* Setup debugging if indicated. */ /* Setup debugging if indicated. */
if (!TAILQ_EMPTY(debug_files)) { if (debug_files != NULL && !TAILQ_EMPTY(debug_files)) {
if (plugin_path != NULL) { if (program != NULL) {
sudoers_debug_instance = sudo_debug_register(plugin_path, sudoers_debug_instance = sudo_debug_register(program,
sudoers_subsystem_names, sudoers_subsystem_ids, debug_files); sudoers_subsystem_names, sudoers_subsystem_ids, debug_files);
} }
TAILQ_FOREACH_SAFE(debug_file, debug_files, entries, debug_next) { TAILQ_FOREACH_SAFE(debug_file, debug_files, entries, debug_next) {

View File

@@ -256,11 +256,10 @@ main(int argc, char *argv[])
/* Register fatal/fatalx callback. */ /* Register fatal/fatalx callback. */
sudo_fatal_callback_register(sudoreplay_cleanup); sudo_fatal_callback_register(sudoreplay_cleanup);
/* Read sudo.conf. */ /* Read sudo.conf and initialize the debug subsystem. */
sudo_conf_read(NULL); sudo_conf_read(NULL, SUDO_CONF_DEBUG);
sudoreplay_debug_instance = sudo_debug_register(getprogname(),
/* Set debug instance to use (if configured). */ NULL, NULL, sudo_conf_debug_files(getprogname()));
sudoreplay_debug_instance = sudo_debug_get_instance(getprogname());
while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) { while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (ch) { switch (ch) {

View File

@@ -138,11 +138,9 @@ main(int argc, char *argv[])
bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */ bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
textdomain("sudoers"); textdomain("sudoers");
/* Read sudo.conf. */ /* Initialize the debug subsystem. */
sudo_conf_read(NULL); sudo_conf_read(NULL, SUDO_CONF_DEBUG);
sudoers_debug_register(sudo_conf_debug_files(getprogname()), getprogname());
/* Set debug instance to use (if configured). */
sudoers_debug_instance = sudo_debug_get_instance(getprogname());
dflag = 0; dflag = 0;
grfile = pwfile = NULL; grfile = pwfile = NULL;

View File

@@ -169,11 +169,9 @@ main(int argc, char *argv[])
/* Register fatal/fatalx callback. */ /* Register fatal/fatalx callback. */
sudo_fatal_callback_register(visudo_cleanup); sudo_fatal_callback_register(visudo_cleanup);
/* Read sudo.conf. */ /* Initialize the debug subsystem. */
sudo_conf_read(NULL); sudo_conf_read(NULL, SUDO_CONF_DEBUG);
sudoers_debug_register(sudo_conf_debug_files(getprogname()), getprogname());
/* Set debug instance to use (if configured). */
sudoers_debug_instance = sudo_debug_get_instance(getprogname());
/* /*
* Arg handling. * Arg handling.

View File

@@ -240,9 +240,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
policy_plugin->options = info->options; policy_plugin->options = info->options;
policy_plugin->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER; policy_plugin->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
policy_plugin->u.generic = plugin; policy_plugin->u.generic = plugin;
TAILQ_INIT(&policy_plugin->debug_files); policy_plugin->debug_files = sudo_conf_debug_files(path);
TAILQ_SWAP(&policy_plugin->debug_files, &info->debug_files,
sudo_debug_file, entries);
} }
} else if (plugin->type == SUDO_IO_PLUGIN) { } else if (plugin->type == SUDO_IO_PLUGIN) {
/* Check for duplicate entries. */ /* Check for duplicate entries. */
@@ -263,9 +261,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
container->options = info->options; container->options = info->options;
container->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER; container->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
container->u.generic = plugin; container->u.generic = plugin;
TAILQ_INIT(&container->debug_files); policy_plugin->debug_files = sudo_conf_debug_files(path);
TAILQ_SWAP(&container->debug_files, &info->debug_files,
sudo_debug_file, entries);
TAILQ_INSERT_TAIL(io_plugins, container, entries); TAILQ_INSERT_TAIL(io_plugins, container, entries);
} }
} }

View File

@@ -154,6 +154,8 @@ main(int argc, char *argv[], char *envp[])
sigset_t mask; sigset_t mask;
debug_decl(main, SUDO_DEBUG_MAIN, sudo_debug_instance) debug_decl(main, SUDO_DEBUG_MAIN, sudo_debug_instance)
/* Make sure fds 0-2 are open and do OS-specific initialization. */
fix_fds();
os_init(argc, argv, envp); os_init(argc, argv, envp);
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
@@ -175,6 +177,11 @@ main(int argc, char *argv[], char *envp[])
/* Use conversation function for sudo_(warn|fatal)x?. */ /* Use conversation function for sudo_(warn|fatal)x?. */
sudo_warn_set_conversation(sudo_conversation); sudo_warn_set_conversation(sudo_conversation);
/* Initialize the debug subsystem. */
sudo_conf_read(NULL, SUDO_CONF_DEBUG);
sudo_debug_instance = sudo_debug_register(getprogname(),
NULL, NULL, sudo_conf_debug_files(getprogname()));
/* Make sure we are setuid root. */ /* Make sure we are setuid root. */
sudo_check_suid(argv[0]); sudo_check_suid(argv[0]);
@@ -182,13 +189,9 @@ main(int argc, char *argv[], char *envp[])
(void) sigemptyset(&mask); (void) sigemptyset(&mask);
(void) sigprocmask(SIG_SETMASK, &mask, NULL); (void) sigprocmask(SIG_SETMASK, &mask, NULL);
save_signals(); save_signals();
fix_fds();
/* Read sudo.conf. */ /* Parse the rest of sudo.conf. */
sudo_conf_read(NULL); sudo_conf_read(NULL, SUDO_CONF_ALL & ~SUDO_CONF_DEBUG);
/* Set debug instance to use with sudo front end (if configured). */
sudo_debug_instance = sudo_debug_get_instance(getprogname());
/* Fill in user_info with user name, uid, cwd, etc. */ /* Fill in user_info with user name, uid, cwd, etc. */
memset(&user_details, 0, sizeof(user_details)); memset(&user_details, 0, sizeof(user_details));
@@ -1101,8 +1104,10 @@ format_plugin_settings(struct plugin_container *plugin,
plugin_settings_size = 2; plugin_settings_size = 2;
for (setting = sudo_settings; setting->name != NULL; setting++) for (setting = sudo_settings; setting->name != NULL; setting++)
plugin_settings_size++; plugin_settings_size++;
TAILQ_FOREACH(debug_file, &plugin->debug_files, entries) if (plugin->debug_files != NULL) {
plugin_settings_size++; TAILQ_FOREACH(debug_file, plugin->debug_files, entries)
plugin_settings_size++;
}
/* Allocate and fill in. */ /* Allocate and fill in. */
plugin_settings = sudo_emallocarray(plugin_settings_size, sizeof(char *)); plugin_settings = sudo_emallocarray(plugin_settings_size, sizeof(char *));
@@ -1119,10 +1124,12 @@ format_plugin_settings(struct plugin_container *plugin,
num_plugin_settings++; num_plugin_settings++;
} }
} }
TAILQ_FOREACH(debug_file, &plugin->debug_files, entries) { if (plugin->debug_files != NULL) {
/* XXX - quote filename? */ TAILQ_FOREACH(debug_file, plugin->debug_files, entries) {
sudo_easprintf(&plugin_settings[num_plugin_settings++], /* XXX - quote filename? */
"debug_flags=%s %s", debug_file->debug_file, debug_file->debug_flags); sudo_easprintf(&plugin_settings[num_plugin_settings++],
"debug_flags=%s %s", debug_file->debug_file, debug_file->debug_flags);
}
} }
plugin_settings[num_plugin_settings] = NULL; plugin_settings[num_plugin_settings] = NULL;

View File

@@ -82,7 +82,7 @@ struct io_plugin_1_1 {
*/ */
struct plugin_container { struct plugin_container {
TAILQ_ENTRY(plugin_container) entries; TAILQ_ENTRY(plugin_container) entries;
struct sudo_conf_debug_file_list debug_files; struct sudo_conf_debug_file_list *debug_files;
const char *name; const char *name;
const char *path; const char *path;
char * const *options; char * const *options;