#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
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;
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);
__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);
#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()
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);
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.
*/
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)
{
* 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;
}
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;
fclose(fp);
free(line);
- /* First, init the debug system. */
- set_debugging(conf_file);
-
- /* Then set paths and variables. */
- set_paths(conf_file);
- set_variables(conf_file);
+ /* 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:
/* Restore locale if needed. */
@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
}
/*
- * 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) {
/* 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) {
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;
/* 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.
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. */
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);
}
}
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, "");
/* 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]);
(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));
plugin_settings_size = 2;
for (setting = sudo_settings; setting->name != NULL; setting++)
plugin_settings_size++;
- TAILQ_FOREACH(debug_file, &plugin->debug_files, entries)
- plugin_settings_size++;
+ 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 *));
num_plugin_settings++;
}
}
- 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);
+ 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;
*/
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;