Add struct sudoers_parser_config and pass it to init_parser().

This struct contains parser configuration such as the sudoers file
uid/gid/mode and parse flags such as verbose, strict and recovery.
This commit is contained in:
Todd C. Miller
2023-05-08 17:03:31 -06:00
parent fb9d0d79a7
commit 9d7c30c5a8
15 changed files with 604 additions and 477 deletions

View File

@@ -770,7 +770,7 @@ parse_sudoers(const char *input_file, struct cvtsudoers_config *conf)
input_file = "stdin";
} else if ((sudoersin = fopen(input_file, "r")) == NULL)
sudo_fatal(U_("unable to open %s"), input_file);
init_parser(input_file, NULL, false, 1);
init_parser(input_file, NULL, NULL);
if (sudoersparse() && !parse_error) {
sudo_warnx(U_("failed to parse %s file, unknown error"), input_file);
parse_error = true;

View File

@@ -73,8 +73,10 @@ sudo_file_open(struct sudo_nss *nss)
handle = malloc(sizeof(*handle));
if (handle != NULL) {
handle->fp = open_sudoers(policy_path_sudoers(), &outfile, false, NULL);
const char *path_sudoers = policy_path_sudoers();
handle->fp = open_sudoers(path_sudoers, &outfile, false, NULL);
if (handle->fp != NULL) {
init_parser(NULL, path_sudoers, policy_sudoers_conf());
init_parse_tree(&handle->parse_tree, NULL, NULL, nss);
if (outfile != NULL) {
/* Update path to open sudoers file. */
@@ -108,7 +110,7 @@ sudo_file_parse(const struct sudo_nss *nss)
sudoersin = handle->fp;
error = sudoersparse();
if (error || (parse_error && !sudoers_recovery)) {
if (error || (parse_error && !sudoers_error_recovery())) {
/* unrecoverable error */
debug_return_ptr(NULL);
}

File diff suppressed because it is too large Load Diff

View File

@@ -48,15 +48,15 @@
/*
* Globals
*/
bool sudoers_recovery = true;
bool sudoers_strict = false;
bool parse_error = false;
static struct sudoers_parser_config parser_conf =
SUDOERS_PARSER_CONFIG_INITIALIZER;
/* Optional logging function for parse errors. */
sudoers_logger_t sudoers_error_hook;
static int alias_line, alias_column;
static int sudoers_verbose = 1;
#ifdef NO_LEAKS
static struct parser_leak_list parser_leak_list =
@@ -216,17 +216,19 @@ entry : '\n' {
yyerrok;
}
| include {
const bool success = push_include($1, sudoers_verbose);
const bool success = push_include($1,
parser_conf.verbose);
parser_leak_remove(LEAK_PTR, $1);
free($1);
if (!success && !sudoers_recovery)
if (!success && !parser_conf.recovery)
YYERROR;
}
| includedir {
const bool success = push_includedir($1, sudoers_verbose);
const bool success = push_includedir($1,
parser_conf.verbose);
parser_leak_remove(LEAK_PTR, $1);
free($1);
if (!success && !sudoers_recovery)
if (!success && !parser_conf.recovery)
YYERROR;
}
| userlist privileges '\n' {
@@ -1216,7 +1218,7 @@ sudoerserrorf(const char *fmt, ...)
sudoers_error_hook(sudoers, this_lineno, column, fmt, ap);
va_end(ap);
}
if (sudoers_verbose > 0 && fmt != NULL) {
if (parser_conf.verbose > 0 && fmt != NULL) {
LEXTRACE("<*> ");
#ifndef TRACELEXER
if (trace_print == NULL || trace_print == sudoers_trace_print) {
@@ -1782,7 +1784,8 @@ free_parse_tree(struct sudoers_parse_tree *parse_tree)
* the current sudoers file to path.
*/
bool
init_parser(const char *file, const char *path, bool strict, int verbose)
init_parser(const char *file, const char *path,
const struct sudoers_parser_config *conf)
{
bool ret = true;
debug_decl(init_parser, SUDOERS_DEBUG_PARSER);
@@ -1811,9 +1814,14 @@ init_parser(const char *file, const char *path, bool strict, int verbose)
sudoers_search_path = NULL;
}
if (conf != NULL) {
parser_conf = *conf;
} else {
const struct sudoers_parser_config def_conf =
SUDOERS_PARSER_CONFIG_INITIALIZER;
parser_conf = def_conf;
}
parse_error = false;
sudoers_strict = strict;
sudoers_verbose = verbose;
debug_return_bool(ret);
}
@@ -1821,7 +1829,7 @@ init_parser(const char *file, const char *path, bool strict, int verbose)
bool
reset_parser(void)
{
return init_parser(NULL, NULL, false, 1);
return init_parser(NULL, NULL, NULL);
}
/*
@@ -1848,6 +1856,36 @@ init_options(struct command_options *opts)
#endif
}
uid_t
sudoers_file_uid(void)
{
return parser_conf.sudoers_uid;
}
gid_t
sudoers_file_gid(void)
{
return parser_conf.sudoers_gid;
}
mode_t
sudoers_file_mode(void)
{
return parser_conf.sudoers_mode;
}
bool
sudoers_error_recovery(void)
{
return parser_conf.recovery;
}
bool
sudoers_strict(void)
{
return parser_conf.strict;
}
bool
parser_leak_add(enum parser_leak_types type, void *v)
{

View File

@@ -322,6 +322,26 @@ struct cmnd_info {
bool intercepted;
};
/*
* Parse configuration settings, passed to init_parser().
*/
struct sudoers_parser_config {
bool strict;
bool recovery;
int verbose;
mode_t sudoers_mode;
uid_t sudoers_uid;
gid_t sudoers_gid;
};
#define SUDOERS_PARSER_CONFIG_INITIALIZER { \
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
@@ -372,7 +392,7 @@ int check_aliases(struct sudoers_parse_tree *parse_tree, bool strict, bool quiet
/* gram.y */
extern struct sudoers_parse_tree parsed_policy;
extern bool (*sudoers_error_hook)(const char *file, int line, int column, const char *fmt, va_list args);
bool init_parser(const char *file, const char *path, bool strict, int verbose);
bool init_parser(const char *file, const char *path, const struct sudoers_parser_config *conf);
bool reset_parser(void);
void free_member(struct member *m);
void free_members(struct member_list *members);

View File

@@ -1,7 +1,7 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2010-2022 Todd C. Miller <Todd.Miller@sudo.ws>
* Copyright (c) 2010-2023 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -50,6 +50,7 @@ struct sudoers_exec_args {
char ***info;
};
static struct sudoers_parser_config parser_conf = SUDOERS_PARSER_CONFIG_INITIALIZER;
static unsigned int sudo_version;
static const char *interfaces_string;
sudo_conv_t sudo_conv;
@@ -95,12 +96,12 @@ parse_bool(const char *line, int varlen, int *flags, int fval)
int
sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
{
struct sudoers_open_info *info = v;
const char *p, *errstr, *groups = NULL;
struct sudoers_open_info *info = v;
int flags = MODE_UPDATE_TICKET;
const char *remhost = NULL;
unsigned char uuid[16];
char * const *cur;
int flags = MODE_UPDATE_TICKET;
debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN);
#define MATCHES(s, v) \
@@ -124,9 +125,6 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
/* Parse sudo.conf plugin args. */
sudoers_mode = SUDOERS_MODE;
sudoers_uid = SUDOERS_UID;
sudoers_gid = SUDOERS_GID;
if (info->plugin_args != NULL) {
for (cur = info->plugin_args; *cur != NULL; cur++) {
if (MATCHES(*cur, "error_recovery=")) {
@@ -134,7 +132,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
if (val == -1) {
INVALID("error_recovery="); /* Not a fatal error. */
} else {
sudoers_recovery = val;
parser_conf.recovery = val;
}
continue;
}
@@ -145,7 +143,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "sudoers_uid=")) {
p = *cur + sizeof("sudoers_uid=") - 1;
sudoers_uid = (uid_t) sudo_strtoid(p, &errstr);
parser_conf.sudoers_uid = (uid_t)sudo_strtoid(p, &errstr);
if (errstr != NULL) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;
@@ -154,7 +152,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "sudoers_gid=")) {
p = *cur + sizeof("sudoers_gid=") - 1;
sudoers_gid = (gid_t) sudo_strtoid(p, &errstr);
parser_conf.sudoers_gid = (gid_t)sudo_strtoid(p, &errstr);
if (errstr != NULL) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;
@@ -163,7 +161,7 @@ sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults)
}
if (MATCHES(*cur, "sudoers_mode=")) {
p = *cur + sizeof("sudoers_mode=") - 1;
sudoers_mode = sudo_strtomode(p, &errstr);
parser_conf.sudoers_mode = sudo_strtomode(p, &errstr);
if (errstr != NULL) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;
@@ -625,6 +623,13 @@ bad:
debug_return_int(MODE_ERROR);
}
/* Return the policy's struct sudoers_parser_config. */
const struct sudoers_parser_config *
policy_sudoers_conf(void)
{
return &parser_conf;
}
/* Return the path to the sudoers file, which may be set in the plugin args. */
const char *
policy_path_sudoers(void)

View File

@@ -312,7 +312,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
/* Initialize defaults and parse sudoers. */
init_defaults();
init_parser("sudoers", NULL, true, 1);
init_parser("sudoers", NULL, NULL);
sudoersrestart(fp);
sudoersparse();
reparent_parse_tree(&parse_tree);

View File

@@ -295,7 +295,11 @@ set_perms(int perm)
}
break;
case PERM_SUDOERS:
case PERM_SUDOERS: {
const uid_t sudoers_uid = sudoers_file_uid();
const gid_t sudoers_gid = sudoers_file_gid();
const mode_t sudoers_mode = sudoers_file_mode();
state->gidlist = ostate->gidlist;
sudo_gidlist_addref(state->gidlist);
@@ -334,6 +338,7 @@ set_perms(int perm)
goto bad;
}
break;
}
case PERM_TIMESTAMP:
state->gidlist = ostate->gidlist;
@@ -619,7 +624,11 @@ set_perms(int perm)
}
break;
case PERM_SUDOERS:
case PERM_SUDOERS: {
const uid_t sudoers_uid = sudoers_file_uid();
const gid_t sudoers_gid = sudoers_file_gid();
const mode_t sudoers_mode = sudoers_file_mode();
state->gidlist = ostate->gidlist;
sudo_gidlist_addref(state->gidlist);
@@ -667,6 +676,7 @@ set_perms(int perm)
}
}
break;
}
case PERM_TIMESTAMP:
state->gidlist = ostate->gidlist;
@@ -1012,7 +1022,11 @@ set_perms(int perm)
}
break;
case PERM_SUDOERS:
case PERM_SUDOERS: {
const uid_t sudoers_uid = sudoers_file_uid();
const gid_t sudoers_gid = sudoers_file_gid();
const mode_t sudoers_mode = sudoers_file_mode();
state->gidlist = ostate->gidlist;
sudo_gidlist_addref(state->gidlist);
@@ -1047,6 +1061,7 @@ set_perms(int perm)
goto bad;
}
break;
}
case PERM_TIMESTAMP:
state->gidlist = ostate->gidlist;
@@ -1321,7 +1336,11 @@ set_perms(int perm)
}
break;
case PERM_SUDOERS:
case PERM_SUDOERS: {
const uid_t sudoers_uid = sudoers_file_uid();
const gid_t sudoers_gid = sudoers_file_gid();
const mode_t sudoers_mode = sudoers_file_mode();
state->gidlist = ostate->gidlist;
sudo_gidlist_addref(state->gidlist);
@@ -1355,6 +1374,7 @@ set_perms(int perm)
goto bad;
}
break;
}
case PERM_TIMESTAMP:
state->gidlist = ostate->gidlist;

View File

@@ -249,7 +249,6 @@ sudoers_init(void *info, sudoers_logger_t logger, char * const envp[])
}
/* Open and parse sudoers, set global defaults. */
reset_parser();
TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
if (nss->open(nss) == -1 || (nss->parse_tree = nss->parse(nss)) == NULL) {
TAILQ_REMOVE(snl, nss, entries);
@@ -1300,7 +1299,8 @@ open_sudoers(const char *path, char **outfile, bool doedit, bool *keepopen)
debug_decl(open_sudoers, SUDOERS_DEBUG_PLUGIN);
fd = sudo_open_conf_path(path, fname, sizeof(fname), open_file);
error = sudo_secure_fd(fd, S_IFREG, sudoers_uid, sudoers_gid, &sb);
error = sudo_secure_fd(fd, S_IFREG, sudoers_file_uid(), sudoers_file_gid(),
&sb);
switch (error) {
case SUDO_PATH_SECURE:
/*
@@ -1340,7 +1340,7 @@ open_sudoers(const char *path, char **outfile, bool doedit, bool *keepopen)
case SUDO_PATH_WRONG_OWNER:
log_warningx(SLOG_PARSE_ERROR,
N_("%s is owned by uid %u, should be %u"), fname,
(unsigned int)sb.st_uid, (unsigned int)sudoers_uid);
(unsigned int)sb.st_uid, (unsigned int)sudoers_file_uid());
break;
case SUDO_PATH_WORLD_WRITABLE:
log_warningx(SLOG_PARSE_ERROR, N_("%s is world writable"), fname);
@@ -1348,7 +1348,7 @@ open_sudoers(const char *path, char **outfile, bool doedit, bool *keepopen)
case SUDO_PATH_GROUP_WRITABLE:
log_warningx(SLOG_PARSE_ERROR,
N_("%s is owned by gid %u, should be %u"), fname,
(unsigned int)sb.st_gid, (unsigned int)sudoers_gid);
(unsigned int)sb.st_gid, (unsigned int)sudoers_file_gid());
break;
default:
sudo_warnx("%s: internal error, unexpected error %d", __func__, error);

View File

@@ -324,9 +324,12 @@ int pam_prep_user(struct passwd *);
/* gram.y */
int sudoersparse(void);
uid_t sudoers_file_uid(void);
gid_t sudoers_file_gid(void);
mode_t sudoers_file_mode(void);
bool sudoers_error_recovery(void);
bool sudoers_strict(void);
extern bool parse_error;
extern bool sudoers_recovery;
extern bool sudoers_strict;
/* toke.l */
YY_DECL;
@@ -334,9 +337,6 @@ void sudoersrestart(FILE *);
extern FILE *sudoersin;
extern char *sudoers;
extern char *sudoers_search_path;
extern mode_t sudoers_mode;
extern uid_t sudoers_uid;
extern gid_t sudoers_gid;
extern int sudolineno;
/* defaults.c */
@@ -447,6 +447,7 @@ void sudoers_debug_deregister(void);
/* policy.c */
int sudoers_policy_deserialize_info(void *v, struct defaults_list *defaults);
bool sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], mode_t cmnd_umask, char *iolog_path, void *v);
const struct sudoers_parser_config *policy_sudoers_conf(void);
const char *policy_path_sudoers(void);
const char *policy_path_ldap_conf(void);
const char *policy_path_ldap_secret(void);

View File

@@ -97,6 +97,7 @@ sudo_dso_public int main(int argc, char *argv[]);
int
main(int argc, char *argv[])
{
struct sudoers_parser_config parser_conf = SUDOERS_PARSER_CONFIG_INITIALIZER;
enum sudoers_formats input_format = format_sudoers;
struct cmndspec *cs;
struct privilege *priv;
@@ -106,6 +107,7 @@ main(int argc, char *argv[])
int match, host_match, runas_match, cmnd_match;
int ch, dflag, exitcode = EXIT_FAILURE;
struct sudo_lbuf lbuf;
id_t id;
debug_decl(main, SUDOERS_DEBUG_MAIN);
#if defined(SUDO_DEVEL) && defined(__OpenBSD__)
@@ -140,9 +142,10 @@ main(int argc, char *argv[])
dflag = 1;
break;
case 'G':
sudoers_gid = (gid_t)sudo_strtoid(optarg, &errstr);
id = sudo_strtoid(optarg, &errstr);
if (errstr != NULL)
sudo_fatalx("group-ID %s: %s", optarg, errstr);
parser_conf.sudoers_gid = (gid_t)id;
break;
case 'g':
runas_group = optarg;
@@ -171,9 +174,10 @@ main(int argc, char *argv[])
trace_print = testsudoers_error;
break;
case 'U':
sudoers_uid = (uid_t)sudo_strtoid(optarg, &errstr);
id = sudo_strtoid(optarg, &errstr);
if (errstr != NULL)
sudo_fatalx("user-ID %s: %s", optarg, errstr);
parser_conf.sudoers_uid = (uid_t)id;
break;
case 'u':
runas_user = optarg;
@@ -274,7 +278,9 @@ main(int argc, char *argv[])
}
/* Initialize the parser and set sudoers filename to "sudoers". */
init_parser("sudoers", NULL, true, 2);
parser_conf.strict = true;
parser_conf.verbose = 2;
init_parser("sudoers", NULL, &parser_conf);
/*
* Set runas passwd/group entries based on command line or sudoers.
@@ -452,7 +458,8 @@ open_sudoers(const char *file, char **outfile, bool doedit, bool *keepopen)
/* Report errors using the basename for consistent test output. */
base = sudo_basename(file);
fd = sudo_secure_open_file(file, sudoers_uid, sudoers_gid, &sb, &error);
fd = sudo_secure_open_file(file, sudoers_file_uid(), sudoers_file_gid(),
&sb, &error);
if (fd != -1) {
if ((fp = fdopen(fd, "r")) == NULL) {
sudo_warn("unable to open %s", base);
@@ -468,14 +475,14 @@ open_sudoers(const char *file, char **outfile, bool doedit, bool *keepopen)
break;
case SUDO_PATH_WRONG_OWNER:
sudo_warnx("%s should be owned by uid %u",
base, (unsigned int) sudoers_uid);
base, (unsigned int) sudoers_file_uid());
break;
case SUDO_PATH_WORLD_WRITABLE:
sudo_warnx("%s is world writable", base);
break;
case SUDO_PATH_GROUP_WRITABLE:
sudo_warnx("%s should be owned by gid %u",
base, (unsigned int) sudoers_gid);
base, (unsigned int) sudoers_file_gid());
break;
default:
sudo_warnx("%s: internal error, unexpected error %d",

View File

@@ -3036,7 +3036,7 @@ char *sudoerstext;
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 1996, 1998-2005, 2007-2022
* Copyright (c) 1996, 1998-2005, 2007-2023
* Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -3093,11 +3093,6 @@ char *sudoers_search_path; /* colon-separated path of sudoers files. */
const char *sudoers_errstr; /* description of last error from lexer. */
struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */
/* Default sudoers mode and owner (may be set via sudo.conf) */
mode_t sudoers_mode = SUDOERS_MODE;
uid_t sudoers_uid = SUDOERS_UID;
gid_t sudoers_gid = SUDOERS_GID;
static bool continued, sawspace;
static int prev_state;
static int digest_type = -1;
@@ -3135,7 +3130,7 @@ int (*trace_print)(const char *msg) = sudoers_trace_print;
#line 3133 "toke.c"
#line 3128 "toke.c"
#define INITIAL 0
#define GOTDEFS 1
@@ -3356,9 +3351,9 @@ YY_DECL
}
{
#line 124 "toke.l"
#line 119 "toke.l"
#line 3356 "toke.c"
#line 3351 "toke.c"
while ( 1 ) /* loops until end-of-file is reached */
{
@@ -3418,7 +3413,7 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
YY_RULE_SETUP
#line 125 "toke.l"
#line 120 "toke.l"
{
LEXTRACE(", ");
return ',';
@@ -3426,12 +3421,12 @@ YY_RULE_SETUP
YY_BREAK
case 2:
YY_RULE_SETUP
#line 130 "toke.l"
#line 125 "toke.l"
BEGIN STARTDEFS;
YY_BREAK
case 3:
YY_RULE_SETUP
#line 132 "toke.l"
#line 127 "toke.l"
{
BEGIN INDEFS;
LEXTRACE("DEFVAR ");
@@ -3443,7 +3438,7 @@ YY_RULE_SETUP
case 4:
YY_RULE_SETUP
#line 141 "toke.l"
#line 136 "toke.l"
{
BEGIN STARTDEFS;
LEXTRACE(", ");
@@ -3452,7 +3447,7 @@ YY_RULE_SETUP
YY_BREAK
case 5:
YY_RULE_SETUP
#line 147 "toke.l"
#line 142 "toke.l"
{
LEXTRACE("= ");
return '=';
@@ -3460,7 +3455,7 @@ YY_RULE_SETUP
YY_BREAK
case 6:
YY_RULE_SETUP
#line 152 "toke.l"
#line 147 "toke.l"
{
LEXTRACE("+= ");
return '+';
@@ -3468,7 +3463,7 @@ YY_RULE_SETUP
YY_BREAK
case 7:
YY_RULE_SETUP
#line 157 "toke.l"
#line 152 "toke.l"
{
LEXTRACE("-= ");
return '-';
@@ -3476,7 +3471,7 @@ YY_RULE_SETUP
YY_BREAK
case 8:
YY_RULE_SETUP
#line 162 "toke.l"
#line 157 "toke.l"
{
LEXTRACE("BEGINSTR ");
sudoerslval.string = NULL;
@@ -3486,7 +3481,7 @@ YY_RULE_SETUP
YY_BREAK
case 9:
YY_RULE_SETUP
#line 169 "toke.l"
#line 164 "toke.l"
{
LEXTRACE("WORD(2) ");
if (!fill(sudoerstext, sudoersleng))
@@ -3499,7 +3494,7 @@ YY_RULE_SETUP
case 10:
/* rule 10 can match eol */
YY_RULE_SETUP
#line 178 "toke.l"
#line 173 "toke.l"
{
/* Line continuation char followed by newline. */
sudolineno++;
@@ -3508,7 +3503,7 @@ YY_RULE_SETUP
YY_BREAK
case 11:
YY_RULE_SETUP
#line 184 "toke.l"
#line 179 "toke.l"
{
LEXTRACE("ENDSTR ");
BEGIN prev_state;
@@ -3550,7 +3545,7 @@ YY_RULE_SETUP
YY_BREAK
case 12:
YY_RULE_SETUP
#line 223 "toke.l"
#line 218 "toke.l"
{
LEXTRACE("BACKSLASH ");
if (!append(sudoerstext, sudoersleng))
@@ -3559,7 +3554,7 @@ YY_RULE_SETUP
YY_BREAK
case 13:
YY_RULE_SETUP
#line 229 "toke.l"
#line 224 "toke.l"
{
LEXTRACE("STRBODY ");
if (!append(sudoerstext, sudoersleng))
@@ -3570,7 +3565,7 @@ YY_RULE_SETUP
case 14:
YY_RULE_SETUP
#line 237 "toke.l"
#line 232 "toke.l"
{
/* quoted fnmatch glob char, pass verbatim */
LEXTRACE("QUOTEDCHAR ");
@@ -3581,7 +3576,7 @@ YY_RULE_SETUP
YY_BREAK
case 15:
YY_RULE_SETUP
#line 245 "toke.l"
#line 240 "toke.l"
{
/* quoted sudoers special char, strip backslash */
LEXTRACE("QUOTEDCHAR ");
@@ -3593,7 +3588,7 @@ YY_RULE_SETUP
case 16:
/* rule 16 can match eol */
YY_RULE_SETUP
#line 253 "toke.l"
#line 248 "toke.l"
{
BEGIN INITIAL;
sudoersless(0);
@@ -3603,7 +3598,7 @@ YY_RULE_SETUP
YY_BREAK
case 17:
YY_RULE_SETUP
#line 260 "toke.l"
#line 255 "toke.l"
{
if (sudoerslval.command.args == NULL && sudoerstext[0] == '^') {
LEXTRACE("ARG REGEX ");
@@ -3622,7 +3617,7 @@ YY_RULE_SETUP
case 18:
YY_RULE_SETUP
#line 276 "toke.l"
#line 271 "toke.l"
{
/* quoted character, pass verbatim */
LEXTRACE("QUOTEDCHAR ");
@@ -3633,7 +3628,7 @@ YY_RULE_SETUP
case 19:
/* rule 19 can match eol */
YY_RULE_SETUP
#line 283 "toke.l"
#line 278 "toke.l"
{
/* Let the parser attempt to recover. */
sudoersless(0);
@@ -3647,13 +3642,13 @@ YY_RULE_SETUP
YY_BREAK
case 20:
YY_RULE_SETUP
#line 294 "toke.l"
#line 289 "toke.l"
{
if (!fill_args("$", 1, false))
yyterminate();
BEGIN INITIAL;
continued = false;
if (sudoers_strict) {
if (sudoers_strict()) {
if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) {
LEXTRACE("ERROR ");
return ERROR;
@@ -3664,7 +3659,7 @@ YY_RULE_SETUP
YY_BREAK
case 21:
YY_RULE_SETUP
#line 308 "toke.l"
#line 303 "toke.l"
{
if (continued) {
/* remove whitespace after line continuation */
@@ -3683,7 +3678,7 @@ YY_RULE_SETUP
case 22:
YY_RULE_SETUP
#line 324 "toke.l"
#line 319 "toke.l"
{
/* Only return DIGEST if the length is correct. */
yy_size_t digest_len =
@@ -3701,7 +3696,7 @@ YY_RULE_SETUP
YY_BREAK
case 23:
YY_RULE_SETUP
#line 339 "toke.l"
#line 334 "toke.l"
{
/* Only return DIGEST if the length is correct. */
yy_size_t len, digest_len =
@@ -3726,7 +3721,7 @@ YY_RULE_SETUP
YY_BREAK
case 24:
YY_RULE_SETUP
#line 361 "toke.l"
#line 356 "toke.l"
{
if (continued) {
sudoers_errstr = N_("invalid line continuation");
@@ -3741,7 +3736,7 @@ YY_RULE_SETUP
YY_BREAK
case 25:
YY_RULE_SETUP
#line 373 "toke.l"
#line 368 "toke.l"
{
if (continued) {
sudoers_errstr = N_("invalid line continuation");
@@ -3757,7 +3752,7 @@ YY_RULE_SETUP
case 26:
/* rule 26 can match eol */
YY_RULE_SETUP
#line 385 "toke.l"
#line 380 "toke.l"
{
if (continued) {
sudoers_errstr = N_("invalid line continuation");
@@ -3777,7 +3772,7 @@ YY_RULE_SETUP
case 27:
/* rule 27 can match eol */
YY_RULE_SETUP
#line 401 "toke.l"
#line 396 "toke.l"
{
if (continued) {
sudoers_errstr = N_("invalid line continuation");
@@ -3796,7 +3791,7 @@ YY_RULE_SETUP
YY_BREAK
case 28:
YY_RULE_SETUP
#line 417 "toke.l"
#line 412 "toke.l"
{
char deftype;
int n;
@@ -3840,7 +3835,7 @@ YY_RULE_SETUP
YY_BREAK
case 29:
YY_RULE_SETUP
#line 458 "toke.l"
#line 453 "toke.l"
{
int n;
@@ -3870,7 +3865,7 @@ YY_RULE_SETUP
YY_BREAK
case 30:
YY_RULE_SETUP
#line 485 "toke.l"
#line 480 "toke.l"
{
/* cmnd does not require passwd for this user */
LEXTRACE("NOPASSWD ");
@@ -3879,7 +3874,7 @@ YY_RULE_SETUP
YY_BREAK
case 31:
YY_RULE_SETUP
#line 491 "toke.l"
#line 486 "toke.l"
{
/* cmnd requires passwd for this user */
LEXTRACE("PASSWD ");
@@ -3888,7 +3883,7 @@ YY_RULE_SETUP
YY_BREAK
case 32:
YY_RULE_SETUP
#line 497 "toke.l"
#line 492 "toke.l"
{
LEXTRACE("NOEXEC ");
return NOEXEC;
@@ -3896,7 +3891,7 @@ YY_RULE_SETUP
YY_BREAK
case 33:
YY_RULE_SETUP
#line 502 "toke.l"
#line 497 "toke.l"
{
LEXTRACE("EXEC ");
return EXEC;
@@ -3904,7 +3899,7 @@ YY_RULE_SETUP
YY_BREAK
case 34:
YY_RULE_SETUP
#line 507 "toke.l"
#line 502 "toke.l"
{
LEXTRACE("INTERCEPT ");
return INTERCEPT;
@@ -3912,7 +3907,7 @@ YY_RULE_SETUP
YY_BREAK
case 35:
YY_RULE_SETUP
#line 512 "toke.l"
#line 507 "toke.l"
{
LEXTRACE("NOINTERCEPT ");
return NOINTERCEPT;
@@ -3920,7 +3915,7 @@ YY_RULE_SETUP
YY_BREAK
case 36:
YY_RULE_SETUP
#line 517 "toke.l"
#line 512 "toke.l"
{
LEXTRACE("SETENV ");
return SETENV;
@@ -3928,7 +3923,7 @@ YY_RULE_SETUP
YY_BREAK
case 37:
YY_RULE_SETUP
#line 522 "toke.l"
#line 517 "toke.l"
{
LEXTRACE("NOSETENV ");
return NOSETENV;
@@ -3936,7 +3931,7 @@ YY_RULE_SETUP
YY_BREAK
case 38:
YY_RULE_SETUP
#line 527 "toke.l"
#line 522 "toke.l"
{
LEXTRACE("LOG_OUTPUT ");
return LOG_OUTPUT;
@@ -3944,7 +3939,7 @@ YY_RULE_SETUP
YY_BREAK
case 39:
YY_RULE_SETUP
#line 532 "toke.l"
#line 527 "toke.l"
{
LEXTRACE("NOLOG_OUTPUT ");
return NOLOG_OUTPUT;
@@ -3952,7 +3947,7 @@ YY_RULE_SETUP
YY_BREAK
case 40:
YY_RULE_SETUP
#line 537 "toke.l"
#line 532 "toke.l"
{
LEXTRACE("LOG_INPUT ");
return LOG_INPUT;
@@ -3960,7 +3955,7 @@ YY_RULE_SETUP
YY_BREAK
case 41:
YY_RULE_SETUP
#line 542 "toke.l"
#line 537 "toke.l"
{
LEXTRACE("NOLOG_INPUT ");
return NOLOG_INPUT;
@@ -3968,7 +3963,7 @@ YY_RULE_SETUP
YY_BREAK
case 42:
YY_RULE_SETUP
#line 547 "toke.l"
#line 542 "toke.l"
{
LEXTRACE("MAIL ");
return MAIL;
@@ -3976,7 +3971,7 @@ YY_RULE_SETUP
YY_BREAK
case 43:
YY_RULE_SETUP
#line 552 "toke.l"
#line 547 "toke.l"
{
LEXTRACE("NOMAIL ");
return NOMAIL;
@@ -3984,7 +3979,7 @@ YY_RULE_SETUP
YY_BREAK
case 44:
YY_RULE_SETUP
#line 557 "toke.l"
#line 552 "toke.l"
{
LEXTRACE("FOLLOW ");
return FOLLOWLNK;
@@ -3992,7 +3987,7 @@ YY_RULE_SETUP
YY_BREAK
case 45:
YY_RULE_SETUP
#line 562 "toke.l"
#line 557 "toke.l"
{
LEXTRACE("NOFOLLOW ");
return NOFOLLOWLNK;
@@ -4000,7 +3995,7 @@ YY_RULE_SETUP
YY_BREAK
case 46:
YY_RULE_SETUP
#line 567 "toke.l"
#line 562 "toke.l"
{
if (sudoerstext[0] == '+')
sudoers_errstr = N_("empty netgroup");
@@ -4012,7 +4007,7 @@ YY_RULE_SETUP
YY_BREAK
case 47:
YY_RULE_SETUP
#line 576 "toke.l"
#line 571 "toke.l"
{
/* netgroup */
if (!fill(sudoerstext, sudoersleng))
@@ -4023,7 +4018,7 @@ YY_RULE_SETUP
YY_BREAK
case 48:
YY_RULE_SETUP
#line 584 "toke.l"
#line 579 "toke.l"
{
/* group */
if (!fill(sudoerstext, sudoersleng))
@@ -4034,7 +4029,7 @@ YY_RULE_SETUP
YY_BREAK
case 49:
YY_RULE_SETUP
#line 592 "toke.l"
#line 587 "toke.l"
{
if (!fill(sudoerstext, sudoersleng))
yyterminate();
@@ -4044,7 +4039,7 @@ YY_RULE_SETUP
YY_BREAK
case 50:
YY_RULE_SETUP
#line 599 "toke.l"
#line 594 "toke.l"
{
if (!fill(sudoerstext, sudoersleng))
yyterminate();
@@ -4054,7 +4049,7 @@ YY_RULE_SETUP
YY_BREAK
case 51:
YY_RULE_SETUP
#line 606 "toke.l"
#line 601 "toke.l"
{
if (!ipv6_valid(sudoerstext)) {
sudoers_errstr = N_("invalid IPv6 address");
@@ -4069,7 +4064,7 @@ YY_RULE_SETUP
YY_BREAK
case 52:
YY_RULE_SETUP
#line 618 "toke.l"
#line 613 "toke.l"
{
if (!ipv6_valid(sudoerstext)) {
sudoers_errstr = N_("invalid IPv6 address");
@@ -4084,7 +4079,7 @@ YY_RULE_SETUP
YY_BREAK
case 53:
YY_RULE_SETUP
#line 630 "toke.l"
#line 625 "toke.l"
{
LEXTRACE("ALL ");
return ALL;
@@ -4093,7 +4088,7 @@ YY_RULE_SETUP
YY_BREAK
case 54:
YY_RULE_SETUP
#line 636 "toke.l"
#line 631 "toke.l"
{
LEXTRACE("CMND_TIMEOUT ");
return CMND_TIMEOUT;
@@ -4101,7 +4096,7 @@ YY_RULE_SETUP
YY_BREAK
case 55:
YY_RULE_SETUP
#line 641 "toke.l"
#line 636 "toke.l"
{
LEXTRACE("NOTBEFORE ");
return NOTBEFORE;
@@ -4109,7 +4104,7 @@ YY_RULE_SETUP
YY_BREAK
case 56:
YY_RULE_SETUP
#line 646 "toke.l"
#line 641 "toke.l"
{
LEXTRACE("NOTAFTER ");
return NOTAFTER;
@@ -4117,7 +4112,7 @@ YY_RULE_SETUP
YY_BREAK
case 57:
YY_RULE_SETUP
#line 651 "toke.l"
#line 646 "toke.l"
{
LEXTRACE("CWD ");
prev_state = YY_START;
@@ -4127,7 +4122,7 @@ YY_RULE_SETUP
YY_BREAK
case 58:
YY_RULE_SETUP
#line 658 "toke.l"
#line 653 "toke.l"
{
LEXTRACE("CHROOT ");
prev_state = YY_START;
@@ -4137,7 +4132,7 @@ YY_RULE_SETUP
YY_BREAK
case 59:
YY_RULE_SETUP
#line 665 "toke.l"
#line 660 "toke.l"
{
#ifdef HAVE_SELINUX
LEXTRACE("ROLE ");
@@ -4149,7 +4144,7 @@ YY_RULE_SETUP
YY_BREAK
case 60:
YY_RULE_SETUP
#line 674 "toke.l"
#line 669 "toke.l"
{
#ifdef HAVE_SELINUX
LEXTRACE("TYPE ");
@@ -4161,7 +4156,7 @@ YY_RULE_SETUP
YY_BREAK
case 61:
YY_RULE_SETUP
#line 682 "toke.l"
#line 677 "toke.l"
{
#ifdef HAVE_APPARMOR
LEXTRACE("APPARMOR_PROFILE ");
@@ -4173,7 +4168,7 @@ YY_RULE_SETUP
YY_BREAK
case 62:
YY_RULE_SETUP
#line 690 "toke.l"
#line 685 "toke.l"
{
#ifdef HAVE_PRIV_SET
LEXTRACE("PRIVS ");
@@ -4185,7 +4180,7 @@ YY_RULE_SETUP
YY_BREAK
case 63:
YY_RULE_SETUP
#line 699 "toke.l"
#line 694 "toke.l"
{
#ifdef HAVE_PRIV_SET
LEXTRACE("LIMITPRIVS ");
@@ -4197,7 +4192,7 @@ YY_RULE_SETUP
YY_BREAK
case 64:
YY_RULE_SETUP
#line 708 "toke.l"
#line 703 "toke.l"
{
got_alias:
if (!fill(sudoerstext, sudoersleng))
@@ -4208,7 +4203,7 @@ YY_RULE_SETUP
YY_BREAK
case 65:
YY_RULE_SETUP
#line 716 "toke.l"
#line 711 "toke.l"
{
/* XXX - no way to specify digest for command */
/* no command args allowed for Defaults!/path */
@@ -4220,7 +4215,7 @@ YY_RULE_SETUP
YY_BREAK
case 66:
YY_RULE_SETUP
#line 725 "toke.l"
#line 720 "toke.l"
{
digest_type = SUDO_DIGEST_SHA224;
BEGIN WANTDIGEST;
@@ -4230,7 +4225,7 @@ YY_RULE_SETUP
YY_BREAK
case 67:
YY_RULE_SETUP
#line 732 "toke.l"
#line 727 "toke.l"
{
digest_type = SUDO_DIGEST_SHA256;
BEGIN WANTDIGEST;
@@ -4240,7 +4235,7 @@ YY_RULE_SETUP
YY_BREAK
case 68:
YY_RULE_SETUP
#line 739 "toke.l"
#line 734 "toke.l"
{
digest_type = SUDO_DIGEST_SHA384;
BEGIN WANTDIGEST;
@@ -4250,7 +4245,7 @@ YY_RULE_SETUP
YY_BREAK
case 69:
YY_RULE_SETUP
#line 746 "toke.l"
#line 741 "toke.l"
{
digest_type = SUDO_DIGEST_SHA512;
BEGIN WANTDIGEST;
@@ -4260,7 +4255,7 @@ YY_RULE_SETUP
YY_BREAK
case 70:
YY_RULE_SETUP
#line 753 "toke.l"
#line 748 "toke.l"
{
BEGIN GOTCMND;
LEXTRACE("COMMAND ");
@@ -4270,7 +4265,7 @@ YY_RULE_SETUP
YY_BREAK
case 71:
YY_RULE_SETUP
#line 760 "toke.l"
#line 755 "toke.l"
{
BEGIN prev_state;
if (!fill(sudoerstext, sudoersleng))
@@ -4281,7 +4276,7 @@ YY_RULE_SETUP
YY_BREAK
case 72:
YY_RULE_SETUP
#line 768 "toke.l"
#line 763 "toke.l"
{
/* directories can't have args... */
if (sudoerstext[sudoersleng - 1] == '/') {
@@ -4298,9 +4293,9 @@ YY_RULE_SETUP
YY_BREAK
case 73:
YY_RULE_SETUP
#line 782 "toke.l"
#line 777 "toke.l"
{
if (sudoers_strict) {
if (sudoers_strict()) {
if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) {
LEXTRACE("ERROR ");
return ERROR;
@@ -4314,7 +4309,7 @@ YY_RULE_SETUP
YY_BREAK
case 74:
YY_RULE_SETUP
#line 795 "toke.l"
#line 790 "toke.l"
{
LEXTRACE("BEGINSTR ");
sudoerslval.string = NULL;
@@ -4324,7 +4319,7 @@ YY_RULE_SETUP
YY_BREAK
case 75:
YY_RULE_SETUP
#line 802 "toke.l"
#line 797 "toke.l"
{
/* a word */
if (!fill(sudoerstext, sudoersleng))
@@ -4336,7 +4331,7 @@ YY_RULE_SETUP
case 76:
YY_RULE_SETUP
#line 811 "toke.l"
#line 806 "toke.l"
{
/* include file/directory */
if (!fill(sudoerstext, sudoersleng))
@@ -4348,7 +4343,7 @@ YY_RULE_SETUP
YY_BREAK
case 77:
YY_RULE_SETUP
#line 820 "toke.l"
#line 815 "toke.l"
{
LEXTRACE("BEGINSTR ");
sudoerslval.string = NULL;
@@ -4359,7 +4354,7 @@ YY_RULE_SETUP
case 78:
YY_RULE_SETUP
#line 828 "toke.l"
#line 823 "toke.l"
{
LEXTRACE("( ");
return '(';
@@ -4367,7 +4362,7 @@ YY_RULE_SETUP
YY_BREAK
case 79:
YY_RULE_SETUP
#line 833 "toke.l"
#line 828 "toke.l"
{
LEXTRACE(") ");
return ')';
@@ -4375,7 +4370,7 @@ YY_RULE_SETUP
YY_BREAK
case 80:
YY_RULE_SETUP
#line 838 "toke.l"
#line 833 "toke.l"
{
LEXTRACE(", ");
return ',';
@@ -4383,7 +4378,7 @@ YY_RULE_SETUP
YY_BREAK
case 81:
YY_RULE_SETUP
#line 843 "toke.l"
#line 838 "toke.l"
{
LEXTRACE("= ");
return '=';
@@ -4391,7 +4386,7 @@ YY_RULE_SETUP
YY_BREAK
case 82:
YY_RULE_SETUP
#line 848 "toke.l"
#line 843 "toke.l"
{
LEXTRACE(": ");
return ':';
@@ -4399,7 +4394,7 @@ YY_RULE_SETUP
YY_BREAK
case 83:
YY_RULE_SETUP
#line 853 "toke.l"
#line 848 "toke.l"
{
if (sudoersleng & 1) {
LEXTRACE("!");
@@ -4410,7 +4405,7 @@ YY_RULE_SETUP
case 84:
/* rule 84 can match eol */
YY_RULE_SETUP
#line 860 "toke.l"
#line 855 "toke.l"
{
if (YY_START == INSTR) {
/* throw away old string */
@@ -4432,7 +4427,7 @@ YY_RULE_SETUP
YY_BREAK
case 85:
YY_RULE_SETUP
#line 879 "toke.l"
#line 874 "toke.l"
{ /* throw away space/tabs */
sawspace = true; /* but remember for fill_args */
}
@@ -4440,7 +4435,7 @@ YY_RULE_SETUP
case 86:
/* rule 86 can match eol */
YY_RULE_SETUP
#line 883 "toke.l"
#line 878 "toke.l"
{
sawspace = true; /* remember for fill_args */
sudolineno++;
@@ -4450,7 +4445,7 @@ YY_RULE_SETUP
case 87:
/* rule 87 can match eol */
YY_RULE_SETUP
#line 889 "toke.l"
#line 884 "toke.l"
{
if (sudoerstext[sudoersleng - 1] == '\n') {
/* comment ending in a newline */
@@ -4468,7 +4463,7 @@ YY_RULE_SETUP
YY_BREAK
case 88:
YY_RULE_SETUP
#line 904 "toke.l"
#line 899 "toke.l"
{
LEXTRACE("NOMATCH ");
return NOMATCH;
@@ -4484,7 +4479,7 @@ case YY_STATE_EOF(INSTR):
case YY_STATE_EOF(WANTDIGEST):
case YY_STATE_EOF(GOTINC):
case YY_STATE_EOF(EXPECTPATH):
#line 909 "toke.l"
#line 904 "toke.l"
{
if (!pop_include())
yyterminate();
@@ -4492,10 +4487,10 @@ case YY_STATE_EOF(EXPECTPATH):
YY_BREAK
case 89:
YY_RULE_SETUP
#line 914 "toke.l"
#line 909 "toke.l"
ECHO;
YY_BREAK
#line 4493 "toke.c"
#line 4488 "toke.c"
case YY_END_OF_BUFFER:
{
@@ -5456,7 +5451,7 @@ void sudoersfree (void * ptr )
#define YYTABLES_NAME "yytables"
#line 914 "toke.l"
#line 909 "toke.l"
struct path_list {
@@ -5861,7 +5856,8 @@ push_include_int(const char *opath, bool isdir, int verbose)
int count, fd, status;
fd = sudo_open_conf_path(path, dname, sizeof(dname), NULL);
status = sudo_secure_fd(fd, S_IFDIR, sudoers_uid, sudoers_gid, &sb);
status = sudo_secure_fd(fd, S_IFDIR, sudoers_file_uid(),
sudoers_file_gid(), &sb);
if (fd != -1)
close(fd); /* XXX use in read_dir_files? */
if (status != SUDO_PATH_SECURE) {
@@ -5874,7 +5870,7 @@ push_include_int(const char *opath, bool isdir, int verbose)
case SUDO_PATH_WRONG_OWNER:
sudo_warnx(U_("%s is owned by uid %u, should be %u"),
path, (unsigned int) sb.st_uid,
(unsigned int) sudoers_uid);
(unsigned int) sudoers_file_uid());
break;
case SUDO_PATH_WORLD_WRITABLE:
sudo_warnx(U_("%s is world writable"), path);
@@ -5882,7 +5878,7 @@ push_include_int(const char *opath, bool isdir, int verbose)
case SUDO_PATH_GROUP_WRITABLE:
sudo_warnx(U_("%s is owned by gid %u, should be %u"),
path, (unsigned int) sb.st_gid,
(unsigned int) sudoers_gid);
(unsigned int) sudoers_file_gid());
break;
default:
break;

View File

@@ -2,7 +2,7 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 1996, 1998-2005, 2007-2022
* Copyright (c) 1996, 1998-2005, 2007-2023
* Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -59,11 +59,6 @@ char *sudoers_search_path; /* colon-separated path of sudoers files. */
const char *sudoers_errstr; /* description of last error from lexer. */
struct sudolinebuf sudolinebuf; /* sudoers line being parsed. */
/* Default sudoers mode and owner (may be set via sudo.conf) */
mode_t sudoers_mode = SUDOERS_MODE;
uid_t sudoers_uid = SUDOERS_UID;
gid_t sudoers_gid = SUDOERS_GID;
static bool continued, sawspace;
static int prev_state;
static int digest_type = -1;
@@ -296,7 +291,7 @@ DEFVAR [a-z_]+
yyterminate();
BEGIN INITIAL;
continued = false;
if (sudoers_strict) {
if (sudoers_strict()) {
if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) {
LEXTRACE("ERROR ");
return ERROR;
@@ -780,7 +775,7 @@ sudoedit {
} /* a pathname */
{REGEX} {
if (sudoers_strict) {
if (sudoers_strict()) {
if (!sudo_regex_compile(NULL, sudoerstext, &sudoers_errstr)) {
LEXTRACE("ERROR ");
return ERROR;
@@ -1314,7 +1309,8 @@ push_include_int(const char *opath, bool isdir, int verbose)
int count, fd, status;
fd = sudo_open_conf_path(path, dname, sizeof(dname), NULL);
status = sudo_secure_fd(fd, S_IFDIR, sudoers_uid, sudoers_gid, &sb);
status = sudo_secure_fd(fd, S_IFDIR, sudoers_file_uid(),
sudoers_file_gid(), &sb);
if (fd != -1)
close(fd); /* XXX use in read_dir_files? */
if (status != SUDO_PATH_SECURE) {
@@ -1327,7 +1323,7 @@ push_include_int(const char *opath, bool isdir, int verbose)
case SUDO_PATH_WRONG_OWNER:
sudo_warnx(U_("%s is owned by uid %u, should be %u"),
path, (unsigned int) sb.st_uid,
(unsigned int) sudoers_uid);
(unsigned int) sudoers_file_uid());
break;
case SUDO_PATH_WORLD_WRITABLE:
sudo_warnx(U_("%s is world writable"), path);
@@ -1335,7 +1331,7 @@ push_include_int(const char *opath, bool isdir, int verbose)
case SUDO_PATH_GROUP_WRITABLE:
sudo_warnx(U_("%s is owned by gid %u, should be %u"),
path, (unsigned int) sb.st_gid,
(unsigned int) sudoers_gid);
(unsigned int) sudoers_file_gid());
break;
default:
break;

View File

@@ -151,7 +151,7 @@ fill_cmnd(const char *src, size_t len)
/* Check for sudoedit specified as a fully-qualified path. */
if ((dst = strrchr(sudoerslval.command.cmnd, '/')) != NULL) { // -V575
if (strcmp(dst, "/sudoedit") == 0) {
if (sudoers_strict) {
if (sudoers_strict()) {
sudoerserror(
N_("sudoedit should not be specified with a path"));
}

View File

@@ -111,6 +111,7 @@ struct sudo_user sudo_user;
struct passwd *list_pw;
static const char *path_sudoers = _PATH_SUDOERS;
static struct sudoersfile_list sudoerslist = TAILQ_HEAD_INITIALIZER(sudoerslist);
static struct sudoers_parser_config parser_conf = SUDOERS_PARSER_CONFIG_INITIALIZER;
static bool checkonly;
static bool edit_includes = true;
static unsigned int errors;
@@ -240,11 +241,11 @@ main(int argc, char *argv[])
if (fflag) {
/* Looser owner/permission checks for an uninstalled sudoers file. */
if (!use_owner) {
sudoers_uid = -1;
sudoers_gid = -1;
parser_conf.sudoers_uid = (uid_t)-1;
parser_conf.sudoers_gid = (gid_t)-1;
}
if (!use_perms)
SET(sudoers_mode, S_IWUSR);
parser_conf.sudoers_mode |= S_IWUSR;
} else {
/* Check/set owner and mode for installed sudoers file. */
use_owner = true;
@@ -288,7 +289,9 @@ 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.
*/
init_parser(NULL, path_sudoers, true, quiet ? 0 : 2);
parser_conf.strict = true;
parser_conf.verbose = quiet ? 0 : 2;
init_parser(NULL, path_sudoers, &parser_conf);
if ((sudoersin = open_sudoers(path_sudoers, &sudoers, true, NULL)) == NULL)
exit(EXIT_FAILURE);
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
@@ -651,7 +654,7 @@ reparse_sudoers(char *editor, int editor_argc, char **editor_argv,
/* Clean slate for each parse */
if (!init_defaults())
sudo_fatalx("%s", U_("unable to initialize sudoers default values"));
init_parser(sp->opath, path_sudoers, true, quiet ? 0 : 2);
init_parser(sp->opath, path_sudoers, &parser_conf);
sp->errorline = -1;
/* Parse the sudoers temp file(s) */
@@ -742,19 +745,19 @@ install_sudoers(struct sudoersfile *sp, bool set_owner, bool set_mode)
(void) unlink(sp->tpath);
if (fstat(sp->fd, &sb) == 0) {
if (set_owner) {
if (sb.st_uid != sudoers_uid || sb.st_gid != sudoers_gid) {
if (chown(sp->opath, sudoers_uid, sudoers_gid) != 0) {
if (sb.st_uid != sudoers_file_uid() || sb.st_gid != sudoers_file_gid()) {
if (chown(sp->opath, sudoers_file_uid(), sudoers_file_gid()) != 0) {
sudo_warn(U_("unable to set (uid, gid) of %s to (%u, %u)"),
sp->opath, (unsigned int)sudoers_uid,
(unsigned int)sudoers_gid);
sp->opath, (unsigned int)sudoers_file_uid(),
(unsigned int)sudoers_file_gid());
}
}
}
if (set_mode) {
if ((sb.st_mode & ACCESSPERMS) != sudoers_mode) {
if (chmod(sp->opath, sudoers_mode) != 0) {
if ((sb.st_mode & ACCESSPERMS) != sudoers_file_mode()) {
if (chmod(sp->opath, sudoers_file_mode()) != 0) {
sudo_warn(U_("unable to change mode of %s to 0%o"),
sp->opath, (unsigned int)sudoers_mode);
sp->opath, (unsigned int)sudoers_file_mode());
}
}
}
@@ -773,10 +776,10 @@ install_sudoers(struct sudoersfile *sp, bool set_owner, bool set_mode)
sudo_fatal(U_("unable to stat %s"), sp->opath);
}
if (set_owner) {
if (chown(sp->tpath, sudoers_uid, sudoers_gid) != 0) {
if (chown(sp->tpath, sudoers_file_uid(), sudoers_file_gid()) != 0) {
sudo_warn(U_("unable to set (uid, gid) of %s to (%u, %u)"),
sp->tpath, (unsigned int)sudoers_uid,
(unsigned int)sudoers_gid);
sp->tpath, (unsigned int)sudoers_file_uid(),
(unsigned int)sudoers_file_gid());
goto done;
}
} else {
@@ -786,9 +789,9 @@ install_sudoers(struct sudoersfile *sp, bool set_owner, bool set_mode)
}
}
if (set_mode) {
if (chmod(sp->tpath, sudoers_mode) != 0) {
if (chmod(sp->tpath, sudoers_file_mode()) != 0) {
sudo_warn(U_("unable to change mode of %s to 0%o"), sp->tpath,
(unsigned int)sudoers_mode);
(unsigned int)sudoers_file_mode());
goto done;
}
} else {
@@ -1022,23 +1025,23 @@ check_file(const char *path, bool quiet, bool check_owner, bool check_mode)
if (stat(path, &sb) == 0) {
if (check_owner) {
if (sb.st_uid != sudoers_uid || sb.st_gid != sudoers_gid) {
if (sb.st_uid != sudoers_file_uid() || sb.st_gid != sudoers_file_gid()) {
ok = false;
if (!quiet) {
fprintf(stderr,
_("%s: wrong owner (uid, gid) should be (%u, %u)\n"),
path, (unsigned int)sudoers_uid,
(unsigned int)sudoers_gid);
path, (unsigned int)sudoers_file_uid(),
(unsigned int)sudoers_file_gid());
}
}
}
if (check_mode) {
if ((sb.st_mode & ALLPERMS) != sudoers_mode) {
if ((sb.st_mode & ALLPERMS) != sudoers_file_mode()) {
ok = false;
if (!quiet) {
fprintf(stderr,
_("%s: bad permissions, should be mode 0%o\n"),
path, (unsigned int)sudoers_mode);
path, (unsigned int)sudoers_file_mode());
}
}
}
@@ -1068,7 +1071,7 @@ check_syntax(const char *path, bool quiet, bool strict, bool check_owner,
goto done;
}
}
init_parser(fname, path, true, quiet ? 0 : 2);
init_parser(fname, path, &parser_conf);
sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
if (sudoersparse() && !parse_error) {
if (!quiet)
@@ -1181,7 +1184,7 @@ new_sudoers(const char *path, bool doedit)
if (fd == -1) {
if (!checkonly) {
/* No sudoers file, create the destination file for editing. */
fd = open(entry->dpath, O_RDWR|O_CREAT, sudoers_mode);
fd = open(entry->dpath, O_RDWR|O_CREAT, sudoers_file_mode());
}
if (fd == -1) {
sudo_warn("%s", entry->dpath);
@@ -1329,6 +1332,7 @@ parse_sudoers_options(void)
for (cur = info->options; *cur != NULL; cur++) {
const char *errstr, *p;
id_t id;
mode_t mode;
if (MATCHES(*cur, "sudoers_file=")) {
path_sudoers = *cur + sizeof("sudoers_file=") - 1;
@@ -1338,21 +1342,21 @@ parse_sudoers_options(void)
p = *cur + sizeof("sudoers_uid=") - 1;
id = sudo_strtoid(p, &errstr);
if (errstr == NULL)
sudoers_uid = (uid_t) id;
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_gid = (gid_t) id;
parser_conf.sudoers_gid = (gid_t)id;
continue;
}
if (MATCHES(*cur, "sudoers_mode=")) {
p = *cur + sizeof("sudoers_mode=") - 1;
id = (id_t) sudo_strtomode(p, &errstr);
mode = sudo_strtomode(p, &errstr);
if (errstr == NULL)
sudoers_mode = (mode_t) id;
parser_conf.sudoers_mode = mode;
continue;
}
}