| version 1.1, 2012/02/21 16:23:02 | version 1.1.1.2, 2012/05/29 12:26:49 | 
| Line 1 | Line 1 | 
 | %{ | %{ | 
 | /* | /* | 
| * Copyright (c) 1996, 1998-2005, 2007-2011 | * Copyright (c) 1996, 1998-2005, 2007-2012 | 
 | *      Todd C. Miller <Todd.Miller@courtesan.com> | *      Todd C. Miller <Todd.Miller@courtesan.com> | 
 | * | * | 
 | * Permission to use, copy, modify, and distribute this software for any | * Permission to use, copy, modify, and distribute this software for any | 
| Line 52 | Line 52 | 
 | #include "sudoers.h" /* XXX */ | #include "sudoers.h" /* XXX */ | 
 | #include "parse.h" | #include "parse.h" | 
 | #include "toke.h" | #include "toke.h" | 
 |  | #include "gram.h" | 
 |  |  | 
 | /* | /* | 
 | * We must define SIZE_MAX for yacc's skeleton.c. | * We must define SIZE_MAX for yacc's skeleton.c. | 
| Line 70 | Line 71 | 
 | * Globals | * Globals | 
 | */ | */ | 
 | extern int sudolineno; | extern int sudolineno; | 
 |  | extern int last_token; | 
 | extern char *sudoers; | extern char *sudoers; | 
| static int verbose = FALSE; | bool sudoers_warnings = true; | 
| int parse_error = FALSE; | bool parse_error = false; | 
| int pedantic = FALSE; |  | 
 | int errorlineno = -1; | int errorlineno = -1; | 
 | char *errorfile = NULL; | char *errorfile = NULL; | 
 |  |  | 
| Line 92  static struct member *new_member(char *, int); | Line 93  static struct member *new_member(char *, int); | 
 | void | void | 
 | yyerror(const char *s) | yyerror(const char *s) | 
 | { | { | 
 |  | debug_decl(yyerror, SUDO_DEBUG_PARSER) | 
 |  |  | 
 |  | /* If we last saw a newline the error is on the preceding line. */ | 
 |  | if (last_token == COMMENT) | 
 |  | sudolineno--; | 
 |  |  | 
 | /* Save the line the first error occurred on. */ | /* Save the line the first error occurred on. */ | 
 | if (errorlineno == -1) { | if (errorlineno == -1) { | 
| errorlineno = sudolineno ? sudolineno - 1 : 0; | errorlineno = sudolineno; | 
 | errorfile = estrdup(sudoers); | errorfile = estrdup(sudoers); | 
 | } | } | 
 | if (trace_print != NULL) { | if (trace_print != NULL) { | 
 | LEXTRACE("<*> "); | LEXTRACE("<*> "); | 
| } else if (verbose && s != NULL) { | } else if (sudoers_warnings && s != NULL) { | 
| warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, | warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno); | 
| sudolineno ? sudolineno - 1 : 0); |  | 
 | } | } | 
| parse_error = TRUE; | parse_error = true; | 
|  | debug_return; | 
 | } | } | 
 | %} | %} | 
 |  |  | 
| Line 236  defaults_list : defaults_entry | Line 243  defaults_list : defaults_entry | 
 | ; | ; | 
 |  |  | 
 | defaults_entry  :       DEFVAR { | defaults_entry  :       DEFVAR { | 
| $$ = new_default($1, NULL, TRUE); | $$ = new_default($1, NULL, true); | 
 | } | } | 
 | |       '!' DEFVAR { | |       '!' DEFVAR { | 
| $$ = new_default($2, NULL, FALSE); | $$ = new_default($2, NULL, false); | 
 | } | } | 
 | |       DEFVAR '=' WORD { | |       DEFVAR '=' WORD { | 
| $$ = new_default($1, $3, TRUE); | $$ = new_default($1, $3, true); | 
 | } | } | 
 | |       DEFVAR '+' WORD { | |       DEFVAR '+' WORD { | 
 | $$ = new_default($1, $3, '+'); | $$ = new_default($1, $3, '+'); | 
| Line 260  privileges : privilege | Line 267  privileges : privilege | 
 | ; | ; | 
 |  |  | 
 | privilege       :       hostlist '=' cmndspeclist { | privilege       :       hostlist '=' cmndspeclist { | 
| struct privilege *p = emalloc(sizeof(*p)); | struct privilege *p = ecalloc(1, sizeof(*p)); | 
 | list2tq(&p->hostlist, $1); | list2tq(&p->hostlist, $1); | 
 | list2tq(&p->cmndlist, $3); | list2tq(&p->cmndlist, $3); | 
 | p->prev = p; | p->prev = p; | 
| p->next = NULL; | /* p->next = NULL; */ | 
 | $$ = p; | $$ = p; | 
 | } | } | 
 | ; | ; | 
 |  |  | 
 | ophost          :       host { | ophost          :       host { | 
 | $$ = $1; | $$ = $1; | 
| $$->negated = FALSE; | $$->negated = false; | 
 | } | } | 
 | |       '!' host { | |       '!' host { | 
 | $$ = $2; | $$ = $2; | 
| $$->negated = TRUE; | $$->negated = true; | 
 | } | } | 
 | ; | ; | 
 |  |  | 
| Line 330  cmndspeclist : cmndspec | Line 337  cmndspeclist : cmndspec | 
 | ; | ; | 
 |  |  | 
 | cmndspec        :       runasspec selinux cmndtag opcmnd { | cmndspec        :       runasspec selinux cmndtag opcmnd { | 
| struct cmndspec *cs = emalloc(sizeof(*cs)); | struct cmndspec *cs = ecalloc(1, sizeof(*cs)); | 
 | if ($1 != NULL) { | if ($1 != NULL) { | 
 | list2tq(&cs->runasuserlist, $1->runasusers); | list2tq(&cs->runasuserlist, $1->runasusers); | 
 | list2tq(&cs->runasgrouplist, $1->runasgroups); | list2tq(&cs->runasgrouplist, $1->runasgroups); | 
| Line 357  cmndspec : runasspec selinux cmndtag opcmnd { | Line 364  cmndspec : runasspec selinux cmndtag opcmnd { | 
 |  |  | 
 | opcmnd          :       cmnd { | opcmnd          :       cmnd { | 
 | $$ = $1; | $$ = $1; | 
| $$->negated = FALSE; | $$->negated = false; | 
 | } | } | 
 | |       '!' cmnd { | |       '!' cmnd { | 
 | $$ = $2; | $$ = $2; | 
| $$->negated = TRUE; | $$->negated = true; | 
 | } | } | 
 | ; | ; | 
 |  |  | 
| Line 406  runasspec : /* empty */ { | Line 413  runasspec : /* empty */ { | 
 | ; | ; | 
 |  |  | 
 | runaslist       :       userlist { | runaslist       :       userlist { | 
| $$ = emalloc(sizeof(struct runascontainer)); | $$ = ecalloc(1, sizeof(struct runascontainer)); | 
 | $$->runasusers = $1; | $$->runasusers = $1; | 
| $$->runasgroups = NULL; | /* $$->runasgroups = NULL; */ | 
 | } | } | 
 | |       userlist ':' grouplist { | |       userlist ':' grouplist { | 
| $$ = emalloc(sizeof(struct runascontainer)); | $$ = ecalloc(1, sizeof(struct runascontainer)); | 
 | $$->runasusers = $1; | $$->runasusers = $1; | 
 | $$->runasgroups = $3; | $$->runasgroups = $3; | 
 | } | } | 
 | |       ':' grouplist { | |       ':' grouplist { | 
| $$ = emalloc(sizeof(struct runascontainer)); | $$ = ecalloc(1, sizeof(struct runascontainer)); | 
| $$->runasusers = NULL; | /* $$->runasusers = NULL; */ | 
 | $$->runasgroups = $2; | $$->runasgroups = $2; | 
 | } | } | 
 | ; | ; | 
| Line 427  cmndtag  : /* empty */ { | Line 434  cmndtag  : /* empty */ { | 
 | $$.log_input = $$.log_output = UNSPEC; | $$.log_input = $$.log_output = UNSPEC; | 
 | } | } | 
 | |       cmndtag NOPASSWD { | |       cmndtag NOPASSWD { | 
| $$.nopasswd = TRUE; | $$.nopasswd = true; | 
 | } | } | 
 | |       cmndtag PASSWD { | |       cmndtag PASSWD { | 
| $$.nopasswd = FALSE; | $$.nopasswd = false; | 
 | } | } | 
 | |       cmndtag NOEXEC { | |       cmndtag NOEXEC { | 
| $$.noexec = TRUE; | $$.noexec = true; | 
 | } | } | 
 | |       cmndtag EXEC { | |       cmndtag EXEC { | 
| $$.noexec = FALSE; | $$.noexec = false; | 
 | } | } | 
 | |       cmndtag SETENV { | |       cmndtag SETENV { | 
| $$.setenv = TRUE; | $$.setenv = true; | 
 | } | } | 
 | |       cmndtag NOSETENV { | |       cmndtag NOSETENV { | 
| $$.setenv = FALSE; | $$.setenv = false; | 
 | } | } | 
 | |       cmndtag LOG_INPUT { | |       cmndtag LOG_INPUT { | 
| $$.log_input = TRUE; | $$.log_input = true; | 
 | } | } | 
 | |       cmndtag NOLOG_INPUT { | |       cmndtag NOLOG_INPUT { | 
| $$.log_input = FALSE; | $$.log_input = false; | 
 | } | } | 
 | |       cmndtag LOG_OUTPUT { | |       cmndtag LOG_OUTPUT { | 
| $$.log_output = TRUE; | $$.log_output = true; | 
 | } | } | 
 | |       cmndtag NOLOG_OUTPUT { | |       cmndtag NOLOG_OUTPUT { | 
| $$.log_output = FALSE; | $$.log_output = false; | 
 | } | } | 
 | ; | ; | 
 |  |  | 
| Line 465  cmnd  : ALL { | Line 472  cmnd  : ALL { | 
 | $$ = new_member($1, ALIAS); | $$ = new_member($1, ALIAS); | 
 | } | } | 
 | |       COMMAND { | |       COMMAND { | 
| struct sudo_command *c = emalloc(sizeof(*c)); | struct sudo_command *c = ecalloc(1, sizeof(*c)); | 
 | c->cmnd = $1.cmnd; | c->cmnd = $1.cmnd; | 
 | c->args = $1.args; | c->args = $1.args; | 
 | $$ = new_member((char *)c, COMMAND); | $$ = new_member((char *)c, COMMAND); | 
| Line 547  userlist : opuser | Line 554  userlist : opuser | 
 |  |  | 
 | opuser          :       user { | opuser          :       user { | 
 | $$ = $1; | $$ = $1; | 
| $$->negated = FALSE; | $$->negated = false; | 
 | } | } | 
 | |       '!' user { | |       '!' user { | 
 | $$ = $2; | $$ = $2; | 
| $$->negated = TRUE; | $$->negated = true; | 
 | } | } | 
 | ; | ; | 
 |  |  | 
| Line 581  grouplist : opgroup | Line 588  grouplist : opgroup | 
 |  |  | 
 | opgroup         :       group { | opgroup         :       group { | 
 | $$ = $1; | $$ = $1; | 
| $$->negated = FALSE; | $$->negated = false; | 
 | } | } | 
 | |       '!' group { | |       '!' group { | 
 | $$ = $2; | $$ = $2; | 
| $$->negated = TRUE; | $$->negated = true; | 
 | } | } | 
 | ; | ; | 
 |  |  | 
| Line 605  static struct defaults * | Line 612  static struct defaults * | 
 | new_default(char *var, char *val, int op) | new_default(char *var, char *val, int op) | 
 | { | { | 
 | struct defaults *d; | struct defaults *d; | 
 |  | debug_decl(new_default, SUDO_DEBUG_PARSER) | 
 |  |  | 
| d = emalloc(sizeof(struct defaults)); | d = ecalloc(1, sizeof(struct defaults)); | 
 | d->var = var; | d->var = var; | 
 | d->val = val; | d->val = val; | 
 | tq_init(&d->binding); | tq_init(&d->binding); | 
| d->type = 0; | /* d->type = 0; */ | 
 | d->op = op; | d->op = op; | 
 | d->prev = d; | d->prev = d; | 
| d->next = NULL; | /* d->next = NULL; */ | 
 |  |  | 
| return d; | debug_return_ptr(d); | 
 | } | } | 
 |  |  | 
 | static struct member * | static struct member * | 
 | new_member(char *name, int type) | new_member(char *name, int type) | 
 | { | { | 
 | struct member *m; | struct member *m; | 
 |  | debug_decl(new_member, SUDO_DEBUG_PARSER) | 
 |  |  | 
| m = emalloc(sizeof(struct member)); | m = ecalloc(1, sizeof(struct member)); | 
 | m->name = name; | m->name = name; | 
 | m->type = type; | m->type = type; | 
 | m->prev = m; | m->prev = m; | 
| m->next = NULL; | /* m->next = NULL; */ | 
 |  |  | 
| return m; | debug_return_ptr(m); | 
 | } | } | 
 |  |  | 
 | /* | /* | 
| Line 642  add_defaults(int type, struct member *bmem, struct def | Line 651  add_defaults(int type, struct member *bmem, struct def | 
 | { | { | 
 | struct defaults *d; | struct defaults *d; | 
 | struct member_list binding; | struct member_list binding; | 
 |  | debug_decl(add_defaults, SUDO_DEBUG_PARSER) | 
 |  |  | 
 | /* | /* | 
 | * We can only call list2tq once on bmem as it will zero | * We can only call list2tq once on bmem as it will zero | 
| Line 657  add_defaults(int type, struct member *bmem, struct def | Line 667  add_defaults(int type, struct member *bmem, struct def | 
 | d->binding = binding; | d->binding = binding; | 
 | } | } | 
 | tq_append(&defaults, defs); | tq_append(&defaults, defs); | 
 |  |  | 
 |  | debug_return; | 
 | } | } | 
 |  |  | 
 | /* | /* | 
| Line 667  static void | Line 679  static void | 
 | add_userspec(struct member *members, struct privilege *privs) | add_userspec(struct member *members, struct privilege *privs) | 
 | { | { | 
 | struct userspec *u; | struct userspec *u; | 
 |  | debug_decl(add_userspec, SUDO_DEBUG_PARSER) | 
 |  |  | 
| u = emalloc(sizeof(*u)); | u = ecalloc(1, sizeof(*u)); | 
 | list2tq(&u->users, members); | list2tq(&u->users, members); | 
 | list2tq(&u->privileges, privs); | list2tq(&u->privileges, privs); | 
 | u->prev = u; | u->prev = u; | 
| u->next = NULL; | /* u->next = NULL; */ | 
 | tq_append(&userspecs, u); | tq_append(&userspecs, u); | 
 |  |  | 
 |  | debug_return; | 
 | } | } | 
 |  |  | 
 | /* | /* | 
| Line 689  init_parser(const char *path, int quiet) | Line 704  init_parser(const char *path, int quiet) | 
 | struct privilege *priv; | struct privilege *priv; | 
 | struct cmndspec *cs; | struct cmndspec *cs; | 
 | struct sudo_command *c; | struct sudo_command *c; | 
 |  | debug_decl(init_parser, SUDO_DEBUG_PARSER) | 
 |  |  | 
 | while ((us = tq_pop(&userspecs)) != NULL) { | while ((us = tq_pop(&userspecs)) != NULL) { | 
 | while ((m = tq_pop(&us->users)) != NULL) { | while ((m = tq_pop(&us->users)) != NULL) { | 
| Line 773  init_parser(const char *path, int quiet) | Line 789  init_parser(const char *path, int quiet) | 
 | efree(sudoers); | efree(sudoers); | 
 | sudoers = path ? estrdup(path) : NULL; | sudoers = path ? estrdup(path) : NULL; | 
 |  |  | 
| parse_error = FALSE; | parse_error = false; | 
 | errorlineno = -1; | errorlineno = -1; | 
| errorfile = NULL; | errorfile = sudoers; | 
| verbose = !quiet; | sudoers_warnings = !quiet; | 
|  |  | 
|  | debug_return; | 
 | } | } |