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:
@@ -19,6 +19,14 @@
|
||||
|
||||
#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_STATIC 1
|
||||
#define GROUP_SOURCE_DYNAMIC 2
|
||||
@@ -28,7 +36,6 @@ TAILQ_HEAD(sudo_conf_debug_file_list, sudo_debug_file);
|
||||
|
||||
struct plugin_info {
|
||||
TAILQ_ENTRY(plugin_info) entries;
|
||||
struct sudo_conf_debug_file_list debug_files;
|
||||
const char *path;
|
||||
const char *symbol_name;
|
||||
char * const * options;
|
||||
@@ -44,8 +51,8 @@ struct sudo_conf_debug {
|
||||
TAILQ_HEAD(sudo_conf_debug_list, sudo_conf_debug);
|
||||
|
||||
/* Read main sudo.conf file. */
|
||||
__dso_public void sudo_conf_read_v1(const char *conf_file);
|
||||
#define sudo_conf_read(_a) sudo_conf_read_v1((_a))
|
||||
__dso_public void sudo_conf_read_v1(const char *conf_file, int conf_types);
|
||||
#define sudo_conf_read(_a, _b) sudo_conf_read_v1((_a), (_b))
|
||||
|
||||
/* Accessor functions. */
|
||||
__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_plugin_dir_path_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 bool sudo_conf_disable_coredump_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_plugin_dir_path() sudo_conf_plugin_dir_path_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_disable_coredump() sudo_conf_disable_coredump_v1()
|
||||
#define sudo_conf_probe_interfaces() sudo_conf_probe_interfaces_v1()
|
||||
|
@@ -63,7 +63,7 @@ main(int argc, char *argv[])
|
||||
fprintf(stderr, "usage: %s conf_file\n", getprogname());
|
||||
exit(1);
|
||||
}
|
||||
sudo_conf_read(argv[1]);
|
||||
sudo_conf_read(argv[1], SUDO_CONF_ALL);
|
||||
sudo_conf_dump();
|
||||
|
||||
exit(0);
|
||||
|
@@ -323,58 +323,9 @@ store_plugin(const char *cp, unsigned int lineno)
|
||||
info->path = sudo_estrndup(path, pathlen);
|
||||
info->options = options;
|
||||
info->lineno = lineno;
|
||||
TAILQ_INIT(&info->debug_files);
|
||||
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.
|
||||
*/
|
||||
@@ -558,6 +509,42 @@ sudo_conf_debugging_v1(void)
|
||||
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
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
FILE *fp;
|
||||
char *cp, *line = NULL;
|
||||
char *line = NULL;
|
||||
char *prev_locale = sudo_estrdup(setlocale(LC_ALL, NULL));
|
||||
unsigned int conf_lineno = 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) {
|
||||
struct sudo_conf_table *cur;
|
||||
unsigned int i;
|
||||
char *cp;
|
||||
|
||||
if (*(cp = line) == '\0')
|
||||
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 &&
|
||||
isblank((unsigned char)cp[cur->namelen])) {
|
||||
cp += cur->namelen;
|
||||
@@ -641,11 +633,10 @@ sudo_conf_read_v1(const char *conf_file)
|
||||
fclose(fp);
|
||||
free(line);
|
||||
|
||||
/* First, init the debug system. */
|
||||
set_debugging(conf_file);
|
||||
|
||||
/* Then set paths and variables. */
|
||||
/* Parse paths and variables as needed. */
|
||||
if (ISSET(conf_types, SUDO_CONF_PATHS))
|
||||
set_paths(conf_file);
|
||||
if (ISSET(conf_types, SUDO_CONF_SETTINGS))
|
||||
set_variables(conf_file);
|
||||
|
||||
done:
|
||||
|
@@ -1,5 +1,6 @@
|
||||
@COMPAT_EXP@initprogname
|
||||
sudo_conf_askpass_path_v1
|
||||
sudo_conf_debug_files_v1
|
||||
sudo_conf_debugging_v1
|
||||
sudo_conf_disable_coredump_v1
|
||||
sudo_conf_group_source_v1
|
||||
|
@@ -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
|
||||
* debug subsystem.
|
||||
* Register the specified debug files and program with the
|
||||
* debug subsystem, freeing the debug list when done.
|
||||
*/
|
||||
void
|
||||
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;
|
||||
|
||||
/* Setup debugging if indicated. */
|
||||
if (!TAILQ_EMPTY(debug_files)) {
|
||||
if (plugin_path != NULL) {
|
||||
sudoers_debug_instance = sudo_debug_register(plugin_path,
|
||||
if (debug_files != NULL && !TAILQ_EMPTY(debug_files)) {
|
||||
if (program != NULL) {
|
||||
sudoers_debug_instance = sudo_debug_register(program,
|
||||
sudoers_subsystem_names, sudoers_subsystem_ids, debug_files);
|
||||
}
|
||||
TAILQ_FOREACH_SAFE(debug_file, debug_files, entries, debug_next) {
|
||||
|
@@ -256,11 +256,10 @@ main(int argc, char *argv[])
|
||||
/* Register fatal/fatalx callback. */
|
||||
sudo_fatal_callback_register(sudoreplay_cleanup);
|
||||
|
||||
/* Read sudo.conf. */
|
||||
sudo_conf_read(NULL);
|
||||
|
||||
/* Set debug instance to use (if configured). */
|
||||
sudoreplay_debug_instance = sudo_debug_get_instance(getprogname());
|
||||
/* Read sudo.conf and initialize the debug subsystem. */
|
||||
sudo_conf_read(NULL, SUDO_CONF_DEBUG);
|
||||
sudoreplay_debug_instance = sudo_debug_register(getprogname(),
|
||||
NULL, NULL, sudo_conf_debug_files(getprogname()));
|
||||
|
||||
while ((ch = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
|
@@ -138,11 +138,9 @@ main(int argc, char *argv[])
|
||||
bindtextdomain("sudoers", LOCALEDIR); /* XXX - should have own domain */
|
||||
textdomain("sudoers");
|
||||
|
||||
/* Read sudo.conf. */
|
||||
sudo_conf_read(NULL);
|
||||
|
||||
/* Set debug instance to use (if configured). */
|
||||
sudoers_debug_instance = sudo_debug_get_instance(getprogname());
|
||||
/* Initialize the debug subsystem. */
|
||||
sudo_conf_read(NULL, SUDO_CONF_DEBUG);
|
||||
sudoers_debug_register(sudo_conf_debug_files(getprogname()), getprogname());
|
||||
|
||||
dflag = 0;
|
||||
grfile = pwfile = NULL;
|
||||
|
@@ -169,11 +169,9 @@ main(int argc, char *argv[])
|
||||
/* Register fatal/fatalx callback. */
|
||||
sudo_fatal_callback_register(visudo_cleanup);
|
||||
|
||||
/* Read sudo.conf. */
|
||||
sudo_conf_read(NULL);
|
||||
|
||||
/* Set debug instance to use (if configured). */
|
||||
sudoers_debug_instance = sudo_debug_get_instance(getprogname());
|
||||
/* Initialize the debug subsystem. */
|
||||
sudo_conf_read(NULL, SUDO_CONF_DEBUG);
|
||||
sudoers_debug_register(sudo_conf_debug_files(getprogname()), getprogname());
|
||||
|
||||
/*
|
||||
* Arg handling.
|
||||
|
@@ -240,9 +240,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
|
||||
policy_plugin->options = info->options;
|
||||
policy_plugin->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
|
||||
policy_plugin->u.generic = plugin;
|
||||
TAILQ_INIT(&policy_plugin->debug_files);
|
||||
TAILQ_SWAP(&policy_plugin->debug_files, &info->debug_files,
|
||||
sudo_debug_file, entries);
|
||||
policy_plugin->debug_files = sudo_conf_debug_files(path);
|
||||
}
|
||||
} else if (plugin->type == SUDO_IO_PLUGIN) {
|
||||
/* Check for duplicate entries. */
|
||||
@@ -263,9 +261,7 @@ sudo_load_plugin(struct plugin_container *policy_plugin,
|
||||
container->options = info->options;
|
||||
container->debug_instance = SUDO_DEBUG_INSTANCE_INITIALIZER;
|
||||
container->u.generic = plugin;
|
||||
TAILQ_INIT(&container->debug_files);
|
||||
TAILQ_SWAP(&container->debug_files, &info->debug_files,
|
||||
sudo_debug_file, entries);
|
||||
policy_plugin->debug_files = sudo_conf_debug_files(path);
|
||||
TAILQ_INSERT_TAIL(io_plugins, container, entries);
|
||||
}
|
||||
}
|
||||
|
23
src/sudo.c
23
src/sudo.c
@@ -154,6 +154,8 @@ main(int argc, char *argv[], char *envp[])
|
||||
sigset_t mask;
|
||||
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);
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
@@ -175,6 +177,11 @@ main(int argc, char *argv[], char *envp[])
|
||||
/* Use conversation function for sudo_(warn|fatal)x?. */
|
||||
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. */
|
||||
sudo_check_suid(argv[0]);
|
||||
|
||||
@@ -182,13 +189,9 @@ main(int argc, char *argv[], char *envp[])
|
||||
(void) sigemptyset(&mask);
|
||||
(void) sigprocmask(SIG_SETMASK, &mask, NULL);
|
||||
save_signals();
|
||||
fix_fds();
|
||||
|
||||
/* Read sudo.conf. */
|
||||
sudo_conf_read(NULL);
|
||||
|
||||
/* Set debug instance to use with sudo front end (if configured). */
|
||||
sudo_debug_instance = sudo_debug_get_instance(getprogname());
|
||||
/* Parse the rest of sudo.conf. */
|
||||
sudo_conf_read(NULL, SUDO_CONF_ALL & ~SUDO_CONF_DEBUG);
|
||||
|
||||
/* Fill in user_info with user name, uid, cwd, etc. */
|
||||
memset(&user_details, 0, sizeof(user_details));
|
||||
@@ -1101,8 +1104,10 @@ format_plugin_settings(struct plugin_container *plugin,
|
||||
plugin_settings_size = 2;
|
||||
for (setting = sudo_settings; setting->name != NULL; setting++)
|
||||
plugin_settings_size++;
|
||||
TAILQ_FOREACH(debug_file, &plugin->debug_files, entries)
|
||||
if (plugin->debug_files != NULL) {
|
||||
TAILQ_FOREACH(debug_file, plugin->debug_files, entries)
|
||||
plugin_settings_size++;
|
||||
}
|
||||
|
||||
/* Allocate and fill in. */
|
||||
plugin_settings = sudo_emallocarray(plugin_settings_size, sizeof(char *));
|
||||
@@ -1119,11 +1124,13 @@ format_plugin_settings(struct plugin_container *plugin,
|
||||
num_plugin_settings++;
|
||||
}
|
||||
}
|
||||
TAILQ_FOREACH(debug_file, &plugin->debug_files, entries) {
|
||||
if (plugin->debug_files != NULL) {
|
||||
TAILQ_FOREACH(debug_file, plugin->debug_files, entries) {
|
||||
/* XXX - quote filename? */
|
||||
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;
|
||||
|
||||
debug_return_ptr(plugin_settings);
|
||||
|
@@ -82,7 +82,7 @@ struct io_plugin_1_1 {
|
||||
*/
|
||||
struct plugin_container {
|
||||
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 *path;
|
||||
char * const *options;
|
||||
|
Reference in New Issue
Block a user