add doc about interaction with RAMRUN to README.Debian in response to #581393
[debian/sudo] / gram.y
1 %{
2 /*
3  * Copyright (c) 1996, 1998-2005, 2007-2009
4  *      Todd C. Miller <Todd.Miller@courtesan.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
18  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19  *
20  * Sponsored in part by the Defense Advanced Research Projects
21  * Agency (DARPA) and Air Force Research Laboratory, Air Force
22  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
23  */
24
25 #include <config.h>
26
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <stdio.h>
30 #ifdef STDC_HEADERS
31 # include <stdlib.h>
32 # include <stddef.h>
33 #else
34 # ifdef HAVE_STDLIB_H
35 #  include <stdlib.h>
36 # endif
37 #endif /* STDC_HEADERS */
38 #ifdef HAVE_STRING_H
39 # include <string.h>
40 #else
41 # ifdef HAVE_STRINGS_H
42 #  include <strings.h>
43 # endif
44 #endif /* HAVE_STRING_H */
45 #ifdef HAVE_UNISTD_H
46 # include <unistd.h>
47 #endif /* HAVE_UNISTD_H */
48 #if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
49 # include <alloca.h>
50 #endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */
51 #include <limits.h>
52
53 #include "sudo.h"
54 #include "parse.h"
55
56 /*
57  * We must define SIZE_MAX for yacc's skeleton.c.
58  * If there is no SIZE_MAX or SIZE_T_MAX we have to assume that size_t
59  * could be signed (as it is on SunOS 4.x).
60  */
61 #ifndef SIZE_MAX
62 # ifdef SIZE_T_MAX
63 #  define SIZE_MAX      SIZE_T_MAX
64 # else
65 #  define SIZE_MAX      INT_MAX
66 # endif /* SIZE_T_MAX */
67 #endif /* SIZE_MAX */
68
69 /*
70  * Globals
71  */
72 extern int sudolineno;
73 extern char *sudoers;
74 int parse_error;
75 int pedantic = FALSE;
76 int verbose = FALSE;
77 int errorlineno = -1;
78 char *errorfile = NULL;
79
80 struct defaults_list defaults;
81 struct userspec_list userspecs;
82
83 /*
84  * Local protoypes
85  */
86 static void  add_defaults       __P((int, struct member *, struct defaults *));
87 static void  add_userspec       __P((struct member *, struct privilege *));
88 static struct defaults *new_default __P((char *, char *, int));
89 static struct member *new_member __P((char *, int));
90        void  yyerror            __P((const char *));
91
92 void
93 yyerror(s)
94     const char *s;
95 {
96     /* Save the line the first error occurred on. */
97     if (errorlineno == -1) {
98         errorlineno = sudolineno ? sudolineno - 1 : 0;
99         errorfile = estrdup(sudoers);
100     }
101     if (verbose && s != NULL) {
102 #ifndef TRACELEXER
103         (void) fprintf(stderr, ">>> %s: %s near line %d <<<\n", sudoers, s,
104             sudolineno ? sudolineno - 1 : 0);
105 #else
106         (void) fprintf(stderr, "<*> ");
107 #endif
108     }
109     parse_error = TRUE;
110 }
111 %}
112
113 %union {
114     struct cmndspec *cmndspec;
115     struct defaults *defaults;
116     struct member *member;
117     struct runascontainer *runas;
118     struct privilege *privilege;
119     struct sudo_command command;
120     struct cmndtag tag;
121     struct selinux_info seinfo;
122     char *string;
123     int tok;
124 }
125
126 %start file                             /* special start symbol */
127 %token <command> COMMAND                /* absolute pathname w/ optional args */
128 %token <string>  ALIAS                  /* an UPPERCASE alias name */
129 %token <string>  DEFVAR                 /* a Defaults variable name */
130 %token <string>  NTWKADDR               /* ipv4 or ipv6 address */
131 %token <string>  NETGROUP               /* a netgroup (+NAME) */
132 %token <string>  USERGROUP              /* a usergroup (%NAME) */
133 %token <string>  WORD                   /* a word */
134 %token <tok>     DEFAULTS               /* Defaults entry */
135 %token <tok>     DEFAULTS_HOST          /* Host-specific defaults entry */
136 %token <tok>     DEFAULTS_USER          /* User-specific defaults entry */
137 %token <tok>     DEFAULTS_RUNAS         /* Runas-specific defaults entry */
138 %token <tok>     DEFAULTS_CMND          /* Command-specific defaults entry */
139 %token <tok>     NOPASSWD               /* no passwd req for command */
140 %token <tok>     PASSWD                 /* passwd req for command (default) */
141 %token <tok>     NOEXEC                 /* preload dummy execve() for cmnd */
142 %token <tok>     EXEC                   /* don't preload dummy execve() */
143 %token <tok>     SETENV                 /* user may set environment for cmnd */
144 %token <tok>     NOSETENV               /* user may not set environment */
145 %token <tok>     ALL                    /* ALL keyword */
146 %token <tok>     COMMENT                /* comment and/or carriage return */
147 %token <tok>     HOSTALIAS              /* Host_Alias keyword */
148 %token <tok>     CMNDALIAS              /* Cmnd_Alias keyword */
149 %token <tok>     USERALIAS              /* User_Alias keyword */
150 %token <tok>     RUNASALIAS             /* Runas_Alias keyword */
151 %token <tok>     ':' '=' ',' '!' '+' '-' /* union member tokens */
152 %token <tok>     '(' ')'                /* runas tokens */
153 %token <tok>     ERROR
154 %token <tok>     TYPE                   /* SELinux type */
155 %token <tok>     ROLE                   /* SELinux role */
156
157 %type <cmndspec>  cmndspec
158 %type <cmndspec>  cmndspeclist
159 %type <defaults>  defaults_entry
160 %type <defaults>  defaults_list
161 %type <member>    cmnd
162 %type <member>    opcmnd
163 %type <member>    cmndlist
164 %type <member>    host
165 %type <member>    hostlist
166 %type <member>    ophost
167 %type <member>    opuser
168 %type <member>    user
169 %type <member>    userlist
170 %type <member>    opgroup
171 %type <member>    group
172 %type <member>    grouplist
173 %type <runas>     runasspec
174 %type <runas>     runaslist
175 %type <privilege> privilege
176 %type <privilege> privileges
177 %type <tag>       cmndtag
178 %type <seinfo>    selinux
179 %type <string>    rolespec
180 %type <string>    typespec
181
182 %%
183
184 file            :       { ; }
185                 |       line
186                 ;
187
188 line            :       entry
189                 |       line entry
190                 ;
191
192 entry           :       COMMENT {
193                             ;
194                         }
195                 |       error COMMENT {
196                             yyerrok;
197                         }
198                 |       userlist privileges {
199                             add_userspec($1, $2);
200                         }
201                 |       USERALIAS useraliases {
202                             ;
203                         }
204                 |       HOSTALIAS hostaliases {
205                             ;
206                         }
207                 |       CMNDALIAS cmndaliases {
208                             ;
209                         }
210                 |       RUNASALIAS runasaliases {
211                             ;
212                         }
213                 |       DEFAULTS defaults_list {
214                             add_defaults(DEFAULTS, NULL, $2);
215                         }
216                 |       DEFAULTS_USER userlist defaults_list {
217                             add_defaults(DEFAULTS_USER, $2, $3);
218                         }
219                 |       DEFAULTS_RUNAS userlist defaults_list {
220                             add_defaults(DEFAULTS_RUNAS, $2, $3);
221                         }
222                 |       DEFAULTS_HOST hostlist defaults_list {
223                             add_defaults(DEFAULTS_HOST, $2, $3);
224                         }
225                 |       DEFAULTS_CMND cmndlist defaults_list {
226                             add_defaults(DEFAULTS_CMND, $2, $3);
227                         }
228                 ;
229
230 defaults_list   :       defaults_entry
231                 |       defaults_list ',' defaults_entry {
232                             list_append($1, $3);
233                             $$ = $1;
234                         }
235                 ;
236
237 defaults_entry  :       DEFVAR {
238                             $$ = new_default($1, NULL, TRUE);
239                         }
240                 |       '!' DEFVAR {
241                             $$ = new_default($2, NULL, FALSE);
242                         }
243                 |       DEFVAR '=' WORD {
244                             $$ = new_default($1, $3, TRUE);
245                         }
246                 |       DEFVAR '+' WORD {
247                             $$ = new_default($1, $3, '+');
248                         }
249                 |       DEFVAR '-' WORD {
250                             $$ = new_default($1, $3, '-');
251                         }
252                 ;
253
254 privileges      :       privilege
255                 |       privileges ':' privilege {
256                             list_append($1, $3);
257                             $$ = $1;
258                         }
259                 ;
260
261 privilege       :       hostlist '=' cmndspeclist {
262                             struct privilege *p = emalloc(sizeof(*p));
263                             list2tq(&p->hostlist, $1);
264                             list2tq(&p->cmndlist, $3);
265                             p->prev = p;
266                             p->next = NULL;
267                             $$ = p;
268                         }
269                 ;
270
271 ophost          :       host {
272                             $$ = $1;
273                             $$->negated = FALSE;
274                         }
275                 |       '!' host {
276                             $$ = $2;
277                             $$->negated = TRUE;
278                         }
279                 ;
280
281 host            :       ALIAS {
282                             $$ = new_member($1, ALIAS);
283                         }
284                 |       ALL {
285                             $$ = new_member(NULL, ALL);
286                         }
287                 |       NETGROUP {
288                             $$ = new_member($1, NETGROUP);
289                         }
290                 |       NTWKADDR {
291                             $$ = new_member($1, NTWKADDR);
292                         }
293                 |       WORD {
294                             $$ = new_member($1, WORD);
295                         }
296                 ;
297
298 cmndspeclist    :       cmndspec
299                 |       cmndspeclist ',' cmndspec {
300                             list_append($1, $3);
301 #ifdef HAVE_SELINUX
302                             /* propagate role and type */
303                             if ($3->role == NULL)
304                                 $3->role = $3->prev->role;
305                             if ($3->type == NULL)
306                                 $3->type = $3->prev->type;
307 #endif /* HAVE_SELINUX */
308                             /* propagate tags and runas list */
309                             if ($3->tags.nopasswd == UNSPEC)
310                                 $3->tags.nopasswd = $3->prev->tags.nopasswd;
311                             if ($3->tags.noexec == UNSPEC)
312                                 $3->tags.noexec = $3->prev->tags.noexec;
313                             if ($3->tags.setenv == UNSPEC &&
314                                 $3->prev->tags.setenv != IMPLIED)
315                                 $3->tags.setenv = $3->prev->tags.setenv;
316                             if ((tq_empty(&$3->runasuserlist) &&
317                                  tq_empty(&$3->runasgrouplist)) &&
318                                 (!tq_empty(&$3->prev->runasuserlist) ||
319                                  !tq_empty(&$3->prev->runasgrouplist))) {
320                                 $3->runasuserlist = $3->prev->runasuserlist;
321                                 $3->runasgrouplist = $3->prev->runasgrouplist;
322                             }
323                             $$ = $1;
324                         }
325                 ;
326
327 cmndspec        :       runasspec selinux cmndtag opcmnd {
328                             struct cmndspec *cs = emalloc(sizeof(*cs));
329                             if ($1 != NULL) {
330                                 list2tq(&cs->runasuserlist, $1->runasusers);
331                                 list2tq(&cs->runasgrouplist, $1->runasgroups);
332                                 efree($1);
333                             } else {
334                                 tq_init(&cs->runasuserlist);
335                                 tq_init(&cs->runasgrouplist);
336                             }
337 #ifdef HAVE_SELINUX
338                             cs->role = $2.role;
339                             cs->type = $2.type;
340 #endif
341                             cs->tags = $3;
342                             cs->cmnd = $4;
343                             cs->prev = cs;
344                             cs->next = NULL;
345                             /* sudo "ALL" implies the SETENV tag */
346                             if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
347                                 cs->tags.setenv == UNSPEC)
348                                 cs->tags.setenv = IMPLIED;
349                             $$ = cs;
350                         }
351                 ;
352
353 opcmnd          :       cmnd {
354                             $$ = $1;
355                             $$->negated = FALSE;
356                         }
357                 |       '!' cmnd {
358                             $$ = $2;
359                             $$->negated = TRUE;
360                         }
361                 ;
362
363 rolespec        :       ROLE '=' WORD {
364                             $$ = $3;
365                         }
366                 ;
367
368 typespec        :       TYPE '=' WORD {
369                             $$ = $3;
370                         }
371                 ;
372
373 selinux         :       /* empty */ {
374                             $$.role = NULL;
375                             $$.type = NULL;
376                         }
377                 |       rolespec {
378                             $$.role = $1;
379                             $$.type = NULL;
380                         }
381                 |       typespec {
382                             $$.type = $1;
383                             $$.role = NULL;
384                         }
385                 |       rolespec typespec {
386                             $$.role = $1;
387                             $$.type = $2;
388                         }
389                 |       typespec rolespec {
390                             $$.type = $1;
391                             $$.role = $2;
392                         }
393                 ;
394
395 runasspec       :       /* empty */ {
396                             $$ = NULL;
397                         }
398                 |       '(' runaslist ')' {
399                             $$ = $2;
400                         }
401                 ;
402
403 runaslist       :       userlist {
404                             $$ = emalloc(sizeof(struct runascontainer));
405                             $$->runasusers = $1;
406                             $$->runasgroups = NULL;
407                         }
408                 |       userlist ':' grouplist {
409                             $$ = emalloc(sizeof(struct runascontainer));
410                             $$->runasusers = $1;
411                             $$->runasgroups = $3;
412                         }
413                 |       ':' grouplist {
414                             $$ = emalloc(sizeof(struct runascontainer));
415                             $$->runasusers = NULL;
416                             $$->runasgroups = $2;
417                         }
418                 ;
419
420 cmndtag         :       /* empty */ {
421                             $$.nopasswd = $$.noexec = $$.setenv = UNSPEC;
422                         }
423                 |       cmndtag NOPASSWD {
424                             $$.nopasswd = TRUE;
425                         }
426                 |       cmndtag PASSWD {
427                             $$.nopasswd = FALSE;
428                         }
429                 |       cmndtag NOEXEC {
430                             $$.noexec = TRUE;
431                         }
432                 |       cmndtag EXEC {
433                             $$.noexec = FALSE;
434                         }
435                 |       cmndtag SETENV {
436                             $$.setenv = TRUE;
437                         }
438                 |       cmndtag NOSETENV {
439                             $$.setenv = FALSE;
440                         }
441                 ;
442
443 cmnd            :       ALL {
444                             $$ = new_member(NULL, ALL);
445                         }
446                 |       ALIAS {
447                             $$ = new_member($1, ALIAS);
448                         }
449                 |       COMMAND {
450                             struct sudo_command *c = emalloc(sizeof(*c));
451                             c->cmnd = $1.cmnd;
452                             c->args = $1.args;
453                             $$ = new_member((char *)c, COMMAND);
454                         }
455                 ;
456
457 hostaliases     :       hostalias
458                 |       hostaliases ':' hostalias
459                 ;
460
461 hostalias       :       ALIAS '=' hostlist {
462                             char *s;
463                             if ((s = alias_add($1, HOSTALIAS, $3)) != NULL) {
464                                 yyerror(s);
465                                 YYERROR;
466                             }
467                         }
468                 ;
469
470 hostlist        :       ophost
471                 |       hostlist ',' ophost {
472                             list_append($1, $3);
473                             $$ = $1;
474                         }
475                 ;
476
477 cmndaliases     :       cmndalias
478                 |       cmndaliases ':' cmndalias
479                 ;
480
481 cmndalias       :       ALIAS '=' cmndlist {
482                             char *s;
483                             if ((s = alias_add($1, CMNDALIAS, $3)) != NULL) {
484                                 yyerror(s);
485                                 YYERROR;
486                             }
487                         }
488                 ;
489
490 cmndlist        :       opcmnd
491                 |       cmndlist ',' opcmnd {
492                             list_append($1, $3);
493                             $$ = $1;
494                         }
495                 ;
496
497 runasaliases    :       runasalias
498                 |       runasaliases ':' runasalias
499                 ;
500
501 runasalias      :       ALIAS '=' userlist {
502                             char *s;
503                             if ((s = alias_add($1, RUNASALIAS, $3)) != NULL) {
504                                 yyerror(s);
505                                 YYERROR;
506                             }
507                         }
508                 ;
509
510 useraliases     :       useralias
511                 |       useraliases ':' useralias
512                 ;
513
514 useralias       :       ALIAS '=' userlist {
515                             char *s;
516                             if ((s = alias_add($1, USERALIAS, $3)) != NULL) {
517                                 yyerror(s);
518                                 YYERROR;
519                             }
520                         }
521                 ;
522
523 userlist        :       opuser
524                 |       userlist ',' opuser {
525                             list_append($1, $3);
526                             $$ = $1;
527                         }
528                 ;
529
530 opuser          :       user {
531                             $$ = $1;
532                             $$->negated = FALSE;
533                         }
534                 |       '!' user {
535                             $$ = $2;
536                             $$->negated = TRUE;
537                         }
538                 ;
539
540 user            :       ALIAS {
541                             $$ = new_member($1, ALIAS);
542                         }
543                 |       ALL {
544                             $$ = new_member(NULL, ALL);
545                         }
546                 |       NETGROUP {
547                             $$ = new_member($1, NETGROUP);
548                         }
549                 |       USERGROUP {
550                             $$ = new_member($1, USERGROUP);
551                         }
552                 |       WORD {
553                             $$ = new_member($1, WORD);
554                         }
555                 ;
556
557 grouplist       :       opgroup
558                 |       grouplist ',' opgroup {
559                             list_append($1, $3);
560                             $$ = $1;
561                         }
562                 ;
563
564 opgroup         :       group {
565                             $$ = $1;
566                             $$->negated = FALSE;
567                         }
568                 |       '!' group {
569                             $$ = $2;
570                             $$->negated = TRUE;
571                         }
572                 ;
573
574 group           :       ALIAS {
575                             $$ = new_member($1, ALIAS);
576                         }
577                 |       ALL {
578                             $$ = new_member(NULL, ALL);
579                         }
580                 |       WORD {
581                             $$ = new_member($1, WORD);
582                         }
583                 ;
584
585 %%
586 static struct defaults *
587 new_default(var, val, op)
588     char *var;
589     char *val;
590     int op;
591 {
592     struct defaults *d;
593
594     d = emalloc(sizeof(struct defaults));
595     d->var = var;
596     d->val = val;
597     tq_init(&d->binding);
598     d->type = 0;
599     d->op = op;
600     d->prev = d;
601     d->next = NULL;
602
603     return(d);
604 }
605
606 static struct member *
607 new_member(name, type)
608     char *name;
609     int type;
610 {
611     struct member *m;
612
613     m = emalloc(sizeof(struct member));
614     m->name = name;
615     m->type = type;
616     m->prev = m;
617     m->next = NULL;
618
619     return(m);
620 }
621
622 /*
623  * Add a list of defaults structures to the defaults list.
624  * The binding, if non-NULL, specifies a list of hosts, users, or
625  * runas users the entries apply to (specified by the type).
626  */
627 static void
628 add_defaults(type, bmem, defs)
629     int type;
630     struct member *bmem;
631     struct defaults *defs;
632 {
633     struct defaults *d;
634     struct member_list binding;
635
636     /*
637      * We can only call list2tq once on bmem as it will zero
638      * out the prev pointer when it consumes bmem.
639      */
640     list2tq(&binding, bmem);
641
642     /*
643      * Set type and binding (who it applies to) for new entries.
644      */
645     for (d = defs; d != NULL; d = d->next) {
646         d->type = type;
647         d->binding = binding;
648     }
649     tq_append(&defaults, defs);
650 }
651
652 /*
653  * Allocate a new struct userspec, populate it, and insert it at the
654  * and of the userspecs list.
655  */
656 static void
657 add_userspec(members, privs)
658     struct member *members;
659     struct privilege *privs;
660 {
661     struct userspec *u;
662
663     u = emalloc(sizeof(*u));
664     list2tq(&u->users, members);
665     list2tq(&u->privileges, privs);
666     u->prev = u;
667     u->next = NULL;
668     tq_append(&userspecs, u);
669 }
670
671 /*
672  * Free up space used by data structures from a previous parser run and sets
673  * the current sudoers file to path.
674  */
675 void
676 init_parser(path, quiet)
677     char *path;
678     int quiet;
679 {
680     struct defaults *d;
681     struct member *m, *binding;
682     struct userspec *us;
683     struct privilege *priv;
684     struct cmndspec *cs;
685     struct sudo_command *c;
686
687     while ((us = tq_pop(&userspecs)) != NULL) {
688         while ((m = tq_pop(&us->users)) != NULL) {
689             efree(m->name);
690             efree(m);
691         }
692         while ((priv = tq_pop(&us->privileges)) != NULL) {
693             struct member *runasuser = NULL, *runasgroup = NULL;
694 #ifdef HAVE_SELINUX
695             char *role = NULL, *type = NULL;
696 #endif /* HAVE_SELINUX */
697
698             while ((m = tq_pop(&priv->hostlist)) != NULL) {
699                 efree(m->name);
700                 efree(m);
701             }
702             while ((cs = tq_pop(&priv->cmndlist)) != NULL) {
703 #ifdef HAVE_SELINUX
704                 /* Only free the first instance of a role/type. */
705                 if (cs->role != role) {
706                     role = cs->role;
707                     efree(cs->role);
708                 }
709                 if (cs->type != type) {
710                     type = cs->type;
711                     efree(cs->type);
712                 }
713 #endif /* HAVE_SELINUX */
714                 if (tq_last(&cs->runasuserlist) != runasuser) {
715                     runasuser = tq_last(&cs->runasuserlist);
716                     while ((m = tq_pop(&cs->runasuserlist)) != NULL) {
717                         efree(m->name);
718                         efree(m);
719                     }
720                 }
721                 if (tq_last(&cs->runasgrouplist) != runasgroup) {
722                     runasgroup = tq_last(&cs->runasgrouplist);
723                     while ((m = tq_pop(&cs->runasgrouplist)) != NULL) {
724                         efree(m->name);
725                         efree(m);
726                     }
727                 }
728                 if (cs->cmnd->type == COMMAND) {
729                         c = (struct sudo_command *) cs->cmnd->name;
730                         efree(c->cmnd);
731                         efree(c->args);
732                 }
733                 efree(cs->cmnd->name);
734                 efree(cs->cmnd);
735                 efree(cs);
736             }
737             efree(priv);
738         }
739         efree(us);
740     }
741     tq_init(&userspecs);
742
743     binding = NULL;
744     while ((d = tq_pop(&defaults)) != NULL) {
745         if (tq_last(&d->binding) != binding) {
746             binding = tq_last(&d->binding);
747             while ((m = tq_pop(&d->binding)) != NULL) {
748                 if (m->type == COMMAND) {
749                         c = (struct sudo_command *) m->name;
750                         efree(c->cmnd);
751                         efree(c->args);
752                 }
753                 efree(m->name);
754                 efree(m);
755             }
756         }
757         efree(d->var);
758         efree(d->val);
759         efree(d);
760     }
761     tq_init(&defaults);
762
763     init_aliases();
764
765     init_lexer();
766
767     efree(sudoers);
768     sudoers = path ? estrdup(path) : NULL;
769
770     parse_error = FALSE;
771     errorlineno = -1;
772     errorfile = NULL;
773     sudolineno = 1;
774     verbose = !quiet;
775 }