diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-05-08 17:03:31 -0600 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2023-05-08 17:03:31 -0600 |
commit | 6c8f8d3e7f9d43db5d9cae47ec8cffdc93c77861 (patch) | |
tree | d583029d6e415c794ae7f61c9206299103c662e5 | |
parent | 131e61b5ef0484ce10f418e0e19c4cf2b0b4abe6 (diff) | |
download | sudo-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.c | 2 | ||||
-rw-r--r-- | plugins/sudoers/file.c | 6 | ||||
-rw-r--r-- | plugins/sudoers/gram.c | 608 | ||||
-rw-r--r-- | plugins/sudoers/gram.y | 62 | ||||
-rw-r--r-- | plugins/sudoers/parse.h | 22 | ||||
-rw-r--r-- | plugins/sudoers/policy.c | 25 | ||||
-rw-r--r-- | plugins/sudoers/regress/fuzz/fuzz_sudoers.c | 2 | ||||
-rw-r--r-- | plugins/sudoers/set_perms.c | 28 | ||||
-rw-r--r-- | plugins/sudoers/sudoers.c | 8 | ||||
-rw-r--r-- | plugins/sudoers/sudoers.h | 11 | ||||
-rw-r--r-- | plugins/sudoers/testsudoers.c | 19 | ||||
-rw-r--r-- | plugins/sudoers/toke.c | 208 | ||||
-rw-r--r-- | plugins/sudoers/toke.l | 18 | ||||
-rw-r--r-- | plugins/sudoers/toke_util.c | 2 | ||||
-rw-r--r-- | plugins/sudoers/visudo.c | 60 |
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; } } |