summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2023-05-08 17:03:31 -0600
committerTodd C. Miller <Todd.Miller@sudo.ws>2023-05-08 17:03:31 -0600
commit6c8f8d3e7f9d43db5d9cae47ec8cffdc93c77861 (patch)
treed583029d6e415c794ae7f61c9206299103c662e5
parent131e61b5ef0484ce10f418e0e19c4cf2b0b4abe6 (diff)
downloadsudo-6c8f8d3e7f9d43db5d9cae47ec8cffdc93c77861.tar.gz
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.
-rw-r--r--plugins/sudoers/cvtsudoers.c2
-rw-r--r--plugins/sudoers/file.c6
-rw-r--r--plugins/sudoers/gram.c608
-rw-r--r--plugins/sudoers/gram.y62
-rw-r--r--plugins/sudoers/parse.h22
-rw-r--r--plugins/sudoers/policy.c25
-rw-r--r--plugins/sudoers/regress/fuzz/fuzz_sudoers.c2
-rw-r--r--plugins/sudoers/set_perms.c28
-rw-r--r--plugins/sudoers/sudoers.c8
-rw-r--r--plugins/sudoers/sudoers.h11
-rw-r--r--plugins/sudoers/testsudoers.c19
-rw-r--r--plugins/sudoers/toke.c208
-rw-r--r--plugins/sudoers/toke.l18
-rw-r--r--plugins/sudoers/toke_util.c2
-rw-r--r--plugins/sudoers/visudo.c60
15 files changed, 604 insertions, 477 deletions
diff --git a/plugins/sudoers/cvtsudoers.c b/plugins/sudoers/cvtsudoers.c
index 870049bbb..7eeeae9c7 100644
--- a/plugins/sudoers/cvtsudoers.c
+++ b/plugins/sudoers/cvtsudoers.c
@@ -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;
diff --git a/plugins/sudoers/file.c b/plugins/sudoers/file.c
index 1d9a2eb8c..7e03df751 100644
--- a/plugins/sudoers/file.c
+++ b/plugins/sudoers/file.c
@@ -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);
}
diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c
index d45c2d1ec..f5a046bb9 100644
--- a/plugins/sudoers/gram.c
+++ b/plugins/sudoers/gram.c
@@ -131,15 +131,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 =
@@ -876,22 +876,22 @@ static const yytype_int8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_int16 yyrline[] =
{
- 0, 202, 202, 205, 208, 209, 212, 215, 218, 225,
- 232, 238, 241, 244, 247, 250, 254, 258, 262, 266,
- 272, 275, 281, 284, 290, 291, 298, 307, 316, 326,
- 336, 348, 349, 354, 360, 377, 381, 387, 396, 404,
- 413, 422, 433, 434, 496, 566, 575, 584, 593, 604,
- 605, 612, 615, 629, 633, 639, 655, 671, 676, 680,
- 685, 690, 695, 700, 704, 709, 712, 717, 733, 744,
- 756, 767, 785, 786, 787, 788, 789, 790, 791, 792,
- 793, 794, 795, 798, 804, 807, 812, 817, 826, 835,
- 847, 854, 861, 868, 875, 884, 887, 890, 893, 896,
- 899, 902, 905, 908, 911, 914, 917, 920, 923, 926,
- 929, 932, 937, 951, 960, 981, 1004, 1005, 1008, 1008,
- 1020, 1023, 1024, 1031, 1032, 1035, 1035, 1047, 1050, 1051,
- 1058, 1059, 1062, 1062, 1074, 1077, 1078, 1081, 1081, 1093,
- 1096, 1097, 1104, 1108, 1114, 1123, 1131, 1140, 1149, 1160,
- 1161, 1168, 1172, 1178, 1187, 1195
+ 0, 202, 202, 205, 208, 209, 212, 215, 218, 226,
+ 234, 240, 243, 246, 249, 252, 256, 260, 264, 268,
+ 274, 277, 283, 286, 292, 293, 300, 309, 318, 328,
+ 338, 350, 351, 356, 362, 379, 383, 389, 398, 406,
+ 415, 424, 435, 436, 498, 568, 577, 586, 595, 606,
+ 607, 614, 617, 631, 635, 641, 657, 673, 678, 682,
+ 687, 692, 697, 702, 706, 711, 714, 719, 735, 746,
+ 758, 769, 787, 788, 789, 790, 791, 792, 793, 794,
+ 795, 796, 797, 800, 806, 809, 814, 819, 828, 837,
+ 849, 856, 863, 870, 877, 886, 889, 892, 895, 898,
+ 901, 904, 907, 910, 913, 916, 919, 922, 925, 928,
+ 931, 934, 939, 953, 962, 983, 1006, 1007, 1010, 1010,
+ 1022, 1025, 1026, 1033, 1034, 1037, 1037, 1049, 1052, 1053,
+ 1060, 1061, 1064, 1064, 1076, 1079, 1080, 1083, 1083, 1095,
+ 1098, 1099, 1106, 1110, 1116, 1125, 1133, 1142, 1151, 1162,
+ 1163, 1170, 1174, 1180, 1189, 1197
};
#endif
@@ -1675,161 +1675,163 @@ yyreduce:
case 8: /* entry: include */
#line 218 "gram.y"
{
- const bool success = push_include((yyvsp[0].string), sudoers_verbose);
+ const bool success = push_include((yyvsp[0].string),
+ parser_conf.verbose);
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
- if (!success && !sudoers_recovery)
+ if (!success && !parser_conf.recovery)
YYERROR;
}
-#line 1679 "gram.c"
+#line 1680 "gram.c"
break;
case 9: /* entry: includedir */
-#line 225 "gram.y"
+#line 226 "gram.y"
{
- const bool success = push_includedir((yyvsp[0].string), sudoers_verbose);
+ const bool success = push_includedir((yyvsp[0].string),
+ parser_conf.verbose);
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
free((yyvsp[0].string));
- if (!success && !sudoers_recovery)
+ if (!success && !parser_conf.recovery)
YYERROR;
}
-#line 1691 "gram.c"
+#line 1693 "gram.c"
break;
case 10: /* entry: userlist privileges '\n' */
-#line 232 "gram.y"
+#line 234 "gram.y"
{
if (!add_userspec((yyvsp[-2].member), (yyvsp[-1].privilege))) {
sudoerserror(N_("unable to allocate memory"));
YYERROR;
}
}
-#line 1702 "gram.c"
+#line 1704 "gram.c"
break;
case 11: /* entry: USERALIAS useraliases '\n' */
-#line 238 "gram.y"
+#line 240 "gram.y"
{
;
}
-#line 1710 "gram.c"
+#line 1712 "gram.c"
break;
case 12: /* entry: HOSTALIAS hostaliases '\n' */
-#line 241 "gram.y"
+#line 243 "gram.y"
{
;
}
-#line 1718 "gram.c"
+#line 1720 "gram.c"
break;
case 13: /* entry: CMNDALIAS cmndaliases '\n' */
-#line 244 "gram.y"
+#line 246 "gram.y"
{
;
}
-#line 1726 "gram.c"
+#line 1728 "gram.c"
break;
case 14: /* entry: RUNASALIAS runasaliases '\n' */
-#line 247 "gram.y"
+#line 249 "gram.y"
{
;
}
-#line 1734 "gram.c"
+#line 1736 "gram.c"
break;
case 15: /* entry: DEFAULTS defaults_list '\n' */
-#line 250 "gram.y"
+#line 252 "gram.y"
{
if (!add_defaults(DEFAULTS, NULL, (yyvsp[-1].defaults)))
YYERROR;
}
-#line 1743 "gram.c"
+#line 1745 "gram.c"
break;
case 16: /* entry: DEFAULTS_USER userlist defaults_list '\n' */
-#line 254 "gram.y"
+#line 256 "gram.y"
{
if (!add_defaults(DEFAULTS_USER, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
-#line 1752 "gram.c"
+#line 1754 "gram.c"
break;
case 17: /* entry: DEFAULTS_RUNAS userlist defaults_list '\n' */
-#line 258 "gram.y"
+#line 260 "gram.y"
{
if (!add_defaults(DEFAULTS_RUNAS, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
-#line 1761 "gram.c"
+#line 1763 "gram.c"
break;
case 18: /* entry: DEFAULTS_HOST hostlist defaults_list '\n' */
-#line 262 "gram.y"
+#line 264 "gram.y"
{
if (!add_defaults(DEFAULTS_HOST, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
-#line 1770 "gram.c"
+#line 1772 "gram.c"
break;
case 19: /* entry: DEFAULTS_CMND cmndlist defaults_list '\n' */
-#line 266 "gram.y"
+#line 268 "gram.y"
{
if (!add_defaults(DEFAULTS_CMND, (yyvsp[-2].member), (yyvsp[-1].defaults)))
YYERROR;
}
-#line 1779 "gram.c"
+#line 1781 "gram.c"
break;
case 20: /* include: INCLUDE WORD '\n' */
-#line 272 "gram.y"
+#line 274 "gram.y"
{
(yyval.string) = (yyvsp[-1].string);
}
-#line 1787 "gram.c"
+#line 1789 "gram.c"
break;
case 21: /* include: INCLUDE WORD error '\n' */
-#line 275 "gram.y"
+#line 277 "gram.y"
{
yyerrok;
(yyval.string) = (yyvsp[-2].string);
}
-#line 1796 "gram.c"
+#line 1798 "gram.c"
break;
case 22: /* includedir: INCLUDEDIR WORD '\n' */
-#line 281 "gram.y"
+#line 283 "gram.y"
{
(yyval.string) = (yyvsp[-1].string);
}
-#line 1804 "gram.c"
+#line 1806 "gram.c"
break;
case 23: /* includedir: INCLUDEDIR WORD error '\n' */
-#line 284 "gram.y"
+#line 286 "gram.y"
{
yyerrok;
(yyval.string) = (yyvsp[-2].string);
}
-#line 1813 "gram.c"
+#line 1815 "gram.c"
break;
case 25: /* defaults_list: defaults_list ',' defaults_entry */
-#line 291 "gram.y"
+#line 293 "gram.y"
{
parser_leak_remove(LEAK_DEFAULTS, (yyvsp[0].defaults));
HLTQ_CONCAT((yyvsp[-2].defaults), (yyvsp[0].defaults), entries);
(yyval.defaults) = (yyvsp[-2].defaults);
}
-#line 1823 "gram.c"
+#line 1825 "gram.c"
break;
case 26: /* defaults_entry: DEFVAR */
-#line 298 "gram.y"
+#line 300 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[0].string), NULL, true);
if ((yyval.defaults) == NULL) {
@@ -1839,11 +1841,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
-#line 1837 "gram.c"
+#line 1839 "gram.c"
break;
case 27: /* defaults_entry: '!' DEFVAR */
-#line 307 "gram.y"
+#line 309 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[0].string), NULL, false);
if ((yyval.defaults) == NULL) {
@@ -1853,11 +1855,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
-#line 1851 "gram.c"
+#line 1853 "gram.c"
break;
case 28: /* defaults_entry: DEFVAR '=' WORD */
-#line 316 "gram.y"
+#line 318 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), true);
if ((yyval.defaults) == NULL) {
@@ -1868,11 +1870,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
-#line 1866 "gram.c"
+#line 1868 "gram.c"
break;
case 29: /* defaults_entry: DEFVAR '+' WORD */
-#line 326 "gram.y"
+#line 328 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '+');
if ((yyval.defaults) == NULL) {
@@ -1883,11 +1885,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
-#line 1881 "gram.c"
+#line 1883 "gram.c"
break;
case 30: /* defaults_entry: DEFVAR '-' WORD */
-#line 336 "gram.y"
+#line 338 "gram.y"
{
(yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '-');
if ((yyval.defaults) == NULL) {
@@ -1898,30 +1900,30 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DEFAULTS, (yyval.defaults));
}
-#line 1896 "gram.c"
+#line 1898 "gram.c"
break;
case 32: /* privileges: privileges ':' privilege */
-#line 349 "gram.y"
+#line 351 "gram.y"
{
parser_leak_remove(LEAK_PRIVILEGE, (yyvsp[0].privilege));
HLTQ_CONCAT((yyvsp[-2].privilege), (yyvsp[0].privilege), entries);
(yyval.privilege) = (yyvsp[-2].privilege);
}
-#line 1906 "gram.c"
+#line 1908 "gram.c"
break;
case 33: /* privileges: privileges ':' error */
-#line 354 "gram.y"
+#line 356 "gram.y"
{
yyerrok;
(yyval.privilege) = (yyvsp[-2].privilege);
}
-#line 1915 "gram.c"
+#line 1917 "gram.c"
break;
case 34: /* privilege: hostlist '=' cmndspeclist */
-#line 360 "gram.y"
+#line 362 "gram.y"
{
struct privilege *p = calloc(1, sizeof(*p));
if (p == NULL) {
@@ -1937,29 +1939,29 @@ yyreduce:
HLTQ_INIT(p, entries);
(yyval.privilege) = p;
}
-#line 1935 "gram.c"
+#line 1937 "gram.c"
break;
case 35: /* ophost: host */
-#line 377 "gram.y"
+#line 379 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
-#line 1944 "gram.c"
+#line 1946 "gram.c"
break;
case 36: /* ophost: '!' host */
-#line 381 "gram.y"
+#line 383 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
-#line 1953 "gram.c"
+#line 1955 "gram.c"
break;
case 37: /* host: ALIAS */
-#line 387 "gram.y"
+#line 389 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
@@ -1969,11 +1971,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 1967 "gram.c"
+#line 1969 "gram.c"
break;
case 38: /* host: ALL */
-#line 396 "gram.y"
+#line 398 "gram.y"
{
(yyval.member) = new_member(NULL, ALL);
if ((yyval.member) == NULL) {
@@ -1982,11 +1984,11 @@ yyreduce:
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 1980 "gram.c"
+#line 1982 "gram.c"
break;
case 39: /* host: NETGROUP */
-#line 404 "gram.y"
+#line 406 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), NETGROUP);
if ((yyval.member) == NULL) {
@@ -1996,11 +1998,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 1994 "gram.c"
+#line 1996 "gram.c"
break;
case 40: /* host: NTWKADDR */
-#line 413 "gram.y"
+#line 415 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), NTWKADDR);
if ((yyval.member) == NULL) {
@@ -2010,11 +2012,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 2008 "gram.c"
+#line 2010 "gram.c"
break;
case 41: /* host: WORD */
-#line 422 "gram.y"
+#line 424 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), WORD);
if ((yyval.member) == NULL) {
@@ -2024,11 +2026,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 2022 "gram.c"
+#line 2024 "gram.c"
break;
case 43: /* cmndspeclist: cmndspeclist ',' cmndspec */
-#line 434 "gram.y"
+#line 436 "gram.y"
{
struct cmndspec *prev;
prev = HLTQ_LAST((yyvsp[-2].cmndspec), cmndspec, entries);
@@ -2089,11 +2091,11 @@ yyreduce:
}
(yyval.cmndspec) = (yyvsp[-2].cmndspec);
}
-#line 2087 "gram.c"
+#line 2089 "gram.c"
break;
case 44: /* cmndspec: runasspec options cmndtag digcmnd */
-#line 496 "gram.y"
+#line 498 "gram.y"
{
struct cmndspec *cs = calloc(1, sizeof(*cs));
if (cs == NULL) {
@@ -2162,11 +2164,11 @@ yyreduce:
cs->tags.setenv = IMPLIED;
(yyval.cmndspec) = cs;
}
-#line 2160 "gram.c"
+#line 2162 "gram.c"
break;
case 45: /* digestspec: SHA224_TOK ':' DIGEST */
-#line 566 "gram.y"
+#line 568 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
@@ -2176,11 +2178,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
-#line 2174 "gram.c"
+#line 2176 "gram.c"
break;
case 46: /* digestspec: SHA256_TOK ':' DIGEST */
-#line 575 "gram.y"
+#line 577 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
@@ -2190,11 +2192,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
-#line 2188 "gram.c"
+#line 2190 "gram.c"
break;
case 47: /* digestspec: SHA384_TOK ':' DIGEST */
-#line 584 "gram.y"
+#line 586 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
@@ -2204,11 +2206,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
-#line 2202 "gram.c"
+#line 2204 "gram.c"
break;
case 48: /* digestspec: SHA512_TOK ':' DIGEST */
-#line 593 "gram.y"
+#line 595 "gram.y"
{
(yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[0].string));
if ((yyval.digest) == NULL) {
@@ -2218,29 +2220,29 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_DIGEST, (yyval.digest));
}
-#line 2216 "gram.c"
+#line 2218 "gram.c"
break;
case 50: /* digestlist: digestlist ',' digestspec */
-#line 605 "gram.y"
+#line 607 "gram.y"
{
parser_leak_remove(LEAK_DIGEST, (yyvsp[0].digest));
HLTQ_CONCAT((yyvsp[-2].digest), (yyvsp[0].digest), entries);
(yyval.digest) = (yyvsp[-2].digest);
}
-#line 2226 "gram.c"
+#line 2228 "gram.c"
break;
case 51: /* digcmnd: opcmnd */
-#line 612 "gram.y"
+#line 614 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
}
-#line 2234 "gram.c"
+#line 2236 "gram.c"
break;
case 52: /* digcmnd: digestlist opcmnd */
-#line 615 "gram.y"
+#line 617 "gram.y"
{
struct sudo_command *c =
(struct sudo_command *) (yyvsp[0].member)->name;
@@ -2253,29 +2255,29 @@ yyreduce:
HLTQ_TO_TAILQ(&c->digests, (yyvsp[-1].digest), entries);
(yyval.member) = (yyvsp[0].member);
}
-#line 2251 "gram.c"
+#line 2253 "gram.c"
break;
case 53: /* opcmnd: cmnd */
-#line 629 "gram.y"
+#line 631 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
-#line 2260 "gram.c"
+#line 2262 "gram.c"
break;
case 54: /* opcmnd: '!' cmnd */
-#line 633 "gram.y"
+#line 635 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
-#line 2269 "gram.c"
+#line 2271 "gram.c"
break;
case 55: /* chdirspec: CWD '=' WORD */
-#line 639 "gram.y"
+#line 641 "gram.y"
{
if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') {
if (strcmp((yyvsp[0].string), "*") != 0) {
@@ -2290,11 +2292,11 @@ yyreduce:
}
(yyval.string) = (yyvsp[0].string);
}
-#line 2288 "gram.c"
+#line 2290 "gram.c"
break;
case 56: /* chrootspec: CHROOT '=' WORD */
-#line 655 "gram.y"
+#line 657 "gram.y"
{
if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') {
if (strcmp((yyvsp[0].string), "*") != 0) {
@@ -2309,91 +2311,91 @@ yyreduce:
}
(yyval.string) = (yyvsp[0].string);
}
-#line 2307 "gram.c"
+#line 2309 "gram.c"
break;
case 57: /* timeoutspec: CMND_TIMEOUT '=' WORD */
-#line 671 "gram.y"
+#line 673 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2315 "gram.c"
+#line 2317 "gram.c"
break;
case 58: /* notbeforespec: NOTBEFORE '=' WORD */
-#line 676 "gram.y"
+#line 678 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2323 "gram.c"
+#line 2325 "gram.c"
break;
case 59: /* notafterspec: NOTAFTER '=' WORD */
-#line 680 "gram.y"
+#line 682 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2331 "gram.c"
+#line 2333 "gram.c"
break;
case 60: /* rolespec: ROLE '=' WORD */
-#line 685 "gram.y"
+#line 687 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2339 "gram.c"
+#line 2341 "gram.c"
break;
case 61: /* typespec: TYPE '=' WORD */
-#line 690 "gram.y"
+#line 692 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2347 "gram.c"
+#line 2349 "gram.c"
break;
case 62: /* apparmor_profilespec: APPARMOR_PROFILE '=' WORD */
-#line 695 "gram.y"
+#line 697 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2355 "gram.c"
+#line 2357 "gram.c"
break;
case 63: /* privsspec: PRIVS '=' WORD */
-#line 700 "gram.y"
+#line 702 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2363 "gram.c"
+#line 2365 "gram.c"
break;
case 64: /* limitprivsspec: LIMITPRIVS '=' WORD */
-#line 704 "gram.y"
+#line 706 "gram.y"
{
(yyval.string) = (yyvsp[0].string);
}
-#line 2371 "gram.c"
+#line 2373 "gram.c"
break;
case 65: /* runasspec: %empty */
-#line 709 "gram.y"
+#line 711 "gram.y"
{
(yyval.runas) = NULL;
}
-#line 2379 "gram.c"
+#line 2381 "gram.c"
break;
case 66: /* runasspec: '(' runaslist ')' */
-#line 712 "gram.y"
+#line 714 "gram.y"
{
(yyval.runas) = (yyvsp[-1].runas);
}
-#line 2387 "gram.c"
+#line 2389 "gram.c"
break;
case 67: /* runaslist: %empty */
-#line 717 "gram.y"
+#line 719 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) != NULL) {
@@ -2410,11 +2412,11 @@ yyreduce:
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
}
-#line 2408 "gram.c"
+#line 2410 "gram.c"
break;
case 68: /* runaslist: userlist */
-#line 733 "gram.y"
+#line 735 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) == NULL) {
@@ -2426,11 +2428,11 @@ yyreduce:
(yyval.runas)->runasusers = (yyvsp[0].member);
/* $$->runasgroups = NULL; */
}
-#line 2424 "gram.c"
+#line 2426 "gram.c"
break;
case 69: /* runaslist: userlist ':' grouplist */
-#line 744 "gram.y"
+#line 746 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) == NULL) {
@@ -2443,11 +2445,11 @@ yyreduce:
(yyval.runas)->runasusers = (yyvsp[-2].member);
(yyval.runas)->runasgroups = (yyvsp[0].member);
}
-#line 2441 "gram.c"
+#line 2443 "gram.c"
break;
case 70: /* runaslist: ':' grouplist */
-#line 756 "gram.y"
+#line 758 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) == NULL) {
@@ -2459,11 +2461,11 @@ yyreduce:
/* $$->runasusers = NULL; */
(yyval.runas)->runasgroups = (yyvsp[0].member);
}
-#line 2457 "gram.c"
+#line 2459 "gram.c"
break;
case 71: /* runaslist: ':' */
-#line 767 "gram.y"
+#line 769 "gram.y"
{
(yyval.runas) = calloc(1, sizeof(struct runascontainer));
if ((yyval.runas) != NULL) {
@@ -2480,114 +2482,114 @@ yyreduce:
}
parser_leak_add(LEAK_RUNAS, (yyval.runas));
}
-#line 2478 "gram.c"
+#line 2480 "gram.c"
break;
case 72: /* reserved_word: ALL */
-#line 785 "gram.y"
+#line 787 "gram.y"
{ (yyval.cstring) = "ALL"; }
-#line 2484 "gram.c"
+#line 2486 "gram.c"
break;
case 73: /* reserved_word: CHROOT */
-#line 786 "gram.y"
+#line 788 "gram.y"
{ (yyval.cstring) = "CHROOT"; }
-#line 2490 "gram.c"
+#line 2492 "gram.c"
break;
case 74: /* reserved_word: CWD */
-#line 787 "gram.y"
+#line 789 "gram.y"
{ (yyval.cstring) = "CWD"; }
-#line 2496 "gram.c"
+#line 2498 "gram.c"
break;
case 75: /* reserved_word: CMND_TIMEOUT */
-#line 788 "gram.y"
+#line 790 "gram.y"
{ (yyval.cstring) = "CMND_TIMEOUT"; }
-#line 2502 "gram.c"
+#line 2504 "gram.c"
break;
case 76: /* reserved_word: NOTBEFORE */
-#line 789 "gram.y"
+#line 791 "gram.y"
{ (yyval.cstring) = "NOTBEFORE"; }
-#line 2508 "gram.c"
+#line 2510 "gram.c"
break;
case 77: /* reserved_word: NOTAFTER */
-#line 790 "gram.y"
+#line 792 "gram.y"
{ (yyval.cstring) = "NOTAFTER"; }
-#line 2514 "gram.c"
+#line 2516 "gram.c"
break;
case 78: /* reserved_word: ROLE */
-#line 791 "gram.y"
+#line 793 "gram.y"
{ (yyval.cstring) = "ROLE"; }
-#line 2520 "gram.c"
+#line 2522 "gram.c"
break;
case 79: /* reserved_word: TYPE */
-#line 792 "gram.y"
+#line 794 "gram.y"
{ (yyval.cstring) = "TYPE"; }
-#line 2526 "gram.c"
+#line 2528 "gram.c"
break;
case 80: /* reserved_word: PRIVS */
-#line 793 "gram.y"
+#line 795 "gram.y"
{ (yyval.cstring) = "PRIVS"; }
-#line 2532 "gram.c"
+#line 2534 "gram.c"
break;
case 81: /* reserved_word: LIMITPRIVS */
-#line 794 "gram.y"
+#line 796 "gram.y"
{ (yyval.cstring) = "LIMITPRIVS"; }
-#line 2538 "gram.c"
+#line 2540 "gram.c"
break;
case 82: /* reserved_word: APPARMOR_PROFILE */
-#line 795 "gram.y"
+#line 797 "gram.y"
{ (yyval.cstring) = "APPARMOR_PROFILE"; }
-#line 2544 "gram.c"
+#line 2546 "gram.c"
break;
case 83: /* reserved_alias: reserved_word */
-#line 798 "gram.y"
+#line 800 "gram.y"
{
sudoerserrorf(U_("syntax error, reserved word %s used as an alias name"), (yyvsp[0].cstring));
YYERROR;
}
-#line 2553 "gram.c"
+#line 2555 "gram.c"
break;
case 84: /* options: %empty */
-#line 804 "gram.y"
+#line 806 "gram.y"
{
init_options(&(yyval.options));
}
-#line 2561 "gram.c"
+#line 2563 "gram.c"
break;
case 85: /* options: options chdirspec */
-#line 807 "gram.y"
+#line 809 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).runcwd);
free((yyval.options).runcwd);
(yyval.options).runcwd = (yyvsp[0].string);
}
-#line 2571 "gram.c"
+#line 2573 "gram.c"
break;
case 86: /* options: options chrootspec */
-#line 812 "gram.y"
+#line 814 "gram.y"
{
parser_leak_remove(LEAK_PTR, (yyval.options).runchroot);
free((yyval.options).runchroot);
(yyval.options).runchroot = (yyvsp[0].string);
}
-#line 2581 "gram.c"
+#line 2583 "gram.c"
break;
case 87: /* options: options notbeforespec */
-#line 817 "gram.y"
+#line 819 "gram.y"
{
(yyval.options).notbefore = parse_gentime((yyvsp[0].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
@@ -2597,11 +2599,11 @@ yyreduce:
YYERROR;
}
}
-#line 2595 "gram.c"
+#line 2597 "gram.c"
break;
case 88: /* options: options notafterspec */
-#line 826 "gram.y"
+#line 828 "gram.y"
{
(yyval.options).notafter = parse_gentime((yyvsp[0].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
@@ -2611,11 +2613,11 @@ yyreduce:
YYERROR;
}
}
-#line 2609 "gram.c"
+#line 2611 "gram.c"
break;
case 89: /* options: options timeoutspec */
-#line 835 "gram.y"
+#line 837 "gram.y"
{
(yyval.options).timeout = parse_timeout((yyvsp[0].string));
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
@@ -2628,11 +2630,11 @@ yyreduce:
YYERROR;
}
}
-#line 2626 "gram.c"
+#line 2628 "gram.c"
break;
case 90: /* options: options rolespec */
-#line 847 "gram.y"
+#line 849 "gram.y"
{
#ifdef HAVE_SELINUX
parser_leak_remove(LEAK_PTR, (yyval.options).role);
@@ -2640,11 +2642,11 @@ yyreduce:
(yyval.options).role = (yyvsp[0].string);
#endif
}
-#line 2638 "gram.c"
+#line 2640 "gram.c"
break;
case 91: /* options: options typespec */
-#line 854 "gram.y"
+#line 856 "gram.y"
{
#ifdef HAVE_SELINUX
parser_leak_remove(LEAK_PTR, (yyval.options).type);
@@ -2652,11 +2654,11 @@ yyreduce:
(yyval.options).type = (yyvsp[0].string);
#endif
}
-#line 2650 "gram.c"
+#line 2652 "gram.c"
break;
case 92: /* options: options apparmor_profilespec */
-#line 861 "gram.y"
+#line 863 "gram.y"
{
#ifdef HAVE_APPARMOR
parser_leak_remove(LEAK_PTR, (yyval.options).apparmor_profile);
@@ -2664,11 +2666,11 @@ yyreduce:
(yyval.options).apparmor_profile = (yyvsp[0].string);
#endif
}
-#line 2662 "gram.c"
+#line 2664 "gram.c"
break;
case 93: /* options: options privsspec */
-#line 868 "gram.y"
+#line 870 "gram.y"
{
#ifdef HAVE_PRIV_SET
parser_leak_remove(LEAK_PTR, (yyval.options).privs);
@@ -2676,11 +2678,11 @@ yyreduce:
(yyval.options).privs = (yyvsp[0].string);
#endif
}
-#line 2674 "gram.c"
+#line 2676 "gram.c"
break;
case 94: /* options: options limitprivsspec */
-#line 875 "gram.y"
+#line 877 "gram.y"
{
#ifdef HAVE_PRIV_SET
parser_leak_remove(LEAK_PTR, (yyval.options).limitprivs);
@@ -2688,147 +2690,147 @@ yyreduce:
(yyval.options).limitprivs = (yyvsp[0].string);
#endif
}
-#line 2686 "gram.c"
+#line 2688 "gram.c"
break;
case 95: /* cmndtag: %empty */
-#line 884 "gram.y"
+#line 886 "gram.y"
{
TAGS_INIT(&(yyval.tag));
}
-#line 2694 "gram.c"
+#line 2696 "gram.c"
break;
case 96: /* cmndtag: cmndtag NOPASSWD */
-#line 887 "gram.y"
+#line 889 "gram.y"
{
(yyval.tag).nopasswd = true;
}
-#line 2702 "gram.c"
+#line 2704 "gram.c"
break;
case 97: /* cmndtag: cmndtag PASSWD */
-#line 890 "gram.y"
+#line 892 "gram.y"
{
(yyval.tag).nopasswd = false;
}
-#line 2710 "gram.c"
+#line 2712 "gram.c"
break;
case 98: /* cmndtag: cmndtag NOEXEC */
-#line 893 "gram.y"
+#line 895 "gram.y"
{
(yyval.tag).noexec = true;
}
-#line 2718 "gram.c"
+#line 2720 "gram.c"
break;
case 99: /* cmndtag: cmndtag EXEC */
-#line 896 "gram.y"
+#line 898 "gram.y"
{
(yyval.tag).noexec = false;
}
-#line 2726 "gram.c"
+#line 2728 "gram.c"
break;
case 100: /* cmndtag: cmndtag INTERCEPT */
-#line 899 "gram.y"
+#line 901 "gram.y"
{
(yyval.tag).intercept = true;
}
-#line 2734 "gram.c"
+#line 2736 "gram.c"
break;
case 101: /* cmndtag: cmndtag NOINTERCEPT */
-#line 902 "gram.y"
+#line 904 "gram.y"
{
(yyval.tag).intercept = false;
}
-#line 2742 "gram.c"
+#line 2744 "gram.c"
break;
case 102: /* cmndtag: cmndtag SETENV */
-#line 905 "gram.y"
+#line 907 "gram.y"
{
(yyval.tag).setenv = true;
}
-#line 2750 "gram.c"
+#line 2752 "gram.c"
break;
case 103: /* cmndtag: cmndtag NOSETENV */
-#line 908 "gram.y"
+#line 910 "gram.y"
{
(yyval.tag).setenv = false;
}
-#line 2758 "gram.c"
+#line 2760 "gram.c"
break;
case 104: /* cmndtag: cmndtag LOG_INPUT */
-#line 911 "gram.y"
+#line 913 "gram.y"
{
(yyval.tag).log_input = true;
}
-#line 2766 "gram.c"
+#line 2768 "gram.c"
break;
case 105: /* cmndtag: cmndtag NOLOG_INPUT */
-#line 914 "gram.y"
+#line 916 "gram.y"
{
(yyval.tag).log_input = false;
}
-#line 2774 "gram.c"
+#line 2776 "gram.c"
break;
case 106: /* cmndtag: cmndtag LOG_OUTPUT */
-#line 917 "gram.y"
+#line 919 "gram.y"
{
(yyval.tag).log_output = true;
}
-#line 2782 "gram.c"
+#line 2784 "gram.c"
break;
case 107: /* cmndtag: cmndtag NOLOG_OUTPUT */
-#line 920 "gram.y"
+#line 922 "gram.y"
{
(yyval.tag).log_output = false;
}
-#line 2790 "gram.c"
+#line 2792 "gram.c"
break;
case 108: /* cmndtag: cmndtag FOLLOWLNK */
-#line 923 "gram.y"
+#line 925 "gram.y"
{
(yyval.tag).follow = true;
}
-#line 2798 "gram.c"
+#line 2800 "gram.c"
break;
case 109: /* cmndtag: cmndtag NOFOLLOWLNK */
-#line 926 "gram.y"
+#line 928 "gram.y"
{
(yyval.tag).follow = false;
}
-#line 2806 "gram.c"
+#line 2808 "gram.c"
break;
case 110: /* cmndtag: cmndtag MAIL */
-#line 929 "gram.y"
+#line 931 "gram.y"
{
(yyval.tag).send_mail = true;
}
-#line 2814 "gram.c"
+#line 2816 "gram.c"
break;
case 111: /* cmndtag: cmndtag NOMAIL */
-#line 932 "gram.y"
+#line 934 "gram.y"
{
(yyval.tag).send_mail = false;
}
-#line 2822 "gram.c"
+#line 2824 "gram.c"
break;
case 112: /* cmnd: ALL */
-#line 937 "gram.y"
+#line 939 "gram.y"
{
struct sudo_command *c;
@@ -2843,11 +2845,11 @@ yyreduce:
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 2841 "gram.c"
+#line 2843 "gram.c"
break;
case 113: /* cmnd: ALIAS */
-#line 951 "gram.y"
+#line 953 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
@@ -2857,11 +2859,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 2855 "gram.c"
+#line 2857 "gram.c"
break;
case 114: /* cmnd: COMMAND */
-#line 960 "gram.y"
+#line 962 "gram.y"
{
struct sudo_command *c;
@@ -2883,11 +2885,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].command).args);
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 2881 "gram.c"
+#line 2883 "gram.c"
break;
case 115: /* cmnd: WORD */
-#line 981 "gram.y"
+#line 983 "gram.y"
{
if (strcmp((yyvsp[0].string), "list") == 0) {
struct sudo_command *c;
@@ -2909,20 +2911,20 @@ yyreduce:
YYERROR;
}
}
-#line 2907 "gram.c"
+#line 2909 "gram.c"
break;
case 118: /* $@1: %empty */
-#line 1008 "gram.y"
+#line 1010 "gram.y"
{
alias_line = this_lineno;
alias_column = sudolinebuf.toke_start + 1;
}
-#line 2916 "gram.c"
+#line 2918 "gram.c"
break;
case 119: /* hostalias: ALIAS $@1 '=' hostlist */
-#line 1011 "gram.y"
+#line 1013 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
@@ -2932,30 +2934,30 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
-#line 2930 "gram.c"
+#line 2932 "gram.c"
break;
case 122: /* hostlist: hostlist ',' ophost */
-#line 1024 "gram.y"
+#line 1026 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
-#line 2940 "gram.c"
+#line 2942 "gram.c"
break;
case 125: /* $@2: %empty */
-#line 1035 "gram.y"
+#line 1037 "gram.y"
{
alias_line = this_lineno;
alias_column = sudolinebuf.toke_start + 1;
}
-#line 2949 "gram.c"
+#line 2951 "gram.c"
break;
case 126: /* cmndalias: ALIAS $@2 '=' cmndlist */
-#line 1038 "gram.y"
+#line 1040 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
@@ -2965,30 +2967,30 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
-#line 2963 "gram.c"
+#line 2965 "gram.c"
break;
case 129: /* cmndlist: cmndlist ',' digcmnd */
-#line 1051 "gram.y"
+#line 1053 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
-#line 2973 "gram.c"
+#line 2975 "gram.c"
break;
case 132: /* $@3: %empty */
-#line 1062 "gram.y"
+#line 1064 "gram.y"
{
alias_line = this_lineno;
alias_column = sudolinebuf.toke_start + 1;
}
-#line 2982 "gram.c"
+#line 2984 "gram.c"
break;
case 133: /* runasalias: ALIAS $@3 '=' userlist */
-#line 1065 "gram.y"
+#line 1067 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
@@ -2998,20 +3000,20 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
-#line 2996 "gram.c"
+#line 2998 "gram.c"
break;
case 137: /* $@4: %empty */
-#line 1081 "gram.y"
+#line 1083 "gram.y"
{
alias_line = this_lineno;
alias_column = sudolinebuf.toke_start + 1;
}
-#line 3005 "gram.c"
+#line 3007 "gram.c"
break;
case 138: /* useralias: ALIAS $@4 '=' userlist */
-#line 1084 "gram.y"
+#line 1086 "gram.y"
{
if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS,
sudoers, alias_line, alias_column, (yyvsp[0].member))) {
@@ -3021,39 +3023,39 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[-3].string));
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
}
-#line 3019 "gram.c"
+#line 3021 "gram.c"
break;
case 141: /* userlist: userlist ',' opuser */
-#line 1097 "gram.y"
+#line 1099 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
-#line 3029 "gram.c"
+#line 3031 "gram.c"
break;
case 142: /* opuser: user */
-#line 1104 "gram.y"
+#line 1106 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
-#line 3038 "gram.c"
+#line 3040 "gram.c"
break;
case 143: /* opuser: '!' user */
-#line 1108 "gram.y"
+#line 1110 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
-#line 3047 "gram.c"
+#line 3049 "gram.c"
break;
case 144: /* user: ALIAS */
-#line 1114 "gram.y"
+#line 1116 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
@@ -3063,11 +3065,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3061 "gram.c"
+#line 3063 "gram.c"
break;
case 145: /* user: ALL */
-#line 1123 "gram.y"
+#line 1125 "gram.y"
{
(yyval.member) = new_member(NULL, ALL);
if ((yyval.member) == NULL) {
@@ -3076,11 +3078,11 @@ yyreduce:
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3074 "gram.c"
+#line 3076 "gram.c"
break;
case 146: /* user: NETGROUP */
-#line 1131 "gram.y"
+#line 1133 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), NETGROUP);
if ((yyval.member) == NULL) {
@@ -3090,11 +3092,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3088 "gram.c"
+#line 3090 "gram.c"
break;
case 147: /* user: USERGROUP */
-#line 1140 "gram.y"
+#line 1142 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), USERGROUP);
if ((yyval.member) == NULL) {
@@ -3104,11 +3106,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3102 "gram.c"
+#line 3104 "gram.c"
break;
case 148: /* user: WORD */
-#line 1149 "gram.y"
+#line 1151 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), WORD);
if ((yyval.member) == NULL) {
@@ -3118,39 +3120,39 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3116 "gram.c"
+#line 3118 "gram.c"
break;
case 150: /* grouplist: grouplist ',' opgroup */
-#line 1161 "gram.y"
+#line 1163 "gram.y"
{
parser_leak_remove(LEAK_MEMBER, (yyvsp[0].member));
HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries);
(yyval.member) = (yyvsp[-2].member);
}
-#line 3126 "gram.c"
+#line 3128 "gram.c"
break;
case 151: /* opgroup: group */
-#line 1168 "gram.y"
+#line 1170 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = false;
}
-#line 3135 "gram.c"
+#line 3137 "gram.c"
break;
case 152: /* opgroup: '!' group */
-#line 1172 "gram.y"
+#line 1174 "gram.y"
{
(yyval.member) = (yyvsp[0].member);
(yyval.member)->negated = true;
}
-#line 3144 "gram.c"
+#line 3146 "gram.c"
break;
case 153: /* group: ALIAS */
-#line 1178 "gram.y"
+#line 1180 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), ALIAS);
if ((yyval.member) == NULL) {
@@ -3160,11 +3162,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3158 "gram.c"
+#line 3160 "gram.c"
break;
case 154: /* group: ALL */
-#line 1187 "gram.y"
+#line 1189 "gram.y"
{
(yyval.member) = new_member(NULL, ALL);
if ((yyval.member) == NULL) {
@@ -3173,11 +3175,11 @@ yyreduce:
}
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3171 "gram.c"
+#line 3173 "gram.c"
break;
case 155: /* group: WORD */
-#line 1195 "gram.y"
+#line 1197 "gram.y"
{
(yyval.member) = new_member((yyvsp[0].string), WORD);
if ((yyval.member) == NULL) {
@@ -3187,11 +3189,11 @@ yyreduce:
parser_leak_remove(LEAK_PTR, (yyvsp[0].string));
parser_leak_add(LEAK_MEMBER, (yyval.member));
}
-#line 3185 "gram.c"
+#line 3187 "gram.c"
break;
-#line 3189 "gram.c"
+#line 3191 "gram.c"
default: break;
}
@@ -3384,7 +3386,7 @@ yyreturnlab:
return yyresult;
}
-#line 1205 "gram.y"
+#line 1207 "gram.y"
/* Like yyerror() but takes a printf-style format string. */
void
@@ -3399,7 +3401,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) {
@@ -3965,7 +3967,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);
@@ -3994,9 +3997,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);
}
@@ -4004,7 +4012,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);
}
/*
@@ -4031,6 +4039,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)
{
diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y
index 887b01577..d0f264c66 100644
--- a/plugins/sudoers/gram.y
+++ b/plugins/sudoers/gram.y
@@ -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)
{
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
index 9092e4d8c..204382b53 100644
--- a/plugins/sudoers/parse.h
+++ b/plugins/sudoers/parse.h
@@ -323,6 +323,26 @@ struct cmnd_info {
};
/*
+ * 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
* the list when they are stored in another data structure.
@@ -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);
diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
index 1f439afd4..a82393df2 100644
--- a/plugins/sudoers/policy.c
+++ b/plugins/sudoers/policy.c
@@ -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)
diff --git a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c
index 0919c4d76..408bab363 100644
--- a/plugins/sudoers/regress/fuzz/fuzz_sudoers.c
+++ b/plugins/sudoers/regress/fuzz/fuzz_sudoers.c
@@ -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);
diff --git a/plugins/sudoers/set_perms.c b/plugins/sudoers/set_perms.c
index 9eb88b44a..a4de109ab 100644
--- a/plugins/sudoers/set_perms.c
+++ b/plugins/sudoers/set_perms.c
@@ -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;
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
index 283698d93..9f11b3146 100644
--- a/plugins/sudoers/sudoers.c
+++ b/plugins/sudoers/sudoers.c
@@ -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);
diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
index fb7bd7995..6cf967c38 100644
--- a/plugins/sudoers/sudoers.h
+++ b/plugins/sudoers/sudoers.h
@@ -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);
diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c
index 4e7275398..c2a699d9c 100644
--- a/plugins/sudoers/testsudoers.c
+++ b/plugins/sudoers/testsudoers.c
@@ -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",
diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c
index 670357600..e91b13a45 100644
--- a/plugins/sudoers/toke.c
+++ b/plugins/sudoers/toke.c
@@ -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;
diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l
index fdcd27232..c732645eb 100644
--- a/plugins/sudoers/toke.l
+++ b/plugins/sudoers/toke.l
@@ -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;
diff --git a/plugins/sudoers/toke_util.c b/plugins/sudoers/toke_util.c
index d38ae96ca..e75c96115 100644
--- a/plugins/sudoers/toke_util.c
+++ b/plugins/sudoers/toke_util.c
@@ -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"));
}
diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c
index 7e97ab61b..2a17194ba 100644
--- a/plugins/sudoers/visudo.c
+++ b/plugins/sudoers/visudo.c
@@ -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;
}
}