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