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.
This commit is contained in:
Todd C. Miller
2023-08-21 09:21:54 -06:00
parent 9e53d903ea
commit 87571dab0a
12 changed files with 82 additions and 91 deletions

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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);
}
/*

View File

@@ -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);
}
/*

View File

@@ -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);

View File

@@ -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.

View File

@@ -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);

View File

@@ -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[]);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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.

View File

@@ -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;
}
}