From: Todd C. Miller Date: Thu, 12 Jan 2012 15:18:57 +0000 (-0500) Subject: Keep track of the last token returned. On error, if the last token X-Git-Tag: SUDO_1_7_9~57 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2eb0bee6b30eb749a9bf308485d63ab1441dea76;p=sudo Keep track of the last token returned. On error, if the last token was COMMENT, decrement sudolineno since the error most likely occurred on the preceding line. Previously we always uses sudolineno-1 which will give the wrong line number for errors within a line. --HG-- branch : 1.7 --- diff --git a/gram.c b/gram.c index 6a789c8bf..8e9eee458 100644 --- a/gram.c +++ b/gram.c @@ -63,6 +63,7 @@ #include "sudo.h" #include "parse.h" +#include "gram.h" /* * We must define SIZE_MAX for yacc's skeleton.c. @@ -81,6 +82,7 @@ * Globals */ extern int sudolineno; +extern int last_token; extern char *sudoers; static int verbose = FALSE; int parse_error = FALSE; @@ -104,22 +106,26 @@ void yyerror(s) const char *s; { + /* If we last saw a newline the error is on the preceding line. */ + if (last_token == COMMENT) + sudolineno--; + /* Save the line the first error occurred on. */ if (errorlineno == -1) { - errorlineno = sudolineno ? sudolineno - 1 : 0; + errorlineno = sudolineno; errorfile = estrdup(sudoers); } if (verbose && s != NULL) { #ifndef TRACELEXER (void) fprintf(stderr, ">>> %s: %s near line %d <<<\n", sudoers, s, - sudolineno ? sudolineno - 1 : 0); + sudolineno); #else (void) fprintf(stderr, "<*> "); #endif } parse_error = TRUE; } -#line 112 "gram.y" +#line 118 "gram.y" #ifndef YYSTYPE_DEFINED #define YYSTYPE_DEFINED typedef union { @@ -135,7 +141,7 @@ typedef union { int tok; } YYSTYPE; #endif /* YYSTYPE_DEFINED */ -#line 138 "y.tab.c" +#line 144 "y.tab.c" #define COMMAND 257 #define ALIAS 258 #define DEFVAR 259 @@ -633,7 +639,7 @@ short *yyss; short *yysslim; YYSTYPE *yyvs; int yystacksize; -#line 606 "gram.y" +#line 612 "gram.y" static struct defaults * new_default(var, val, op) char *var; @@ -823,7 +829,7 @@ init_parser(path, quiet) errorfile = NULL; verbose = !quiet; } -#line 774 "y.tab.c" +#line 780 "y.tab.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ #if defined(__cplusplus) || defined(__STDC__) static int yygrowstack(void) @@ -1029,127 +1035,127 @@ yyreduce: switch (yyn) { case 1: -#line 187 "gram.y" +#line 193 "gram.y" { ; } break; case 5: -#line 195 "gram.y" +#line 201 "gram.y" { ; } break; case 6: -#line 198 "gram.y" +#line 204 "gram.y" { yyerrok; } break; case 7: -#line 201 "gram.y" +#line 207 "gram.y" { add_userspec(yyvsp[-1].member, yyvsp[0].privilege); } break; case 8: -#line 204 "gram.y" +#line 210 "gram.y" { ; } break; case 9: -#line 207 "gram.y" +#line 213 "gram.y" { ; } break; case 10: -#line 210 "gram.y" +#line 216 "gram.y" { ; } break; case 11: -#line 213 "gram.y" +#line 219 "gram.y" { ; } break; case 12: -#line 216 "gram.y" +#line 222 "gram.y" { add_defaults(DEFAULTS, NULL, yyvsp[0].defaults); } break; case 13: -#line 219 "gram.y" +#line 225 "gram.y" { add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults); } break; case 14: -#line 222 "gram.y" +#line 228 "gram.y" { add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults); } break; case 15: -#line 225 "gram.y" +#line 231 "gram.y" { add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults); } break; case 16: -#line 228 "gram.y" +#line 234 "gram.y" { add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults); } break; case 18: -#line 234 "gram.y" +#line 240 "gram.y" { list_append(yyvsp[-2].defaults, yyvsp[0].defaults); yyval.defaults = yyvsp[-2].defaults; } break; case 19: -#line 240 "gram.y" +#line 246 "gram.y" { yyval.defaults = new_default(yyvsp[0].string, NULL, TRUE); } break; case 20: -#line 243 "gram.y" +#line 249 "gram.y" { yyval.defaults = new_default(yyvsp[0].string, NULL, FALSE); } break; case 21: -#line 246 "gram.y" +#line 252 "gram.y" { yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, TRUE); } break; case 22: -#line 249 "gram.y" +#line 255 "gram.y" { yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+'); } break; case 23: -#line 252 "gram.y" +#line 258 "gram.y" { yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-'); } break; case 25: -#line 258 "gram.y" +#line 264 "gram.y" { list_append(yyvsp[-2].privilege, yyvsp[0].privilege); yyval.privilege = yyvsp[-2].privilege; } break; case 26: -#line 264 "gram.y" +#line 270 "gram.y" { struct privilege *p = emalloc(sizeof(*p)); list2tq(&p->hostlist, yyvsp[-2].member); @@ -1160,51 +1166,51 @@ case 26: } break; case 27: -#line 274 "gram.y" +#line 280 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = FALSE; } break; case 28: -#line 278 "gram.y" +#line 284 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = TRUE; } break; case 29: -#line 284 "gram.y" +#line 290 "gram.y" { yyval.member = new_member(yyvsp[0].string, ALIAS); } break; case 30: -#line 287 "gram.y" +#line 293 "gram.y" { yyval.member = new_member(NULL, ALL); } break; case 31: -#line 290 "gram.y" +#line 296 "gram.y" { yyval.member = new_member(yyvsp[0].string, NETGROUP); } break; case 32: -#line 293 "gram.y" +#line 299 "gram.y" { yyval.member = new_member(yyvsp[0].string, NTWKADDR); } break; case 33: -#line 296 "gram.y" +#line 302 "gram.y" { yyval.member = new_member(yyvsp[0].string, WORD); } break; case 35: -#line 302 "gram.y" +#line 308 "gram.y" { list_append(yyvsp[-2].cmndspec, yyvsp[0].cmndspec); #ifdef HAVE_SELINUX @@ -1237,7 +1243,7 @@ case 35: } break; case 36: -#line 334 "gram.y" +#line 340 "gram.y" { struct cmndspec *cs = emalloc(sizeof(*cs)); if (yyvsp[-3].runas != NULL) { @@ -1264,80 +1270,80 @@ case 36: } break; case 37: -#line 360 "gram.y" +#line 366 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = FALSE; } break; case 38: -#line 364 "gram.y" +#line 370 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = TRUE; } break; case 39: -#line 370 "gram.y" +#line 376 "gram.y" { yyval.string = yyvsp[0].string; } break; case 40: -#line 375 "gram.y" +#line 381 "gram.y" { yyval.string = yyvsp[0].string; } break; case 41: -#line 380 "gram.y" +#line 386 "gram.y" { yyval.seinfo.role = NULL; yyval.seinfo.type = NULL; } break; case 42: -#line 384 "gram.y" +#line 390 "gram.y" { yyval.seinfo.role = yyvsp[0].string; yyval.seinfo.type = NULL; } break; case 43: -#line 388 "gram.y" +#line 394 "gram.y" { yyval.seinfo.type = yyvsp[0].string; yyval.seinfo.role = NULL; } break; case 44: -#line 392 "gram.y" +#line 398 "gram.y" { yyval.seinfo.role = yyvsp[-1].string; yyval.seinfo.type = yyvsp[0].string; } break; case 45: -#line 396 "gram.y" +#line 402 "gram.y" { yyval.seinfo.type = yyvsp[-1].string; yyval.seinfo.role = yyvsp[0].string; } break; case 46: -#line 402 "gram.y" +#line 408 "gram.y" { yyval.runas = NULL; } break; case 47: -#line 405 "gram.y" +#line 411 "gram.y" { yyval.runas = yyvsp[-1].runas; } break; case 48: -#line 410 "gram.y" +#line 416 "gram.y" { yyval.runas = emalloc(sizeof(struct runascontainer)); yyval.runas->runasusers = yyvsp[0].member; @@ -1345,7 +1351,7 @@ case 48: } break; case 49: -#line 415 "gram.y" +#line 421 "gram.y" { yyval.runas = emalloc(sizeof(struct runascontainer)); yyval.runas->runasusers = yyvsp[-2].member; @@ -1353,7 +1359,7 @@ case 49: } break; case 50: -#line 420 "gram.y" +#line 426 "gram.y" { yyval.runas = emalloc(sizeof(struct runascontainer)); yyval.runas->runasusers = NULL; @@ -1361,86 +1367,86 @@ case 50: } break; case 51: -#line 427 "gram.y" +#line 433 "gram.y" { yyval.tag.nopasswd = yyval.tag.noexec = yyval.tag.setenv = yyval.tag.log_input = yyval.tag.log_output = UNSPEC; } break; case 52: -#line 431 "gram.y" +#line 437 "gram.y" { yyval.tag.nopasswd = TRUE; } break; case 53: -#line 434 "gram.y" +#line 440 "gram.y" { yyval.tag.nopasswd = FALSE; } break; case 54: -#line 437 "gram.y" +#line 443 "gram.y" { yyval.tag.noexec = TRUE; } break; case 55: -#line 440 "gram.y" +#line 446 "gram.y" { yyval.tag.noexec = FALSE; } break; case 56: -#line 443 "gram.y" +#line 449 "gram.y" { yyval.tag.setenv = TRUE; } break; case 57: -#line 446 "gram.y" +#line 452 "gram.y" { yyval.tag.setenv = FALSE; } break; case 58: -#line 449 "gram.y" +#line 455 "gram.y" { yyval.tag.log_input = TRUE; } break; case 59: -#line 452 "gram.y" +#line 458 "gram.y" { yyval.tag.log_input = FALSE; } break; case 60: -#line 455 "gram.y" +#line 461 "gram.y" { yyval.tag.log_output = TRUE; } break; case 61: -#line 458 "gram.y" +#line 464 "gram.y" { yyval.tag.log_output = FALSE; } break; case 62: -#line 463 "gram.y" +#line 469 "gram.y" { yyval.member = new_member(NULL, ALL); } break; case 63: -#line 466 "gram.y" +#line 472 "gram.y" { yyval.member = new_member(yyvsp[0].string, ALIAS); } break; case 64: -#line 469 "gram.y" +#line 475 "gram.y" { struct sudo_command *c = emalloc(sizeof(*c)); c->cmnd = yyvsp[0].command.cmnd; @@ -1449,7 +1455,7 @@ case 64: } break; case 67: -#line 481 "gram.y" +#line 487 "gram.y" { char *s; if ((s = alias_add(yyvsp[-2].string, HOSTALIAS, yyvsp[0].member)) != NULL) { @@ -1459,14 +1465,14 @@ case 67: } break; case 69: -#line 491 "gram.y" +#line 497 "gram.y" { list_append(yyvsp[-2].member, yyvsp[0].member); yyval.member = yyvsp[-2].member; } break; case 72: -#line 501 "gram.y" +#line 507 "gram.y" { char *s; if ((s = alias_add(yyvsp[-2].string, CMNDALIAS, yyvsp[0].member)) != NULL) { @@ -1476,14 +1482,14 @@ case 72: } break; case 74: -#line 511 "gram.y" +#line 517 "gram.y" { list_append(yyvsp[-2].member, yyvsp[0].member); yyval.member = yyvsp[-2].member; } break; case 77: -#line 521 "gram.y" +#line 527 "gram.y" { char *s; if ((s = alias_add(yyvsp[-2].string, RUNASALIAS, yyvsp[0].member)) != NULL) { @@ -1493,7 +1499,7 @@ case 77: } break; case 80: -#line 534 "gram.y" +#line 540 "gram.y" { char *s; if ((s = alias_add(yyvsp[-2].string, USERALIAS, yyvsp[0].member)) != NULL) { @@ -1503,96 +1509,96 @@ case 80: } break; case 82: -#line 544 "gram.y" +#line 550 "gram.y" { list_append(yyvsp[-2].member, yyvsp[0].member); yyval.member = yyvsp[-2].member; } break; case 83: -#line 550 "gram.y" +#line 556 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = FALSE; } break; case 84: -#line 554 "gram.y" +#line 560 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = TRUE; } break; case 85: -#line 560 "gram.y" +#line 566 "gram.y" { yyval.member = new_member(yyvsp[0].string, ALIAS); } break; case 86: -#line 563 "gram.y" +#line 569 "gram.y" { yyval.member = new_member(NULL, ALL); } break; case 87: -#line 566 "gram.y" +#line 572 "gram.y" { yyval.member = new_member(yyvsp[0].string, NETGROUP); } break; case 88: -#line 569 "gram.y" +#line 575 "gram.y" { yyval.member = new_member(yyvsp[0].string, USERGROUP); } break; case 89: -#line 572 "gram.y" +#line 578 "gram.y" { yyval.member = new_member(yyvsp[0].string, WORD); } break; case 91: -#line 578 "gram.y" +#line 584 "gram.y" { list_append(yyvsp[-2].member, yyvsp[0].member); yyval.member = yyvsp[-2].member; } break; case 92: -#line 584 "gram.y" +#line 590 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = FALSE; } break; case 93: -#line 588 "gram.y" +#line 594 "gram.y" { yyval.member = yyvsp[0].member; yyval.member->negated = TRUE; } break; case 94: -#line 594 "gram.y" +#line 600 "gram.y" { yyval.member = new_member(yyvsp[0].string, ALIAS); } break; case 95: -#line 597 "gram.y" +#line 603 "gram.y" { yyval.member = new_member(NULL, ALL); } break; case 96: -#line 600 "gram.y" +#line 606 "gram.y" { yyval.member = new_member(yyvsp[0].string, WORD); } break; -#line 1543 "y.tab.c" +#line 1549 "y.tab.c" } yyssp -= yym; yystate = *yyssp; diff --git a/gram.y b/gram.y index ed58fb54b..225fd20dc 100644 --- a/gram.y +++ b/gram.y @@ -51,6 +51,7 @@ #include "sudo.h" #include "parse.h" +#include "gram.h" /* * We must define SIZE_MAX for yacc's skeleton.c. @@ -69,6 +70,7 @@ * Globals */ extern int sudolineno; +extern int last_token; extern char *sudoers; static int verbose = FALSE; int parse_error = FALSE; @@ -92,15 +94,19 @@ void yyerror(s) const char *s; { + /* If we last saw a newline the error is on the preceding line. */ + if (last_token == COMMENT) + sudolineno--; + /* Save the line the first error occurred on. */ if (errorlineno == -1) { - errorlineno = sudolineno ? sudolineno - 1 : 0; + errorlineno = sudolineno; errorfile = estrdup(sudoers); } if (verbose && s != NULL) { #ifndef TRACELEXER (void) fprintf(stderr, ">>> %s: %s near line %d <<<\n", sudoers, s, - sudolineno ? sudolineno - 1 : 0); + sudolineno); #else (void) fprintf(stderr, "<*> "); #endif diff --git a/toke.c b/toke.c index 344eb7c05..63015a43a 100644 --- a/toke.c +++ b/toke.c @@ -4,7 +4,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /cvs/src/usr.bin/lex/flex.skl,v 1.11 2010/08/04 18:24:50 millert Exp $ + * $Header: /home/cvs/openbsd/src/usr.bin/lex/flex.skl,v 1.11 2010/08/04 18:24:50 millert Exp $ */ #define FLEX_SCANNER @@ -1479,6 +1479,7 @@ char *yytext; extern YYSTYPE yylval; extern int parse_error; int sudolineno; +int last_token; char *sudoers; static int continued, prev_state, sawspace; @@ -1489,6 +1490,11 @@ static char *parse_include __P((char *)); #define fill(a, b) fill_txt(a, b, 0) +#define LEXRETURN(n) do { \ + last_token = (n); \ + return (n); \ +} while (0) + #define push_include(_p) (_push_include((_p), FALSE)) #define push_includedir(_p) (_push_include((_p), TRUE)) @@ -1509,7 +1515,7 @@ static char *parse_include __P((char *)); #define INSTR 5 -#line 1512 "lex.yy.c" +#line 1518 "lex.yy.c" /* Macros after this point can all be overridden by user definitions in * section 1. @@ -1663,9 +1669,9 @@ YY_DECL register char *yy_cp, *yy_bp; register int yy_act; -#line 120 "toke.l" +#line 126 "toke.l" -#line 1668 "lex.yy.c" +#line 1674 "lex.yy.c" if ( yy_init ) { @@ -1751,65 +1757,65 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 121 "toke.l" +#line 127 "toke.l" { LEXTRACE(", "); - return ','; + LEXRETURN(','); } /* return ',' */ YY_BREAK case 2: YY_RULE_SETUP -#line 126 "toke.l" +#line 132 "toke.l" BEGIN STARTDEFS; YY_BREAK case 3: YY_RULE_SETUP -#line 128 "toke.l" +#line 134 "toke.l" { BEGIN INDEFS; LEXTRACE("DEFVAR "); if (!fill(yytext, yyleng)) yyterminate(); - return DEFVAR; + LEXRETURN(DEFVAR); } YY_BREAK case 4: YY_RULE_SETUP -#line 137 "toke.l" +#line 143 "toke.l" { BEGIN STARTDEFS; LEXTRACE(", "); - return ','; + LEXRETURN(','); } /* return ',' */ YY_BREAK case 5: YY_RULE_SETUP -#line 143 "toke.l" +#line 149 "toke.l" { LEXTRACE("= "); - return '='; + LEXRETURN('='); } /* return '=' */ YY_BREAK case 6: YY_RULE_SETUP -#line 148 "toke.l" +#line 154 "toke.l" { LEXTRACE("+= "); - return '+'; + LEXRETURN('+'); } /* return '+' */ YY_BREAK case 7: YY_RULE_SETUP -#line 153 "toke.l" +#line 159 "toke.l" { LEXTRACE("-= "); - return '-'; + LEXRETURN('-'); } /* return '-' */ YY_BREAK case 8: YY_RULE_SETUP -#line 158 "toke.l" +#line 164 "toke.l" { LEXTRACE("BEGINSTR "); yylval.string = NULL; @@ -1819,35 +1825,35 @@ YY_RULE_SETUP YY_BREAK case 9: YY_RULE_SETUP -#line 165 "toke.l" +#line 171 "toke.l" { LEXTRACE("WORD(2) "); if (!fill(yytext, yyleng)) yyterminate(); - return WORD; + LEXRETURN(WORD); } YY_BREAK case 10: YY_RULE_SETUP -#line 174 "toke.l" +#line 180 "toke.l" { /* Line continuation char followed by newline. */ - ++sudolineno; + sudolineno++; continued = TRUE; } YY_BREAK case 11: YY_RULE_SETUP -#line 180 "toke.l" +#line 186 "toke.l" { LEXTRACE("ENDSTR "); BEGIN prev_state; if (yylval.string == NULL) { LEXTRACE("ERROR "); /* empty string */ - return ERROR; + LEXRETURN(ERROR); } if (prev_state == INITIAL) { switch (yylval.string[0]) { @@ -1856,26 +1862,26 @@ YY_RULE_SETUP (yylval.string[1] == ':' && yylval.string[2] == '\0')) { LEXTRACE("ERROR "); /* empty group */ - return ERROR; + LEXRETURN(ERROR); } LEXTRACE("USERGROUP "); - return USERGROUP; + LEXRETURN(USERGROUP); case '+': if (yylval.string[1] == '\0') { LEXTRACE("ERROR "); /* empty netgroup */ - return ERROR; + LEXRETURN(ERROR); } LEXTRACE("NETGROUP "); - return NETGROUP; + LEXRETURN(NETGROUP); } } LEXTRACE("WORD(4) "); - return WORD; + LEXRETURN(WORD); } YY_BREAK case 12: YY_RULE_SETUP -#line 212 "toke.l" +#line 218 "toke.l" { LEXTRACE("BACKSLASH "); if (!append(yytext, yyleng)) @@ -1884,7 +1890,7 @@ YY_RULE_SETUP YY_BREAK case 13: YY_RULE_SETUP -#line 218 "toke.l" +#line 224 "toke.l" { LEXTRACE("STRBODY "); if (!append(yytext, yyleng)) @@ -1895,7 +1901,7 @@ YY_RULE_SETUP case 14: YY_RULE_SETUP -#line 226 "toke.l" +#line 232 "toke.l" { /* quoted fnmatch glob char, pass verbatim */ LEXTRACE("QUOTEDCHAR "); @@ -1906,7 +1912,7 @@ YY_RULE_SETUP YY_BREAK case 15: YY_RULE_SETUP -#line 234 "toke.l" +#line 240 "toke.l" { /* quoted sudoers special char, strip backslash */ LEXTRACE("QUOTEDCHAR "); @@ -1917,16 +1923,16 @@ YY_RULE_SETUP YY_BREAK case 16: YY_RULE_SETUP -#line 242 "toke.l" +#line 248 "toke.l" { BEGIN INITIAL; yyless(0); - return COMMAND; + LEXRETURN(COMMAND); } /* end of command line args */ YY_BREAK case 17: YY_RULE_SETUP -#line 248 "toke.l" +#line 254 "toke.l" { LEXTRACE("ARG "); if (!fill_args(yytext, yyleng, sawspace)) @@ -1937,13 +1943,13 @@ YY_RULE_SETUP case 18: YY_RULE_SETUP -#line 256 "toke.l" +#line 262 "toke.l" { char *path; if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if ((path = parse_include(yytext)) == NULL) @@ -1958,13 +1964,13 @@ YY_RULE_SETUP YY_BREAK case 19: YY_RULE_SETUP -#line 274 "toke.l" +#line 280 "toke.l" { char *path; if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if ((path = parse_include(yytext)) == NULL) @@ -1982,14 +1988,14 @@ YY_RULE_SETUP YY_BREAK case 20: YY_RULE_SETUP -#line 295 "toke.l" +#line 301 "toke.l" { char deftype; int n; if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } for (n = 0; isblank((unsigned char)yytext[n]); n++) @@ -2004,34 +2010,34 @@ YY_RULE_SETUP case ':': yyless(n); LEXTRACE("DEFAULTS_USER "); - return DEFAULTS_USER; + LEXRETURN(DEFAULTS_USER); case '>': yyless(n); LEXTRACE("DEFAULTS_RUNAS "); - return DEFAULTS_RUNAS; + LEXRETURN(DEFAULTS_RUNAS); case '@': yyless(n); LEXTRACE("DEFAULTS_HOST "); - return DEFAULTS_HOST; + LEXRETURN(DEFAULTS_HOST); case '!': yyless(n); LEXTRACE("DEFAULTS_CMND "); - return DEFAULTS_CMND; + LEXRETURN(DEFAULTS_CMND); default: LEXTRACE("DEFAULTS "); - return DEFAULTS; + LEXRETURN(DEFAULTS); } } YY_BREAK case 21: YY_RULE_SETUP -#line 335 "toke.l" +#line 341 "toke.l" { int n; if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } for (n = 0; isblank((unsigned char)yytext[n]); n++) @@ -2039,196 +2045,196 @@ YY_RULE_SETUP switch (yytext[n]) { case 'H': LEXTRACE("HOSTALIAS "); - return HOSTALIAS; + LEXRETURN(HOSTALIAS); case 'C': LEXTRACE("CMNDALIAS "); - return CMNDALIAS; + LEXRETURN(CMNDALIAS); case 'U': LEXTRACE("USERALIAS "); - return USERALIAS; + LEXRETURN(USERALIAS); case 'R': LEXTRACE("RUNASALIAS "); - return RUNASALIAS; + LEXRETURN(RUNASALIAS); } } YY_BREAK case 22: YY_RULE_SETUP -#line 361 "toke.l" +#line 367 "toke.l" { /* cmnd does not require passwd for this user */ LEXTRACE("NOPASSWD "); - return NOPASSWD; + LEXRETURN(NOPASSWD); } YY_BREAK case 23: YY_RULE_SETUP -#line 367 "toke.l" +#line 373 "toke.l" { /* cmnd requires passwd for this user */ LEXTRACE("PASSWD "); - return PASSWD; + LEXRETURN(PASSWD); } YY_BREAK case 24: YY_RULE_SETUP -#line 373 "toke.l" +#line 379 "toke.l" { LEXTRACE("NOEXEC "); - return NOEXEC; + LEXRETURN(NOEXEC); } YY_BREAK case 25: YY_RULE_SETUP -#line 378 "toke.l" +#line 384 "toke.l" { LEXTRACE("EXEC "); - return EXEC; + LEXRETURN(EXEC); } YY_BREAK case 26: YY_RULE_SETUP -#line 383 "toke.l" +#line 389 "toke.l" { LEXTRACE("SETENV "); - return SETENV; + LEXRETURN(SETENV); } YY_BREAK case 27: YY_RULE_SETUP -#line 388 "toke.l" +#line 394 "toke.l" { LEXTRACE("NOSETENV "); - return NOSETENV; + LEXRETURN(NOSETENV); } YY_BREAK case 28: YY_RULE_SETUP -#line 393 "toke.l" +#line 399 "toke.l" { LEXTRACE("LOG_OUTPUT "); - return LOG_OUTPUT; + LEXRETURN(LOG_OUTPUT); } YY_BREAK case 29: YY_RULE_SETUP -#line 398 "toke.l" +#line 404 "toke.l" { LEXTRACE("NOLOG_OUTPUT "); - return NOLOG_OUTPUT; + LEXRETURN(NOLOG_OUTPUT); } YY_BREAK case 30: YY_RULE_SETUP -#line 403 "toke.l" +#line 409 "toke.l" { LEXTRACE("LOG_INPUT "); - return LOG_INPUT; + LEXRETURN(LOG_INPUT); } YY_BREAK case 31: YY_RULE_SETUP -#line 408 "toke.l" +#line 414 "toke.l" { LEXTRACE("NOLOG_INPUT "); - return NOLOG_INPUT; + LEXRETURN(NOLOG_INPUT); } YY_BREAK case 32: YY_RULE_SETUP -#line 413 "toke.l" +#line 419 "toke.l" { /* empty group or netgroup */ LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } YY_BREAK case 33: YY_RULE_SETUP -#line 419 "toke.l" +#line 425 "toke.l" { /* netgroup */ if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NETGROUP "); - return NETGROUP; + LEXRETURN(NETGROUP); } YY_BREAK case 34: YY_RULE_SETUP -#line 427 "toke.l" +#line 433 "toke.l" { /* group */ if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("USERGROUP "); - return USERGROUP; + LEXRETURN(USERGROUP); } YY_BREAK case 35: YY_RULE_SETUP -#line 435 "toke.l" +#line 441 "toke.l" { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } YY_BREAK case 36: YY_RULE_SETUP -#line 442 "toke.l" +#line 448 "toke.l" { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } YY_BREAK case 37: YY_RULE_SETUP -#line 449 "toke.l" +#line 455 "toke.l" { if (!ipv6_valid(yytext)) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } YY_BREAK case 38: YY_RULE_SETUP -#line 460 "toke.l" +#line 466 "toke.l" { if (!ipv6_valid(yytext)) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } YY_BREAK case 39: YY_RULE_SETUP -#line 471 "toke.l" +#line 477 "toke.l" { LEXTRACE("ALL "); - return ALL; + LEXRETURN(ALL); } YY_BREAK case 40: YY_RULE_SETUP -#line 477 "toke.l" +#line 483 "toke.l" { #ifdef HAVE_SELINUX LEXTRACE("ROLE "); - return ROLE; + LEXRETURN(ROLE); #else goto got_alias; #endif @@ -2236,11 +2242,11 @@ YY_RULE_SETUP YY_BREAK case 41: YY_RULE_SETUP -#line 486 "toke.l" +#line 492 "toke.l" { #ifdef HAVE_SELINUX LEXTRACE("TYPE "); - return TYPE; + LEXRETURN(TYPE); #else goto got_alias; #endif @@ -2248,29 +2254,29 @@ YY_RULE_SETUP YY_BREAK case 42: YY_RULE_SETUP -#line 495 "toke.l" +#line 501 "toke.l" { got_alias: if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("ALIAS "); - return ALIAS; + LEXRETURN(ALIAS); } YY_BREAK case 43: YY_RULE_SETUP -#line 503 "toke.l" +#line 509 "toke.l" { /* no command args allowed for Defaults!/path */ if (!fill_cmnd(yytext, yyleng)) yyterminate(); LEXTRACE("COMMAND "); - return COMMAND; + LEXRETURN(COMMAND); } YY_BREAK case 44: YY_RULE_SETUP -#line 511 "toke.l" +#line 517 "toke.l" { BEGIN GOTCMND; LEXTRACE("COMMAND "); @@ -2280,14 +2286,14 @@ YY_RULE_SETUP YY_BREAK case 45: YY_RULE_SETUP -#line 518 "toke.l" +#line 524 "toke.l" { /* directories can't have args... */ if (yytext[yyleng - 1] == '/') { LEXTRACE("COMMAND "); if (!fill_cmnd(yytext, yyleng)) yyterminate(); - return COMMAND; + LEXRETURN(COMMAND); } else { BEGIN GOTCMND; LEXTRACE("COMMAND "); @@ -2298,7 +2304,7 @@ YY_RULE_SETUP YY_BREAK case 46: YY_RULE_SETUP -#line 533 "toke.l" +#line 539 "toke.l" { LEXTRACE("BEGINSTR "); yylval.string = NULL; @@ -2308,113 +2314,113 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -#line 540 "toke.l" +#line 546 "toke.l" { /* a word */ if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("WORD(5) "); - return WORD; + LEXRETURN(WORD); } YY_BREAK case 48: YY_RULE_SETUP -#line 548 "toke.l" +#line 554 "toke.l" { LEXTRACE("( "); - return '('; + LEXRETURN('('); } YY_BREAK case 49: YY_RULE_SETUP -#line 553 "toke.l" +#line 559 "toke.l" { LEXTRACE(") "); - return ')'; + LEXRETURN(')'); } YY_BREAK case 50: YY_RULE_SETUP -#line 558 "toke.l" +#line 564 "toke.l" { LEXTRACE(", "); - return ','; + LEXRETURN(','); } /* return ',' */ YY_BREAK case 51: YY_RULE_SETUP -#line 563 "toke.l" +#line 569 "toke.l" { LEXTRACE("= "); - return '='; + LEXRETURN('='); } /* return '=' */ YY_BREAK case 52: YY_RULE_SETUP -#line 568 "toke.l" +#line 574 "toke.l" { LEXTRACE(": "); - return ':'; + LEXRETURN(':'); } /* return ':' */ YY_BREAK case 53: YY_RULE_SETUP -#line 573 "toke.l" +#line 579 "toke.l" { if (yyleng & 1) { LEXTRACE("!"); - return '!'; /* return '!' */ + LEXRETURN('!'); /* return '!' */ } } YY_BREAK case 54: YY_RULE_SETUP -#line 580 "toke.l" +#line 586 "toke.l" { if (YY_START == INSTR) { LEXTRACE("ERROR "); - return ERROR; /* line break in string */ + LEXRETURN(ERROR); /* line break in string */ } BEGIN INITIAL; - ++sudolineno; + sudolineno++; continued = FALSE; LEXTRACE("\n"); - return COMMENT; + LEXRETURN(COMMENT); } /* return newline */ YY_BREAK case 55: YY_RULE_SETUP -#line 592 "toke.l" +#line 598 "toke.l" { /* throw away space/tabs */ sawspace = TRUE; /* but remember for fill_args */ } YY_BREAK case 56: YY_RULE_SETUP -#line 596 "toke.l" +#line 602 "toke.l" { sawspace = TRUE; /* remember for fill_args */ - ++sudolineno; + sudolineno++; continued = TRUE; } /* throw away EOL after \ */ YY_BREAK case 57: YY_RULE_SETUP -#line 602 "toke.l" +#line 608 "toke.l" { BEGIN INITIAL; - ++sudolineno; + sudolineno++; continued = FALSE; LEXTRACE("#\n"); - return COMMENT; + LEXRETURN(COMMENT); } /* comment, not uid/gid */ YY_BREAK case 58: YY_RULE_SETUP -#line 610 "toke.l" +#line 616 "toke.l" { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } /* parse error */ YY_BREAK case YY_STATE_EOF(INITIAL): @@ -2423,12 +2429,12 @@ case YY_STATE_EOF(GOTCMND): case YY_STATE_EOF(STARTDEFS): case YY_STATE_EOF(INDEFS): case YY_STATE_EOF(INSTR): -#line 615 "toke.l" +#line 621 "toke.l" { if (YY_START != INITIAL) { BEGIN INITIAL; LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if (!pop_include()) yyterminate(); @@ -2436,10 +2442,10 @@ case YY_STATE_EOF(INSTR): YY_BREAK case 59: YY_RULE_SETUP -#line 625 "toke.l" +#line 631 "toke.l" ECHO; YY_BREAK -#line 2442 "lex.yy.c" +#line 2448 "lex.yy.c" case YY_END_OF_BUFFER: { @@ -3330,7 +3336,7 @@ int main() return 0; } #endif -#line 625 "toke.l" +#line 631 "toke.l" struct path_list { char *path; diff --git a/toke.l b/toke.l index b1569b4e9..cc89d0be0 100644 --- a/toke.l +++ b/toke.l @@ -75,6 +75,7 @@ extern YYSTYPE yylval; extern int parse_error; int sudolineno; +int last_token; char *sudoers; static int continued, prev_state, sawspace; @@ -85,6 +86,11 @@ static char *parse_include __P((char *)); #define fill(a, b) fill_txt(a, b, 0) +#define LEXRETURN(n) do { \ + last_token = (n); \ + return (n); \ +} while (0) + #define push_include(_p) (_push_include((_p), FALSE)) #define push_includedir(_p) (_push_include((_p), TRUE)) @@ -120,7 +126,7 @@ DEFVAR [a-z_]+ %% [[:blank:]]*,[[:blank:]]* { LEXTRACE(", "); - return ','; + LEXRETURN(','); } /* return ',' */ [[:blank:]]+ BEGIN STARTDEFS; @@ -130,29 +136,29 @@ DEFVAR [a-z_]+ LEXTRACE("DEFVAR "); if (!fill(yytext, yyleng)) yyterminate(); - return DEFVAR; + LEXRETURN(DEFVAR); } { , { BEGIN STARTDEFS; LEXTRACE(", "); - return ','; + LEXRETURN(','); } /* return ',' */ = { LEXTRACE("= "); - return '='; + LEXRETURN('='); } /* return '=' */ \+= { LEXTRACE("+= "); - return '+'; + LEXRETURN('+'); } /* return '+' */ -= { LEXTRACE("-= "); - return '-'; + LEXRETURN('-'); } /* return '-' */ \" { @@ -166,14 +172,14 @@ DEFVAR [a-z_]+ LEXTRACE("WORD(2) "); if (!fill(yytext, yyleng)) yyterminate(); - return WORD; + LEXRETURN(WORD); } } { \\[[:blank:]]*\n[[:blank:]]* { /* Line continuation char followed by newline. */ - ++sudolineno; + sudolineno++; continued = TRUE; } @@ -183,7 +189,7 @@ DEFVAR [a-z_]+ if (yylval.string == NULL) { LEXTRACE("ERROR "); /* empty string */ - return ERROR; + LEXRETURN(ERROR); } if (prev_state == INITIAL) { switch (yylval.string[0]) { @@ -192,21 +198,21 @@ DEFVAR [a-z_]+ (yylval.string[1] == ':' && yylval.string[2] == '\0')) { LEXTRACE("ERROR "); /* empty group */ - return ERROR; + LEXRETURN(ERROR); } LEXTRACE("USERGROUP "); - return USERGROUP; + LEXRETURN(USERGROUP); case '+': if (yylval.string[1] == '\0') { LEXTRACE("ERROR "); /* empty netgroup */ - return ERROR; + LEXRETURN(ERROR); } LEXTRACE("NETGROUP "); - return NETGROUP; + LEXRETURN(NETGROUP); } } LEXTRACE("WORD(4) "); - return WORD; + LEXRETURN(WORD); } \\ { @@ -242,7 +248,7 @@ DEFVAR [a-z_]+ [#:\,=\n] { BEGIN INITIAL; yyless(0); - return COMMAND; + LEXRETURN(COMMAND); } /* end of command line args */ [^#\\:, \t\n]+ { @@ -258,7 +264,7 @@ DEFVAR [a-z_]+ if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if ((path = parse_include(yytext)) == NULL) @@ -276,7 +282,7 @@ DEFVAR [a-z_]+ if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if ((path = parse_include(yytext)) == NULL) @@ -298,7 +304,7 @@ DEFVAR [a-z_]+ if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } for (n = 0; isblank((unsigned char)yytext[n]); n++) @@ -313,22 +319,22 @@ DEFVAR [a-z_]+ case ':': yyless(n); LEXTRACE("DEFAULTS_USER "); - return DEFAULTS_USER; + LEXRETURN(DEFAULTS_USER); case '>': yyless(n); LEXTRACE("DEFAULTS_RUNAS "); - return DEFAULTS_RUNAS; + LEXRETURN(DEFAULTS_RUNAS); case '@': yyless(n); LEXTRACE("DEFAULTS_HOST "); - return DEFAULTS_HOST; + LEXRETURN(DEFAULTS_HOST); case '!': yyless(n); LEXTRACE("DEFAULTS_CMND "); - return DEFAULTS_CMND; + LEXRETURN(DEFAULTS_CMND); default: LEXTRACE("DEFAULTS "); - return DEFAULTS; + LEXRETURN(DEFAULTS); } } @@ -337,7 +343,7 @@ DEFVAR [a-z_]+ if (continued) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } for (n = 0; isblank((unsigned char)yytext[n]); n++) @@ -345,75 +351,75 @@ DEFVAR [a-z_]+ switch (yytext[n]) { case 'H': LEXTRACE("HOSTALIAS "); - return HOSTALIAS; + LEXRETURN(HOSTALIAS); case 'C': LEXTRACE("CMNDALIAS "); - return CMNDALIAS; + LEXRETURN(CMNDALIAS); case 'U': LEXTRACE("USERALIAS "); - return USERALIAS; + LEXRETURN(USERALIAS); case 'R': LEXTRACE("RUNASALIAS "); - return RUNASALIAS; + LEXRETURN(RUNASALIAS); } } NOPASSWD[[:blank:]]*: { /* cmnd does not require passwd for this user */ LEXTRACE("NOPASSWD "); - return NOPASSWD; + LEXRETURN(NOPASSWD); } PASSWD[[:blank:]]*: { /* cmnd requires passwd for this user */ LEXTRACE("PASSWD "); - return PASSWD; + LEXRETURN(PASSWD); } NOEXEC[[:blank:]]*: { LEXTRACE("NOEXEC "); - return NOEXEC; + LEXRETURN(NOEXEC); } EXEC[[:blank:]]*: { LEXTRACE("EXEC "); - return EXEC; + LEXRETURN(EXEC); } SETENV[[:blank:]]*: { LEXTRACE("SETENV "); - return SETENV; + LEXRETURN(SETENV); } NOSETENV[[:blank:]]*: { LEXTRACE("NOSETENV "); - return NOSETENV; + LEXRETURN(NOSETENV); } LOG_OUTPUT[[:blank:]]*: { LEXTRACE("LOG_OUTPUT "); - return LOG_OUTPUT; + LEXRETURN(LOG_OUTPUT); } NOLOG_OUTPUT[[:blank:]]*: { LEXTRACE("NOLOG_OUTPUT "); - return NOLOG_OUTPUT; + LEXRETURN(NOLOG_OUTPUT); } LOG_INPUT[[:blank:]]*: { LEXTRACE("LOG_INPUT "); - return LOG_INPUT; + LEXRETURN(LOG_INPUT); } NOLOG_INPUT[[:blank:]]*: { LEXTRACE("NOLOG_INPUT "); - return NOLOG_INPUT; + LEXRETURN(NOLOG_INPUT); } (\+|\%|\%:) { /* empty group or netgroup */ LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } \+{WORD} { @@ -421,7 +427,7 @@ NOLOG_INPUT[[:blank:]]*: { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NETGROUP "); - return NETGROUP; + LEXRETURN(NETGROUP); } \%:?({WORD}|{ID}) { @@ -429,55 +435,55 @@ NOLOG_INPUT[[:blank:]]*: { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("USERGROUP "); - return USERGROUP; + LEXRETURN(USERGROUP); } {IPV4ADDR}(\/{IPV4ADDR})? { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } {IPV4ADDR}\/([12]?[0-9]|3[0-2]) { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } {IPV6ADDR}(\/{IPV6ADDR})? { if (!ipv6_valid(yytext)) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } {IPV6ADDR}\/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]) { if (!ipv6_valid(yytext)) { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("NTWKADDR "); - return NTWKADDR; + LEXRETURN(NTWKADDR); } ALL { LEXTRACE("ALL "); - return ALL; + LEXRETURN(ALL); } ROLE { #ifdef HAVE_SELINUX LEXTRACE("ROLE "); - return ROLE; + LEXRETURN(ROLE); #else goto got_alias; #endif @@ -486,7 +492,7 @@ ALL { TYPE { #ifdef HAVE_SELINUX LEXTRACE("TYPE "); - return TYPE; + LEXRETURN(TYPE); #else goto got_alias; #endif @@ -497,7 +503,7 @@ ALL { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("ALIAS "); - return ALIAS; + LEXRETURN(ALIAS); } ({PATH}|sudoedit) { @@ -505,7 +511,7 @@ ALL { if (!fill_cmnd(yytext, yyleng)) yyterminate(); LEXTRACE("COMMAND "); - return COMMAND; + LEXRETURN(COMMAND); } sudoedit { @@ -521,7 +527,7 @@ sudoedit { LEXTRACE("COMMAND "); if (!fill_cmnd(yytext, yyleng)) yyterminate(); - return COMMAND; + LEXRETURN(COMMAND); } else { BEGIN GOTCMND; LEXTRACE("COMMAND "); @@ -542,51 +548,51 @@ sudoedit { if (!fill(yytext, yyleng)) yyterminate(); LEXTRACE("WORD(5) "); - return WORD; + LEXRETURN(WORD); } \( { LEXTRACE("( "); - return '('; + LEXRETURN('('); } \) { LEXTRACE(") "); - return ')'; + LEXRETURN(')'); } , { LEXTRACE(", "); - return ','; + LEXRETURN(','); } /* return ',' */ = { LEXTRACE("= "); - return '='; + LEXRETURN('='); } /* return '=' */ : { LEXTRACE(": "); - return ':'; + LEXRETURN(':'); } /* return ':' */ <*>!+ { if (yyleng & 1) { LEXTRACE("!"); - return '!'; /* return '!' */ + LEXRETURN('!'); /* return '!' */ } } <*>\n { if (YY_START == INSTR) { LEXTRACE("ERROR "); - return ERROR; /* line break in string */ + LEXRETURN(ERROR); /* line break in string */ } BEGIN INITIAL; - ++sudolineno; + sudolineno++; continued = FALSE; LEXTRACE("\n"); - return COMMENT; + LEXRETURN(COMMENT); } /* return newline */ <*>[[:blank:]]+ { /* throw away space/tabs */ @@ -595,28 +601,28 @@ sudoedit { <*>\\[[:blank:]]*\n { sawspace = TRUE; /* remember for fill_args */ - ++sudolineno; + sudolineno++; continued = TRUE; } /* throw away EOL after \ */ #(-[^\n0-9].*|[^\n0-9-].*)?\n { BEGIN INITIAL; - ++sudolineno; + sudolineno++; continued = FALSE; LEXTRACE("#\n"); - return COMMENT; + LEXRETURN(COMMENT); } /* comment, not uid/gid */ <*>. { LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } /* parse error */ <*><> { if (YY_START != INITIAL) { BEGIN INITIAL; LEXTRACE("ERROR "); - return ERROR; + LEXRETURN(ERROR); } if (!pop_include()) yyterminate();