--- embedaddon/sudo/plugins/sudoers/gram.y 2012/05/29 12:26:49 1.1.1.2 +++ embedaddon/sudo/plugins/sudoers/gram.y 2012/10/09 09:29:52 1.1.1.3 @@ -44,6 +44,9 @@ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_INTTYPES_H +# include +#endif #if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__) # include #endif /* YYBISON && HAVE_ALLOCA_H && !__GNUC__ */ @@ -104,10 +107,12 @@ yyerror(const char *s) errorlineno = sudolineno; errorfile = estrdup(sudoers); } - if (trace_print != NULL) { + if (sudoers_warnings && s != NULL) { LEXTRACE("<*> "); - } else if (sudoers_warnings && s != NULL) { - warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno); +#ifndef TRACELEXER + if (trace_print == NULL || trace_print == sudoers_trace_print) + warningx(_(">>> %s: %s near line %d <<<"), sudoers, s, sudolineno); +#endif } parse_error = true; debug_return; @@ -123,6 +128,7 @@ yyerror(const char *s) struct sudo_command command; struct cmndtag tag; struct selinux_info seinfo; + struct solaris_privs_info privinfo; char *string; int tok; } @@ -161,6 +167,9 @@ yyerror(const char *s) %token ERROR %token TYPE /* SELinux type */ %token ROLE /* SELinux role */ +%token PRIVS /* Solaris privileges */ +%token LIMITPRIVS /* Solaris limit privileges */ +%token MYSELF /* run as myself, not another user */ %type cmndspec %type cmndspeclist @@ -186,6 +195,9 @@ yyerror(const char *s) %type selinux %type rolespec %type typespec +%type solarisprivs +%type privsspec +%type limitprivsspec %% @@ -313,6 +325,13 @@ cmndspeclist : cmndspec if ($3->type == NULL) $3->type = $3->prev->type; #endif /* HAVE_SELINUX */ +#ifdef HAVE_PRIV_SET + /* propagate privs & limitprivs */ + if ($3->privs == NULL) + $3->privs = $3->prev->privs; + if ($3->limitprivs == NULL) + $3->limitprivs = $3->prev->limitprivs; +#endif /* HAVE_PRIV_SET */ /* propagate tags and runas list */ if ($3->tags.nopasswd == UNSPEC) $3->tags.nopasswd = $3->prev->tags.nopasswd; @@ -336,7 +355,7 @@ cmndspeclist : cmndspec } ; -cmndspec : runasspec selinux cmndtag opcmnd { +cmndspec : runasspec selinux solarisprivs cmndtag opcmnd { struct cmndspec *cs = ecalloc(1, sizeof(*cs)); if ($1 != NULL) { list2tq(&cs->runasuserlist, $1->runasusers); @@ -350,8 +369,12 @@ cmndspec : runasspec selinux cmndtag opcmnd { cs->role = $2.role; cs->type = $2.type; #endif - cs->tags = $3; - cs->cmnd = $4; +#ifdef HAVE_PRIV_SET + cs->privs = $3.privs; + cs->limitprivs = $3.limitprivs; +#endif + cs->tags = $4; + cs->cmnd = $5; cs->prev = cs; cs->next = NULL; /* sudo "ALL" implies the SETENV tag */ @@ -404,6 +427,36 @@ selinux : /* empty */ { } ; +privsspec : PRIVS '=' WORD { + $$ = $3; + } + ; +limitprivsspec : LIMITPRIVS '=' WORD { + $$ = $3; + } + ; + +solarisprivs : /* empty */ { + $$.privs = NULL; + $$.limitprivs = NULL; + } + | privsspec { + $$.privs = $1; + $$.limitprivs = NULL; + } + | limitprivsspec { + $$.privs = NULL; + $$.limitprivs = $1; + } + | privsspec limitprivsspec { + $$.privs = $1; + $$.limitprivs = $2; + } + | limitprivsspec privsspec { + $$.limitprivs = $1; + $$.privs = $2; + } + runasspec : /* empty */ { $$ = NULL; } @@ -412,8 +465,13 @@ runasspec : /* empty */ { } ; -runaslist : userlist { +runaslist : /* empty */ { $$ = ecalloc(1, sizeof(struct runascontainer)); + $$->runasusers = new_member(NULL, MYSELF); + /* $$->runasgroups = NULL; */ + } + | userlist { + $$ = ecalloc(1, sizeof(struct runascontainer)); $$->runasusers = $1; /* $$->runasgroups = NULL; */ } @@ -427,6 +485,11 @@ runaslist : userlist { /* $$->runasusers = NULL; */ $$->runasgroups = $2; } + | ':' { + $$ = ecalloc(1, sizeof(struct runascontainer)); + $$->runasusers = new_member(NULL, MYSELF); + /* $$->runasgroups = NULL; */ + } ; cmndtag : /* empty */ { @@ -696,7 +759,7 @@ add_userspec(struct member *members, struct privilege * the current sudoers file to path. */ void -init_parser(const char *path, int quiet) +init_parser(const char *path, bool quiet) { struct defaults *d; struct member *m, *binding; @@ -716,6 +779,9 @@ init_parser(const char *path, int quiet) #ifdef HAVE_SELINUX char *role = NULL, *type = NULL; #endif /* HAVE_SELINUX */ +#ifdef HAVE_PRIV_SET + char *privs = NULL, *limitprivs = NULL; +#endif /* HAVE_PRIV_SET */ while ((m = tq_pop(&priv->hostlist)) != NULL) { efree(m->name); @@ -733,6 +799,17 @@ init_parser(const char *path, int quiet) efree(cs->type); } #endif /* HAVE_SELINUX */ +#ifdef HAVE_PRIV_SET + /* Only free the first instance of privs/limitprivs. */ + if (cs->privs != privs) { + privs = cs->privs; + efree(cs->privs); + } + if (cs->limitprivs != limitprivs) { + limitprivs = cs->limitprivs; + efree(cs->limitprivs); + } +#endif /* HAVE_PRIV_SET */ if (tq_last(&cs->runasuserlist) != runasuser) { runasuser = tq_last(&cs->runasuserlist); while ((m = tq_pop(&cs->runasuserlist)) != NULL) {