Imported Upstream version 1.6.9p6
[debian/sudo] / sudo.tab.c
index 1bd3a18a5d2aaeb1e1b171ca2571f5a23415bbe5..6740c724f305b5b0f0e6d686f7047812d68dfb92 100644 (file)
@@ -4,7 +4,7 @@ static char yyrcsid[]
 #if __GNUC__ >= 2
   __attribute__ ((unused))
 #endif /* __GNUC__ >= 2 */
-  = "$OpenBSD: skeleton.c,v 1.24 2005/06/10 16:40:45 pvalchev Exp $";
+  = "$OpenBSD: skeleton.c,v 1.26 2006/04/20 16:51:32 deraadt Exp $";
 #endif
 #include <stdlib.h>
 #define YYBYACC 1
@@ -18,7 +18,8 @@ static char yyrcsid[]
 #define YYPREFIX "yy"
 #line 2 "parse.yacc"
 /*
- * Copyright (c) 1996, 1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1996, 1998-2004, 2007
+ *     Todd C. Miller <Todd.Miller@courtesan.com>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -47,7 +48,7 @@ static char yyrcsid[]
  *       list_matches() can format things the way it wants.
  */
 
-#include "config.h"
+#include <config.h>
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -89,7 +90,7 @@ static char yyrcsid[]
 #endif /* HAVE_LSEARCH */
 
 #ifndef lint
-static const char rcsid[] = "$Sudo: parse.yacc,v 1.204 2004/08/11 18:29:10 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: sudo.tab.c,v 1.76.2.6 2007/08/13 16:30:47 millert Exp $";
 #endif /* lint */
 
 /*
@@ -142,6 +143,7 @@ int top = 0, stacksize = 0;
        match[top].runas  = UNSPEC; \
        match[top].nopass = def_authenticate ? UNSPEC : TRUE; \
        match[top].noexec = def_noexec ? TRUE : UNSPEC; \
+       match[top].setenv = def_setenv ? TRUE : UNSPEC; \
        top++; \
     } while (0)
 
@@ -157,6 +159,7 @@ int top = 0, stacksize = 0;
        match[top].runas  = match[top-1].runas; \
        match[top].nopass = match[top-1].nopass; \
        match[top].noexec = match[top-1].noexec; \
+       match[top].setenv = match[top-1].setenv; \
        top++; \
     } while (0)
 
@@ -234,7 +237,7 @@ yyerror(s)
     }
     parse_error = TRUE;
 }
-#line 221 "parse.yacc"
+#line 224 "parse.yacc"
 #ifndef YYSTYPE_DEFINED
 #define YYSTYPE_DEFINED
 typedef union {
@@ -244,7 +247,7 @@ typedef union {
     int tok;
 } YYSTYPE;
 #endif /* YYSTYPE_DEFINED */
-#line 248 "sudo.tab.c"
+#line 251 "sudo.tab.c"
 #define COMMAND 257
 #define ALIAS 258
 #define DEFVAR 259
@@ -261,13 +264,15 @@ typedef union {
 #define PASSWD 270
 #define NOEXEC 271
 #define EXEC 272
-#define ALL 273
-#define COMMENT 274
-#define HOSTALIAS 275
-#define CMNDALIAS 276
-#define USERALIAS 277
-#define RUNASALIAS 278
-#define ERROR 279
+#define SETENV 273
+#define NOSETENV 274
+#define ALL 275
+#define COMMENT 276
+#define HOSTALIAS 277
+#define CMNDALIAS 278
+#define USERALIAS 279
+#define RUNASALIAS 280
+#define ERROR 281
 #define YYERRCODE 256
 #if defined(__cplusplus) || defined(__STDC__)
 const short yylhs[] =
@@ -280,11 +285,11 @@ short yylhs[] =
    17,   22,   22,   22,   22,   22,   10,   10,   23,   25,
    25,    2,    2,    2,    2,    2,   24,   24,   26,   29,
    30,   29,   27,   27,    5,    5,    4,   31,    4,    3,
-    3,    3,    3,    3,   28,   28,   28,   28,   28,    1,
-    1,    1,   12,   12,   33,   32,   20,   20,   13,   13,
-   35,   34,   36,   36,   14,   14,   38,   37,   11,   11,
-   40,   39,    8,    8,   41,   41,    6,    6,    6,    6,
-    6,
+    3,    3,    3,    3,   28,   28,   28,   28,   28,   28,
+   28,    1,    1,    1,   12,   12,   33,   32,   20,   20,
+   13,   13,   35,   34,   36,   36,   14,   14,   38,   37,
+   11,   11,   40,   39,    8,    8,   41,   41,    6,    6,
+    6,    6,    6,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yylen[] =
@@ -297,11 +302,11 @@ short yylen[] =
     3,    1,    2,    3,    3,    3,    1,    3,    3,    1,
     2,    1,    1,    1,    1,    1,    1,    3,    3,    1,
     0,    3,    0,    2,    1,    3,    1,    0,    3,    1,
-    1,    1,    1,    1,    0,    2,    2,    2,    2,    1,
-    1,    1,    1,    3,    0,    4,    1,    3,    1,    3,
-    0,    4,    1,    3,    1,    3,    0,    4,    1,    3,
-    0,    4,    1,    3,    1,    2,    1,    1,    1,    1,
-    1,
+    1,    1,    1,    1,    0,    2,    2,    2,    2,    2,
+    2,    1,    1,    1,    1,    3,    0,    4,    1,    3,
+    1,    3,    0,    4,    1,    3,    1,    3,    0,    4,
+    1,    3,    0,    4,    1,    3,    1,    2,    1,    1,
+    1,    1,    1,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yydefred[] =
@@ -310,19 +315,19 @@ short yydefred[] =
 #endif
        {                                      0,
     0,   13,   18,   14,   16,    3,    0,    0,    0,    0,
-    0,    1,    0,   11,    0,    4,    0,    0,    0,   65,
-    0,   63,   71,    0,   69,   81,    0,   79,   77,    0,
-   75,    2,   90,   89,   88,   87,   91,    0,   85,    0,
-   83,    0,    0,   12,    0,   36,   33,   34,   35,   32,
-    0,   30,    0,   67,    0,   53,   52,   51,   50,   54,
+    0,    1,    0,   11,    0,    4,    0,    0,    0,   67,
+    0,   65,   73,    0,   71,   83,    0,   81,   79,    0,
+   77,    2,   92,   91,   90,   89,   93,    0,   87,    0,
+   85,    0,    0,   12,    0,   36,   33,   34,   35,   32,
+    0,   30,    0,   69,    0,   53,   52,   51,   50,   54,
    48,   47,   45,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   86,    0,    0,    0,   27,    0,    0,    0,
-   23,    0,   31,    0,    0,    0,    0,   64,    0,   70,
-    0,   80,    0,   76,   84,    0,    0,   24,   25,   26,
-   21,   68,   49,   46,    0,   62,   61,   60,   41,   40,
-   73,    0,    0,    0,   28,    0,    0,   37,   55,    0,
-    0,    0,    0,    0,   42,   74,   38,   56,   57,   58,
-   59,   39,
+    0,    0,   88,    0,    0,    0,   27,    0,    0,    0,
+   23,    0,   31,    0,    0,    0,    0,   66,    0,   72,
+    0,   82,    0,   78,   86,    0,    0,   24,   25,   26,
+   21,   70,   49,   46,    0,   64,   63,   62,   41,   40,
+   75,    0,    0,    0,   28,    0,    0,   37,   55,    0,
+    0,    0,    0,    0,   42,   76,   38,   56,   57,   58,
+   59,   60,   61,   39,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yydgoto[] =
@@ -341,122 +346,118 @@ const short yysindex[] =
 #else
 short yysindex[] =
 #endif
-       {                                   -239,
- -264,    0,    0,    0,    0,    0, -247, -240, -236, -235,
- -239,    0,  307,    0,  -31,    0,  328,  307,  320,    0,
-   -9,    0,    0,   -8,    0,    0,   -4,    0,    0,    2,
-    0,    0,    0,    0,    0,    0,    0, -242,    0,  294,
-    0,   -3, -226,    0,   11,    0,    0,    0,    0,    0,
- -217,    0,   17,    0,   20,    0,    0,    0,    0,    0,
-    0,    0,    0,   21,    5, -247,    6, -240,    7, -236,
-    8, -235,    0,  307,   13,  -32,    0, -191, -190, -189,
-    0,  -31,    0,  328, -210,  320,  328,    0,  -33,    0,
-  307,    0,  320,    0,    0,  328, -192,    0,    0,    0,
-    0,    0,    0,    0,   17,    0,    0,    0,    0,    0,
-    0,   34,   20,   21,    0,  320,   35,    0,    0, -243,
-  -33,   21, -192,  -27,    0,    0,    0,    0,    0,    0,
-    0,    0,};
+       {                                   -229,
+ -256,    0,    0,    0,    0,    0, -237, -234, -226, -225,
+ -229,    0,   62,    0,  -33,    0,   88,   62,  114,    0,
+  -15,    0,    0,  -12,    0,    0,   -5,    0,    0,   -4,
+    0,    0,    0,    0,    0,    0,    0, -244,    0,  -28,
+    0,  -36, -204,    0,   14,    0,    0,    0,    0,    0,
+ -219,    0,   19,    0,   20,    0,    0,    0,    0,    0,
+    0,    0,    0,   21,    5, -237,    6, -234,    7, -226,
+    8, -225,    0,   62,   12,  -21,    0, -192, -191, -187,
+    0,  -33,    0,   88, -201,  114,   88,    0,  276,    0,
+   62,    0,  114,    0,    0,   88, -189,    0,    0,    0,
+    0,    0,    0,    0,   19,    0,    0,    0,    0,    0,
+    0,   33,   20,   21,    0,  114,   36,    0,    0, -247,
+  276,   21, -189,  -29,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short yyrindex[] =
 #else
 short yyrindex[] =
 #endif
-       {                                    342,
+       {                                    140,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-  342,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-  139,    0,    0,  162,    0,    0,  185,    0,    0,  208,
+  140,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  156,    0,    0,  181,    0,    0,  206,    0,    0,  236,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    1,    0,    0,  236,    0,    0,    0,    0,    0,
-    0,    0,  -30,    0,  -26,    0,    0,    0,    0,    0,
-    0,    0,    0,  -25,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,  260,    0,    0,    0,    0,    0,
+    0,    1,    0,    0,  261,    0,    0,    0,    0,    0,
+    0,    0,  -25,    0,  -11,    0,    0,    0,    0,    0,
+    0,    0,    0,   -3,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  300,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,  -20,    0,    0,    0,
-    0,    0,    0,    0,   24,    0,    0,    0,    0,    0,
-    0,   47,   70,   93,    0,    0,  116,    0,    0,    0,
-    0,  271,  -20,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,};
+    0,    0,    0,    0,   26,    0,    0,    0,    0,    0,
+    0,   52,   78,  104,    0,    0,  130,    0,    0,    0,
+    0,  274,  -20,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short yygindex[] =
 #else
 short yygindex[] =
 #endif
        {                                      0,
-  -39,   32,   -1,    3,  -84,   48,   74,  -14,    0,    0,
-    0,    0,    0,    0,    0,    0,    9,    0,    0,  -12,
-    0,    0,   -6,    0,    4,  -36,    0,    0,  -62,    0,
-    0,   26,    0,   27,    0,    0,   22,    0,   28,    0,
-   23,
+  -39,   31,   -2,    2,  -87,   48,   76,  -16,    0,    0,
+    0,    0,    0,    0,    0,    0,    9,    0,    0,  -14,
+    0,    0,   -7,    0,   10,  -31,    0,    0, -109,    0,
+    0,   24,    0,   25,    0,    0,   27,    0,   28,    0,
+   22,
 };
-#define YYTABLESIZE 615
+#define YYTABLESIZE 580
 #if defined(__cplusplus) || defined(__STDC__)
 const short yytable[] =
 #else
 short yytable[] =
 #endif
-       {                                     109,
-   22,   43,   19,   55,   53,  109,   15,   17,  114,   16,
-   20,   84,   43,  106,  107,   33,    1,   23,   34,   35,
-   36,   26,   29,   66,    2,    3,    4,    5,   97,  108,
-   37,  122,   81,   22,    6,    7,    8,    9,   10,   79,
-   46,   80,   47,   48,   22,   49,   72,   56,   66,   68,
-   57,   58,   59,   70,   82,   50,   66,   78,  126,   72,
-   84,  132,   60,   74,   86,   87,   89,   91,   93,   82,
-   96,   98,   99,  100,  105,  116,  113,  121,  123,   72,
-  125,   66,   83,  103,   32,   73,  127,  102,  104,  115,
-  101,   88,   78,   94,   90,    0,   95,   92,    0,    0,
-    0,    0,   82,    0,   72,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   29,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   78,    0,   82,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    8,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,   29,    0,
-   78,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    9,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    8,    0,   29,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    7,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    9,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,   10,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    7,    0,    0,
-    0,    0,    0,  106,  107,    0,    0,   42,   19,  106,
-  107,    0,   15,   17,    0,   20,   43,   43,    0,  108,
-   10,  128,  129,  130,  131,  108,    0,    0,   43,   43,
-   43,   43,   43,    0,    0,    0,   22,    0,   22,    6,
-    0,   22,   22,   22,   22,   22,   22,   22,   20,    0,
-    0,    0,    0,   22,   22,   22,   22,   22,   22,   66,
-    0,   66,    0,    0,   66,   66,   66,   66,   66,   66,
-   66,    0,    6,    0,    0,    0,   66,   66,   66,   66,
-   66,   66,   72,   44,   72,    0,    0,   72,   72,   72,
-   72,   72,   72,   72,    0,    0,    0,    0,    0,   72,
-   72,   72,   72,   72,   72,   82,   51,   82,    0,    0,
-   82,   82,   82,   82,   82,   82,   82,   74,    0,   38,
-    0,    0,   82,   82,   82,   82,   82,   82,   78,    0,
-   78,    0,   61,   78,   78,   78,   78,   78,   78,   78,
-   51,    0,    0,    0,    0,   78,   78,   78,   78,   78,
-   78,   29,    0,   29,    5,    0,   29,   29,   29,   29,
-   29,   29,   29,    0,    0,    0,    0,    0,   29,   29,
-   29,   29,   29,   29,    8,    0,    8,    0,    0,    8,
-    8,    8,    8,    8,    8,    8,    0,    0,    0,    0,
-    0,    8,    8,    8,    8,    8,    8,    9,    0,    9,
-    0,    0,    9,    9,    9,    9,    9,    9,    9,    0,
-    0,    0,    0,    0,    9,    9,    9,    9,    9,    9,
-    7,    0,    7,    0,    0,    7,    7,    7,    7,    7,
-    7,    7,    0,    0,    0,    0,    0,    7,    7,    7,
-    7,    7,    7,   10,    0,   10,    0,    0,   10,   10,
-   10,   10,   10,   10,   10,    0,    0,    0,    0,    0,
-   10,   10,   10,   10,   10,   10,    0,    0,    0,    0,
-    0,   20,    0,   20,    0,    0,   20,   20,   20,   20,
-   20,   20,   20,    0,    0,    0,    0,    0,   20,   20,
-   20,   20,   20,   20,    0,    6,    0,    6,    0,    0,
-    6,    6,    6,    6,    6,    6,    6,   44,   44,    0,
-    0,    0,    6,    6,    6,    6,    6,    6,    0,   44,
-   44,   44,   44,   44,    0,    0,    0,    0,    0,    0,
-    0,   46,    0,   47,   48,    0,   49,    0,    0,    0,
-    0,    0,    0,    0,   33,    0,   50,   34,   35,   36,
-    0,    0,    0,    0,    0,    0,    0,   56,    0,   37,
-   57,   58,   59,    0,    0,   46,    0,   47,   48,    0,
-   49,    0,   60,    0,    0,    0,    0,    0,    0,    5,
-   50,    0,    5,    5,    5,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    5,
+       {                                      43,
+   22,   55,   53,  109,   51,  114,   79,   19,   80,  106,
+  107,  126,   43,   33,  134,   74,   34,   35,   36,   16,
+   20,   15,   84,   23,   78,   68,    1,  108,  122,   17,
+   37,   26,   29,   22,    2,    3,    4,    5,   46,   97,
+   47,   48,   66,   49,   22,   68,    6,    7,    8,    9,
+   10,   74,   70,   72,   81,   50,   56,   82,   68,   57,
+   58,   59,   84,   74,   86,   87,   89,   91,   93,   96,
+   98,   99,  105,   60,  113,  100,  121,   84,  116,  123,
+  125,   83,  103,   68,   74,   73,   32,  104,  115,   88,
+  101,  127,   90,  102,   38,   95,    0,   92,   94,    0,
+    0,    0,    0,   80,    0,    0,    0,    0,    0,   74,
+   84,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+   51,    0,    0,    0,    0,    0,    0,    0,    0,   29,
+    0,    0,    0,    0,    0,   84,   80,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,   61,    0,    0,    0,
+    0,    0,    0,    0,    0,    8,    0,    0,    0,    0,
+    0,   80,   29,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    5,    0,    0,    0,    0,    0,    0,    0,
+    9,    0,    0,    0,    0,    0,    0,   29,    8,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
+    0,    0,    0,    9,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   42,    0,  106,  107,   46,
+    0,   47,   48,   19,   49,   10,   43,   43,    7,  128,
+  129,  130,  131,  132,  133,  108,   50,   15,   43,   43,
+   43,   43,   43,   43,   43,   17,   22,    0,   22,    0,
+   20,   22,   22,   22,   22,   22,   22,   22,   10,    0,
+    0,    0,    0,    0,    0,   22,   22,   22,   22,   22,
+   22,   68,    0,   68,    0,    0,   68,   68,   68,   68,
+   68,   68,   68,   20,    0,    0,    0,    0,    0,    6,
+   68,   68,   68,   68,   68,   68,   44,   74,  109,   74,
+    0,    0,   74,   74,   74,   74,   74,   74,   74,   33,
+    0,    0,   34,   35,   36,    0,   74,   74,   74,   74,
+   74,   74,    6,   84,    0,   84,   37,    0,   84,   84,
+   84,   84,   84,   84,   84,   46,    0,   47,   48,    0,
+   49,    0,   84,   84,   84,   84,   84,   84,    0,   80,
+    0,   80,   50,    0,   80,   80,   80,   80,   80,   80,
+   80,   56,    0,    0,   57,   58,   59,    0,   80,   80,
+   80,   80,   80,   80,    0,   29,    0,   29,   60,    0,
+   29,   29,   29,   29,   29,   29,   29,    5,    0,    0,
+    5,    5,    5,    0,   29,   29,   29,   29,   29,   29,
+    0,    8,    0,    8,    5,    0,    8,    8,    8,    8,
+    8,    8,    8,    0,    0,    0,    0,    0,    0,    0,
+    8,    8,    8,    8,    8,    8,    9,    0,    9,    0,
+    0,    9,    9,    9,    9,    9,    9,    9,    0,    0,
+    0,    0,    0,    0,    0,    9,    9,    9,    9,    9,
+    9,    7,    0,    7,    0,    0,    7,    7,    7,    7,
+    7,    7,    7,    0,    0,    0,    0,    0,    0,    0,
+    7,    7,    7,    7,    7,    7,    0,    0,    0,    0,
+    0,   10,    0,   10,    0,    0,   10,   10,   10,   10,
+   10,   10,   10,    0,    0,    0,    0,    0,    0,    0,
+   10,   10,   10,   10,   10,   10,   20,    0,   20,    0,
+    0,   20,   20,   20,   20,   20,   20,   20,    0,    0,
+   44,   44,  106,  107,    0,   20,   20,   20,   20,   20,
+   20,    0,   44,   44,   44,   44,   44,   44,   44,    0,
+  108,    0,    0,    0,    0,    6,    0,    6,    0,    0,
+    6,    6,    6,    6,    6,    6,    6,    0,    0,    0,
+    0,    0,    0,    0,    6,    6,    6,    6,    6,    6,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yycheck[] =
@@ -464,74 +465,70 @@ const short yycheck[] =
 short yycheck[] =
 #endif
        {                                      33,
-    0,   33,   33,   18,   17,   33,   33,   33,   93,  274,
-  258,   44,   33,  257,  258,  258,  256,  258,  261,  262,
-  263,  258,  258,    0,  264,  265,  266,  267,   61,  273,
-  273,  116,  259,   33,  274,  275,  276,  277,  278,   43,
-  258,   45,  260,  261,   44,  263,    0,  258,   58,   58,
-  261,  262,  263,   58,   44,  273,   33,   61,  121,   58,
-   44,  124,  273,   44,   44,   61,   61,   61,   61,    0,
-   58,  263,  263,  263,   87,  268,   91,   44,   44,   33,
-  120,   58,   51,   85,   11,   38,  123,   84,   86,   96,
-   82,   66,    0,   72,   68,   -1,   74,   70,   -1,   -1,
-   -1,   -1,   33,   -1,   58,   -1,   -1,   -1,   -1,   -1,
+    0,   18,   17,   33,   33,   93,   43,   33,   45,  257,
+  258,  121,   33,  258,  124,   44,  261,  262,  263,  276,
+  258,   33,   44,  258,   61,    0,  256,  275,  116,   33,
+  275,  258,  258,   33,  264,  265,  266,  267,  258,   61,
+  260,  261,   58,  263,   44,   58,  276,  277,  278,  279,
+  280,    0,   58,   58,  259,  275,  258,   44,   33,  261,
+  262,  263,   44,   44,   44,   61,   61,   61,   61,   58,
+  263,  263,   87,  275,   91,  263,   44,    0,  268,   44,
+  120,   51,   85,   58,   33,   38,   11,   86,   96,   66,
+   82,  123,   68,   84,   33,   74,   -1,   70,   72,   -1,
+   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,   58,
+   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,
+   -1,   -1,   -1,   -1,   -1,   58,   33,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
+   -1,   58,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+    0,   -1,   -1,   -1,   -1,   -1,   -1,   58,   33,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   33,   -1,   58,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,
-   58,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,    0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   33,   -1,   58,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,
-   -1,   -1,   -1,  257,  258,   -1,   -1,  259,  259,  257,
-  258,   -1,  259,  259,   -1,    0,  257,  258,   -1,  273,
-   33,  269,  270,  271,  272,  273,   -1,   -1,  269,  270,
-  271,  272,  273,   -1,   -1,   -1,  256,   -1,  258,    0,
-   -1,  261,  262,  263,  264,  265,  266,  267,   33,   -1,
-   -1,   -1,   -1,  273,  274,  275,  276,  277,  278,  256,
-   -1,  258,   -1,   -1,  261,  262,  263,  264,  265,  266,
-  267,   -1,   33,   -1,   -1,   -1,  273,  274,  275,  276,
-  277,  278,  256,   33,  258,   -1,   -1,  261,  262,  263,
-  264,  265,  266,  267,   -1,   -1,   -1,   -1,   -1,  273,
-  274,  275,  276,  277,  278,  256,   33,  258,   -1,   -1,
-  261,  262,  263,  264,  265,  266,  267,   44,   -1,   33,
-   -1,   -1,  273,  274,  275,  276,  277,  278,  256,   -1,
-  258,   -1,   33,  261,  262,  263,  264,  265,  266,  267,
-   33,   -1,   -1,   -1,   -1,  273,  274,  275,  276,  277,
-  278,  256,   -1,  258,   33,   -1,  261,  262,  263,  264,
-  265,  266,  267,   -1,   -1,   -1,   -1,   -1,  273,  274,
-  275,  276,  277,  278,  256,   -1,  258,   -1,   -1,  261,
-  262,  263,  264,  265,  266,  267,   -1,   -1,   -1,   -1,
-   -1,  273,  274,  275,  276,  277,  278,  256,   -1,  258,
-   -1,   -1,  261,  262,  263,  264,  265,  266,  267,   -1,
-   -1,   -1,   -1,   -1,  273,  274,  275,  276,  277,  278,
-  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,  265,
-  266,  267,   -1,   -1,   -1,   -1,   -1,  273,  274,  275,
-  276,  277,  278,  256,   -1,  258,   -1,   -1,  261,  262,
-  263,  264,  265,  266,  267,   -1,   -1,   -1,   -1,   -1,
-  273,  274,  275,  276,  277,  278,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  259,   -1,  257,  258,  258,
+   -1,  260,  261,  259,  263,    0,  257,  258,   33,  269,
+  270,  271,  272,  273,  274,  275,  275,  259,  269,  270,
+  271,  272,  273,  274,  275,  259,  256,   -1,  258,   -1,
+    0,  261,  262,  263,  264,  265,  266,  267,   33,   -1,
+   -1,   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,
+  280,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
+  265,  266,  267,   33,   -1,   -1,   -1,   -1,   -1,    0,
+  275,  276,  277,  278,  279,  280,   33,  256,   33,  258,
+   -1,   -1,  261,  262,  263,  264,  265,  266,  267,  258,
+   -1,   -1,  261,  262,  263,   -1,  275,  276,  277,  278,
+  279,  280,   33,  256,   -1,  258,  275,   -1,  261,  262,
+  263,  264,  265,  266,  267,  258,   -1,  260,  261,   -1,
+  263,   -1,  275,  276,  277,  278,  279,  280,   -1,  256,
+   -1,  258,  275,   -1,  261,  262,  263,  264,  265,  266,
+  267,  258,   -1,   -1,  261,  262,  263,   -1,  275,  276,
+  277,  278,  279,  280,   -1,  256,   -1,  258,  275,   -1,
+  261,  262,  263,  264,  265,  266,  267,  258,   -1,   -1,
+  261,  262,  263,   -1,  275,  276,  277,  278,  279,  280,
+   -1,  256,   -1,  258,  275,   -1,  261,  262,  263,  264,
+  265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  275,  276,  277,  278,  279,  280,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,  267,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,
+  280,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
+  265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  275,  276,  277,  278,  279,  280,   -1,   -1,   -1,   -1,
    -1,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
-  265,  266,  267,   -1,   -1,   -1,   -1,   -1,  273,  274,
-  275,  276,  277,  278,   -1,  256,   -1,  258,   -1,   -1,
-  261,  262,  263,  264,  265,  266,  267,  257,  258,   -1,
-   -1,   -1,  273,  274,  275,  276,  277,  278,   -1,  269,
-  270,  271,  272,  273,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,  258,   -1,  260,  261,   -1,  263,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  258,   -1,  273,  261,  262,  263,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,   -1,  273,
-  261,  262,  263,   -1,   -1,  258,   -1,  260,  261,   -1,
-  263,   -1,  273,   -1,   -1,   -1,   -1,   -1,   -1,  258,
-  273,   -1,  261,  262,  263,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  273,
+  265,  266,  267,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  275,  276,  277,  278,  279,  280,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,  267,   -1,   -1,
+  257,  258,  257,  258,   -1,  275,  276,  277,  278,  279,
+  280,   -1,  269,  270,  271,  272,  273,  274,  275,   -1,
+  275,   -1,   -1,   -1,   -1,  256,   -1,  258,   -1,   -1,
+  261,  262,  263,  264,  265,  266,  267,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  275,  276,  277,  278,  279,  280,
 };
 #define YYFINAL 11
 #ifndef YYDEBUG
 #define YYDEBUG 0
 #endif
-#define YYMAXTOKEN 279
+#define YYMAXTOKEN 281
 #if YYDEBUG
 #if defined(__cplusplus) || defined(__STDC__)
 const char * const yyname[] =
@@ -548,8 +545,8 @@ char *yyname[] =
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
 "COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS",
 "DEFAULTS_HOST","DEFAULTS_USER","DEFAULTS_RUNAS","RUNAS","NOPASSWD","PASSWD",
-"NOEXEC","EXEC","ALL","COMMENT","HOSTALIAS","CMNDALIAS","USERALIAS",
-"RUNASALIAS","ERROR",
+"NOEXEC","EXEC","SETENV","NOSETENV","ALL","COMMENT","HOSTALIAS","CMNDALIAS",
+"USERALIAS","RUNASALIAS","ERROR",
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const char * const yyrule[] =
@@ -616,6 +613,8 @@ char *yyrule[] =
 "cmndtag : cmndtag PASSWD",
 "cmndtag : cmndtag NOEXEC",
 "cmndtag : cmndtag EXEC",
+"cmndtag : cmndtag SETENV",
+"cmndtag : cmndtag NOSETENV",
 "cmnd : ALL",
 "cmnd : ALIAS",
 "cmnd : COMMAND",
@@ -662,6 +661,7 @@ char *yyrule[] =
 #endif
 #endif
 #define YYINITSTACKSIZE 200
+/* LINTUSED */
 int yydebug;
 int yynerrs;
 int yyerrflag;
@@ -674,7 +674,7 @@ short *yyss;
 short *yysslim;
 YYSTYPE *yyvs;
 int yystacksize;
-#line 886 "parse.yacc"
+#line 909 "parse.yacc"
 
 #define MOREALIASES (32)
 aliasinfo *aliases = NULL;
@@ -876,6 +876,12 @@ list_matches()
        else if (cm_list[count].nopasswd == FALSE && !def_authenticate)
            (void) fputs("PASSWD: ", stdout);
 
+       /* Is setenv enabled? */
+       if (cm_list[count].setenv == TRUE && !def_setenv)
+           (void) fputs("SETENV: ", stdout);
+       else if (cm_list[count].setenv == FALSE && def_setenv)
+           (void) fputs("NOSETENV: ", stdout);
+
        /* Print the actual command or expanded Cmnd_Alias. */
        key.alias = cm_list[count].cmnd;
        key.type = CMND_ALIAS;
@@ -888,17 +894,17 @@ list_matches()
 
     /* Be nice and free up space now that we are done. */
     for (count = 0; count < ga_list_len; count++) {
-       free(ga_list[count].alias);
-       free(ga_list[count].entries);
+       efree(ga_list[count].alias);
+       efree(ga_list[count].entries);
     }
-    free(ga_list);
+    efree(ga_list);
     ga_list = NULL;
 
     for (count = 0; count < cm_list_len; count++) {
-       free(cm_list[count].runas);
-       free(cm_list[count].cmnd);
+       efree(cm_list[count].runas);
+       efree(cm_list[count].cmnd);
     }
-    free(cm_list);
+    efree(cm_list);
     cm_list = NULL;
     cm_list_len = 0;
     cm_list_size = 0;
@@ -960,8 +966,8 @@ reset_aliases()
 
     if (aliases) {
        for (n = 0; n < naliases; n++)
-           free(aliases[n].name);
-       free(aliases);
+           efree(aliases[n].name);
+       efree(aliases);
        aliases = NULL;
     }
     naliases = nslots = 0;
@@ -1003,6 +1009,7 @@ expand_match_list()
     cm_list[cm_list_len].runas = cm_list[cm_list_len].cmnd = NULL;
     cm_list[cm_list_len].nopasswd = FALSE;
     cm_list[cm_list_len].noexecve = FALSE;
+    cm_list[cm_list_len].setenv = FALSE;
 }
 
 /*
@@ -1015,7 +1022,7 @@ init_parser()
 
     /* Free up old data structures if we run the parser more than once. */
     if (match) {
-       free(match);
+       efree(match);
        match = NULL;
        top = 0;
        parse_error = FALSE;
@@ -1032,7 +1039,7 @@ init_parser()
     if (printmatches == TRUE)
        expand_match_list();
 }
-#line 984 "sudo.tab.c"
+#line 991 "sudo.tab.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1226,143 +1233,143 @@ yyreduce:
     switch (yyn)
     {
 case 3:
-#line 275 "parse.yacc"
+#line 280 "parse.yacc"
 { ; }
 break;
 case 4:
-#line 277 "parse.yacc"
+#line 282 "parse.yacc"
 { yyerrok; }
 break;
 case 5:
-#line 278 "parse.yacc"
+#line 283 "parse.yacc"
 { push; }
 break;
 case 6:
-#line 278 "parse.yacc"
+#line 283 "parse.yacc"
 {
                            while (top && user_matches != TRUE)
                                pop;
                        }
 break;
 case 7:
-#line 283 "parse.yacc"
+#line 288 "parse.yacc"
 { ; }
 break;
 case 8:
-#line 285 "parse.yacc"
+#line 290 "parse.yacc"
 { ; }
 break;
 case 9:
-#line 287 "parse.yacc"
+#line 292 "parse.yacc"
 { ; }
 break;
 case 10:
-#line 289 "parse.yacc"
+#line 294 "parse.yacc"
 { ; }
 break;
 case 11:
-#line 291 "parse.yacc"
+#line 296 "parse.yacc"
 { ; }
 break;
 case 13:
-#line 297 "parse.yacc"
+#line 302 "parse.yacc"
 {
                            defaults_matches = TRUE;
                        }
 break;
 case 14:
-#line 300 "parse.yacc"
+#line 305 "parse.yacc"
 { push; }
 break;
 case 15:
-#line 300 "parse.yacc"
+#line 305 "parse.yacc"
 {
                            defaults_matches = user_matches;
                            pop;
                        }
 break;
 case 16:
-#line 304 "parse.yacc"
+#line 309 "parse.yacc"
 { push; }
 break;
 case 17:
-#line 304 "parse.yacc"
+#line 309 "parse.yacc"
 {
                            defaults_matches = yyvsp[0].BOOLEAN == TRUE;
                            pop;
                        }
 break;
 case 18:
-#line 308 "parse.yacc"
+#line 313 "parse.yacc"
 { push; }
 break;
 case 19:
-#line 308 "parse.yacc"
+#line 313 "parse.yacc"
 {
                            defaults_matches = host_matches;
                            pop;
                        }
 break;
 case 22:
-#line 318 "parse.yacc"
+#line 323 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[0].string, NULL, TRUE)) {
                                yyerror(NULL);
                                YYERROR;
                            }
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 23:
-#line 326 "parse.yacc"
+#line 331 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[0].string, NULL, FALSE)) {
                                yyerror(NULL);
                                YYERROR;
                            }
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 24:
-#line 334 "parse.yacc"
+#line 339 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[-2].string, yyvsp[0].string, TRUE)) {
                                yyerror(NULL);
                                YYERROR;
                            }
-                           free(yyvsp[-2].string);
-                           free(yyvsp[0].string);
+                           efree(yyvsp[-2].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 25:
-#line 343 "parse.yacc"
+#line 348 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[-2].string, yyvsp[0].string, '+')) {
                                yyerror(NULL);
                                YYERROR;
                            }
-                           free(yyvsp[-2].string);
-                           free(yyvsp[0].string);
+                           efree(yyvsp[-2].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 26:
-#line 352 "parse.yacc"
+#line 357 "parse.yacc"
 {
                            if (defaults_matches == TRUE &&
                                !set_default(yyvsp[-2].string, yyvsp[0].string, '-')) {
                                yyerror(NULL);
                                YYERROR;
                            }
-                           free(yyvsp[-2].string);
-                           free(yyvsp[0].string);
+                           efree(yyvsp[-2].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 29:
-#line 367 "parse.yacc"
+#line 372 "parse.yacc"
 {
                            /*
                             * We already did a push if necessary in
@@ -1373,58 +1380,59 @@ case 29:
                            runas_matches = UNSPEC;
                            no_passwd = def_authenticate ? UNSPEC : TRUE;
                            no_execve = def_noexec ? TRUE : UNSPEC;
+                           setenv_ok = def_setenv ? TRUE : UNSPEC;
                        }
 break;
 case 30:
-#line 380 "parse.yacc"
+#line 386 "parse.yacc"
 {
                            SETMATCH(host_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 31:
-#line 383 "parse.yacc"
+#line 389 "parse.yacc"
 {
                            SETNMATCH(host_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 32:
-#line 388 "parse.yacc"
+#line 394 "parse.yacc"
 {
                            yyval.BOOLEAN = TRUE;
                        }
 break;
 case 33:
-#line 391 "parse.yacc"
+#line 397 "parse.yacc"
 {
                            if (addr_matches(yyvsp[0].string))
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 34:
-#line 398 "parse.yacc"
+#line 404 "parse.yacc"
 {
                            if (netgr_matches(yyvsp[0].string, user_host, user_shost, NULL))
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 35:
-#line 405 "parse.yacc"
+#line 411 "parse.yacc"
 {
                            if (hostname_matches(user_shost, user_host, yyvsp[0].string) == 0)
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 36:
-#line 412 "parse.yacc"
+#line 418 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, HOST_ALIAS);
 
@@ -1445,11 +1453,11 @@ case 36:
                                }
                                yyval.BOOLEAN = NOMATCH;
                            }
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
 case 39:
-#line 440 "parse.yacc"
+#line 446 "parse.yacc"
 {
                            /*
                             * Push the entry onto the stack if it is worth
@@ -1479,13 +1487,13 @@ case 39:
                        }
 break;
 case 40:
-#line 469 "parse.yacc"
+#line 475 "parse.yacc"
 {
                            SETMATCH(cmnd_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 41:
-#line 472 "parse.yacc"
+#line 478 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1497,13 +1505,13 @@ case 41:
                        }
 break;
 case 42:
-#line 480 "parse.yacc"
+#line 486 "parse.yacc"
 {
                            SETNMATCH(cmnd_matches, yyvsp[0].BOOLEAN);
                        }
 break;
 case 43:
-#line 485 "parse.yacc"
+#line 491 "parse.yacc"
 {
                            if (printmatches == TRUE && host_matches == TRUE &&
                                user_matches == TRUE) {
@@ -1531,17 +1539,17 @@ case 43:
                        }
 break;
 case 44:
-#line 510 "parse.yacc"
+#line 516 "parse.yacc"
 {
                            runas_matches = yyvsp[0].BOOLEAN;
                        }
 break;
 case 45:
-#line 515 "parse.yacc"
+#line 521 "parse.yacc"
 { ; }
 break;
 case 46:
-#line 516 "parse.yacc"
+#line 522 "parse.yacc"
 {
                            /* Later entries override earlier ones. */
                            if (yyvsp[0].BOOLEAN != NOMATCH)
@@ -1551,11 +1559,11 @@ case 46:
                        }
 break;
 case 47:
-#line 525 "parse.yacc"
+#line 531 "parse.yacc"
 { ; }
 break;
 case 48:
-#line 526 "parse.yacc"
+#line 532 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1567,14 +1575,14 @@ case 48:
                        }
 break;
 case 49:
-#line 534 "parse.yacc"
+#line 540 "parse.yacc"
 {
                            /* Set $$ to the negation of runasuser */
                            yyval.BOOLEAN = (yyvsp[0].BOOLEAN == NOMATCH ? NOMATCH : ! yyvsp[0].BOOLEAN);
                        }
 break;
 case 50:
-#line 540 "parse.yacc"
+#line 546 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1587,12 +1595,12 @@ case 50:
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                            used_runas = TRUE;
                        }
 break;
 case 51:
-#line 555 "parse.yacc"
+#line 561 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1605,12 +1613,12 @@ case 51:
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                            used_runas = TRUE;
                        }
 break;
 case 52:
-#line 570 "parse.yacc"
+#line 576 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1623,12 +1631,12 @@ case 52:
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                            used_runas = TRUE;
                        }
 break;
 case 53:
-#line 585 "parse.yacc"
+#line 591 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, RUNAS_ALIAS);
 
@@ -1656,12 +1664,12 @@ case 53:
                                }
                                yyval.BOOLEAN = NOMATCH;
                            }
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                            used_runas = TRUE;
                        }
 break;
 case 54:
-#line 615 "parse.yacc"
+#line 621 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1674,9 +1682,9 @@ case 54:
                        }
 break;
 case 55:
-#line 627 "parse.yacc"
+#line 633 "parse.yacc"
 {
-                           /* Inherit {NOPASSWD,PASSWD,NOEXEC,EXEC} status. */
+                           /* Inherit {NO,}{PASSWD,EXEC,SETENV} status. */
                            if (printmatches == TRUE && host_matches == TRUE &&
                                user_matches == TRUE) {
                                if (no_passwd == TRUE)
@@ -1687,11 +1695,15 @@ case 55:
                                    cm_list[cm_list_len].noexecve = TRUE;
                                else
                                    cm_list[cm_list_len].noexecve = FALSE;
+                               if (setenv_ok == TRUE)
+                                   cm_list[cm_list_len].setenv = TRUE;
+                               else
+                                   cm_list[cm_list_len].setenv = FALSE;
                            }
                        }
 break;
 case 56:
-#line 641 "parse.yacc"
+#line 651 "parse.yacc"
 {
                            no_passwd = TRUE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1700,7 +1712,7 @@ case 56:
                        }
 break;
 case 57:
-#line 647 "parse.yacc"
+#line 657 "parse.yacc"
 {
                            no_passwd = FALSE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1709,7 +1721,7 @@ case 57:
                        }
 break;
 case 58:
-#line 653 "parse.yacc"
+#line 663 "parse.yacc"
 {
                            no_execve = TRUE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1718,7 +1730,7 @@ case 58:
                        }
 break;
 case 59:
-#line 659 "parse.yacc"
+#line 669 "parse.yacc"
 {
                            no_execve = FALSE;
                            if (printmatches == TRUE && host_matches == TRUE &&
@@ -1727,7 +1739,25 @@ case 59:
                        }
 break;
 case 60:
-#line 667 "parse.yacc"
+#line 675 "parse.yacc"
+{
+                           setenv_ok = TRUE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               cm_list[cm_list_len].setenv = TRUE;
+                       }
+break;
+case 61:
+#line 681 "parse.yacc"
+{
+                           setenv_ok = FALSE;
+                           if (printmatches == TRUE && host_matches == TRUE &&
+                               user_matches == TRUE)
+                               cm_list[cm_list_len].setenv = FALSE;
+                       }
+break;
+case 62:
+#line 689 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE)
@@ -1739,11 +1769,13 @@ case 60:
                                }
                            }
 
+                           efree(safe_cmnd);
+                           safe_cmnd = NULL;
                            yyval.BOOLEAN = TRUE;
                        }
 break;
-case 61:
-#line 680 "parse.yacc"
+case 63:
+#line 704 "parse.yacc"
 {
                            aliasinfo *aip;
 
@@ -1771,11 +1803,11 @@ case 61:
                                }
                                yyval.BOOLEAN = NOMATCH;
                            }
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
-case 62:
-#line 709 "parse.yacc"
+case 64:
+#line 733 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                if (in_alias == TRUE) {
@@ -1797,17 +1829,16 @@ case 62:
                            else
                                yyval.BOOLEAN = NOMATCH;
 
-                           free(yyvsp[0].command.cmnd);
-                           if (yyvsp[0].command.args)
-                               free(yyvsp[0].command.args);
+                           efree(yyvsp[0].command.cmnd);
+                           efree(yyvsp[0].command.args);
                        }
 break;
-case 65:
-#line 740 "parse.yacc"
+case 67:
+#line 763 "parse.yacc"
 { push; }
 break;
-case 66:
-#line 740 "parse.yacc"
+case 68:
+#line 763 "parse.yacc"
 {
                            if ((MATCHED(host_matches) || pedantic) &&
                                !add_alias(yyvsp[-3].string, HOST_ALIAS, host_matches)) {
@@ -1817,8 +1848,8 @@ case 66:
                            pop;
                        }
 break;
-case 71:
-#line 758 "parse.yacc"
+case 73:
+#line 781 "parse.yacc"
 {
                            push;
                            if (printmatches == TRUE) {
@@ -1830,8 +1861,8 @@ case 71:
                             }
                        }
 break;
-case 72:
-#line 767 "parse.yacc"
+case 74:
+#line 790 "parse.yacc"
 {
                            if ((MATCHED(cmnd_matches) || pedantic) &&
                                !add_alias(yyvsp[-3].string, CMND_ALIAS, cmnd_matches)) {
@@ -1839,18 +1870,18 @@ case 72:
                                YYERROR;
                            }
                            pop;
-                           free(yyvsp[-3].string);
+                           efree(yyvsp[-3].string);
 
                            if (printmatches == TRUE)
                                in_alias = FALSE;
                        }
 break;
-case 73:
-#line 781 "parse.yacc"
+case 75:
+#line 804 "parse.yacc"
 { ; }
 break;
-case 77:
-#line 789 "parse.yacc"
+case 79:
+#line 812 "parse.yacc"
 {
                            if (printmatches == TRUE) {
                                in_alias = TRUE;
@@ -1861,26 +1892,26 @@ case 77:
                            }
                        }
 break;
-case 78:
-#line 797 "parse.yacc"
+case 80:
+#line 820 "parse.yacc"
 {
                            if ((yyvsp[0].BOOLEAN != NOMATCH || pedantic) &&
                                !add_alias(yyvsp[-3].string, RUNAS_ALIAS, yyvsp[0].BOOLEAN)) {
                                yyerror(NULL);
                                YYERROR;
                            }
-                           free(yyvsp[-3].string);
+                           efree(yyvsp[-3].string);
 
                            if (printmatches == TRUE)
                                in_alias = FALSE;
                        }
 break;
-case 81:
-#line 814 "parse.yacc"
+case 83:
+#line 837 "parse.yacc"
 { push; }
 break;
-case 82:
-#line 814 "parse.yacc"
+case 84:
+#line 837 "parse.yacc"
 {
                            if ((MATCHED(user_matches) || pedantic) &&
                                !add_alias(yyvsp[-3].string, USER_ALIAS, user_matches)) {
@@ -1888,53 +1919,53 @@ case 82:
                                YYERROR;
                            }
                            pop;
-                           free(yyvsp[-3].string);
+                           efree(yyvsp[-3].string);
                        }
 break;
-case 85:
-#line 829 "parse.yacc"
+case 87:
+#line 852 "parse.yacc"
 {
                            SETMATCH(user_matches, yyvsp[0].BOOLEAN);
                        }
 break;
-case 86:
-#line 832 "parse.yacc"
+case 88:
+#line 855 "parse.yacc"
 {
                            SETNMATCH(user_matches, yyvsp[0].BOOLEAN);
                        }
 break;
-case 87:
-#line 837 "parse.yacc"
+case 89:
+#line 860 "parse.yacc"
 {
                            if (userpw_matches(yyvsp[0].string, user_name, sudo_user.pw))
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
-case 88:
-#line 844 "parse.yacc"
+case 90:
+#line 867 "parse.yacc"
 {
                            if (usergr_matches(yyvsp[0].string, user_name, sudo_user.pw))
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
-case 89:
-#line 851 "parse.yacc"
+case 91:
+#line 874 "parse.yacc"
 {
                            if (netgr_matches(yyvsp[0].string, NULL, NULL, user_name))
                                yyval.BOOLEAN = TRUE;
                            else
                                yyval.BOOLEAN = NOMATCH;
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
-case 90:
-#line 858 "parse.yacc"
+case 92:
+#line 881 "parse.yacc"
 {
                            aliasinfo *aip = find_alias(yyvsp[0].string, USER_ALIAS);
 
@@ -1955,16 +1986,16 @@ case 90:
                                }
                                yyval.BOOLEAN = NOMATCH;
                            }
-                           free(yyvsp[0].string);
+                           efree(yyvsp[0].string);
                        }
 break;
-case 91:
-#line 880 "parse.yacc"
+case 93:
+#line 903 "parse.yacc"
 {
                            yyval.BOOLEAN = TRUE;
                        }
 break;
-#line 1916 "sudo.tab.c"
+#line 1947 "sudo.tab.c"
     }
     yyssp -= yym;
     yystate = *yyssp;