From 1c3965f53436952f6ca9d72597c8386239b80e95 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Tue, 20 Dec 2011 08:50:07 -0500 Subject: [PATCH] Separate sudo.conf parsing from plugin loading and move the parse functions into the common lib so that visudo, etc. can use them. --- MANIFEST | 4 +- common/Makefile.in | 11 ++- src/Makefile.in | 3 +- src/load_plugins.c | 195 ++---------------------------------------- src/parse_args.c | 6 +- src/sudo.c | 10 +-- src/sudo_plugin_int.h | 10 --- 7 files changed, 27 insertions(+), 212 deletions(-) diff --git a/MANIFEST b/MANIFEST index e3d6f352a..42d92f42f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -16,6 +16,7 @@ common/fmt_string.c common/lbuf.c common/list.c common/setgroups.c +common/sudo_conf.c common/sudo_debug.c common/term.c common/zero_bytes.c @@ -45,10 +46,10 @@ compat/regress/fnmatch/fnm_test.in compat/regress/glob/files compat/regress/glob/globtest.c compat/regress/glob/globtest.in -compat/stdbool.h compat/setenv.c compat/siglist.in compat/snprintf.c +compat/stdbool.h compat/strlcat.c compat/strlcpy.c compat/strsignal.c @@ -105,6 +106,7 @@ include/gettext.h include/lbuf.h include/list.h include/missing.h +include/sudo_conf.h include/sudo_debug.h include/sudo_plugin.h indent.pro diff --git a/common/Makefile.in b/common/Makefile.in index c14932f87..07f738a83 100644 --- a/common/Makefile.in +++ b/common/Makefile.in @@ -42,8 +42,9 @@ DEFS = @OSDEFS@ SHELL = @SHELL@ -LTOBJS = alloc.lo atobool.lo fileops.lo fmt_string.lo lbuf.lo list.lo \ - setgroups.lo sudo_debug.lo term.lo zero_bytes.lo @COMMON_OBJS@ +LTOBJS = alloc.lo atobool.lo fileops.lo fmt_string.lo lbuf.lo \ + list.lo setgroups.lo sudo_conf.lo sudo_debug.lo term.lo \ + zero_bytes.lo @COMMON_OBJS@ all: libcommon.la @@ -118,6 +119,12 @@ list.lo: $(srcdir)/list.c $(top_builddir)/config.h $(incdir)/missing.h \ setgroups.lo: $(srcdir)/setgroups.c $(top_builddir)/config.h \ $(incdir)/missing.h $(incdir)/sudo_debug.h $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/setgroups.c +sudo_conf.lo: $(srcdir)/sudo_conf.c $(top_builddir)/config.h \ + $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \ + $(incdir)/alloc.h $(incdir)/error.h $(incdir)/fileops.h \ + $(top_builddir)/pathnames.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_conf.h $(incdir)/list.h $(incdir)/sudo_debug.h + $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/sudo_conf.c sudo_debug.lo: $(srcdir)/sudo_debug.c $(top_builddir)/config.h \ $(top_srcdir)/compat/stdbool.h $(incdir)/missing.h \ $(incdir)/alloc.h $(incdir)/error.h $(incdir)/gettext.h \ diff --git a/src/Makefile.in b/src/Makefile.in index bc7396f72..792f28883 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -187,7 +187,8 @@ load_plugins.o: $(srcdir)/load_plugins.c $(top_builddir)/config.h \ $(incdir)/missing.h $(incdir)/alloc.h $(incdir)/error.h \ $(incdir)/fileops.h $(incdir)/list.h $(incdir)/sudo_debug.h \ $(incdir)/gettext.h $(incdir)/sudo_plugin.h \ - $(srcdir)/sudo_plugin_int.h $(incdir)/sudo_debug.h + $(srcdir)/sudo_plugin_int.h $(incdir)/sudo_conf.h \ + $(incdir)/list.h $(incdir)/sudo_debug.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(srcdir)/load_plugins.c net_ifs.o: $(srcdir)/net_ifs.c $(top_builddir)/config.h $(incdir)/missing.h \ $(incdir)/alloc.h $(incdir)/error.h $(incdir)/sudo_debug.h \ diff --git a/src/load_plugins.c b/src/load_plugins.c index 5fb677b74..e86c1432c 100644 --- a/src/load_plugins.c +++ b/src/load_plugins.c @@ -42,204 +42,18 @@ #else # include "compat/dlfcn.h" #endif -#include #include -#define SUDO_ERROR_WRAP 0 - #include "sudo.h" #include "sudo_plugin.h" #include "sudo_plugin_int.h" +#include "sudo_conf.h" #include "sudo_debug.h" #ifndef RTLD_GLOBAL # define RTLD_GLOBAL 0 #endif -#ifdef _PATH_SUDO_NOEXEC -const char *noexec_path = _PATH_SUDO_NOEXEC; -#endif - -/* XXX - for parse_args() */ -const char *debug_flags; - -struct sudo_conf_table { - const char *name; - unsigned int namelen; - bool (*setter)(const char *entry, void *data); -}; - -struct sudo_conf_paths { - const char *pname; - unsigned int pnamelen; - const char **pval; -}; - -static bool set_debug(const char *entry, void *data); -static bool set_path(const char *entry, void *data); -static bool set_plugin(const char *entry, void *data); - -static struct plugin_info_list plugin_info_list; - -static struct sudo_conf_table sudo_conf_table[] = { - { "Debug", sizeof("Debug") - 1, set_debug }, - { "Path", sizeof("Path") - 1, set_path }, - { "Plugin", sizeof("Plugin") - 1, set_plugin }, - { NULL } -}; - -static struct sudo_conf_paths sudo_conf_paths[] = { - { "askpass", sizeof("askpass"), &askpass_path }, -#ifdef _PATH_SUDO_NOEXEC - { "noexec", sizeof("noexec"), &noexec_path }, -#endif - { NULL } -}; - -/* - * "Debug progname debug_file debug_flags" - */ -static bool -set_debug(const char *entry, void *data) -{ - size_t filelen, proglen; - const char *progname; - char *debug_file; - - /* Is this debug setting for me? */ - progname = getprogname(); - if (strcmp(progname, "sudoedit") == 0) - progname = "sudo"; - proglen = strlen(progname); - if (strncmp(entry, progname, proglen) != 0 || - !isblank((unsigned char)entry[proglen])) - return false; - entry += proglen + 1; - while (isblank((unsigned char)*entry)) - entry++; - - debug_flags = strpbrk(entry, " \t"); - if (debug_flags == NULL) - return false; - filelen = (size_t)(debug_flags - entry); - while (isblank((unsigned char)*debug_flags)) - debug_flags++; - - /* Set debug file and parse the flags. */ - debug_file = estrndup(entry, filelen); - debug_flags = estrdup(debug_flags); - sudo_debug_init(debug_file, debug_flags); - efree(debug_file); - - return true; -} - -static bool -set_path(const char *entry, void *data) -{ - const char *name, *path; - struct sudo_conf_paths *cur; - - /* Parse Path line */ - name = entry; - path = strpbrk(entry, " \t"); - if (path == NULL) - return false; - while (isblank((unsigned char)*path)) - path++; - - /* Match supported paths, ignore the rest. */ - for (cur = sudo_conf_paths; cur->pname != NULL; cur++) { - if (strncasecmp(name, cur->pname, cur->pnamelen) == 0 && - isblank((unsigned char)name[cur->pnamelen])) { - *(cur->pval) = estrdup(path); - break; - } - } - - return true; -} - -static bool -set_plugin(const char *entry, void *data) -{ - struct plugin_info_list *pil = data; - struct plugin_info *info; - const char *name, *path; - size_t namelen; - - /* Parse Plugin line */ - name = entry; - path = strpbrk(entry, " \t"); - if (path == NULL) - return false; - namelen = (size_t)(path - name); - while (isblank((unsigned char)*path)) - path++; - - info = emalloc(sizeof(*info)); - info->symbol_name = estrndup(name, namelen); - info->path = estrdup(path); - info->prev = info; - info->next = NULL; - tq_append(pil, info); - - return true; -} - -/* - * Reads in /etc/sudo.conf - * Returns a list of plugins. - */ -void -sudo_read_conf(void) -{ - struct sudo_conf_table *cur; - struct plugin_info *info; - FILE *fp; - char *cp; - - if ((fp = fopen(_PATH_SUDO_CONF, "r")) == NULL) - goto done; - - while ((cp = sudo_parseln(fp)) != NULL) { - /* Skip blank or comment lines */ - if (*cp == '\0') - continue; - - for (cur = sudo_conf_table; cur->name != NULL; cur++) { - if (strncasecmp(cp, cur->name, cur->namelen) == 0 && - isblank((unsigned char)cp[cur->namelen])) { - cp += cur->namelen; - while (isblank((unsigned char)*cp)) - cp++; - if (cur->setter(cp, &plugin_info_list)) - break; - } - } - } - fclose(fp); - -done: - if (tq_empty(&plugin_info_list)) { - /* Default policy plugin */ - info = emalloc(sizeof(*info)); - info->symbol_name = "sudoers_policy"; - info->path = SUDOERS_PLUGIN; - info->prev = info; - info->next = NULL; - tq_append(&plugin_info_list, info); - - /* Default I/O plugin */ - info = emalloc(sizeof(*info)); - info->symbol_name = "sudoers_io"; - info->path = SUDOERS_PLUGIN; - info->prev = info; - info->next = NULL; - tq_append(&plugin_info_list, info); - } -} - /* * Load the plugins listed in sudo.conf. */ @@ -247,6 +61,7 @@ bool sudo_load_plugins(struct plugin_container *policy_plugin, struct plugin_container_list *io_plugins) { + struct plugin_info_list *plugins; struct generic_plugin *plugin; struct plugin_container *container; struct plugin_info *info; @@ -254,9 +69,11 @@ sudo_load_plugins(struct plugin_container *policy_plugin, void *handle; char path[PATH_MAX]; bool rval = false; + debug_decl(sudo_load_plugins, SUDO_DEBUG_PLUGIN) /* Walk plugin list. */ - tq_foreach_fwd(&plugin_info_list, info) { + plugins = sudo_conf_plugins(); + tq_foreach_fwd(plugins, info) { if (info->path[0] == '/') { if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) { warningx(_("%s: %s"), info->path, strerror(ENAMETOOLONG)); @@ -339,5 +156,5 @@ sudo_load_plugins(struct plugin_container *policy_plugin, rval = true; done: - return rval; + debug_return_bool(rval); } diff --git a/src/parse_args.c b/src/parse_args.c index babec845a..8a9032348 100644 --- a/src/parse_args.c +++ b/src/parse_args.c @@ -53,9 +53,6 @@ extern char *optarg; extern int optind; -/* XXX */ -extern const char *debug_flags; - int tgetpass_flags; /* @@ -130,7 +127,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp, int flags = 0; /* mode flags */ int valid_flags, ch; int i, j; - char *cp, **env_add, **settings; + char *cp, **env_add, **settings, *debug_flags; int nenv = 0; int env_size = 32; debug_decl(parse_args, SUDO_DEBUG_ARGS) @@ -151,6 +148,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp, sudo_settings[ARG_NET_ADDRS].value = cp; /* Set debug file and flags from sudo.conf. */ + debug_flags = sudo_conf_debug_flags(); if (debug_flags != NULL) sudo_settings[ARG_DEBUG_FLAGS].value = debug_flags; diff --git a/src/sudo.c b/src/sudo.c index 52299537c..15e78e9e5 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -209,7 +209,7 @@ main(int argc, char *argv[], char *envp[]) user_info = get_user_info(&user_details); /* Read sudo.conf. */ - sudo_read_conf(); + sudo_conf_read(); /* Parse command line arguments. */ sudo_mode = parse_args(argc, argv, &nargc, &nargv, &settings, &env_add); @@ -884,13 +884,13 @@ disable_execute(struct command_details *details) */ # if defined(__darwin__) || defined(__APPLE__) nenvp[env_len++] = "DYLD_FORCE_FLAT_NAMESPACE="; - cp = fmt_string("DYLD_INSERT_LIBRARIES", noexec_path); + cp = fmt_string("DYLD_INSERT_LIBRARIES", sudo_conf_noexec_path()); # elif defined(__osf__) || defined(__sgi) - easprintf(&cp, "_RLD_LIST=%s:DEFAULT", noexec_path); + easprintf(&cp, "_RLD_LIST=%s:DEFAULT", sudo_conf_noexec_path()); # elif defined(_AIX) - cp = fmt_string("LDR_PRELOAD", noexec_path); + cp = fmt_string("LDR_PRELOAD", sudo_conf_noexec_path()); # else - cp = fmt_string("LD_PRELOAD", noexec_path); + cp = fmt_string("LD_PRELOAD", sudo_conf_noexec_path()); # endif if (cp == NULL) error(1, NULL); diff --git a/src/sudo_plugin_int.h b/src/sudo_plugin_int.h index 364bd0c44..135c12344 100644 --- a/src/sudo_plugin_int.h +++ b/src/sudo_plugin_int.h @@ -48,15 +48,6 @@ struct io_plugin_1_0 { /* * Sudo plugin internals. */ - -struct plugin_info { - struct plugin_info *prev; /* required */ - struct plugin_info *next; /* required */ - const char *path; - const char *symbol_name; -}; -TQ_DECLARE(plugin_info) - struct plugin_container { struct plugin_container *prev; /* required */ struct plugin_container *next; /* required */ @@ -78,7 +69,6 @@ int sudo_conversation(int num_msgs, const struct sudo_conv_message msgs[], struct sudo_conv_reply replies[]); int _sudo_printf(int msg_type, const char *fmt, ...); -void sudo_read_conf(void); bool sudo_load_plugins(struct plugin_container *policy_plugin, struct plugin_container_list *io_plugins); -- 2.40.0