efb314f70b5568d1509441a17d6f1f9db209645e
[debian/sudo] / sudo.tab.c
1 #ifndef lint
2 /*static char yysccsid[] = "from: @(#)yaccpar   1.9 (Berkeley) 02/21/93";*/
3 static char yyrcsid[]
4 #if __GNUC__ >= 2
5   __attribute__ ((unused))
6 #endif /* __GNUC__ >= 2 */
7   = "$OpenBSD: skeleton.c,v 1.28 2007/09/03 21:14:58 deraadt Exp $";
8 #endif
9 #include <stdlib.h>
10 #define YYBYACC 1
11 #define YYMAJOR 1
12 #define YYMINOR 9
13 #define YYLEX yylex()
14 #define YYEMPTY -1
15 #define yyclearin (yychar=(YYEMPTY))
16 #define yyerrok (yyerrflag=0)
17 #define YYRECOVERING() (yyerrflag!=0)
18 #define YYPREFIX "yy"
19 #line 2 "parse.yacc"
20 /*
21  * Copyright (c) 1996, 1998-2004, 2007
22  *      Todd C. Miller <Todd.Miller@courtesan.com>
23  *
24  * Permission to use, copy, modify, and distribute this software for any
25  * purpose with or without fee is hereby granted, provided that the above
26  * copyright notice and this permission notice appear in all copies.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
29  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
30  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
31  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
32  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
33  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
34  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37  *
38  * Sponsored in part by the Defense Advanced Research Projects
39  * Agency (DARPA) and Air Force Research Laboratory, Air Force
40  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
41  */
42
43 /*
44  * XXX - the whole opFOO naming thing is somewhat bogus.
45  *
46  * XXX - the way things are stored for printmatches is stupid,
47  *       they should be stored as elements in an array and then
48  *       list_matches() can format things the way it wants.
49  */
50
51 #include <config.h>
52
53 #include <sys/types.h>
54 #include <sys/param.h>
55 #include <stdio.h>
56 #ifdef STDC_HEADERS
57 # include <stdlib.h>
58 # include <stddef.h>
59 #else
60 # ifdef HAVE_STDLIB_H
61 #  include <stdlib.h>
62 # endif
63 #endif /* STDC_HEADERS */
64 #ifdef HAVE_STRING_H
65 # include <string.h>
66 #else
67 # ifdef HAVE_STRINGS_H
68 #  include <strings.h>
69 # endif
70 #endif /* HAVE_STRING_H */
71 #ifdef HAVE_UNISTD_H
72 # include <unistd.h>
73 #endif /* HAVE_UNISTD_H */
74 #include <pwd.h>
75 #if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
76 # include <alloca.h>
77 #endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
78 #ifdef HAVE_LSEARCH
79 # include <search.h>
80 #endif /* HAVE_LSEARCH */
81
82 #include "sudo.h"
83 #include "parse.h"
84
85 #ifndef HAVE_LSEARCH
86 #include "emul/search.h"
87 #endif /* HAVE_LSEARCH */
88
89 #ifndef lint
90 __unused static const char rcsid[] = "$Sudo: sudo.tab.c,v 1.76.2.8 2007/11/21 18:15:49 millert Exp $";
91 #endif /* lint */
92
93 /*
94  * Globals
95  */
96 extern int sudolineno, parse_error;
97 int errorlineno = -1;
98 int clearaliases = TRUE;
99 int printmatches = FALSE;
100 int pedantic = FALSE;
101 int keepall = FALSE;
102 int quiet = FALSE;
103 int used_runas = FALSE;
104
105 /*
106  * Alias types
107  */
108 #define HOST_ALIAS               1
109 #define CMND_ALIAS               2
110 #define USER_ALIAS               3
111 #define RUNAS_ALIAS              4
112
113 #define SETMATCH(_var, _val)    do { \
114         if ((_var) == UNSPEC || (_val) != NOMATCH) \
115             (_var) = (_val); \
116 } while (0)
117
118 #define SETNMATCH(_var, _val)   do { \
119         if ((_val) != NOMATCH) \
120             (_var) = ! (_val); \
121         else if ((_var) == UNSPEC) \
122             (_var) = NOMATCH; \
123 } while (0)
124
125 #define SETENV_RESET \
126         if (setenv_ok == IMPLIED) setenv_ok = def_setenv ? TRUE : UNSPEC
127
128 /*
129  * The matching stack, initial space allocated in init_parser().
130  */
131 struct matchstack *match;
132 int top = 0, stacksize = 0;
133
134 #define push \
135     do { \
136         if (top >= stacksize) { \
137             while ((stacksize += STACKINCREMENT) < top); \
138             match = (struct matchstack *) erealloc3(match, stacksize, sizeof(struct matchstack)); \
139         } \
140         match[top].user   = UNSPEC; \
141         match[top].cmnd   = UNSPEC; \
142         match[top].host   = UNSPEC; \
143         match[top].runas  = UNSPEC; \
144         match[top].nopass = def_authenticate ? UNSPEC : TRUE; \
145         match[top].noexec = def_noexec ? TRUE : UNSPEC; \
146         match[top].setenv = def_setenv ? TRUE : UNSPEC; \
147         top++; \
148     } while (0)
149
150 #define pushcp \
151     do { \
152         if (top >= stacksize) { \
153             while ((stacksize += STACKINCREMENT) < top); \
154             match = (struct matchstack *) erealloc3(match, stacksize, sizeof(struct matchstack)); \
155         } \
156         match[top].user   = match[top-1].user; \
157         match[top].cmnd   = match[top-1].cmnd; \
158         match[top].host   = match[top-1].host; \
159         match[top].runas  = match[top-1].runas; \
160         match[top].nopass = match[top-1].nopass; \
161         match[top].noexec = match[top-1].noexec; \
162         match[top].setenv = match[top-1].setenv; \
163         top++; \
164     } while (0)
165
166 #define pop \
167     do { \
168         if (top == 0) \
169             yyerror("matching stack underflow"); \
170         else \
171             top--; \
172     } while (0)
173
174
175 /*
176  * For testing if foo_matches variable was set to TRUE or FALSE
177  */
178 #define MATCHED(_v)     ((_v) >= 0)
179
180 /*
181  * Shortcuts for append()
182  */
183 #define append_cmnd(s, p) append(s, &cm_list[cm_list_len].cmnd, \
184         &cm_list[cm_list_len].cmnd_len, &cm_list[cm_list_len].cmnd_size, p)
185
186 #define append_runas(s, p) append(s, &cm_list[cm_list_len].runas, \
187         &cm_list[cm_list_len].runas_len, &cm_list[cm_list_len].runas_size, p)
188
189 #define append_entries(s, p) append(s, &ga_list[ga_list_len-1].entries, \
190         &ga_list[ga_list_len-1].entries_len, \
191         &ga_list[ga_list_len-1].entries_size, p)
192
193 /*
194  * The stack for printmatches.  A list of allowed commands for the user.
195  */
196 static struct command_match *cm_list = NULL;
197 static size_t cm_list_len = 0, cm_list_size = 0;
198
199 /*
200  * List of Cmnd_Aliases and expansions for `sudo -l'
201  */
202 static int in_alias = FALSE;
203 static size_t ga_list_len = 0, ga_list_size = 0;
204 static struct generic_alias *ga_list = NULL;
205
206 /*
207  * Does this Defaults list pertain to this user?
208  */
209 static int defaults_matches = FALSE;
210
211 /*
212  * Local protoypes
213  */
214 static int  add_alias           __P((char *, int, int));
215 static void append              __P((char *, char **, size_t *, size_t *, char *));
216 static void expand_ga_list      __P((void));
217 static void expand_match_list   __P((void));
218 static aliasinfo *find_alias    __P((char *, int));
219 static void more_aliases        __P((void));
220        void init_parser         __P((void));
221        void yyerror             __P((char *));
222
223 void
224 yyerror(s)
225     char *s;
226 {
227     /* Save the line the first error occurred on. */
228     if (errorlineno == -1)
229         errorlineno = sudolineno ? sudolineno - 1 : 0;
230     if (s && !quiet) {
231 #ifndef TRACELEXER
232         (void) fprintf(stderr, ">>> sudoers file: %s, line %d <<<\n", s,
233             sudolineno ? sudolineno - 1 : 0);
234 #else
235         (void) fprintf(stderr, "<*> ");
236 #endif
237     }
238     parse_error = TRUE;
239 }
240 #line 224 "parse.yacc"
241 #ifndef YYSTYPE_DEFINED
242 #define YYSTYPE_DEFINED
243 typedef union {
244     char *string;
245     int BOOLEAN;
246     struct sudo_command command;
247     int tok;
248 } YYSTYPE;
249 #endif /* YYSTYPE_DEFINED */
250 #line 251 "sudo.tab.c"
251 #define COMMAND 257
252 #define ALIAS 258
253 #define DEFVAR 259
254 #define NTWKADDR 260
255 #define NETGROUP 261
256 #define USERGROUP 262
257 #define WORD 263
258 #define DEFAULTS 264
259 #define DEFAULTS_HOST 265
260 #define DEFAULTS_USER 266
261 #define DEFAULTS_RUNAS 267
262 #define RUNAS 268
263 #define NOPASSWD 269
264 #define PASSWD 270
265 #define NOEXEC 271
266 #define EXEC 272
267 #define SETENV 273
268 #define NOSETENV 274
269 #define ALL 275
270 #define COMMENT 276
271 #define HOSTALIAS 277
272 #define CMNDALIAS 278
273 #define USERALIAS 279
274 #define RUNASALIAS 280
275 #define ERROR 281
276 #define YYERRCODE 256
277 #if defined(__cplusplus) || defined(__STDC__)
278 const short yylhs[] =
279 #else
280 short yylhs[] =
281 #endif
282         {                                        -1,
283     0,    0,    7,    7,    9,    7,    7,    7,    7,    7,
284     7,   15,   16,   18,   16,   19,   16,   21,   16,   17,
285    17,   22,   22,   22,   22,   22,   10,   10,   23,   25,
286    25,    2,    2,    2,    2,    2,   24,   24,   28,   26,
287    30,   31,   30,   27,   27,    5,    5,    4,   32,    4,
288     3,    3,    3,    3,    3,   29,   29,   29,   29,   29,
289    29,   29,    1,    1,    1,   12,   12,   34,   33,   20,
290    20,   13,   13,   36,   35,   37,   37,   14,   14,   39,
291    38,   11,   11,   41,   40,    8,    8,   42,   42,    6,
292     6,    6,    6,    6,
293 };
294 #if defined(__cplusplus) || defined(__STDC__)
295 const short yylen[] =
296 #else
297 short yylen[] =
298 #endif
299         {                                         2,
300     1,    2,    1,    2,    0,    3,    2,    2,    2,    2,
301     1,    2,    1,    0,    3,    0,    3,    0,    3,    1,
302     3,    1,    2,    3,    3,    3,    1,    3,    3,    1,
303     2,    1,    1,    1,    1,    1,    1,    3,    0,    4,
304     1,    0,    3,    0,    2,    1,    3,    1,    0,    3,
305     1,    1,    1,    1,    1,    0,    2,    2,    2,    2,
306     2,    2,    1,    1,    1,    1,    3,    0,    4,    1,
307     3,    1,    3,    0,    4,    1,    3,    1,    3,    0,
308     4,    1,    3,    0,    4,    1,    3,    1,    2,    1,
309     1,    1,    1,    1,
310 };
311 #if defined(__cplusplus) || defined(__STDC__)
312 const short yydefred[] =
313 #else
314 short yydefred[] =
315 #endif
316         {                                      0,
317     0,   13,   18,   14,   16,    3,    0,    0,    0,    0,
318     0,    1,    0,   11,    0,    4,    0,    0,    0,   68,
319     0,   66,   74,    0,   72,   84,    0,   82,   80,    0,
320    78,    2,   93,   92,   91,   90,   94,    0,   88,    0,
321    86,    0,    0,   12,    0,   36,   33,   34,   35,   32,
322     0,   30,    0,   70,    0,   54,   53,   52,   51,   55,
323    49,   48,   46,    0,    0,    0,    0,    0,    0,    0,
324     0,    0,   89,    0,    0,    0,   27,    0,    0,    0,
325    23,    0,   31,    0,    0,    0,    0,   67,    0,   73,
326     0,   83,    0,   79,   87,    0,   39,   24,   25,   26,
327    21,   71,   50,   47,    0,   65,   64,   63,   42,   41,
328    76,    0,    0,    0,   28,    0,   37,    0,    0,    0,
329    39,    0,   56,   43,   77,   38,    0,    0,   57,   58,
330    59,   60,   61,   62,   40,
331 };
332 #if defined(__cplusplus) || defined(__STDC__)
333 const short yydgoto[] =
334 #else
335 short yydgoto[] =
336 #endif
337         {                                      11,
338   110,   52,   62,   63,   64,   39,   12,   40,   13,   75,
339    27,   21,   24,   30,   14,   15,   44,   18,   19,   76,
340    17,   45,   77,  116,   54,  117,  123,  118,  128,  111,
341   119,   85,   22,   65,   25,   67,  112,   31,   71,   28,
342    69,   41,
343 };
344 #if defined(__cplusplus) || defined(__STDC__)
345 const short yysindex[] =
346 #else
347 short yysindex[] =
348 #endif
349         {                                   -223,
350  -256,    0,    0,    0,    0,    0, -237, -234, -231, -226,
351  -223,    0,   62,    0,  -33,    0,   88,   62,  114,    0,
352   -22,    0,    0,  -21,    0,    0,  -19,    0,    0,  -18,
353     0,    0,    0,    0,    0,    0,    0, -244,    0,  -28,
354     0,  -36, -221,    0,    3,    0,    0,    0,    0,    0,
355  -212,    0,    6,    0,   14,    0,    0,    0,    0,    0,
356     0,    0,    0,   16,    7, -237,    8, -234,    9, -231,
357    10, -226,    0,   62,   18,  -32,    0, -202, -199, -191,
358     0,  -33,    0,   88, -196,  114,   88,    0,  276,    0,
359    62,    0,  114,    0,    0,   88,    0,    0,    0,    0,
360     0,    0,    0,    0,    6,    0,    0,    0,    0,    0,
361     0,   30,   14,   16,    0,   33,    0, -188, -247,  276,
362     0,  114,    0,    0,    0,    0,   16,  -29,    0,    0,
363     0,    0,    0,    0,    0,};
364 #if defined(__cplusplus) || defined(__STDC__)
365 const short yyrindex[] =
366 #else
367 short yyrindex[] =
368 #endif
369         {                                    140,
370     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
371   140,    0,    0,    0,    0,    0,    0,    0,    0,    0,
372   156,    0,    0,  181,    0,    0,  206,    0,    0,  236,
373     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
374     0,    1,    0,    0,  261,    0,    0,    0,    0,    0,
375     0,    0,  -25,    0,  -11,    0,    0,    0,    0,    0,
376     0,    0,    0,   -3,    0,    0,    0,    0,    0,    0,
377     0,    0,    0,    0,  300,    0,    0,    0,    0,    0,
378     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
379     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
380     0,    0,    0,    0,   26,    0,    0,    0,    0,    0,
381     0,   52,   78,  104,    0,  130,    0,  -20,    0,    0,
382     0,    0,    0,    0,    0,    0,  274,    0,    0,    0,
383     0,    0,    0,    0,    0,};
384 #if defined(__cplusplus) || defined(__STDC__)
385 const short yygindex[] =
386 #else
387 short yygindex[] =
388 #endif
389         {                                      0,
390   -38,   31,   -2,    2,  -87,   48,   76,  -16,    0,    0,
391     0,    0,    0,    0,    0,    0,   11,    0,    0,  -14,
392     0,    0,   -7,    0,   12,  -31,    0,    0,    0, -105,
393     0,    0,   25,    0,   24,    0,    0,   22,    0,   27,
394     0,   28,
395 };
396 #define YYTABLESIZE 580
397 #if defined(__cplusplus) || defined(__STDC__)
398 const short yytable[] =
399 #else
400 short yytable[] =
401 #endif
402         {                                      43,
403    22,   55,   53,  109,   51,  114,   79,   19,   80,  106,
404   107,   84,   44,   33,  125,   74,   34,   35,   36,   16,
405    20,   15,  135,   23,   78,   69,   26,  108,   97,   17,
406    37,   29,    1,   22,  127,   66,   68,   81,   70,   72,
407     2,    3,    4,    5,   22,   46,   82,   47,   48,   84,
408    49,   75,    6,    7,    8,    9,   10,   74,   69,   86,
409    98,   56,   50,   99,   57,   58,   59,   87,   89,   91,
410    93,  100,  105,  120,  113,   96,  121,   85,   60,  122,
411   124,   83,  103,   69,   75,   73,   32,  104,  115,  126,
412    88,   90,  101,   94,   38,  102,   92,    0,    0,    0,
413     0,   95,    0,   81,    0,    0,    0,    0,    0,   75,
414    85,    0,    0,    0,    0,    0,    0,    0,    0,    0,
415    51,    0,    0,    0,    0,    0,    0,    0,    0,   29,
416     0,    0,    0,    0,    0,   85,   81,    0,    0,    0,
417     0,    0,    0,    0,    0,    0,   61,    0,    0,    0,
418     0,    0,    0,    0,    0,    8,    0,    0,    0,    0,
419     0,   81,   29,    0,    0,    0,    0,    0,    0,    0,
420     0,    0,    5,    0,    0,    0,    0,    0,    0,    0,
421     9,    0,    0,    0,    0,    0,    0,   29,    8,    0,
422     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
423     0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
424     0,    0,    0,    9,    0,    0,    0,    0,    0,    0,
425     0,    0,    0,    0,    0,   42,    0,  106,  107,   46,
426     0,   47,   48,   19,   49,   10,   44,   44,    7,  129,
427   130,  131,  132,  133,  134,  108,   50,   15,   44,   44,
428    44,   44,   44,   44,   44,   17,   22,    0,   22,    0,
429    20,   22,   22,   22,   22,   22,   22,   22,   10,    0,
430     0,    0,    0,    0,    0,   22,   22,   22,   22,   22,
431    22,   69,    0,   69,    0,    0,   69,   69,   69,   69,
432    69,   69,   69,   20,    0,    0,    0,    0,    0,    6,
433    69,   69,   69,   69,   69,   69,   45,   75,  109,   75,
434     0,    0,   75,   75,   75,   75,   75,   75,   75,   33,
435     0,    0,   34,   35,   36,    0,   75,   75,   75,   75,
436    75,   75,    6,   85,    0,   85,   37,    0,   85,   85,
437    85,   85,   85,   85,   85,   46,    0,   47,   48,    0,
438    49,    0,   85,   85,   85,   85,   85,   85,    0,   81,
439     0,   81,   50,    0,   81,   81,   81,   81,   81,   81,
440    81,   56,    0,    0,   57,   58,   59,    0,   81,   81,
441    81,   81,   81,   81,    0,   29,    0,   29,   60,    0,
442    29,   29,   29,   29,   29,   29,   29,    5,    0,    0,
443     5,    5,    5,    0,   29,   29,   29,   29,   29,   29,
444     0,    8,    0,    8,    5,    0,    8,    8,    8,    8,
445     8,    8,    8,    0,    0,    0,    0,    0,    0,    0,
446     8,    8,    8,    8,    8,    8,    9,    0,    9,    0,
447     0,    9,    9,    9,    9,    9,    9,    9,    0,    0,
448     0,    0,    0,    0,    0,    9,    9,    9,    9,    9,
449     9,    7,    0,    7,    0,    0,    7,    7,    7,    7,
450     7,    7,    7,    0,    0,    0,    0,    0,    0,    0,
451     7,    7,    7,    7,    7,    7,    0,    0,    0,    0,
452     0,   10,    0,   10,    0,    0,   10,   10,   10,   10,
453    10,   10,   10,    0,    0,    0,    0,    0,    0,    0,
454    10,   10,   10,   10,   10,   10,   20,    0,   20,    0,
455     0,   20,   20,   20,   20,   20,   20,   20,    0,    0,
456    45,   45,  106,  107,    0,   20,   20,   20,   20,   20,
457    20,    0,   45,   45,   45,   45,   45,   45,   45,    0,
458   108,    0,    0,    0,    0,    6,    0,    6,    0,    0,
459     6,    6,    6,    6,    6,    6,    6,    0,    0,    0,
460     0,    0,    0,    0,    6,    6,    6,    6,    6,    6,
461 };
462 #if defined(__cplusplus) || defined(__STDC__)
463 const short yycheck[] =
464 #else
465 short yycheck[] =
466 #endif
467         {                                      33,
468     0,   18,   17,   33,   33,   93,   43,   33,   45,  257,
469   258,   44,   33,  258,  120,   44,  261,  262,  263,  276,
470   258,   33,  128,  258,   61,    0,  258,  275,   61,   33,
471   275,  258,  256,   33,  122,   58,   58,  259,   58,   58,
472   264,  265,  266,  267,   44,  258,   44,  260,  261,   44,
473   263,    0,  276,  277,  278,  279,  280,   44,   33,   44,
474   263,  258,  275,  263,  261,  262,  263,   61,   61,   61,
475    61,  263,   87,   44,   91,   58,   44,    0,  275,  268,
476   119,   51,   85,   58,   33,   38,   11,   86,   96,  121,
477    66,   68,   82,   72,   33,   84,   70,   -1,   -1,   -1,
478    -1,   74,   -1,    0,   -1,   -1,   -1,   -1,   -1,   58,
479    33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
480    33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,
481    -1,   -1,   -1,   -1,   -1,   58,   33,   -1,   -1,   -1,
482    -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,   -1,
483    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
484    -1,   58,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
485    -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
486     0,   -1,   -1,   -1,   -1,   -1,   -1,   58,   33,   -1,
487    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
488    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
489    -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
490    -1,   -1,   -1,   -1,   -1,  259,   -1,  257,  258,  258,
491    -1,  260,  261,  259,  263,    0,  257,  258,   33,  269,
492   270,  271,  272,  273,  274,  275,  275,  259,  269,  270,
493   271,  272,  273,  274,  275,  259,  256,   -1,  258,   -1,
494     0,  261,  262,  263,  264,  265,  266,  267,   33,   -1,
495    -1,   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,
496   280,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
497   265,  266,  267,   33,   -1,   -1,   -1,   -1,   -1,    0,
498   275,  276,  277,  278,  279,  280,   33,  256,   33,  258,
499    -1,   -1,  261,  262,  263,  264,  265,  266,  267,  258,
500    -1,   -1,  261,  262,  263,   -1,  275,  276,  277,  278,
501   279,  280,   33,  256,   -1,  258,  275,   -1,  261,  262,
502   263,  264,  265,  266,  267,  258,   -1,  260,  261,   -1,
503   263,   -1,  275,  276,  277,  278,  279,  280,   -1,  256,
504    -1,  258,  275,   -1,  261,  262,  263,  264,  265,  266,
505   267,  258,   -1,   -1,  261,  262,  263,   -1,  275,  276,
506   277,  278,  279,  280,   -1,  256,   -1,  258,  275,   -1,
507   261,  262,  263,  264,  265,  266,  267,  258,   -1,   -1,
508   261,  262,  263,   -1,  275,  276,  277,  278,  279,  280,
509    -1,  256,   -1,  258,  275,   -1,  261,  262,  263,  264,
510   265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
511   275,  276,  277,  278,  279,  280,  256,   -1,  258,   -1,
512    -1,  261,  262,  263,  264,  265,  266,  267,   -1,   -1,
513    -1,   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,
514   280,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
515   265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
516   275,  276,  277,  278,  279,  280,   -1,   -1,   -1,   -1,
517    -1,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
518   265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
519   275,  276,  277,  278,  279,  280,  256,   -1,  258,   -1,
520    -1,  261,  262,  263,  264,  265,  266,  267,   -1,   -1,
521   257,  258,  257,  258,   -1,  275,  276,  277,  278,  279,
522   280,   -1,  269,  270,  271,  272,  273,  274,  275,   -1,
523   275,   -1,   -1,   -1,   -1,  256,   -1,  258,   -1,   -1,
524   261,  262,  263,  264,  265,  266,  267,   -1,   -1,   -1,
525    -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,  280,
526 };
527 #define YYFINAL 11
528 #ifndef YYDEBUG
529 #define YYDEBUG 0
530 #endif
531 #define YYMAXTOKEN 281
532 #if YYDEBUG
533 #if defined(__cplusplus) || defined(__STDC__)
534 const char * const yyname[] =
535 #else
536 char *yyname[] =
537 #endif
538         {
539 "end-of-file",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,
540 "'!'",0,0,0,0,0,0,0,0,0,"'+'","','","'-'",0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0,
541 "'='",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,0,0,0,0,
542 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,0,0,0,0,0,0,0,
543 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,0,0,0,0,0,0,0,
544 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,0,0,0,0,0,0,0,
545 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,0,0,0,0,0,
546 "COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS",
547 "DEFAULTS_HOST","DEFAULTS_USER","DEFAULTS_RUNAS","RUNAS","NOPASSWD","PASSWD",
548 "NOEXEC","EXEC","SETENV","NOSETENV","ALL","COMMENT","HOSTALIAS","CMNDALIAS",
549 "USERALIAS","RUNASALIAS","ERROR",
550 };
551 #if defined(__cplusplus) || defined(__STDC__)
552 const char * const yyrule[] =
553 #else
554 char *yyrule[] =
555 #endif
556         {"$accept : file",
557 "file : entry",
558 "file : file entry",
559 "entry : COMMENT",
560 "entry : error COMMENT",
561 "$$1 :",
562 "entry : $$1 userlist privileges",
563 "entry : USERALIAS useraliases",
564 "entry : HOSTALIAS hostaliases",
565 "entry : CMNDALIAS cmndaliases",
566 "entry : RUNASALIAS runasaliases",
567 "entry : defaults_line",
568 "defaults_line : defaults_type defaults_list",
569 "defaults_type : DEFAULTS",
570 "$$2 :",
571 "defaults_type : DEFAULTS_USER $$2 userlist",
572 "$$3 :",
573 "defaults_type : DEFAULTS_RUNAS $$3 runaslist",
574 "$$4 :",
575 "defaults_type : DEFAULTS_HOST $$4 hostlist",
576 "defaults_list : defaults_entry",
577 "defaults_list : defaults_entry ',' defaults_list",
578 "defaults_entry : DEFVAR",
579 "defaults_entry : '!' DEFVAR",
580 "defaults_entry : DEFVAR '=' WORD",
581 "defaults_entry : DEFVAR '+' WORD",
582 "defaults_entry : DEFVAR '-' WORD",
583 "privileges : privilege",
584 "privileges : privileges ':' privilege",
585 "privilege : hostlist '=' cmndspeclist",
586 "ophost : host",
587 "ophost : '!' host",
588 "host : ALL",
589 "host : NTWKADDR",
590 "host : NETGROUP",
591 "host : WORD",
592 "host : ALIAS",
593 "cmndspeclist : cmndspec",
594 "cmndspeclist : cmndspeclist ',' cmndspec",
595 "$$5 :",
596 "cmndspec : $$5 runasspec cmndtag opcmnd",
597 "opcmnd : cmnd",
598 "$$6 :",
599 "opcmnd : '!' $$6 cmnd",
600 "runasspec :",
601 "runasspec : RUNAS runaslist",
602 "runaslist : oprunasuser",
603 "runaslist : runaslist ',' oprunasuser",
604 "oprunasuser : runasuser",
605 "$$7 :",
606 "oprunasuser : '!' $$7 runasuser",
607 "runasuser : WORD",
608 "runasuser : USERGROUP",
609 "runasuser : NETGROUP",
610 "runasuser : ALIAS",
611 "runasuser : ALL",
612 "cmndtag :",
613 "cmndtag : cmndtag NOPASSWD",
614 "cmndtag : cmndtag PASSWD",
615 "cmndtag : cmndtag NOEXEC",
616 "cmndtag : cmndtag EXEC",
617 "cmndtag : cmndtag SETENV",
618 "cmndtag : cmndtag NOSETENV",
619 "cmnd : ALL",
620 "cmnd : ALIAS",
621 "cmnd : COMMAND",
622 "hostaliases : hostalias",
623 "hostaliases : hostaliases ':' hostalias",
624 "$$8 :",
625 "hostalias : ALIAS $$8 '=' hostlist",
626 "hostlist : ophost",
627 "hostlist : hostlist ',' ophost",
628 "cmndaliases : cmndalias",
629 "cmndaliases : cmndaliases ':' cmndalias",
630 "$$9 :",
631 "cmndalias : ALIAS $$9 '=' cmndlist",
632 "cmndlist : opcmnd",
633 "cmndlist : cmndlist ',' opcmnd",
634 "runasaliases : runasalias",
635 "runasaliases : runasaliases ':' runasalias",
636 "$$10 :",
637 "runasalias : ALIAS $$10 '=' runaslist",
638 "useraliases : useralias",
639 "useraliases : useraliases ':' useralias",
640 "$$11 :",
641 "useralias : ALIAS $$11 '=' userlist",
642 "userlist : opuser",
643 "userlist : userlist ',' opuser",
644 "opuser : user",
645 "opuser : '!' user",
646 "user : WORD",
647 "user : USERGROUP",
648 "user : NETGROUP",
649 "user : ALIAS",
650 "user : ALL",
651 };
652 #endif
653 #ifdef YYSTACKSIZE
654 #undef YYMAXDEPTH
655 #define YYMAXDEPTH YYSTACKSIZE
656 #else
657 #ifdef YYMAXDEPTH
658 #define YYSTACKSIZE YYMAXDEPTH
659 #else
660 #define YYSTACKSIZE 10000
661 #define YYMAXDEPTH 10000
662 #endif
663 #endif
664 #define YYINITSTACKSIZE 200
665 /* LINTUSED */
666 int yydebug;
667 int yynerrs;
668 int yyerrflag;
669 int yychar;
670 short *yyssp;
671 YYSTYPE *yyvsp;
672 YYSTYPE yyval;
673 YYSTYPE yylval;
674 short *yyss;
675 short *yysslim;
676 YYSTYPE *yyvs;
677 int yystacksize;
678 #line 911 "parse.yacc"
679
680 #define MOREALIASES (32)
681 aliasinfo *aliases = NULL;
682 size_t naliases = 0;
683 size_t nslots = 0;
684
685
686 /*
687  * Compare two aliasinfo structures, strcmp() style.
688  * Note that we do *not* compare their values.
689  */
690 static int
691 aliascmp(a1, a2)
692     const VOID *a1, *a2;
693 {
694     int r;
695     aliasinfo *ai1, *ai2;
696
697     ai1 = (aliasinfo *) a1;
698     ai2 = (aliasinfo *) a2;
699     if ((r = strcmp(ai1->name, ai2->name)) == 0)
700         r = ai1->type - ai2->type;
701
702     return(r);
703 }
704
705 /*
706  * Compare two generic_alias structures, strcmp() style.
707  */
708 static int
709 genaliascmp(entry, key)
710     const VOID *entry, *key;
711 {
712     int r;
713     struct generic_alias *ga1, *ga2;
714
715     ga1 = (struct generic_alias *) key;
716     ga2 = (struct generic_alias *) entry;
717     if ((r = strcmp(ga1->alias, ga2->alias)) == 0)
718         r = ga1->type - ga2->type;
719
720     return(r);
721 }
722
723
724 /*
725  * Adds the named alias of the specified type to the aliases list.
726  */
727 static int
728 add_alias(alias, type, val)
729     char *alias;
730     int type;
731     int val;
732 {
733     aliasinfo ai, *aip;
734     size_t onaliases;
735     char s[512];
736
737     if (naliases >= nslots)
738         more_aliases();
739
740     ai.type = type;
741     ai.val = val;
742     ai.name = estrdup(alias);
743     onaliases = naliases;
744
745     aip = (aliasinfo *) lsearch((VOID *)&ai, (VOID *)aliases, &naliases,
746                                 sizeof(ai), aliascmp);
747     if (aip == NULL) {
748         (void) snprintf(s, sizeof(s), "Aliases corrupted defining alias `%s'",
749                         alias);
750         yyerror(s);
751         return(FALSE);
752     }
753     if (onaliases == naliases) {
754         (void) snprintf(s, sizeof(s), "Alias `%s' already defined", alias);
755         yyerror(s);
756         return(FALSE);
757     }
758
759     return(TRUE);
760 }
761
762 /*
763  * Searches for the named alias of the specified type.
764  */
765 static aliasinfo *
766 find_alias(alias, type)
767     char *alias;
768     int type;
769 {
770     aliasinfo ai;
771
772     ai.name = alias;
773     ai.type = type;
774
775     return((aliasinfo *) lfind((VOID *)&ai, (VOID *)aliases, &naliases,
776                  sizeof(ai), aliascmp));
777 }
778
779 /*
780  * Allocates more space for the aliases list.
781  */
782 static void
783 more_aliases()
784 {
785
786     nslots += MOREALIASES;
787     aliases = (aliasinfo *) erealloc3(aliases, nslots, sizeof(aliasinfo));
788 }
789
790 /*
791  * Lists the contents of the aliases list.
792  */
793 void
794 dumpaliases()
795 {
796     size_t n;
797
798     for (n = 0; n < naliases; n++) {
799         if (aliases[n].val == -1)
800             continue;
801
802         switch (aliases[n].type) {
803         case HOST_ALIAS:
804             (void) puts("HOST_ALIAS");
805             break;
806
807         case CMND_ALIAS:
808             (void) puts("CMND_ALIAS");
809             break;
810
811         case USER_ALIAS:
812             (void) puts("USER_ALIAS");
813             break;
814
815         case RUNAS_ALIAS:
816             (void) puts("RUNAS_ALIAS");
817             break;
818         }
819         (void) printf("\t%s: %d\n", aliases[n].name, aliases[n].val);
820     }
821 }
822
823 /*
824  * Lists the contents of cm_list and ga_list for `sudo -l'.
825  */
826 void
827 list_matches()
828 {
829     size_t count;
830     char *p;
831     struct generic_alias *ga, key;
832
833     (void) printf("User %s may run the following commands on this host:\n",
834         user_name);
835     for (count = 0; count < cm_list_len; count++) {
836
837         /* Print the runas list. */
838         (void) fputs("    ", stdout);
839         if (cm_list[count].runas) {
840             (void) putchar('(');
841             p = strtok(cm_list[count].runas, ", ");
842             do {
843                 if (p != cm_list[count].runas)
844                     (void) fputs(", ", stdout);
845
846                 key.alias = p;
847                 key.type = RUNAS_ALIAS;
848                 if ((ga = (struct generic_alias *) lfind((VOID *) &key,
849                     (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
850                     (void) fputs(ga->entries, stdout);
851                 else
852                     (void) fputs(p, stdout);
853             } while ((p = strtok(NULL, ", ")));
854             (void) fputs(") ", stdout);
855         } else {
856             (void) printf("(%s) ", def_runas_default);
857         }
858
859         /* Is execve(2) disabled? */
860         if (cm_list[count].noexecve == TRUE && !def_noexec)
861             (void) fputs("NOEXEC: ", stdout);
862         else if (cm_list[count].noexecve == FALSE && def_noexec)
863             (void) fputs("EXEC: ", stdout);
864
865         /* Is a password required? */
866         if (cm_list[count].nopasswd == TRUE && def_authenticate)
867             (void) fputs("NOPASSWD: ", stdout);
868         else if (cm_list[count].nopasswd == FALSE && !def_authenticate)
869             (void) fputs("PASSWD: ", stdout);
870
871         /* Is setenv enabled? */
872         if (cm_list[count].setenv == TRUE && !def_setenv)
873             (void) fputs("SETENV: ", stdout);
874         else if (cm_list[count].setenv == FALSE && def_setenv)
875             (void) fputs("NOSETENV: ", stdout);
876
877         /* Print the actual command or expanded Cmnd_Alias. */
878         key.alias = cm_list[count].cmnd;
879         key.type = CMND_ALIAS;
880         if ((ga = (struct generic_alias *) lfind((VOID *) &key,
881             (VOID *) &ga_list[0], &ga_list_len, sizeof(key), genaliascmp)))
882             (void) puts(ga->entries);
883         else
884             (void) puts(cm_list[count].cmnd);
885     }
886
887     /* Be nice and free up space now that we are done. */
888     for (count = 0; count < ga_list_len; count++) {
889         efree(ga_list[count].alias);
890         efree(ga_list[count].entries);
891     }
892     efree(ga_list);
893     ga_list = NULL;
894
895     for (count = 0; count < cm_list_len; count++) {
896         efree(cm_list[count].runas);
897         efree(cm_list[count].cmnd);
898     }
899     efree(cm_list);
900     cm_list = NULL;
901     cm_list_len = 0;
902     cm_list_size = 0;
903 }
904
905 /*
906  * Appends a source string to the destination, optionally prefixing a separator.
907  */
908 static void
909 append(src, dstp, dst_len, dst_size, separator)
910     char *src, **dstp;
911     size_t *dst_len, *dst_size;
912     char *separator;
913 {
914     size_t src_len = strlen(src);
915     char *dst = *dstp;
916
917     /*
918      * Only add the separator if there is something to separate from.
919      * If the last char is a '!', don't apply the separator (XXX).
920      */
921     if (separator && dst && dst[*dst_len - 1] != '!')
922         src_len += strlen(separator);
923     else
924         separator = NULL;
925
926     /* Assumes dst will be NULL if not set. */
927     if (dst == NULL) {
928         dst = (char *) emalloc(BUFSIZ);
929         *dst = '\0';
930         *dst_size = BUFSIZ;
931         *dst_len = 0;
932         *dstp = dst;
933     }
934
935     /* Allocate more space if necessary. */
936     if (*dst_size <= *dst_len + src_len) {
937         while (*dst_size <= *dst_len + src_len)
938             *dst_size += BUFSIZ;
939
940         dst = (char *) erealloc(dst, *dst_size);
941         *dstp = dst;
942     }
943
944     /* Copy src -> dst adding a separator if appropriate and adjust len. */
945     if (separator)
946         (void) strlcat(dst, separator, *dst_size);
947     (void) strlcat(dst, src, *dst_size);
948     *dst_len += src_len;
949 }
950
951 /*
952  * Frees up space used by the aliases list and resets the associated counters.
953  */
954 void
955 reset_aliases()
956 {
957     size_t n;
958
959     if (aliases) {
960         for (n = 0; n < naliases; n++)
961             efree(aliases[n].name);
962         efree(aliases);
963         aliases = NULL;
964     }
965     naliases = nslots = 0;
966 }
967
968 /*
969  * Increments ga_list_len, allocating more space as necessary.
970  */
971 static void
972 expand_ga_list()
973 {
974
975     if (++ga_list_len >= ga_list_size) {
976         while ((ga_list_size += STACKINCREMENT) < ga_list_len)
977             ;
978         ga_list = (struct generic_alias *)
979             erealloc3(ga_list, ga_list_size, sizeof(struct generic_alias));
980     }
981
982     ga_list[ga_list_len - 1].entries = NULL;
983 }
984
985 /*
986  * Increments cm_list_len, allocating more space as necessary.
987  */
988 static void
989 expand_match_list()
990 {
991
992     if (++cm_list_len >= cm_list_size) {
993         while ((cm_list_size += STACKINCREMENT) < cm_list_len)
994             ;
995         if (cm_list == NULL)
996             cm_list_len = 0;            /* start at 0 since it is a subscript */
997         cm_list = (struct command_match *)
998             erealloc3(cm_list, cm_list_size, sizeof(struct command_match));
999     }
1000
1001     cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
1002     cm_list[cm_list_len].nopasswd = FALSE;
1003     cm_list[cm_list_len].noexecve = FALSE;
1004     cm_list[cm_list_len].setenv = FALSE;
1005 }
1006
1007 /*
1008  * Frees up spaced used by a previous parser run and allocates new space
1009  * for various data structures.
1010  */
1011 void
1012 init_parser()
1013 {
1014
1015     /* Free up old data structures if we run the parser more than once. */
1016     if (match) {
1017         efree(match);
1018         match = NULL;
1019         top = 0;
1020         parse_error = FALSE;
1021         used_runas = FALSE;
1022         errorlineno = -1;
1023         sudolineno = 1;
1024     }
1025
1026     /* Allocate space for the matching stack. */
1027     stacksize = STACKINCREMENT;
1028     match = (struct matchstack *) emalloc2(stacksize, sizeof(struct matchstack));
1029
1030     /* Allocate space for the match list (for `sudo -l'). */
1031     if (printmatches == TRUE)
1032         expand_match_list();
1033 }
1034 #line 983 "sudo.tab.c"
1035 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1036 #if defined(__cplusplus) || defined(__STDC__)
1037 static int yygrowstack(void)
1038 #else
1039 static int yygrowstack()
1040 #endif
1041 {
1042     int newsize, i;
1043     short *newss;
1044     YYSTYPE *newvs;
1045
1046     if ((newsize = yystacksize) == 0)
1047         newsize = YYINITSTACKSIZE;
1048     else if (newsize >= YYMAXDEPTH)
1049         return -1;
1050     else if ((newsize *= 2) > YYMAXDEPTH)
1051         newsize = YYMAXDEPTH;
1052     i = yyssp - yyss;
1053 #ifdef SIZE_MAX
1054 #define YY_SIZE_MAX SIZE_MAX
1055 #else
1056 #define YY_SIZE_MAX 0xffffffffU
1057 #endif
1058     if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1059         goto bail;
1060     newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1061       (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1062     if (newss == NULL)
1063         goto bail;
1064     yyss = newss;
1065     yyssp = newss + i;
1066     if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1067         goto bail;
1068     newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1069       (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1070     if (newvs == NULL)
1071         goto bail;
1072     yyvs = newvs;
1073     yyvsp = newvs + i;
1074     yystacksize = newsize;
1075     yysslim = yyss + newsize - 1;
1076     return 0;
1077 bail:
1078     if (yyss)
1079             free(yyss);
1080     if (yyvs)
1081             free(yyvs);
1082     yyss = yyssp = NULL;
1083     yyvs = yyvsp = NULL;
1084     yystacksize = 0;
1085     return -1;
1086 }
1087
1088 #define YYABORT goto yyabort
1089 #define YYREJECT goto yyabort
1090 #define YYACCEPT goto yyaccept
1091 #define YYERROR goto yyerrlab
1092 int
1093 #if defined(__cplusplus) || defined(__STDC__)
1094 yyparse(void)
1095 #else
1096 yyparse()
1097 #endif
1098 {
1099     int yym, yyn, yystate;
1100 #if YYDEBUG
1101 #if defined(__cplusplus) || defined(__STDC__)
1102     const char *yys;
1103 #else /* !(defined(__cplusplus) || defined(__STDC__)) */
1104     char *yys;
1105 #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
1106
1107     if ((yys = getenv("YYDEBUG")))
1108     {
1109         yyn = *yys;
1110         if (yyn >= '0' && yyn <= '9')
1111             yydebug = yyn - '0';
1112     }
1113 #endif /* YYDEBUG */
1114
1115     yynerrs = 0;
1116     yyerrflag = 0;
1117     yychar = (-1);
1118
1119     if (yyss == NULL && yygrowstack()) goto yyoverflow;
1120     yyssp = yyss;
1121     yyvsp = yyvs;
1122     *yyssp = yystate = 0;
1123
1124 yyloop:
1125     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1126     if (yychar < 0)
1127     {
1128         if ((yychar = yylex()) < 0) yychar = 0;
1129 #if YYDEBUG
1130         if (yydebug)
1131         {
1132             yys = 0;
1133             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1134             if (!yys) yys = "illegal-symbol";
1135             printf("%sdebug: state %d, reading %d (%s)\n",
1136                     YYPREFIX, yystate, yychar, yys);
1137         }
1138 #endif
1139     }
1140     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1141             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1142     {
1143 #if YYDEBUG
1144         if (yydebug)
1145             printf("%sdebug: state %d, shifting to state %d\n",
1146                     YYPREFIX, yystate, yytable[yyn]);
1147 #endif
1148         if (yyssp >= yysslim && yygrowstack())
1149         {
1150             goto yyoverflow;
1151         }
1152         *++yyssp = yystate = yytable[yyn];
1153         *++yyvsp = yylval;
1154         yychar = (-1);
1155         if (yyerrflag > 0)  --yyerrflag;
1156         goto yyloop;
1157     }
1158     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1159             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1160     {
1161         yyn = yytable[yyn];
1162         goto yyreduce;
1163     }
1164     if (yyerrflag) goto yyinrecovery;
1165 #if defined(lint) || defined(__GNUC__)
1166     goto yynewerror;
1167 #endif
1168 yynewerror:
1169     yyerror("syntax error");
1170 #if defined(lint) || defined(__GNUC__)
1171     goto yyerrlab;
1172 #endif
1173 yyerrlab:
1174     ++yynerrs;
1175 yyinrecovery:
1176     if (yyerrflag < 3)
1177     {
1178         yyerrflag = 3;
1179         for (;;)
1180         {
1181             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1182                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1183             {
1184 #if YYDEBUG
1185                 if (yydebug)
1186                     printf("%sdebug: state %d, error recovery shifting\
1187  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1188 #endif
1189                 if (yyssp >= yysslim && yygrowstack())
1190                 {
1191                     goto yyoverflow;
1192                 }
1193                 *++yyssp = yystate = yytable[yyn];
1194                 *++yyvsp = yylval;
1195                 goto yyloop;
1196             }
1197             else
1198             {
1199 #if YYDEBUG
1200                 if (yydebug)
1201                     printf("%sdebug: error recovery discarding state %d\n",
1202                             YYPREFIX, *yyssp);
1203 #endif
1204                 if (yyssp <= yyss) goto yyabort;
1205                 --yyssp;
1206                 --yyvsp;
1207             }
1208         }
1209     }
1210     else
1211     {
1212         if (yychar == 0) goto yyabort;
1213 #if YYDEBUG
1214         if (yydebug)
1215         {
1216             yys = 0;
1217             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1218             if (!yys) yys = "illegal-symbol";
1219             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1220                     YYPREFIX, yystate, yychar, yys);
1221         }
1222 #endif
1223         yychar = (-1);
1224         goto yyloop;
1225     }
1226 yyreduce:
1227 #if YYDEBUG
1228     if (yydebug)
1229         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1230                 YYPREFIX, yystate, yyn, yyrule[yyn]);
1231 #endif
1232     yym = yylen[yyn];
1233     yyval = yyvsp[1-yym];
1234     switch (yyn)
1235     {
1236 case 3:
1237 #line 280 "parse.yacc"
1238 { ; }
1239 break;
1240 case 4:
1241 #line 282 "parse.yacc"
1242 { yyerrok; }
1243 break;
1244 case 5:
1245 #line 283 "parse.yacc"
1246 { push; }
1247 break;
1248 case 6:
1249 #line 283 "parse.yacc"
1250 {
1251                             while (top && user_matches != TRUE)
1252                                 pop;
1253                         }
1254 break;
1255 case 7:
1256 #line 288 "parse.yacc"
1257 { ; }
1258 break;
1259 case 8:
1260 #line 290 "parse.yacc"
1261 { ; }
1262 break;
1263 case 9:
1264 #line 292 "parse.yacc"
1265 { ; }
1266 break;
1267 case 10:
1268 #line 294 "parse.yacc"
1269 { ; }
1270 break;
1271 case 11:
1272 #line 296 "parse.yacc"
1273 { ; }
1274 break;
1275 case 13:
1276 #line 302 "parse.yacc"
1277 {
1278                             defaults_matches = TRUE;
1279                         }
1280 break;
1281 case 14:
1282 #line 305 "parse.yacc"
1283 { push; }
1284 break;
1285 case 15:
1286 #line 305 "parse.yacc"
1287 {
1288                             defaults_matches = user_matches;
1289                             pop;
1290                         }
1291 break;
1292 case 16:
1293 #line 309 "parse.yacc"
1294 { push; }
1295 break;
1296 case 17:
1297 #line 309 "parse.yacc"
1298 {
1299                             defaults_matches = yyvsp[0].BOOLEAN == TRUE;
1300                             pop;
1301                         }
1302 break;
1303 case 18:
1304 #line 313 "parse.yacc"
1305 { push; }
1306 break;
1307 case 19:
1308 #line 313 "parse.yacc"
1309 {
1310                             defaults_matches = host_matches;
1311                             pop;
1312                         }
1313 break;
1314 case 22:
1315 #line 323 "parse.yacc"
1316 {
1317                             if (defaults_matches == TRUE &&
1318                                 !set_default(yyvsp[0].string, NULL, TRUE)) {
1319                                 yyerror(NULL);
1320                                 YYERROR;
1321                             }
1322                             efree(yyvsp[0].string);
1323                         }
1324 break;
1325 case 23:
1326 #line 331 "parse.yacc"
1327 {
1328                             if (defaults_matches == TRUE &&
1329                                 !set_default(yyvsp[0].string, NULL, FALSE)) {
1330                                 yyerror(NULL);
1331                                 YYERROR;
1332                             }
1333                             efree(yyvsp[0].string);
1334                         }
1335 break;
1336 case 24:
1337 #line 339 "parse.yacc"
1338 {
1339                             if (defaults_matches == TRUE &&
1340                                 !set_default(yyvsp[-2].string, yyvsp[0].string, TRUE)) {
1341                                 yyerror(NULL);
1342                                 YYERROR;
1343                             }
1344                             efree(yyvsp[-2].string);
1345                             efree(yyvsp[0].string);
1346                         }
1347 break;
1348 case 25:
1349 #line 348 "parse.yacc"
1350 {
1351                             if (defaults_matches == TRUE &&
1352                                 !set_default(yyvsp[-2].string, yyvsp[0].string, '+')) {
1353                                 yyerror(NULL);
1354                                 YYERROR;
1355                             }
1356                             efree(yyvsp[-2].string);
1357                             efree(yyvsp[0].string);
1358                         }
1359 break;
1360 case 26:
1361 #line 357 "parse.yacc"
1362 {
1363                             if (defaults_matches == TRUE &&
1364                                 !set_default(yyvsp[-2].string, yyvsp[0].string, '-')) {
1365                                 yyerror(NULL);
1366                                 YYERROR;
1367                             }
1368                             efree(yyvsp[-2].string);
1369                             efree(yyvsp[0].string);
1370                         }
1371 break;
1372 case 29:
1373 #line 372 "parse.yacc"
1374 {
1375                             /*
1376                              * We already did a push if necessary in
1377                              * cmndspec so just reset some values so
1378                              * the next 'privilege' gets a clean slate.
1379                              */
1380                             host_matches = UNSPEC;
1381                             runas_matches = UNSPEC;
1382                             no_passwd = def_authenticate ? UNSPEC : TRUE;
1383                             no_execve = def_noexec ? TRUE : UNSPEC;
1384                             setenv_ok = def_setenv ? TRUE : UNSPEC;
1385                         }
1386 break;
1387 case 30:
1388 #line 386 "parse.yacc"
1389 {
1390                             SETMATCH(host_matches, yyvsp[0].BOOLEAN);
1391                         }
1392 break;
1393 case 31:
1394 #line 389 "parse.yacc"
1395 {
1396                             SETNMATCH(host_matches, yyvsp[0].BOOLEAN);
1397                         }
1398 break;
1399 case 32:
1400 #line 394 "parse.yacc"
1401 {
1402                             yyval.BOOLEAN = TRUE;
1403                         }
1404 break;
1405 case 33:
1406 #line 397 "parse.yacc"
1407 {
1408                             if (addr_matches(yyvsp[0].string))
1409                                 yyval.BOOLEAN = TRUE;
1410                             else
1411                                 yyval.BOOLEAN = NOMATCH;
1412                             efree(yyvsp[0].string);
1413                         }
1414 break;
1415 case 34:
1416 #line 404 "parse.yacc"
1417 {
1418                             if (netgr_matches(yyvsp[0].string, user_host, user_shost, NULL))
1419                                 yyval.BOOLEAN = TRUE;
1420                             else
1421                                 yyval.BOOLEAN = NOMATCH;
1422                             efree(yyvsp[0].string);
1423                         }
1424 break;
1425 case 35:
1426 #line 411 "parse.yacc"
1427 {
1428                             if (hostname_matches(user_shost, user_host, yyvsp[0].string) == 0)
1429                                 yyval.BOOLEAN = TRUE;
1430                             else
1431                                 yyval.BOOLEAN = NOMATCH;
1432                             efree(yyvsp[0].string);
1433                         }
1434 break;
1435 case 36:
1436 #line 418 "parse.yacc"
1437 {
1438                             aliasinfo *aip = find_alias(yyvsp[0].string, HOST_ALIAS);
1439
1440                             /* could be an all-caps hostname */
1441                             if (aip)
1442                                 yyval.BOOLEAN = aip->val;
1443                             else if (strcasecmp(user_shost, yyvsp[0].string) == 0)
1444                                 yyval.BOOLEAN = TRUE;
1445                             else {
1446                                 if (pedantic) {
1447                                     (void) fprintf(stderr,
1448                                         "%s: undeclared Host_Alias `%s' referenced near line %d\n",
1449                                         (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
1450                                     if (pedantic > 1) {
1451                                         yyerror(NULL);
1452                                         YYERROR;
1453                                     }
1454                                 }
1455                                 yyval.BOOLEAN = NOMATCH;
1456                             }
1457                             efree(yyvsp[0].string);
1458                         }
1459 break;
1460 case 39:
1461 #line 446 "parse.yacc"
1462 { SETENV_RESET; }
1463 break;
1464 case 40:
1465 #line 446 "parse.yacc"
1466 {
1467                             /*
1468                              * Push the entry onto the stack if it is worth
1469                              * saving and reset cmnd_matches for next cmnd.
1470                              *
1471                              * We need to save at least one entry on
1472                              * the stack so sudoers_lookup() can tell that
1473                              * the user was listed in sudoers.  Also, we
1474                              * need to be able to tell whether or not a
1475                              * user was listed for this specific host.
1476                              *
1477                              * If keepall is set and the user matches then
1478                              * we need to keep entries around too...
1479                              */
1480                             if (MATCHED(user_matches) &&
1481                                 MATCHED(host_matches) &&
1482                                 MATCHED(cmnd_matches) &&
1483                                 MATCHED(runas_matches))
1484                                 pushcp;
1485                             else if (MATCHED(user_matches) && (top == 1 ||
1486                                 (top == 2 && MATCHED(host_matches) &&
1487                                 !MATCHED(match[0].host))))
1488                                 pushcp;
1489                             else if (user_matches == TRUE && keepall)
1490                                 pushcp;
1491                             cmnd_matches = UNSPEC;
1492                         }
1493 break;
1494 case 41:
1495 #line 475 "parse.yacc"
1496 {
1497                             SETMATCH(cmnd_matches, yyvsp[0].BOOLEAN);
1498                         }
1499 break;
1500 case 42:
1501 #line 478 "parse.yacc"
1502 {
1503                             if (printmatches == TRUE) {
1504                                 if (in_alias == TRUE)
1505                                     append_entries("!", ", ");
1506                                 else if (host_matches == TRUE &&
1507                                     user_matches == TRUE)
1508                                     append_cmnd("!", NULL);
1509                             }
1510                         }
1511 break;
1512 case 43:
1513 #line 486 "parse.yacc"
1514 {
1515                             SETNMATCH(cmnd_matches, yyvsp[0].BOOLEAN);
1516                         }
1517 break;
1518 case 44:
1519 #line 491 "parse.yacc"
1520 {
1521                             if (printmatches == TRUE && host_matches == TRUE &&
1522                                 user_matches == TRUE) {
1523                                 if (runas_matches == UNSPEC) {
1524                                     cm_list[cm_list_len].runas_len = 0;
1525                                 } else {
1526                                     /* Inherit runas data. */
1527                                     cm_list[cm_list_len].runas =
1528                                         estrdup(cm_list[cm_list_len-1].runas);
1529                                     cm_list[cm_list_len].runas_len =
1530                                         cm_list[cm_list_len-1].runas_len;
1531                                     cm_list[cm_list_len].runas_size =
1532                                         cm_list[cm_list_len-1].runas_size;
1533                                 }
1534                             }
1535                             /*
1536                              * If this is the first entry in a command list
1537                              * then check against default runas user.
1538                              */
1539                             if (runas_matches == UNSPEC) {
1540                                 runas_matches = userpw_matches(def_runas_default,
1541                                     *user_runas, runas_pw) ? TRUE : NOMATCH;
1542                             }
1543                         }
1544 break;
1545 case 45:
1546 #line 515 "parse.yacc"
1547 {
1548                             runas_matches = yyvsp[0].BOOLEAN;
1549                         }
1550 break;
1551 case 46:
1552 #line 520 "parse.yacc"
1553 { ; }
1554 break;
1555 case 47:
1556 #line 521 "parse.yacc"
1557 {
1558                             /* Later entries override earlier ones. */
1559                             if (yyvsp[0].BOOLEAN != NOMATCH)
1560                                 yyval.BOOLEAN = yyvsp[0].BOOLEAN;
1561                             else
1562                                 yyval.BOOLEAN = yyvsp[-2].BOOLEAN;
1563                         }
1564 break;
1565 case 48:
1566 #line 530 "parse.yacc"
1567 { ; }
1568 break;
1569 case 49:
1570 #line 531 "parse.yacc"
1571 {
1572                             if (printmatches == TRUE) {
1573                                 if (in_alias == TRUE)
1574                                     append_entries("!", ", ");
1575                                 else if (host_matches == TRUE &&
1576                                     user_matches == TRUE)
1577                                     append_runas("!", ", ");
1578                             }
1579                         }
1580 break;
1581 case 50:
1582 #line 539 "parse.yacc"
1583 {
1584                             /* Set $$ to the negation of runasuser */
1585                             yyval.BOOLEAN = (yyvsp[0].BOOLEAN == NOMATCH ? NOMATCH : ! yyvsp[0].BOOLEAN);
1586                         }
1587 break;
1588 case 51:
1589 #line 545 "parse.yacc"
1590 {
1591                             if (printmatches == TRUE) {
1592                                 if (in_alias == TRUE)
1593                                     append_entries(yyvsp[0].string, ", ");
1594                                 else if (host_matches == TRUE &&
1595                                     user_matches == TRUE)
1596                                     append_runas(yyvsp[0].string, ", ");
1597                             }
1598                             if (userpw_matches(yyvsp[0].string, *user_runas, runas_pw))
1599                                 yyval.BOOLEAN = TRUE;
1600                             else
1601                                 yyval.BOOLEAN = NOMATCH;
1602                             efree(yyvsp[0].string);
1603                             used_runas = TRUE;
1604                         }
1605 break;
1606 case 52:
1607 #line 560 "parse.yacc"
1608 {
1609                             if (printmatches == TRUE) {
1610                                 if (in_alias == TRUE)
1611                                     append_entries(yyvsp[0].string, ", ");
1612                                 else if (host_matches == TRUE &&
1613                                     user_matches == TRUE)
1614                                     append_runas(yyvsp[0].string, ", ");
1615                             }
1616                             if (usergr_matches(yyvsp[0].string, *user_runas, runas_pw))
1617                                 yyval.BOOLEAN = TRUE;
1618                             else
1619                                 yyval.BOOLEAN = NOMATCH;
1620                             efree(yyvsp[0].string);
1621                             used_runas = TRUE;
1622                         }
1623 break;
1624 case 53:
1625 #line 575 "parse.yacc"
1626 {
1627                             if (printmatches == TRUE) {
1628                                 if (in_alias == TRUE)
1629                                     append_entries(yyvsp[0].string, ", ");
1630                                 else if (host_matches == TRUE &&
1631                                     user_matches == TRUE)
1632                                     append_runas(yyvsp[0].string, ", ");
1633                             }
1634                             if (netgr_matches(yyvsp[0].string, NULL, NULL, *user_runas))
1635                                 yyval.BOOLEAN = TRUE;
1636                             else
1637                                 yyval.BOOLEAN = NOMATCH;
1638                             efree(yyvsp[0].string);
1639                             used_runas = TRUE;
1640                         }
1641 break;
1642 case 54:
1643 #line 590 "parse.yacc"
1644 {
1645                             aliasinfo *aip = find_alias(yyvsp[0].string, RUNAS_ALIAS);
1646
1647                             if (printmatches == TRUE) {
1648                                 if (in_alias == TRUE)
1649                                     append_entries(yyvsp[0].string, ", ");
1650                                 else if (host_matches == TRUE &&
1651                                     user_matches == TRUE)
1652                                     append_runas(yyvsp[0].string, ", ");
1653                             }
1654                             /* could be an all-caps username */
1655                             if (aip)
1656                                 yyval.BOOLEAN = aip->val;
1657                             else if (strcmp(yyvsp[0].string, *user_runas) == 0)
1658                                 yyval.BOOLEAN = TRUE;
1659                             else {
1660                                 if (pedantic) {
1661                                     (void) fprintf(stderr,
1662                                         "%s: undeclared Runas_Alias `%s' referenced near line %d\n",
1663                                         (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
1664                                     if (pedantic > 1) {
1665                                         yyerror(NULL);
1666                                         YYERROR;
1667                                     }
1668                                 }
1669                                 yyval.BOOLEAN = NOMATCH;
1670                             }
1671                             efree(yyvsp[0].string);
1672                             used_runas = TRUE;
1673                         }
1674 break;
1675 case 55:
1676 #line 620 "parse.yacc"
1677 {
1678                             if (printmatches == TRUE) {
1679                                 if (in_alias == TRUE)
1680                                     append_entries("ALL", ", ");
1681                                 else if (host_matches == TRUE &&
1682                                     user_matches == TRUE)
1683                                     append_runas("ALL", ", ");
1684                             }
1685                             yyval.BOOLEAN = TRUE;
1686                         }
1687 break;
1688 case 56:
1689 #line 632 "parse.yacc"
1690 {
1691                             /* Inherit {NO,}{PASSWD,EXEC,SETENV} status. */
1692                             if (printmatches == TRUE && host_matches == TRUE &&
1693                                 user_matches == TRUE) {
1694                                 if (no_passwd == TRUE)
1695                                     cm_list[cm_list_len].nopasswd = TRUE;
1696                                 else
1697                                     cm_list[cm_list_len].nopasswd = FALSE;
1698                                 if (no_execve == TRUE)
1699                                     cm_list[cm_list_len].noexecve = TRUE;
1700                                 else
1701                                     cm_list[cm_list_len].noexecve = FALSE;
1702                                 if (setenv_ok == TRUE)
1703                                     cm_list[cm_list_len].setenv = TRUE;
1704                                 else
1705                                     cm_list[cm_list_len].setenv = FALSE;
1706                             }
1707                         }
1708 break;
1709 case 57:
1710 #line 650 "parse.yacc"
1711 {
1712                             no_passwd = TRUE;
1713                             if (printmatches == TRUE && host_matches == TRUE &&
1714                                 user_matches == TRUE)
1715                                 cm_list[cm_list_len].nopasswd = TRUE;
1716                         }
1717 break;
1718 case 58:
1719 #line 656 "parse.yacc"
1720 {
1721                             no_passwd = FALSE;
1722                             if (printmatches == TRUE && host_matches == TRUE &&
1723                                 user_matches == TRUE)
1724                                 cm_list[cm_list_len].nopasswd = FALSE;
1725                         }
1726 break;
1727 case 59:
1728 #line 662 "parse.yacc"
1729 {
1730                             no_execve = TRUE;
1731                             if (printmatches == TRUE && host_matches == TRUE &&
1732                                 user_matches == TRUE)
1733                                 cm_list[cm_list_len].noexecve = TRUE;
1734                         }
1735 break;
1736 case 60:
1737 #line 668 "parse.yacc"
1738 {
1739                             no_execve = FALSE;
1740                             if (printmatches == TRUE && host_matches == TRUE &&
1741                                 user_matches == TRUE)
1742                                 cm_list[cm_list_len].noexecve = FALSE;
1743                         }
1744 break;
1745 case 61:
1746 #line 674 "parse.yacc"
1747 {
1748                             setenv_ok = TRUE;
1749                             if (printmatches == TRUE && host_matches == TRUE &&
1750                                 user_matches == TRUE)
1751                                 cm_list[cm_list_len].setenv = TRUE;
1752                         }
1753 break;
1754 case 62:
1755 #line 680 "parse.yacc"
1756 {
1757                             setenv_ok = FALSE;
1758                             if (printmatches == TRUE && host_matches == TRUE &&
1759                                 user_matches == TRUE)
1760                                 cm_list[cm_list_len].setenv = FALSE;
1761                         }
1762 break;
1763 case 63:
1764 #line 688 "parse.yacc"
1765 {
1766                             if (printmatches == TRUE) {
1767                                 if (in_alias == TRUE)
1768                                     append_entries("ALL", ", ");
1769                                 else if (host_matches == TRUE &&
1770                                     user_matches == TRUE) {
1771                                     append_cmnd("ALL", NULL);
1772                                     expand_match_list();
1773                                 }
1774                             }
1775                             /* sudo "ALL" implies the SETENV tag */
1776                             if (setenv_ok == UNSPEC)
1777                                 setenv_ok = IMPLIED;
1778
1779                             efree(safe_cmnd);
1780                             safe_cmnd = NULL;
1781                             yyval.BOOLEAN = TRUE;
1782                         }
1783 break;
1784 case 64:
1785 #line 706 "parse.yacc"
1786 {
1787                             aliasinfo *aip;
1788
1789                             if (printmatches == TRUE) {
1790                                 if (in_alias == TRUE)
1791                                     append_entries(yyvsp[0].string, ", ");
1792                                 else if (host_matches == TRUE &&
1793                                     user_matches == TRUE) {
1794                                     append_cmnd(yyvsp[0].string, NULL);
1795                                     expand_match_list();
1796                                 }
1797                             }
1798
1799                             if ((aip = find_alias(yyvsp[0].string, CMND_ALIAS)))
1800                                 yyval.BOOLEAN = aip->val;
1801                             else {
1802                                 if (pedantic) {
1803                                     (void) fprintf(stderr,
1804                                         "%s: undeclared Cmnd_Alias `%s' referenced near line %d\n",
1805                                         (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
1806                                     if (pedantic > 1) {
1807                                         yyerror(NULL);
1808                                         YYERROR;
1809                                     }
1810                                 }
1811                                 yyval.BOOLEAN = NOMATCH;
1812                             }
1813                             efree(yyvsp[0].string);
1814                         }
1815 break;
1816 case 65:
1817 #line 735 "parse.yacc"
1818 {
1819                             if (printmatches == TRUE) {
1820                                 if (in_alias == TRUE) {
1821                                     append_entries(yyvsp[0].command.cmnd, ", ");
1822                                     if (yyvsp[0].command.args)
1823                                         append_entries(yyvsp[0].command.args, " ");
1824                                 }
1825                                 if (host_matches == TRUE &&
1826                                     user_matches == TRUE)  {
1827                                     append_cmnd(yyvsp[0].command.cmnd, NULL);
1828                                     if (yyvsp[0].command.args)
1829                                         append_cmnd(yyvsp[0].command.args, " ");
1830                                     expand_match_list();
1831                                 }
1832                             }
1833
1834                             if (command_matches(yyvsp[0].command.cmnd, yyvsp[0].command.args))
1835                                 yyval.BOOLEAN = TRUE;
1836                             else
1837                                 yyval.BOOLEAN = NOMATCH;
1838
1839                             efree(yyvsp[0].command.cmnd);
1840                             efree(yyvsp[0].command.args);
1841                         }
1842 break;
1843 case 68:
1844 #line 765 "parse.yacc"
1845 { push; }
1846 break;
1847 case 69:
1848 #line 765 "parse.yacc"
1849 {
1850                             if ((MATCHED(host_matches) || pedantic) &&
1851                                 !add_alias(yyvsp[-3].string, HOST_ALIAS, host_matches)) {
1852                                 yyerror(NULL);
1853                                 YYERROR;
1854                             }
1855                             pop;
1856                         }
1857 break;
1858 case 74:
1859 #line 783 "parse.yacc"
1860 {
1861                             push;
1862                             if (printmatches == TRUE) {
1863                                 in_alias = TRUE;
1864                                 /* Allocate space for ga_list if necessary. */
1865                                 expand_ga_list();
1866                                 ga_list[ga_list_len-1].type = CMND_ALIAS;
1867                                 ga_list[ga_list_len-1].alias = estrdup(yyvsp[0].string);
1868                              }
1869                         }
1870 break;
1871 case 75:
1872 #line 792 "parse.yacc"
1873 {
1874                             if ((MATCHED(cmnd_matches) || pedantic) &&
1875                                 !add_alias(yyvsp[-3].string, CMND_ALIAS, cmnd_matches)) {
1876                                 yyerror(NULL);
1877                                 YYERROR;
1878                             }
1879                             pop;
1880                             efree(yyvsp[-3].string);
1881
1882                             if (printmatches == TRUE)
1883                                 in_alias = FALSE;
1884                         }
1885 break;
1886 case 76:
1887 #line 806 "parse.yacc"
1888 { ; }
1889 break;
1890 case 80:
1891 #line 814 "parse.yacc"
1892 {
1893                             if (printmatches == TRUE) {
1894                                 in_alias = TRUE;
1895                                 /* Allocate space for ga_list if necessary. */
1896                                 expand_ga_list();
1897                                 ga_list[ga_list_len-1].type = RUNAS_ALIAS;
1898                                 ga_list[ga_list_len-1].alias = estrdup(yyvsp[0].string);
1899                             }
1900                         }
1901 break;
1902 case 81:
1903 #line 822 "parse.yacc"
1904 {
1905                             if ((yyvsp[0].BOOLEAN != NOMATCH || pedantic) &&
1906                                 !add_alias(yyvsp[-3].string, RUNAS_ALIAS, yyvsp[0].BOOLEAN)) {
1907                                 yyerror(NULL);
1908                                 YYERROR;
1909                             }
1910                             efree(yyvsp[-3].string);
1911
1912                             if (printmatches == TRUE)
1913                                 in_alias = FALSE;
1914                         }
1915 break;
1916 case 84:
1917 #line 839 "parse.yacc"
1918 { push; }
1919 break;
1920 case 85:
1921 #line 839 "parse.yacc"
1922 {
1923                             if ((MATCHED(user_matches) || pedantic) &&
1924                                 !add_alias(yyvsp[-3].string, USER_ALIAS, user_matches)) {
1925                                 yyerror(NULL);
1926                                 YYERROR;
1927                             }
1928                             pop;
1929                             efree(yyvsp[-3].string);
1930                         }
1931 break;
1932 case 88:
1933 #line 854 "parse.yacc"
1934 {
1935                             SETMATCH(user_matches, yyvsp[0].BOOLEAN);
1936                         }
1937 break;
1938 case 89:
1939 #line 857 "parse.yacc"
1940 {
1941                             SETNMATCH(user_matches, yyvsp[0].BOOLEAN);
1942                         }
1943 break;
1944 case 90:
1945 #line 862 "parse.yacc"
1946 {
1947                             if (userpw_matches(yyvsp[0].string, user_name, sudo_user.pw))
1948                                 yyval.BOOLEAN = TRUE;
1949                             else
1950                                 yyval.BOOLEAN = NOMATCH;
1951                             efree(yyvsp[0].string);
1952                         }
1953 break;
1954 case 91:
1955 #line 869 "parse.yacc"
1956 {
1957                             if (usergr_matches(yyvsp[0].string, user_name, sudo_user.pw))
1958                                 yyval.BOOLEAN = TRUE;
1959                             else
1960                                 yyval.BOOLEAN = NOMATCH;
1961                             efree(yyvsp[0].string);
1962                         }
1963 break;
1964 case 92:
1965 #line 876 "parse.yacc"
1966 {
1967                             if (netgr_matches(yyvsp[0].string, NULL, NULL, user_name))
1968                                 yyval.BOOLEAN = TRUE;
1969                             else
1970                                 yyval.BOOLEAN = NOMATCH;
1971                             efree(yyvsp[0].string);
1972                         }
1973 break;
1974 case 93:
1975 #line 883 "parse.yacc"
1976 {
1977                             aliasinfo *aip = find_alias(yyvsp[0].string, USER_ALIAS);
1978
1979                             /* could be an all-caps username */
1980                             if (aip)
1981                                 yyval.BOOLEAN = aip->val;
1982                             else if (strcmp(yyvsp[0].string, user_name) == 0)
1983                                 yyval.BOOLEAN = TRUE;
1984                             else {
1985                                 if (pedantic) {
1986                                     (void) fprintf(stderr,
1987                                         "%s: undeclared User_Alias `%s' referenced near line %d\n",
1988                                         (pedantic == 1) ? "Warning" : "Error", yyvsp[0].string, sudolineno);
1989                                     if (pedantic > 1) {
1990                                         yyerror(NULL);
1991                                         YYERROR;
1992                                     }
1993                                 }
1994                                 yyval.BOOLEAN = NOMATCH;
1995                             }
1996                             efree(yyvsp[0].string);
1997                         }
1998 break;
1999 case 94:
2000 #line 905 "parse.yacc"
2001 {
2002                             yyval.BOOLEAN = TRUE;
2003                         }
2004 break;
2005 #line 1954 "sudo.tab.c"
2006     }
2007     yyssp -= yym;
2008     yystate = *yyssp;
2009     yyvsp -= yym;
2010     yym = yylhs[yyn];
2011     if (yystate == 0 && yym == 0)
2012     {
2013 #if YYDEBUG
2014         if (yydebug)
2015             printf("%sdebug: after reduction, shifting from state 0 to\
2016  state %d\n", YYPREFIX, YYFINAL);
2017 #endif
2018         yystate = YYFINAL;
2019         *++yyssp = YYFINAL;
2020         *++yyvsp = yyval;
2021         if (yychar < 0)
2022         {
2023             if ((yychar = yylex()) < 0) yychar = 0;
2024 #if YYDEBUG
2025             if (yydebug)
2026             {
2027                 yys = 0;
2028                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
2029                 if (!yys) yys = "illegal-symbol";
2030                 printf("%sdebug: state %d, reading %d (%s)\n",
2031                         YYPREFIX, YYFINAL, yychar, yys);
2032             }
2033 #endif
2034         }
2035         if (yychar == 0) goto yyaccept;
2036         goto yyloop;
2037     }
2038     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
2039             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
2040         yystate = yytable[yyn];
2041     else
2042         yystate = yydgoto[yym];
2043 #if YYDEBUG
2044     if (yydebug)
2045         printf("%sdebug: after reduction, shifting from state %d \
2046 to state %d\n", YYPREFIX, *yyssp, yystate);
2047 #endif
2048     if (yyssp >= yysslim && yygrowstack())
2049     {
2050         goto yyoverflow;
2051     }
2052     *++yyssp = yystate;
2053     *++yyvsp = yyval;
2054     goto yyloop;
2055 yyoverflow:
2056     yyerror("yacc stack overflow");
2057 yyabort:
2058     if (yyss)
2059             free(yyss);
2060     if (yyvs)
2061             free(yyvs);
2062     yyss = yyssp = NULL;
2063     yyvs = yyvsp = NULL;
2064     yystacksize = 0;
2065     return (1);
2066 yyaccept:
2067     if (yyss)
2068             free(yyss);
2069     if (yyvs)
2070             free(yyvs);
2071     yyss = yyssp = NULL;
2072     yyvs = yyvsp = NULL;
2073     yystacksize = 0;
2074     return (0);
2075 }