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