From 87571dab0a180b32f21aebc968dce5a5fe44f71a Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 21 Aug 2023 09:21:54 -0600 Subject: [PATCH] Add struct sudoers_conf to struct sudoers_plugin_context. There's now no need to pass this directly to init_parser() since we already pass in a pointer to a sudoers_context struct. --- plugins/sudoers/cvtsudoers.c | 4 +- plugins/sudoers/file.c | 6 +-- plugins/sudoers/gram.c | 9 ++-- plugins/sudoers/gram.y | 9 ++-- plugins/sudoers/parse.h | 24 +-------- plugins/sudoers/policy.c | 18 ++----- plugins/sudoers/regress/fuzz/fuzz_sudoers.c | 2 +- .../regress/iolog_plugin/check_iolog_plugin.c | 2 +- plugins/sudoers/sudoers.c | 4 +- plugins/sudoers/sudoers.h | 49 ++++++++++++++----- plugins/sudoers/testsudoers.c | 13 +++-- plugins/sudoers/visudo.c | 33 ++++++------- 12 files changed, 82 insertions(+), 91 deletions(-) diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c index a8907ebe9..de61086e8 100644 --- a/plugins/sudoers/cvtsudoers.c +++ b/plugins/sudoers/cvtsudoers.c @@ -106,7 +106,7 @@ int main(int argc, char *argv[]) { struct sudoers_parse_tree_list parse_trees = TAILQ_HEAD_INITIALIZER(parse_trees); - struct sudoers_context ctx = { { NULL } }; + struct sudoers_context ctx = SUDOERS_CONTEXT_INITIALIZER; struct sudoers_parse_tree merged_tree, *parse_tree = NULL; struct cvtsudoers_config *conf = NULL; enum sudoers_formats output_format = format_ldif; @@ -776,7 +776,7 @@ parse_sudoers(struct sudoers_context *ctx, const char *input_file, input_file = "stdin"; } else if ((sudoersin = fopen(input_file, "r")) == NULL) sudo_fatal(U_("unable to open %s"), input_file); - init_parser(ctx, input_file, NULL); + init_parser(ctx, input_file); if (sudoersparse() && !parse_error) { sudo_warnx(U_("failed to parse %s file, unknown error"), input_file); parse_error = true; diff --git a/plugins/sudoers/file.c b/plugins/sudoers/file.c index ced7db5cd..4e18a7d14 100644 --- a/plugins/sudoers/file.c +++ b/plugins/sudoers/file.c @@ -72,10 +72,10 @@ sudo_file_open(struct sudoers_context *ctx, struct sudo_nss *nss) handle = malloc(sizeof(*handle)); if (handle != NULL) { - const struct sudoers_parser_config *conf = policy_sudoers_conf(); - handle->fp = open_sudoers(conf->sudoers_path, &outfile, false, NULL); + handle->fp = open_sudoers(ctx->parser_conf.sudoers_path, &outfile, + false, NULL); if (handle->fp != NULL) { - init_parser(ctx, NULL, conf); + init_parser(ctx, NULL); init_parse_tree(&handle->parse_tree, NULL, NULL, ctx, nss); if (outfile != NULL) { /* Update path to open sudoers file. */ diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c index d9048a813..a7faa59c2 100644 --- a/plugins/sudoers/gram.c +++ b/plugins/sudoers/gram.c @@ -3989,8 +3989,7 @@ free_parse_tree(struct sudoers_parse_tree *parse_tree) * the current sudoers file to path. */ bool -init_parser(struct sudoers_context *ctx, const char *file, - const struct sudoers_parser_config *conf) +init_parser(struct sudoers_context *ctx, const char *file) { bool ret = true; debug_decl(init_parser, SUDOERS_DEBUG_PARSER); @@ -4001,8 +4000,8 @@ init_parser(struct sudoers_context *ctx, const char *file, init_lexer(); parse_error = false; - if (conf != NULL) { - parser_conf = *conf; + if (ctx != NULL) { + parser_conf = ctx->parser_conf; } else { const struct sudoers_parser_config def_conf = SUDOERS_PARSER_CONFIG_INITIALIZER; @@ -4036,7 +4035,7 @@ init_parser(struct sudoers_context *ctx, const char *file, bool reset_parser(void) { - return init_parser(NULL, NULL, NULL); + return init_parser(NULL, NULL); } /* diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y index b718f17e0..2d0e39953 100644 --- a/plugins/sudoers/gram.y +++ b/plugins/sudoers/gram.y @@ -1806,8 +1806,7 @@ free_parse_tree(struct sudoers_parse_tree *parse_tree) * the current sudoers file to path. */ bool -init_parser(struct sudoers_context *ctx, const char *file, - const struct sudoers_parser_config *conf) +init_parser(struct sudoers_context *ctx, const char *file) { bool ret = true; debug_decl(init_parser, SUDOERS_DEBUG_PARSER); @@ -1818,8 +1817,8 @@ init_parser(struct sudoers_context *ctx, const char *file, init_lexer(); parse_error = false; - if (conf != NULL) { - parser_conf = *conf; + if (ctx != NULL) { + parser_conf = ctx->parser_conf; } else { const struct sudoers_parser_config def_conf = SUDOERS_PARSER_CONFIG_INITIALIZER; @@ -1853,7 +1852,7 @@ init_parser(struct sudoers_context *ctx, const char *file, bool reset_parser(void) { - return init_parser(NULL, NULL, NULL); + return init_parser(NULL, NULL); } /* diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h index 33985e378..01e6b25d9 100644 --- a/plugins/sudoers/parse.h +++ b/plugins/sudoers/parse.h @@ -334,28 +334,6 @@ struct cmnd_info { */ typedef void (*sudoers_lookup_callback_fn_t)(const struct sudoers_parse_tree *parse_tree, const struct userspec *us, int user_match, const struct privilege *priv, int host_match, const struct cmndspec *cs, int date_match, int runas_match, int cmnd_match, void *closure); -/* - * Parse configuration settings, passed to init_parser(). - */ -struct sudoers_parser_config { - const char *sudoers_path; - bool strict; - bool recovery; - int verbose; - mode_t sudoers_mode; - uid_t sudoers_uid; - gid_t sudoers_gid; -}; -#define SUDOERS_PARSER_CONFIG_INITIALIZER { \ - NULL, /* sudoers_path */ \ - false, /* strict */ \ - true, /* recovery */ \ - 1, /* verbose level 1 */ \ - SUDOERS_MODE, \ - SUDOERS_UID, \ - SUDOERS_GID \ -} - /* * The parser passes pointers to data structures that are not stored anywhere. * We add them to the leak list at allocation time and remove them from @@ -419,7 +397,7 @@ void free_userspec(struct userspec *us); void free_userspecs(struct userspec_list *usl); void free_default(struct defaults *def); void free_defaults(struct defaults_list *defs); -bool init_parser(struct sudoers_context *ctx, const char *file, const struct sudoers_parser_config *conf); +bool init_parser(struct sudoers_context *ctx, const char *file); void init_parse_tree(struct sudoers_parse_tree *parse_tree, char *lhost, char *shost, struct sudoers_context *ctx, struct sudo_nss *nss); void free_parse_tree(struct sudoers_parse_tree *parse_tree); bool parser_leak_add(enum parser_leak_types type, void *v); diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c index 9b8cb8418..1ce2b0e80 100644 --- a/plugins/sudoers/policy.c +++ b/plugins/sudoers/policy.c @@ -50,7 +50,6 @@ struct sudoers_exec_args { char ***info; }; -static struct sudoers_parser_config sudoers_conf = SUDOERS_PARSER_CONFIG_INITIALIZER; static unsigned int sudo_version; static const char *interfaces_string; sudo_conv_t sudo_conv; @@ -131,7 +130,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, if (val == -1) { INVALID("error_recovery="); /* Not a fatal error. */ } else { - sudoers_conf.recovery = val; + ctx->parser_conf.recovery = val; } continue; } @@ -142,7 +141,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, } if (MATCHES(*cur, "sudoers_uid=")) { p = *cur + sizeof("sudoers_uid=") - 1; - sudoers_conf.sudoers_uid = (uid_t)sudo_strtoid(p, &errstr); + ctx->parser_conf.sudoers_uid = (uid_t)sudo_strtoid(p, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; @@ -151,7 +150,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, } if (MATCHES(*cur, "sudoers_gid=")) { p = *cur + sizeof("sudoers_gid=") - 1; - sudoers_conf.sudoers_gid = (gid_t)sudo_strtoid(p, &errstr); + ctx->parser_conf.sudoers_gid = (gid_t)sudo_strtoid(p, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; @@ -160,7 +159,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, } if (MATCHES(*cur, "sudoers_mode=")) { p = *cur + sizeof("sudoers_mode=") - 1; - sudoers_conf.sudoers_mode = sudo_strtomode(p, &errstr); + ctx->parser_conf.sudoers_mode = sudo_strtomode(p, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; @@ -179,7 +178,7 @@ sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, } } } - sudoers_conf.sudoers_path = path_sudoers; + ctx->parser_conf.sudoers_path = path_sudoers; /* Parse command line settings. */ ctx->settings.flags = 0; @@ -636,13 +635,6 @@ bad: debug_return_uint(MODE_ERROR); } -/* Return the policy's struct sudoers_parser_config. */ -const struct sudoers_parser_config * -policy_sudoers_conf(void) -{ - return &sudoers_conf; -} - /* * Store the execution environment and other front-end settings. * Builds up the command_info list and sets argv and envp. diff --git a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c index ad6c82916..e86c2a21f 100644 --- a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c +++ b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c @@ -317,7 +317,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) /* Initialize defaults and parse sudoers. */ init_defaults(); - init_parser(&ctx, "sudoers", NULL); + init_parser(&ctx, "sudoers"); sudoersrestart(fp); sudoersparse(); reparent_parse_tree(&parse_tree); diff --git a/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c b/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c index 63f03b656..8ed9768ef 100644 --- a/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c +++ b/plugins/sudoers/regress/iolog_plugin/check_iolog_plugin.c @@ -40,7 +40,7 @@ sudo_printf_t sudo_printf; sudo_conv_t sudo_conv; struct sudo_plugin_event * (*plugin_event_alloc)(void); -static struct sudoers_context io_ctx; +static struct sudoers_context io_ctx = SUDOERS_CONTEXT_INITIALIZER; sudo_dso_public int main(int argc, char *argv[], char *envp[]); diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 1c3d98797..b455f3f35 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -82,9 +82,7 @@ static bool tty_present(struct sudoers_context *ctx); unsigned int sudo_mode; static char *prev_user; -static struct sudoers_context sudoers_ctx = { - { _PATH_LDAP_CONF, _PATH_LDAP_SECRET, _PATH_SUDO_PLUGIN_DIR } -}; +static struct sudoers_context sudoers_ctx = SUDOERS_CONTEXT_INITIALIZER; static struct sudo_nss_list *snl; static bool unknown_runas_uid; static bool unknown_runas_gid; diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h index 0404ff9e1..1fc437545 100644 --- a/plugins/sudoers/sudoers.h +++ b/plugins/sudoers/sudoers.h @@ -75,6 +75,39 @@ struct group_list { char **groups; }; +/* + * Parse configuration settings. + */ +struct sudoers_parser_config { + const char *sudoers_path; + bool strict; + bool recovery; + int verbose; + mode_t sudoers_mode; + uid_t sudoers_uid; + gid_t sudoers_gid; +}; +#define SUDOERS_PARSER_CONFIG_INITIALIZER { \ + NULL, /* sudoers_path */ \ + false, /* strict */ \ + true, /* recovery */ \ + 1, /* verbose level 1 */ \ + SUDOERS_MODE, \ + SUDOERS_UID, \ + SUDOERS_GID \ +} + +/* + * Settings passed in from the sudo front-end. + */ +struct sudoers_plugin_settings { + const char *plugin_dir; + const char *ldap_conf; + const char *ldap_secret; + unsigned int flags; + int max_groups; +}; + /* * Info pertaining to the invoking user. */ @@ -144,21 +177,16 @@ struct sudoers_runas_context { #endif }; -/* - * Settings passed in from the sudo front-end. - */ -struct sudoers_plugin_settings { - const char *plugin_dir; - const char *ldap_conf; - const char *ldap_secret; - unsigned int flags; - int max_groups; -}; +#define SUDOERS_CONTEXT_INITIALIZER { \ + SUDOERS_PARSER_CONFIG_INITIALIZER, \ + { _PATH_LDAP_CONF, _PATH_LDAP_SECRET, _PATH_SUDO_PLUGIN_DIR } \ +} /* * Global configuration for the sudoers module. */ struct sudoers_context { + struct sudoers_parser_config parser_conf; struct sudoers_plugin_settings settings; struct sudoers_user_context user; struct sudoers_runas_context runas; @@ -418,7 +446,6 @@ void sudoers_debug_deregister(void); /* policy.c */ unsigned int sudoers_policy_deserialize_info(struct sudoers_context *ctx, void *v, struct defaults_list *defaults); bool sudoers_policy_store_result(struct sudoers_context *ctx, bool accepted, char *argv[], char *envp[], mode_t cmnd_umask, char *iolog_path, void *v); -const struct sudoers_parser_config *policy_sudoers_conf(void); /* group_plugin.c */ void group_plugin_unload(void); diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index 784d48472..21aa5991c 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -92,8 +92,7 @@ sudo_dso_public int main(int argc, char *argv[]); int main(int argc, char *argv[]) { - struct sudoers_parser_config sudoers_conf = SUDOERS_PARSER_CONFIG_INITIALIZER; - struct sudoers_context test_ctx = { { _PATH_SUDO_PLUGIN_DIR } }; + struct sudoers_context test_ctx = SUDOERS_CONTEXT_INITIALIZER; struct sudo_nss_list snl = TAILQ_HEAD_INITIALIZER(snl); enum sudoers_formats input_format = format_sudoers; struct sudo_nss testsudoers_nss; @@ -144,7 +143,7 @@ main(int argc, char *argv[]) id = sudo_strtoid(optarg, &errstr); if (errstr != NULL) sudo_fatalx("group-ID %s: %s", optarg, errstr); - sudoers_conf.sudoers_gid = (gid_t)id; + test_ctx.parser_conf.sudoers_gid = (gid_t)id; break; case 'g': runas_group = optarg; @@ -205,7 +204,7 @@ main(int argc, char *argv[]) id = sudo_strtoid(optarg, &errstr); if (errstr != NULL) sudo_fatalx("user-ID %s: %s", optarg, errstr); - sudoers_conf.sudoers_uid = (uid_t)id; + test_ctx.parser_conf.sudoers_uid = (uid_t)id; break; case 'u': runas_user = optarg; @@ -349,9 +348,9 @@ main(int argc, char *argv[]) } /* Initialize the parser and set sudoers filename to "sudoers". */ - sudoers_conf.strict = true; - sudoers_conf.verbose = 2; - init_parser(&test_ctx, "sudoers", &sudoers_conf); + test_ctx.parser_conf.strict = true; + test_ctx.parser_conf.verbose = 2; + init_parser(&test_ctx, "sudoers"); /* * Set runas passwd/group entries based on command line or sudoers. diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c index 1570b5034..ce2192b3c 100644 --- a/plugins/sudoers/visudo.c +++ b/plugins/sudoers/visudo.c @@ -96,7 +96,7 @@ static bool visudo_track_error(const struct sudoers_context *ctx, const char *fi static int print_unused(struct sudoers_parse_tree *, struct alias *, void *); static bool reparse_sudoers(struct sudoers_context *ctx, char *, int, char **, bool, bool); static int run_command(const char *, char *const *); -static void parse_sudoers_options(void); +static void parse_sudoers_options(struct sudoers_context *ctx); static void setup_signals(void); static void visudo_cleanup(void); sudo_noreturn static void export_sudoers(const char *infile, const char *outfile); @@ -110,7 +110,6 @@ extern void get_hostname(struct sudoers_context *ctx); */ static const char *path_sudoers = _PATH_SUDOERS; static struct sudoersfile_list sudoerslist = TAILQ_HEAD_INITIALIZER(sudoerslist); -static struct sudoers_parser_config sudoers_conf = SUDOERS_PARSER_CONFIG_INITIALIZER; static bool checkonly; static bool edit_includes = true; static unsigned int errors; @@ -134,7 +133,7 @@ sudo_dso_public int main(int argc, char *argv[]); int main(int argc, char *argv[]) { - struct sudoers_context ctx = { { NULL } }; + struct sudoers_context ctx = SUDOERS_CONTEXT_INITIALIZER; struct sudoersfile *sp; char *editor, **editor_argv; const char *export_path = NULL; @@ -174,7 +173,7 @@ main(int argc, char *argv[]) return EXIT_FAILURE; /* Parse sudoers plugin options, if any. */ - parse_sudoers_options(); + parse_sudoers_options(&ctx); /* * Arg handling. @@ -241,11 +240,11 @@ main(int argc, char *argv[]) if (fflag) { /* Looser owner/permission checks for an uninstalled sudoers file. */ if (!use_owner) { - sudoers_conf.sudoers_uid = (uid_t)-1; - sudoers_conf.sudoers_gid = (gid_t)-1; + ctx.parser_conf.sudoers_uid = (uid_t)-1; + ctx.parser_conf.sudoers_gid = (gid_t)-1; } if (!use_perms) - sudoers_conf.sudoers_mode |= S_IWUSR; + ctx.parser_conf.sudoers_mode |= S_IWUSR; } else { /* Check/set owner and mode for installed sudoers file. */ use_owner = true; @@ -289,10 +288,10 @@ main(int argc, char *argv[]) * Parse the existing sudoers file(s) to highlight any existing * errors and to pull in editor and env_editor conf values. */ - sudoers_conf.strict = true; - sudoers_conf.verbose = quiet ? 0 : 2; - sudoers_conf.sudoers_path = path_sudoers; - init_parser(&ctx, NULL, &sudoers_conf); + ctx.parser_conf.strict = true; + ctx.parser_conf.verbose = quiet ? 0 : 2; + ctx.parser_conf.sudoers_path = path_sudoers; + init_parser(&ctx, NULL); if ((sudoersin = open_sudoers(path_sudoers, &sudoers, true, NULL)) == NULL) return EXIT_FAILURE; sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); @@ -667,7 +666,7 @@ reparse_sudoers(struct sudoers_context *ctx, char *editor, int editor_argc, /* Clean slate for each parse */ if (!init_defaults()) sudo_fatalx("%s", U_("unable to initialize sudoers default values")); - init_parser(ctx, sp->opath, &sudoers_conf); + init_parser(ctx, sp->opath); sp->errorline = -1; /* Parse the sudoers temp file(s) */ @@ -995,7 +994,7 @@ check_syntax(struct sudoers_context *ctx, const char *path, bool quiet, goto done; } } - init_parser(ctx, fname, &sudoers_conf); + init_parser(ctx, fname); sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale); if (sudoersparse() && !parse_error) { if (!quiet) @@ -1235,7 +1234,7 @@ print_unused(struct sudoers_parse_tree *parse_tree, struct alias *a, void *v) } static void -parse_sudoers_options(void) +parse_sudoers_options(struct sudoers_context *ctx) { struct plugin_info_list *plugins; debug_decl(parse_sudoers_options, SUDOERS_DEBUG_UTIL); @@ -1267,21 +1266,21 @@ parse_sudoers_options(void) p = *cur + sizeof("sudoers_uid=") - 1; id = sudo_strtoid(p, &errstr); if (errstr == NULL) - sudoers_conf.sudoers_uid = (uid_t)id; + ctx->parser_conf.sudoers_uid = (uid_t)id; continue; } if (MATCHES(*cur, "sudoers_gid=")) { p = *cur + sizeof("sudoers_gid=") - 1; id = sudo_strtoid(p, &errstr); if (errstr == NULL) - sudoers_conf.sudoers_gid = (gid_t)id; + ctx->parser_conf.sudoers_gid = (gid_t)id; continue; } if (MATCHES(*cur, "sudoers_mode=")) { p = *cur + sizeof("sudoers_mode=") - 1; mode = sudo_strtomode(p, &errstr); if (errstr == NULL) - sudoers_conf.sudoers_mode = mode; + ctx->parser_conf.sudoers_mode = mode; continue; } }