From: Todd C. Miller Date: Tue, 6 Apr 1999 05:00:29 +0000 (+0000) Subject: Add VALIDATE_NOT_OK_NOPASS for when user is not allowed to run a command X-Git-Tag: SUDO_1_6_0~303 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=499e86923709d84fff67d3013321763f85e5e4a8;p=sudo Add VALIDATE_NOT_OK_NOPASS for when user is not allowed to run a command but the NOPASSWD flag was set. Make runasspec, runaslist, runasuser, and nopasswd typeless in parse.yacc Add support for '!' in the runas list Fix double printing of '%' and '+' for groups and netgroups respectively Add *_matched macros (no need for local stack variable). Should only be used directly after a pop (since top must be >= 2). --- diff --git a/logging.c b/logging.c index 5e0751c3e..7c569aa68 100644 --- a/logging.c +++ b/logging.c @@ -184,6 +184,7 @@ void log_error(code) break; case VALIDATE_NOT_OK: + case VALIDATE_NOT_OK_NOPASS: (void) sprintf(p, "command not allowed ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=", tty, cwd, runas_user); @@ -580,6 +581,7 @@ void inform_user(code) break; case VALIDATE_NOT_OK: + case VALIDATE_NOT_OK_NOPASS: (void) fprintf(stderr, "Sorry, user %s is not allowed to execute \"%s", user_name, cmnd); @@ -719,6 +721,7 @@ static int appropriate(code) break; case VALIDATE_NOT_OK: + case VALIDATE_NOT_OK_NOPASS: #ifdef SEND_MAIL_WHEN_NOT_OK return (1); #else diff --git a/parse.c b/parse.c index 8fc9829f2..25d868f8a 100644 --- a/parse.c +++ b/parse.c @@ -178,7 +178,10 @@ int validate(check_cmnd) return(VALIDATE_OK); } else if (cmnd_matches == FALSE) { /* User was explicitly denied acces to cmnd on host. */ - return(VALIDATE_NOT_OK); + if (no_passwd == TRUE) + return(VALIDATE_NOT_OK_NOPASS); + else + return(VALIDATE_NOT_OK); } } } diff --git a/parse.yacc b/parse.yacc index 0bd311bef..ea47e3510 100644 --- a/parse.yacc +++ b/parse.yacc @@ -199,10 +199,6 @@ void yyerror(s) %type cmnd %type opcmnd -%type runasspec -%type runaslist -%type runasuser -%type nopasswd %% @@ -287,8 +283,8 @@ cmndspec : { /* Push a new entry onto the stack if needed */ pushcp; cmnd_matches = -1; } runasspec nopasswd opcmnd { - /* XXX - test runas_matches and cmnd_matches instead? */ - if (($2 == -1 || $4 == -1) && printmatches == TRUE) { + if (printmatches == TRUE && + (runas_matches == -1 || cmnd_matches == -1)) { cm_list[cm_list_len].runas_len = 0; cm_list[cm_list_len].cmnd_len = 0; cm_list[cm_list_len].nopasswd = FALSE; @@ -310,7 +306,6 @@ opcmnd : cmnd { ; } push; } } opcmnd { - int cmnd_matched = cmnd_matches; pop; if (cmnd_matched == TRUE) cmnd_matches = FALSE; @@ -328,25 +323,41 @@ runasspec : /* empty */ { if (runas_matches == -1) runas_matches = (strcmp(RUNAS_DEFAULT, runas_user) == 0); - $$ = runas_matches; - } - | RUNAS runaslist { - runas_matches = ($2 > 0); - $$ = runas_matches; } + | RUNAS runaslist { ; } ; -runaslist : runasuser { - $$ = $1; - } - | runaslist ',' runasuser { - $$ = $1 + $3; - } +runaslist : oprunasuser + | runaslist ',' oprunasuser ; +oprunasuser : runasuser { + if (printmatches == TRUE && host_matches == TRUE && + user_matches == TRUE) + append("", &cm_list[cm_list_len].runas, + &cm_list[cm_list_len].runas_len, + &cm_list[cm_list_len].runas_size, ':'); + } + | '!' { + if (printmatches == TRUE && host_matches == TRUE && + user_matches == TRUE) { + append("!", &cm_list[cm_list_len].runas, + &cm_list[cm_list_len].runas_len, + &cm_list[cm_list_len].runas_size, ':'); + pushcp; + } else { + push; + } + } oprunasuser { + pop; + if (runas_matched == TRUE) + runas_matches = FALSE; + else if (runas_matched == FALSE) + runas_matches = TRUE; + } runasuser : NAME { - $$ = (strcmp($1, runas_user) == 0); + runas_matches = (strcmp($1, runas_user) == 0); if (printmatches == TRUE && in_alias == TRUE) append($1, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, @@ -355,20 +366,17 @@ runasuser : NAME { user_matches == TRUE) append($1, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); + &cm_list[cm_list_len].runas_size, 0); (void) free($1); } | USERGROUP { - $$ = usergr_matches($1, runas_user); + runas_matches = usergr_matches($1, runas_user); if (printmatches == TRUE && in_alias == TRUE) append($1, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, &ga_list[ga_list_len-1].entries_size, ','); if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { - append("%", &cm_list[cm_list_len].runas, - &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); append($1, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, 0); @@ -376,16 +384,13 @@ runasuser : NAME { (void) free($1); } | NETGROUP { - $$ = netgr_matches($1, NULL, runas_user); + runas_matches = netgr_matches($1, NULL, runas_user); if (printmatches == TRUE && in_alias == TRUE) append($1, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, &ga_list[ga_list_len-1].entries_size, ','); if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { - append("+", &cm_list[cm_list_len].runas, - &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); append($1, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, 0); @@ -396,9 +401,9 @@ runasuser : NAME { /* could be an all-caps username */ if (find_alias($1, RUNAS_ALIAS) == TRUE || strcmp($1, runas_user) == 0) - $$ = TRUE; + runas_matches = TRUE; else - $$ = FALSE; + runas_matches = FALSE; if (printmatches == TRUE && in_alias == TRUE) append($1, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, @@ -407,11 +412,11 @@ runasuser : NAME { user_matches == TRUE) append($1, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); + &cm_list[cm_list_len].runas_size, 0); (void) free($1); } | ALL { - $$ = TRUE; + runas_matches = TRUE; if (printmatches == TRUE && in_alias == TRUE) append("ALL", &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, @@ -420,7 +425,7 @@ runasuser : NAME { user_matches == TRUE) append("ALL", &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); + &cm_list[cm_list_len].runas_size, 0); } ; @@ -428,13 +433,13 @@ nopasswd : /* empty */ { ; } | NOPASSWD { - no_passwd = $$ = TRUE; + no_passwd = TRUE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = TRUE; } | PASSWD { - no_passwd = $$ = FALSE; + no_passwd = FALSE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = FALSE; @@ -570,7 +575,8 @@ runasalias : ALIAS { ga_list[ga_list_len-1].alias = estrdup($1); } } '=' runaslist { - if ($4 > 0 && add_alias($1, RUNAS_ALIAS) == FALSE) + if (runas_matches > 0 && + add_alias($1, RUNAS_ALIAS) == FALSE) YYERROR; pop; (void) free($1); diff --git a/sudo.c b/sudo.c index 053fbe982..bde0d84d6 100644 --- a/sudo.c +++ b/sudo.c @@ -375,6 +375,7 @@ int main(argc, argv) case VALIDATE_NOT_OK: check_user(); + case VALIDATE_NOT_OK_NOPASS: #ifndef DONT_LEAK_PATH_INFO log_error(rtn); if (cmnd_status == NOT_FOUND_DOT) diff --git a/sudo.h b/sudo.h index 2b598f46a..edefbd91c 100644 --- a/sudo.h +++ b/sudo.h @@ -65,9 +65,13 @@ extern struct matchstack *match; extern int top; #define user_matches (match[top-1].user) +#define user_matched (match[top-2].user) #define cmnd_matches (match[top-1].cmnd) +#define cmnd_matched (match[top-2].cmnd) #define host_matches (match[top-1].host) +#define host_matched (match[top-2].host) #define runas_matches (match[top-1].runas) +#define runas_matched (match[top-2].runas) #define no_passwd (match[top-1].nopass) /* @@ -131,9 +135,10 @@ struct generic_alias { #endif /* LOGGING & SLOG_SYSLOG */ #define VALIDATE_OK 0x00 -#define VALIDATE_NO_USER 0x01 -#define VALIDATE_NOT_OK 0x02 -#define VALIDATE_OK_NOPASS 0x03 +#define VALIDATE_OK_NOPASS 0x01 +#define VALIDATE_NO_USER 0x02 +#define VALIDATE_NOT_OK 0x03 +#define VALIDATE_NOT_OK_NOPASS 0x04 #define VALIDATE_ERROR -1 /* diff --git a/sudo.tab.c b/sudo.tab.c index 32b570e42..8b080ed56 100644 --- a/sudo.tab.c +++ b/sudo.tab.c @@ -212,84 +212,89 @@ typedef union { #define ERROR 273 #define YYERRCODE 256 short yylhs[] = { -1, - 0, 0, 7, 7, 9, 7, 7, 7, 7, 7, - 10, 10, 15, 16, 16, 16, 16, 16, 16, 17, - 17, 19, 18, 2, 20, 2, 3, 3, 4, 4, - 5, 5, 5, 5, 5, 6, 6, 6, 1, 1, - 1, 12, 12, 22, 21, 23, 23, 13, 13, 25, - 24, 26, 26, 14, 14, 28, 27, 11, 11, 30, - 29, 31, 31, 8, 8, 8, 8, 8, + 0, 0, 3, 3, 5, 3, 3, 3, 3, 3, + 6, 6, 11, 12, 12, 12, 12, 12, 12, 13, + 13, 16, 14, 2, 18, 2, 15, 15, 19, 19, + 20, 22, 20, 21, 21, 21, 21, 21, 17, 17, + 17, 1, 1, 1, 8, 8, 24, 23, 25, 25, + 9, 9, 27, 26, 28, 28, 10, 10, 30, 29, + 7, 7, 32, 31, 33, 33, 4, 4, 4, 4, + 4, }; short yylen[] = { 2, 1, 2, 1, 2, 0, 3, 2, 2, 2, 2, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 3, 0, 4, 1, 0, 3, 0, 2, 1, 3, - 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 3, 0, 4, 1, 3, 1, 3, 0, - 4, 1, 3, 1, 3, 0, 4, 1, 3, 0, - 4, 1, 3, 1, 1, 1, 1, 1, + 1, 0, 3, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 3, 0, 4, 1, 3, + 1, 3, 0, 4, 1, 3, 1, 3, 0, 4, + 1, 3, 0, 4, 1, 3, 1, 1, 1, 1, + 1, }; short yydefred[] = { 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 4, - 44, 0, 42, 50, 0, 48, 60, 0, 58, 56, - 0, 54, 2, 67, 66, 65, 64, 68, 0, 0, + 47, 0, 45, 53, 0, 51, 63, 0, 61, 59, + 0, 57, 2, 70, 69, 68, 67, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 15, 18, - 16, 17, 14, 0, 11, 0, 0, 43, 0, 49, - 0, 59, 0, 55, 0, 22, 46, 0, 40, 41, - 39, 52, 0, 62, 0, 34, 33, 32, 31, 35, - 0, 29, 12, 0, 20, 0, 0, 0, 0, 0, - 22, 0, 0, 47, 53, 63, 30, 21, 0, 37, - 38, 0, 25, 24, 23, 0, 26, + 16, 17, 14, 0, 11, 0, 0, 46, 0, 52, + 0, 62, 0, 58, 0, 22, 49, 0, 43, 44, + 42, 55, 0, 65, 0, 37, 36, 35, 34, 38, + 32, 0, 29, 31, 12, 0, 20, 0, 0, 0, + 0, 0, 0, 22, 0, 0, 50, 56, 66, 33, + 30, 21, 0, 40, 41, 0, 25, 24, 23, 0, + 26, }; short yydgoto[] = { 7, - 94, 95, 83, 71, 72, 92, 8, 29, 9, 44, - 18, 12, 15, 21, 45, 46, 74, 75, 76, 96, - 13, 30, 58, 16, 32, 63, 22, 36, 19, 34, - 65, + 98, 99, 8, 29, 9, 44, 18, 12, 15, 21, + 45, 46, 76, 77, 86, 78, 96, 100, 72, 73, + 74, 82, 13, 30, 58, 16, 32, 63, 22, 36, + 19, 34, 65, }; short yysindex[] = { -248, - -258, 0, -246, -245, -243, -241, -248, 0, -211, 0, - 0, -41, 0, 0, -38, 0, 0, -31, 0, 0, - -30, 0, 0, 0, 0, 0, 0, 0, -220, -32, - -246, -20, -245, -18, -243, -17, -241, 0, 0, 0, - 0, 0, 0, -25, 0, -16, -220, 0, -253, 0, - -211, 0, -197, 0, -220, 0, 0, -14, 0, 0, - 0, 0, -10, 0, 3, 0, 0, 0, 0, 0, - 9, 0, 0, 10, 0, -208, -220, -253, -211, -197, - 0, -197, -239, 0, 0, 0, 0, 0, 9, 0, - 0, -27, 0, 0, 0, -27, 0, + -256, 0, -243, -237, -232, -231, -248, 0, -220, 0, + 0, -19, 0, 0, -15, 0, 0, -14, 0, 0, + -13, 0, 0, 0, 0, 0, 0, 0, -230, -8, + -243, -7, -237, -6, -232, -5, -231, 0, 0, 0, + 0, 0, 0, -11, 0, -3, -230, 0, -253, 0, + -220, 0, -33, 0, -230, 0, 0, 16, 0, 0, + 0, 0, 17, 0, 19, 0, 0, 0, 0, 0, + 0, 20, 0, 0, 0, 21, 0, -201, -230, -253, + -220, -33, -33, 0, -33, -255, 0, 0, 0, 0, + 0, 0, 20, 0, 0, -26, 0, 0, 0, -26, + 0, }; -short yyrindex[] = { -187, - 0, 0, 0, 0, 0, 0, -187, 0, 0, 0, +short yyrindex[] = { -211, + 0, 0, 0, 0, 0, 0, -211, 0, 0, 0, 0, 86, 0, 0, 103, 0, 0, 120, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 18, 0, 35, 0, 0, 0, 0, 0, - 52, 0, 0, 69, 0, -33, 0, 0, 0, 0, - 0, 0, -23, 0, 0, 0, 0, 0, -28, 0, - 0, 0, 0, 0, 0, 0, 0, + 0, 52, 0, 0, 0, 69, 0, -27, 0, 0, + 0, 0, 0, 0, 0, -2, 0, 0, 0, 0, + 0, 0, -21, 0, 0, 0, 0, 0, 0, 0, + 0, }; short yygindex[] = { 0, - -42, -40, 0, -24, -19, 0, 55, -48, 0, 0, - 0, 0, 0, 0, 11, -45, 0, -13, 0, 0, - 36, 0, 0, 39, 0, 0, 40, 0, 43, 0, - 0, + -44, -34, 60, -48, 0, 0, 0, 0, 0, 0, + 13, -45, 0, -12, 0, 0, 0, 0, -10, -66, + 0, 0, 39, 0, 0, 38, 0, 0, 36, 0, + 42, 0, 0, }; #define YYTABLESIZE 426 -short yytable[] = { 27, - 45, 57, 64, 59, 28, 93, 62, 1, 10, 36, - 11, 14, 60, 17, 61, 20, 31, 51, 2, 33, - 3, 4, 5, 6, 90, 91, 35, 37, 47, 77, - 86, 84, 55, 78, 61, 85, 38, 39, 40, 41, - 49, 42, 51, 53, 56, 24, 79, 43, 25, 26, - 27, 57, 80, 81, 82, 97, 28, 89, 45, 66, - 87, 23, 67, 68, 69, 73, 48, 88, 13, 5, - 70, 50, 5, 5, 5, 51, 54, 52, 0, 0, - 5, 0, 0, 0, 0, 8, 0, 0, 0, 0, - 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 0, 0, 0, 0, 0, 0, 57, +short yytable[] = { 71, + 48, 57, 64, 59, 62, 27, 97, 1, 94, 95, + 10, 28, 60, 11, 61, 90, 91, 54, 2, 14, + 3, 4, 5, 6, 17, 20, 38, 39, 40, 41, + 39, 42, 89, 87, 64, 88, 24, 43, 31, 25, + 26, 27, 33, 35, 37, 5, 55, 28, 5, 5, + 5, 60, 47, 49, 51, 53, 5, 56, 48, 79, + 80, 85, 81, 83, 84, 101, 23, 75, 13, 48, + 50, 92, 54, 0, 93, 54, 52, 0, 0, 0, + 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, + 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, @@ -301,17 +306,17 @@ short yytable[] = { 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 27, 0, 0, 0, 0, 28, 59, - 27, 27, 27, 36, 27, 28, 28, 28, 60, 28, - 61, 0, 36, 0, 36, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 45, 45, 0, 0, - 45, 45, 45, 0, 0, 0, 0, 45, 45, 45, - 45, 45, 45, 51, 51, 0, 0, 51, 51, 51, - 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, - 61, 61, 0, 0, 61, 61, 61, 0, 0, 0, - 0, 61, 61, 61, 61, 61, 61, 57, 57, 0, - 0, 57, 57, 57, 0, 0, 0, 0, 57, 57, - 57, 57, 57, 57, 13, 13, 0, 0, 13, 13, + 0, 0, 0, 66, 0, 0, 67, 68, 69, 27, + 59, 0, 0, 0, 70, 28, 27, 27, 27, 60, + 27, 61, 28, 28, 28, 0, 28, 0, 0, 0, + 0, 0, 0, 0, 39, 0, 48, 48, 0, 0, + 48, 48, 48, 39, 0, 39, 0, 48, 48, 48, + 48, 48, 48, 54, 54, 0, 0, 54, 54, 54, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 64, 64, 0, 0, 64, 64, 64, 0, 0, 0, + 0, 64, 64, 64, 64, 64, 64, 60, 60, 0, + 0, 60, 60, 60, 0, 0, 0, 0, 60, 60, + 60, 60, 60, 60, 13, 13, 0, 0, 13, 13, 13, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 8, 8, 0, 0, 8, 8, 8, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 9, 9, @@ -324,15 +329,15 @@ short yytable[] = { 27, 6, 6, 6, 6, 6, 6, }; short yycheck[] = { 33, - 0, 47, 51, 257, 33, 33, 49, 256, 267, 33, - 257, 257, 266, 257, 268, 257, 58, 0, 267, 58, - 269, 270, 271, 272, 264, 265, 58, 58, 61, 44, - 79, 77, 58, 44, 0, 78, 257, 258, 259, 260, - 61, 262, 61, 61, 61, 257, 44, 268, 260, 261, - 262, 0, 44, 44, 263, 96, 268, 82, 58, 257, - 80, 7, 260, 261, 262, 55, 31, 81, 0, 257, - 268, 33, 260, 261, 262, 58, 37, 35, -1, -1, - 268, -1, -1, -1, -1, 0, -1, -1, -1, -1, + 0, 47, 51, 257, 49, 33, 33, 256, 264, 265, + 267, 33, 266, 257, 268, 82, 83, 0, 267, 257, + 269, 270, 271, 272, 257, 257, 257, 258, 259, 260, + 33, 262, 81, 79, 0, 80, 257, 268, 58, 260, + 261, 262, 58, 58, 58, 257, 58, 268, 260, 261, + 262, 0, 61, 61, 61, 61, 268, 61, 58, 44, + 44, 263, 44, 44, 44, 100, 7, 55, 0, 31, + 33, 84, 37, -1, 85, 58, 35, -1, -1, -1, + -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, 58, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, @@ -346,11 +351,11 @@ short yycheck[] = { 33, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 257, -1, -1, -1, -1, 257, 257, - 264, 265, 266, 257, 268, 264, 265, 266, 266, 268, - 268, -1, 266, -1, 268, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 256, 257, -1, -1, - 260, 261, 262, -1, -1, -1, -1, 267, 268, 269, + -1, -1, -1, 257, -1, -1, 260, 261, 262, 257, + 257, -1, -1, -1, 268, 257, 264, 265, 266, 266, + 268, 268, 264, 265, 266, -1, 268, -1, -1, -1, + -1, -1, -1, -1, 257, -1, 256, 257, -1, -1, + 260, 261, 262, 266, -1, 268, -1, 267, 268, 269, 270, 271, 272, 256, 257, -1, -1, 260, 261, 262, -1, -1, -1, -1, 267, 268, 269, 270, 271, 272, 256, 257, -1, -1, 260, 261, 262, -1, -1, -1, @@ -416,8 +421,11 @@ char *yyrule[] = { "opcmnd : '!' $$3 opcmnd", "runasspec :", "runasspec : RUNAS runaslist", -"runaslist : runasuser", -"runaslist : runaslist ',' runasuser", +"runaslist : oprunasuser", +"runaslist : runaslist ',' oprunasuser", +"oprunasuser : runasuser", +"$$4 :", +"oprunasuser : '!' $$4 oprunasuser", "runasuser : NAME", "runasuser : USERGROUP", "runasuser : NETGROUP", @@ -431,24 +439,24 @@ char *yyrule[] = { "cmnd : COMMAND", "hostaliases : hostalias", "hostaliases : hostaliases ':' hostalias", -"$$4 :", -"hostalias : ALIAS $$4 '=' hostlist", +"$$5 :", +"hostalias : ALIAS $$5 '=' hostlist", "hostlist : hostspec", "hostlist : hostlist ',' hostspec", "cmndaliases : cmndalias", "cmndaliases : cmndaliases ':' cmndalias", -"$$5 :", -"cmndalias : ALIAS $$5 '=' cmndlist", +"$$6 :", +"cmndalias : ALIAS $$6 '=' cmndlist", "cmndlist : cmnd", "cmndlist : cmndlist ',' cmnd", "runasaliases : runasalias", "runasaliases : runasaliases ':' runasalias", -"$$6 :", -"runasalias : ALIAS $$6 '=' runaslist", +"$$7 :", +"runasalias : ALIAS $$7 '=' runaslist", "useraliases : useralias", "useraliases : useraliases ':' useralias", -"$$7 :", -"useralias : ALIAS $$7 '=' userlist", +"$$8 :", +"useralias : ALIAS $$8 '=' userlist", "userlist : user", "userlist : userlist ',' user", "user : NAME", @@ -482,7 +490,7 @@ short *yyss; short *yysslim; YYSTYPE *yyvs; int yystacksize; -#line 629 "parse.yacc" +#line 635 "parse.yacc" typedef struct { @@ -859,7 +867,7 @@ void init_parser() if (printmatches == TRUE) expand_match_list(); } -#line 863 "sudo.tab.c" +#line 871 "sudo.tab.c" /* allocate initial stack or double stack size, up to YYMAXDEPTH */ #if defined(__cplusplus) || __STDC__ static int yygrowstack(void) @@ -1040,19 +1048,19 @@ yyreduce: switch (yyn) { case 3: -#line 214 "parse.yacc" +#line 210 "parse.yacc" { ; } break; case 4: -#line 216 "parse.yacc" +#line 212 "parse.yacc" { yyerrok; } break; case 5: -#line 217 "parse.yacc" +#line 213 "parse.yacc" { push; } break; case 6: -#line 217 "parse.yacc" +#line 213 "parse.yacc" { while (top && user_matches != TRUE) { pop; @@ -1060,23 +1068,23 @@ case 6: } break; case 7: -#line 223 "parse.yacc" +#line 219 "parse.yacc" { ; } break; case 8: -#line 225 "parse.yacc" +#line 221 "parse.yacc" { ; } break; case 9: -#line 227 "parse.yacc" +#line 223 "parse.yacc" { ; } break; case 10: -#line 229 "parse.yacc" +#line 225 "parse.yacc" { ; } break; case 13: -#line 237 "parse.yacc" +#line 233 "parse.yacc" { if (user_matches == TRUE) { push; @@ -1088,13 +1096,13 @@ case 13: } break; case 14: -#line 248 "parse.yacc" +#line 244 "parse.yacc" { host_matches = TRUE; } break; case 15: -#line 251 "parse.yacc" +#line 247 "parse.yacc" { if (addr_matches(yyvsp[0].string)) host_matches = TRUE; @@ -1102,7 +1110,7 @@ case 15: } break; case 16: -#line 256 "parse.yacc" +#line 252 "parse.yacc" { if (netgr_matches(yyvsp[0].string, host, NULL)) host_matches = TRUE; @@ -1110,7 +1118,7 @@ case 16: } break; case 17: -#line 261 "parse.yacc" +#line 257 "parse.yacc" { if (strcasecmp(shost, yyvsp[0].string) == 0) host_matches = TRUE; @@ -1118,7 +1126,7 @@ case 17: } break; case 18: -#line 266 "parse.yacc" +#line 262 "parse.yacc" { if (strcasecmp(host, yyvsp[0].string) == 0) host_matches = TRUE; @@ -1126,7 +1134,7 @@ case 18: } break; case 19: -#line 271 "parse.yacc" +#line 267 "parse.yacc" { /* could be an all-caps hostname */ if (find_alias(yyvsp[0].string, HOST_ALIAS) == TRUE || @@ -1136,7 +1144,7 @@ case 19: } break; case 22: -#line 284 "parse.yacc" +#line 280 "parse.yacc" { /* Push a new entry onto the stack if needed */ if (user_matches == TRUE && host_matches == TRUE && cmnd_matches != -1 && runas_matches == TRUE) @@ -1145,10 +1153,10 @@ case 22: } break; case 23: -#line 289 "parse.yacc" +#line 285 "parse.yacc" { - /* XXX - test runas_matches and cmnd_matches instead? */ - if ((yyvsp[-2].BOOLEAN == -1 || yyvsp[0].BOOLEAN == -1) && printmatches == TRUE) { + if (printmatches == TRUE && + (runas_matches == -1 || cmnd_matches == -1)) { cm_list[cm_list_len].runas_len = 0; cm_list[cm_list_len].cmnd_len = 0; cm_list[cm_list_len].nopasswd = FALSE; @@ -1156,11 +1164,11 @@ case 23: } break; case 24: -#line 299 "parse.yacc" +#line 295 "parse.yacc" { ; } break; case 25: -#line 300 "parse.yacc" +#line 296 "parse.yacc" { if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { @@ -1176,9 +1184,8 @@ case 25: } break; case 26: -#line 312 "parse.yacc" +#line 308 "parse.yacc" { - int cmnd_matched = cmnd_matches; pop; if (cmnd_matched == TRUE) cmnd_matches = FALSE; @@ -1188,7 +1195,7 @@ case 26: } break; case 27: -#line 323 "parse.yacc" +#line 318 "parse.yacc" { /* * If this is the first entry in a command list @@ -1197,32 +1204,50 @@ case 27: if (runas_matches == -1) runas_matches = (strcmp(RUNAS_DEFAULT, runas_user) == 0); - yyval.BOOLEAN = runas_matches; } break; case 28: -#line 333 "parse.yacc" +#line 327 "parse.yacc" +{ ; } +break; +case 31: +#line 334 "parse.yacc" { - runas_matches = (yyvsp[0].BOOLEAN > 0); - yyval.BOOLEAN = runas_matches; + if (printmatches == TRUE && host_matches == TRUE && + user_matches == TRUE) + append("", &cm_list[cm_list_len].runas, + &cm_list[cm_list_len].runas_len, + &cm_list[cm_list_len].runas_size, ':'); } break; -case 29: -#line 339 "parse.yacc" +case 32: +#line 341 "parse.yacc" { - yyval.BOOLEAN = yyvsp[0].BOOLEAN; + if (printmatches == TRUE && host_matches == TRUE && + user_matches == TRUE) { + append("!", &cm_list[cm_list_len].runas, + &cm_list[cm_list_len].runas_len, + &cm_list[cm_list_len].runas_size, ':'); + pushcp; + } else { + push; + } } break; -case 30: -#line 342 "parse.yacc" +case 33: +#line 351 "parse.yacc" { - yyval.BOOLEAN = yyvsp[-2].BOOLEAN + yyvsp[0].BOOLEAN; + pop; + if (runas_matched == TRUE) + runas_matches = FALSE; + else if (runas_matched == FALSE) + runas_matches = TRUE; } break; -case 31: -#line 348 "parse.yacc" +case 34: +#line 359 "parse.yacc" { - yyval.BOOLEAN = (strcmp(yyvsp[0].string, runas_user) == 0); + runas_matches = (strcmp(yyvsp[0].string, runas_user) == 0); if (printmatches == TRUE && in_alias == TRUE) append(yyvsp[0].string, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, @@ -1231,23 +1256,20 @@ case 31: user_matches == TRUE) append(yyvsp[0].string, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); + &cm_list[cm_list_len].runas_size, 0); (void) free(yyvsp[0].string); } break; -case 32: -#line 361 "parse.yacc" +case 35: +#line 372 "parse.yacc" { - yyval.BOOLEAN = usergr_matches(yyvsp[0].string, runas_user); + runas_matches = usergr_matches(yyvsp[0].string, runas_user); if (printmatches == TRUE && in_alias == TRUE) append(yyvsp[0].string, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, &ga_list[ga_list_len-1].entries_size, ','); if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { - append("%", &cm_list[cm_list_len].runas, - &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); append(yyvsp[0].string, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, 0); @@ -1255,19 +1277,16 @@ case 32: (void) free(yyvsp[0].string); } break; -case 33: -#line 378 "parse.yacc" +case 36: +#line 386 "parse.yacc" { - yyval.BOOLEAN = netgr_matches(yyvsp[0].string, NULL, runas_user); + runas_matches = netgr_matches(yyvsp[0].string, NULL, runas_user); if (printmatches == TRUE && in_alias == TRUE) append(yyvsp[0].string, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, &ga_list[ga_list_len-1].entries_size, ','); if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { - append("+", &cm_list[cm_list_len].runas, - &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); append(yyvsp[0].string, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, 0); @@ -1275,15 +1294,15 @@ case 33: (void) free(yyvsp[0].string); } break; -case 34: -#line 395 "parse.yacc" +case 37: +#line 400 "parse.yacc" { /* could be an all-caps username */ if (find_alias(yyvsp[0].string, RUNAS_ALIAS) == TRUE || strcmp(yyvsp[0].string, runas_user) == 0) - yyval.BOOLEAN = TRUE; + runas_matches = TRUE; else - yyval.BOOLEAN = FALSE; + runas_matches = FALSE; if (printmatches == TRUE && in_alias == TRUE) append(yyvsp[0].string, &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, @@ -1292,14 +1311,14 @@ case 34: user_matches == TRUE) append(yyvsp[0].string, &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); + &cm_list[cm_list_len].runas_size, 0); (void) free(yyvsp[0].string); } break; -case 35: -#line 413 "parse.yacc" +case 38: +#line 418 "parse.yacc" { - yyval.BOOLEAN = TRUE; + runas_matches = TRUE; if (printmatches == TRUE && in_alias == TRUE) append("ALL", &ga_list[ga_list_len-1].entries, &ga_list[ga_list_len-1].entries_len, @@ -1308,35 +1327,35 @@ case 35: user_matches == TRUE) append("ALL", &cm_list[cm_list_len].runas, &cm_list[cm_list_len].runas_len, - &cm_list[cm_list_len].runas_size, ':'); + &cm_list[cm_list_len].runas_size, 0); } break; -case 36: -#line 427 "parse.yacc" +case 39: +#line 432 "parse.yacc" { ; } break; -case 37: -#line 430 "parse.yacc" +case 40: +#line 435 "parse.yacc" { - no_passwd = yyval.BOOLEAN = TRUE; + no_passwd = TRUE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = TRUE; } break; -case 38: -#line 436 "parse.yacc" +case 41: +#line 441 "parse.yacc" { - no_passwd = yyval.BOOLEAN = FALSE; + no_passwd = FALSE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = FALSE; } break; -case 39: -#line 444 "parse.yacc" +case 42: +#line 449 "parse.yacc" { if (printmatches == TRUE && in_alias == TRUE) { append("ALL", &ga_list[ga_list_len-1].entries, @@ -1355,8 +1374,8 @@ case 39: yyval.BOOLEAN = TRUE; } break; -case 40: -#line 461 "parse.yacc" +case 43: +#line 466 "parse.yacc" { if (printmatches == TRUE && in_alias == TRUE) { append(yyvsp[0].string, &ga_list[ga_list_len-1].entries, @@ -1377,8 +1396,8 @@ case 40: (void) free(yyvsp[0].string); } break; -case 41: -#line 480 "parse.yacc" +case 44: +#line 485 "parse.yacc" { if (printmatches == TRUE && in_alias == TRUE) { append(yyvsp[0].command.cmnd, &ga_list[ga_list_len-1].entries, @@ -1413,12 +1432,12 @@ case 41: (void) free(yyvsp[0].command.args); } break; -case 44: -#line 519 "parse.yacc" +case 47: +#line 524 "parse.yacc" { push; } break; -case 45: -#line 519 "parse.yacc" +case 48: +#line 524 "parse.yacc" { if (host_matches == TRUE && add_alias(yyvsp[-3].string, HOST_ALIAS) == FALSE) @@ -1426,8 +1445,8 @@ case 45: pop; } break; -case 50: -#line 535 "parse.yacc" +case 53: +#line 540 "parse.yacc" { push; if (printmatches == TRUE) { @@ -1438,8 +1457,8 @@ case 50: } } break; -case 51: -#line 543 "parse.yacc" +case 54: +#line 548 "parse.yacc" { if (cmnd_matches == TRUE && add_alias(yyvsp[-3].string, CMND_ALIAS) == FALSE) @@ -1451,12 +1470,12 @@ case 51: in_alias = FALSE; } break; -case 52: -#line 556 "parse.yacc" +case 55: +#line 561 "parse.yacc" { ; } break; -case 56: -#line 564 "parse.yacc" +case 59: +#line 569 "parse.yacc" { push; if (printmatches == TRUE) { @@ -1467,10 +1486,11 @@ case 56: } } break; -case 57: -#line 572 "parse.yacc" +case 60: +#line 577 "parse.yacc" { - if (yyvsp[0].BOOLEAN > 0 && add_alias(yyvsp[-3].string, RUNAS_ALIAS) == FALSE) + if (runas_matches > 0 && + add_alias(yyvsp[-3].string, RUNAS_ALIAS) == FALSE) YYERROR; pop; (void) free(yyvsp[-3].string); @@ -1479,12 +1499,12 @@ case 57: in_alias = FALSE; } break; -case 60: -#line 587 "parse.yacc" +case 63: +#line 593 "parse.yacc" { push; } break; -case 61: -#line 587 "parse.yacc" +case 64: +#line 593 "parse.yacc" { if (user_matches == TRUE && add_alias(yyvsp[-3].string, USER_ALIAS) == FALSE) @@ -1493,36 +1513,36 @@ case 61: (void) free(yyvsp[-3].string); } break; -case 62: -#line 597 "parse.yacc" +case 65: +#line 603 "parse.yacc" { ; } break; -case 64: -#line 601 "parse.yacc" +case 67: +#line 607 "parse.yacc" { if (strcmp(yyvsp[0].string, user_name) == 0) user_matches = TRUE; (void) free(yyvsp[0].string); } break; -case 65: -#line 606 "parse.yacc" +case 68: +#line 612 "parse.yacc" { if (usergr_matches(yyvsp[0].string, user_name)) user_matches = TRUE; (void) free(yyvsp[0].string); } break; -case 66: -#line 611 "parse.yacc" +case 69: +#line 617 "parse.yacc" { if (netgr_matches(yyvsp[0].string, NULL, user_name)) user_matches = TRUE; (void) free(yyvsp[0].string); } break; -case 67: -#line 616 "parse.yacc" +case 70: +#line 622 "parse.yacc" { /* could be an all-caps username */ if (find_alias(yyvsp[0].string, USER_ALIAS) == TRUE || @@ -1531,13 +1551,13 @@ case 67: (void) free(yyvsp[0].string); } break; -case 68: -#line 623 "parse.yacc" +case 71: +#line 629 "parse.yacc" { user_matches = TRUE; } break; -#line 1541 "sudo.tab.c" +#line 1561 "sudo.tab.c" } yyssp -= yym; yystate = *yyssp;