=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sudo/Attic/parse.yacc,v retrieving revision 1.9 retrieving revision 1.10 diff -c -r1.9 -r1.10 *** src/usr.bin/sudo/Attic/parse.yacc 2003/04/19 21:57:17 1.9 --- src/usr.bin/sudo/Attic/parse.yacc 2004/09/28 15:10:51 1.10 *************** *** 1,36 **** %{ /* ! * Copyright (c) 1996, 1998-2003 Todd C. Miller ! * All rights reserved. * ! * This code is derived from software contributed by Chris Jepeway. * ! * Redistribution and use in source and binary forms, with or without ! * modification, are permitted provided that the following conditions ! * are met: ! * ! * 1. Redistributions of source code must retain the above copyright ! * notice, this list of conditions and the following disclaimer. ! * ! * 2. Redistributions in binary form must reproduce the above copyright ! * notice, this list of conditions and the following disclaimer in the ! * documentation and/or other materials provided with the distribution. ! * ! * 3. The name of the author may not be used to endorse or promote products ! * derived from this software without specific prior written permission. ! * ! * 4. Products derived from this software may not be called "Sudo" nor ! * may "Sudo" appear in their names without specific prior written ! * permission from the author. ! * ! * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, ! * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ! * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ! * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, ! * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, ! * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ! * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ! * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --- 1,18 ---- %{ /* ! * Copyright (c) 1996, 1998-2004 Todd C. Miller * ! * Permission to use, copy, modify, and distribute this software for any ! * purpose with or without fee is hereby granted, provided that the above ! * copyright notice and this permission notice appear in all copies. * ! * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ! * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ! * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *************** *** 89,95 **** #endif /* HAVE_LSEARCH */ #ifndef lint ! static const char rcsid[] = "$Sudo: parse.yacc,v 1.188 2003/04/16 00:42:10 millert Exp $"; #endif /* lint */ /* --- 71,77 ---- #endif /* HAVE_LSEARCH */ #ifndef lint ! static const char rcsid[] = "$Sudo: parse.yacc,v 1.204 2004/08/11 18:29:10 millert Exp $"; #endif /* lint */ /* *************** *** 102,107 **** --- 84,90 ---- int pedantic = FALSE; int keepall = FALSE; int quiet = FALSE; + int used_runas = FALSE; /* * Alias types *************** *** 111,116 **** --- 94,111 ---- #define USER_ALIAS 3 #define RUNAS_ALIAS 4 + #define SETMATCH(_var, _val) do { \ + if ((_var) == UNSPEC || (_val) != NOMATCH) \ + (_var) = (_val); \ + } while (0) + + #define SETNMATCH(_var, _val) do { \ + if ((_val) != NOMATCH) \ + (_var) = ! (_val); \ + else if ((_var) == UNSPEC) \ + (_var) = NOMATCH; \ + } while (0) + /* * The matching stack, initial space allocated in init_parser(). */ *************** *** 123,133 **** while ((stacksize += STACKINCREMENT) < top); \ match = (struct matchstack *) erealloc3(match, stacksize, sizeof(struct matchstack)); \ } \ ! match[top].user = -1; \ ! match[top].cmnd = -1; \ ! match[top].host = -1; \ ! match[top].runas = -1; \ ! match[top].nopass = def_flag(I_AUTHENTICATE) ? -1 : TRUE; \ top++; \ } while (0) --- 118,129 ---- while ((stacksize += STACKINCREMENT) < top); \ match = (struct matchstack *) erealloc3(match, stacksize, sizeof(struct matchstack)); \ } \ ! match[top].user = UNSPEC; \ ! match[top].cmnd = UNSPEC; \ ! match[top].host = UNSPEC; \ ! match[top].runas = UNSPEC; \ ! match[top].nopass = def_authenticate ? UNSPEC : TRUE; \ ! match[top].noexec = def_noexec ? TRUE : UNSPEC; \ top++; \ } while (0) *************** *** 142,159 **** match[top].host = match[top-1].host; \ match[top].runas = match[top-1].runas; \ match[top].nopass = match[top-1].nopass; \ top++; \ } while (0) #define pop \ ! { \ if (top == 0) \ yyerror("matching stack underflow"); \ else \ top--; \ ! } /* * Shortcuts for append() */ #define append_cmnd(s, p) append(s, &cm_list[cm_list_len].cmnd, \ --- 138,162 ---- match[top].host = match[top-1].host; \ match[top].runas = match[top-1].runas; \ match[top].nopass = match[top-1].nopass; \ + match[top].noexec = match[top-1].noexec; \ top++; \ } while (0) #define pop \ ! do { \ if (top == 0) \ yyerror("matching stack underflow"); \ else \ top--; \ ! } while (0) + /* + * For testing if foo_matches variable was set to TRUE or FALSE + */ + #define MATCHED(_v) ((_v) >= 0) + + /* * Shortcuts for append() */ #define append_cmnd(s, p) append(s, &cm_list[cm_list_len].cmnd, \ *************** *** 182,188 **** /* * Does this Defaults list pertain to this user? */ ! static int defaults_matches = 0; /* * Local protoypes --- 185,191 ---- /* * Does this Defaults list pertain to this user? */ ! static int defaults_matches = FALSE; /* * Local protoypes *************** *** 237,242 **** --- 240,247 ---- %token RUNAS /* ( runas_list ) */ %token NOPASSWD /* no passwd req for command */ %token PASSWD /* passwd req for command (default) */ + %token NOEXEC /* preload dummy execve() for cmnd */ + %token EXEC /* don't preload dummy execve() */ %token ALL /* ALL keyword */ %token COMMENT /* comment and/or carriage return */ %token HOSTALIAS /* Host_Alias keyword */ *************** *** 247,256 **** %token ERROR /* ! * NOTE: these are not true booleans as there are actually 3 possible values: * 1) TRUE (positive match) * 0) FALSE (negative match due to a '!' somewhere) ! * -1) No match (don't change the value of *_matches) */ %type cmnd %type host --- 252,262 ---- %token ERROR /* ! * NOTE: these are not true booleans as there are actually 4 possible values: * 1) TRUE (positive match) * 0) FALSE (negative match due to a '!' somewhere) ! * -1) NOMATCH (don't change the value of *_matches) ! * -2) UNSPEC (uninitialized value) */ %type cmnd %type host *************** *** 364,385 **** * cmndspec so just reset some values so * the next 'privilege' gets a clean slate. */ ! host_matches = -1; ! runas_matches = -1; ! if (def_flag(I_AUTHENTICATE)) ! no_passwd = -1; ! else ! no_passwd = TRUE; } ; ophost : host { ! if ($1 != -1) ! host_matches = $1; } | '!' host { ! if ($2 != -1) ! host_matches = ! $2; } ; --- 370,387 ---- * cmndspec so just reset some values so * the next 'privilege' gets a clean slate. */ ! host_matches = UNSPEC; ! runas_matches = UNSPEC; ! no_passwd = def_authenticate ? UNSPEC : TRUE; ! no_execve = def_noexec ? TRUE : UNSPEC; } ; ophost : host { ! SETMATCH(host_matches, $1); } | '!' host { ! SETNMATCH(host_matches, $2); } ; *************** *** 390,410 **** if (addr_matches($1)) $$ = TRUE; else ! $$ = -1; free($1); } | NETGROUP { if (netgr_matches($1, user_host, user_shost, NULL)) $$ = TRUE; else ! $$ = -1; free($1); } | WORD { if (hostname_matches(user_shost, user_host, $1) == 0) $$ = TRUE; else ! $$ = -1; free($1); } | ALIAS { --- 392,412 ---- if (addr_matches($1)) $$ = TRUE; else ! $$ = NOMATCH; free($1); } | NETGROUP { if (netgr_matches($1, user_host, user_shost, NULL)) $$ = TRUE; else ! $$ = NOMATCH; free($1); } | WORD { if (hostname_matches(user_shost, user_host, $1) == 0) $$ = TRUE; else ! $$ = NOMATCH; free($1); } | ALIAS { *************** *** 425,431 **** YYERROR; } } ! $$ = -1; } free($1); } --- 427,433 ---- YYERROR; } } ! $$ = NOMATCH; } free($1); } *************** *** 435,444 **** | cmndspeclist ',' cmndspec ; ! cmndspec : runasspec nopasswd opcmnd { /* * Push the entry onto the stack if it is worth ! * saving and clear cmnd_matches for next cmnd. * * We need to save at least one entry on * the stack so sudoers_lookup() can tell that --- 437,446 ---- | cmndspeclist ',' cmndspec ; ! cmndspec : runasspec cmndtag opcmnd { /* * Push the entry onto the stack if it is worth ! * saving and reset cmnd_matches for next cmnd. * * We need to save at least one entry on * the stack so sudoers_lookup() can tell that *************** *** 449,470 **** * If keepall is set and the user matches then * we need to keep entries around too... */ ! if (user_matches != -1 && host_matches != -1 && ! cmnd_matches != -1 && runas_matches != -1) pushcp; ! else if (user_matches != -1 && (top == 1 || ! (top == 2 && host_matches != -1 && ! match[0].host == -1))) pushcp; else if (user_matches == TRUE && keepall) pushcp; ! cmnd_matches = -1; } ; opcmnd : cmnd { ! if ($1 != -1) ! cmnd_matches = $1; } | '!' { if (printmatches == TRUE) { --- 451,473 ---- * If keepall is set and the user matches then * we need to keep entries around too... */ ! if (MATCHED(user_matches) && ! MATCHED(host_matches) && ! MATCHED(cmnd_matches) && ! MATCHED(runas_matches)) pushcp; ! else if (MATCHED(user_matches) && (top == 1 || ! (top == 2 && MATCHED(host_matches) && ! !MATCHED(match[0].host)))) pushcp; else if (user_matches == TRUE && keepall) pushcp; ! cmnd_matches = UNSPEC; } ; opcmnd : cmnd { ! SETMATCH(cmnd_matches, $1); } | '!' { if (printmatches == TRUE) { *************** *** 475,489 **** append_cmnd("!", NULL); } } cmnd { ! if ($3 != -1) ! cmnd_matches = ! $3; } ; runasspec : /* empty */ { if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { ! if (runas_matches == -1) { cm_list[cm_list_len].runas_len = 0; } else { /* Inherit runas data. */ --- 478,491 ---- append_cmnd("!", NULL); } } cmnd { ! SETNMATCH(cmnd_matches, $3); } ; runasspec : /* empty */ { if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { ! if (runas_matches == UNSPEC) { cm_list[cm_list_len].runas_len = 0; } else { /* Inherit runas data. */ *************** *** 499,517 **** * If this is the first entry in a command list * then check against default runas user. */ ! if (runas_matches == -1) ! runas_matches = (strcmp(*user_runas, ! def_str(I_RUNAS_DEFAULT)) == 0); } | RUNAS runaslist { ! runas_matches = ($2 == TRUE ? TRUE : FALSE); } ; runaslist : oprunasuser { ; } | runaslist ',' oprunasuser { /* Later entries override earlier ones. */ ! if ($3 != -1) $$ = $3; else $$ = $1; --- 501,521 ---- * If this is the first entry in a command list * then check against default runas user. */ ! if (runas_matches == UNSPEC) { ! runas_matches = ! userpw_matches(def_runas_default, ! *user_runas, runas_pw); ! } } | RUNAS runaslist { ! runas_matches = $2; } ; runaslist : oprunasuser { ; } | runaslist ',' oprunasuser { /* Later entries override earlier ones. */ ! if ($3 != NOMATCH) $$ = $3; else $$ = $1; *************** *** 529,535 **** } } runasuser { /* Set $$ to the negation of runasuser */ ! $$ = ($3 == -1 ? -1 : ! $3); } ; --- 533,539 ---- } } runasuser { /* Set $$ to the negation of runasuser */ ! $$ = ($3 == NOMATCH ? NOMATCH : ! $3); } ; *************** *** 541,551 **** user_matches == TRUE) append_runas($1, ", "); } ! if (strcmp($1, *user_runas) == 0) $$ = TRUE; else ! $$ = -1; free($1); } | USERGROUP { if (printmatches == TRUE) { --- 545,556 ---- user_matches == TRUE) append_runas($1, ", "); } ! if (userpw_matches($1, *user_runas, runas_pw)) $$ = TRUE; else ! $$ = NOMATCH; free($1); + used_runas = TRUE; } | USERGROUP { if (printmatches == TRUE) { *************** *** 555,565 **** user_matches == TRUE) append_runas($1, ", "); } ! if (usergr_matches($1, *user_runas)) $$ = TRUE; else ! $$ = -1; free($1); } | NETGROUP { if (printmatches == TRUE) { --- 560,571 ---- user_matches == TRUE) append_runas($1, ", "); } ! if (usergr_matches($1, *user_runas, runas_pw)) $$ = TRUE; else ! $$ = NOMATCH; free($1); + used_runas = TRUE; } | NETGROUP { if (printmatches == TRUE) { *************** *** 572,579 **** if (netgr_matches($1, NULL, NULL, *user_runas)) $$ = TRUE; else ! $$ = -1; free($1); } | ALIAS { aliasinfo *aip = find_alias($1, RUNAS_ALIAS); --- 578,586 ---- if (netgr_matches($1, NULL, NULL, *user_runas)) $$ = TRUE; else ! $$ = NOMATCH; free($1); + used_runas = TRUE; } | ALIAS { aliasinfo *aip = find_alias($1, RUNAS_ALIAS); *************** *** 600,608 **** YYERROR; } } ! $$ = -1; } free($1); } | ALL { if (printmatches == TRUE) { --- 607,616 ---- YYERROR; } } ! $$ = NOMATCH; } free($1); + used_runas = TRUE; } | ALL { if (printmatches == TRUE) { *************** *** 616,643 **** } ; ! nopasswd : /* empty */ { ! /* Inherit NOPASSWD/PASSWD status. */ if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { if (no_passwd == TRUE) cm_list[cm_list_len].nopasswd = TRUE; else cm_list[cm_list_len].nopasswd = FALSE; } } ! | NOPASSWD { no_passwd = TRUE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = TRUE; } ! | PASSWD { no_passwd = FALSE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = FALSE; } ; cmnd : ALL { --- 624,667 ---- } ; ! cmndtag : /* empty */ { ! /* Inherit {NOPASSWD,PASSWD,NOEXEC,EXEC} status. */ if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) { if (no_passwd == TRUE) cm_list[cm_list_len].nopasswd = TRUE; else cm_list[cm_list_len].nopasswd = FALSE; + if (no_execve == TRUE) + cm_list[cm_list_len].noexecve = TRUE; + else + cm_list[cm_list_len].noexecve = FALSE; } } ! | cmndtag NOPASSWD { no_passwd = TRUE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = TRUE; } ! | cmndtag PASSWD { no_passwd = FALSE; if (printmatches == TRUE && host_matches == TRUE && user_matches == TRUE) cm_list[cm_list_len].nopasswd = FALSE; } + | cmndtag NOEXEC { + no_execve = TRUE; + if (printmatches == TRUE && host_matches == TRUE && + user_matches == TRUE) + cm_list[cm_list_len].noexecve = TRUE; + } + | cmndtag EXEC { + no_execve = FALSE; + if (printmatches == TRUE && host_matches == TRUE && + user_matches == TRUE) + cm_list[cm_list_len].noexecve = FALSE; + } ; cmnd : ALL { *************** *** 682,688 **** YYERROR; } } ! $$ = -1; } free($1); } --- 706,712 ---- YYERROR; } } ! $$ = NOMATCH; } free($1); } *************** *** 702,712 **** } } ! if (command_matches(user_cmnd, user_args, ! $1.cmnd, $1.args)) $$ = TRUE; else ! $$ = -1; free($1.cmnd); if ($1.args) --- 726,735 ---- } } ! if (command_matches($1.cmnd, $1.args)) $$ = TRUE; else ! $$ = NOMATCH; free($1.cmnd); if ($1.args) *************** *** 719,725 **** ; hostalias : ALIAS { push; } '=' hostlist { ! if ((host_matches != -1 || pedantic) && !add_alias($1, HOST_ALIAS, host_matches)) { yyerror(NULL); YYERROR; --- 742,748 ---- ; hostalias : ALIAS { push; } '=' hostlist { ! if ((MATCHED(host_matches) || pedantic) && !add_alias($1, HOST_ALIAS, host_matches)) { yyerror(NULL); YYERROR; *************** *** 746,752 **** ga_list[ga_list_len-1].alias = estrdup($1); } } '=' cmndlist { ! if ((cmnd_matches != -1 || pedantic) && !add_alias($1, CMND_ALIAS, cmnd_matches)) { yyerror(NULL); YYERROR; --- 769,775 ---- ga_list[ga_list_len-1].alias = estrdup($1); } } '=' cmndlist { ! if ((MATCHED(cmnd_matches) || pedantic) && !add_alias($1, CMND_ALIAS, cmnd_matches)) { yyerror(NULL); YYERROR; *************** *** 776,782 **** ga_list[ga_list_len-1].alias = estrdup($1); } } '=' runaslist { ! if (($4 != -1 || pedantic) && !add_alias($1, RUNAS_ALIAS, $4)) { yyerror(NULL); YYERROR; --- 799,805 ---- ga_list[ga_list_len-1].alias = estrdup($1); } } '=' runaslist { ! if (($4 != NOMATCH || pedantic) && !add_alias($1, RUNAS_ALIAS, $4)) { yyerror(NULL); YYERROR; *************** *** 793,799 **** ; useralias : ALIAS { push; } '=' userlist { ! if ((user_matches != -1 || pedantic) && !add_alias($1, USER_ALIAS, user_matches)) { yyerror(NULL); YYERROR; --- 816,822 ---- ; useralias : ALIAS { push; } '=' userlist { ! if ((MATCHED(user_matches) || pedantic) && !add_alias($1, USER_ALIAS, user_matches)) { yyerror(NULL); YYERROR; *************** *** 808,841 **** ; opuser : user { ! if ($1 != -1) ! user_matches = $1; } | '!' user { ! if ($2 != -1) ! user_matches = ! $2; } ; user : WORD { ! if (strcmp($1, user_name) == 0) $$ = TRUE; else ! $$ = -1; free($1); } | USERGROUP { ! if (usergr_matches($1, user_name)) $$ = TRUE; else ! $$ = -1; free($1); } | NETGROUP { if (netgr_matches($1, NULL, NULL, user_name)) $$ = TRUE; else ! $$ = -1; free($1); } | ALIAS { --- 831,862 ---- ; opuser : user { ! SETMATCH(user_matches, $1); } | '!' user { ! SETNMATCH(user_matches, $2); } ; user : WORD { ! if (userpw_matches($1, user_name, sudo_user.pw)) $$ = TRUE; else ! $$ = NOMATCH; free($1); } | USERGROUP { ! if (usergr_matches($1, user_name, sudo_user.pw)) $$ = TRUE; else ! $$ = NOMATCH; free($1); } | NETGROUP { if (netgr_matches($1, NULL, NULL, user_name)) $$ = TRUE; else ! $$ = NOMATCH; free($1); } | ALIAS { *************** *** 856,862 **** YYERROR; } } ! $$ = -1; } free($1); } --- 877,883 ---- YYERROR; } } ! $$ = NOMATCH; } free($1); } *************** *** 1025,1031 **** void list_matches() { ! size_t count; char *p; struct generic_alias *ga, key; --- 1046,1052 ---- void list_matches() { ! size_t count; char *p; struct generic_alias *ga, key; *************** *** 1052,1064 **** } while ((p = strtok(NULL, ", "))); (void) fputs(") ", stdout); } else { ! (void) printf("(%s) ", def_str(I_RUNAS_DEFAULT)); } /* Is a password required? */ ! if (cm_list[count].nopasswd == TRUE && def_flag(I_AUTHENTICATE)) (void) fputs("NOPASSWD: ", stdout); ! else if (cm_list[count].nopasswd == FALSE && !def_flag(I_AUTHENTICATE)) (void) fputs("PASSWD: ", stdout); /* Print the actual command or expanded Cmnd_Alias. */ --- 1073,1091 ---- } while ((p = strtok(NULL, ", "))); (void) fputs(") ", stdout); } else { ! (void) printf("(%s) ", def_runas_default); } + /* Is execve(2) disabled? */ + if (cm_list[count].noexecve == TRUE && !def_noexec) + (void) fputs("NOEXEC: ", stdout); + else if (cm_list[count].noexecve == FALSE && def_noexec) + (void) fputs("EXEC: ", stdout); + /* Is a password required? */ ! if (cm_list[count].nopasswd == TRUE && def_authenticate) (void) fputs("NOPASSWD: ", stdout); ! else if (cm_list[count].nopasswd == FALSE && !def_authenticate) (void) fputs("PASSWD: ", stdout); /* Print the actual command or expanded Cmnd_Alias. */ *************** *** 1187,1192 **** --- 1214,1220 ---- cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL; cm_list[cm_list_len].nopasswd = FALSE; + cm_list[cm_list_len].noexecve = FALSE; } /* *************** *** 1203,1210 **** match = NULL; top = 0; parse_error = FALSE; ! errorlineno = -1; ! sudolineno = 1; } /* Allocate space for the matching stack. */ --- 1231,1239 ---- match = NULL; top = 0; parse_error = FALSE; ! used_runas = FALSE; ! errorlineno = -1; ! sudolineno = 1; } /* Allocate space for the matching stack. */