Imported Upstream version 1.8.6p8
[debian/sudo] / plugins / sudoers / gram.y
index 0315f243751caa4e62f1996677cf5d4db7cc18c9..9c9d39d335c057eedb2bc4ac516999acb6121bf3 100644 (file)
@@ -44,6 +44,9 @@
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif /* HAVE_UNISTD_H */
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
 #if defined(YYBISON) && defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
 # include <alloca.h>
 #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 <tok>    ERROR
 %token <tok>    TYPE                   /* SELinux type */
 %token <tok>    ROLE                   /* SELinux role */
+%token <tok>    PRIVS                  /* Solaris privileges */
+%token <tok>    LIMITPRIVS             /* Solaris limit privileges */
+%token <tok>    MYSELF                 /* run as myself, not another user */
 
 %type <cmndspec>  cmndspec
 %type <cmndspec>  cmndspeclist
@@ -186,6 +195,9 @@ yyerror(const char *s)
 %type <seinfo>   selinux
 %type <string>   rolespec
 %type <string>   typespec
+%type <privinfo>  solarisprivs
+%type <string>   privsspec
+%type <string>   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,7 +465,12 @@ 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 *privs)
  * 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) {