diff --git a/doc/sudoers.cat b/doc/sudoers.cat
index 9b1583ca7..be615baab 100644
--- a/doc/sudoers.cat
+++ b/doc/sudoers.cat
@@ -474,10 +474,12 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
      Cmnd_Spec_List ::= Cmnd_Spec |
                         Cmnd_Spec ',' Cmnd_Spec_List
 
-     Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Solaris_Priv_Spec? Tag_Spec* Cmnd
+     Cmnd_Spec ::= Runas_Spec? Option_Spec* Cmnd
 
      Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
 
+     Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Tag_Spec)
+
      SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
 
      Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
@@ -564,6 +566,12 @@ SSUUDDOOEERRSS FFIILLEE FFOORRMMAATT
      user aallaann may run any command as either user root or bin, optionally
      setting the group to operator or system.
 
+   OOppttiioonn__SSppeecc
+     A command may include zero or more options.  These options include
+     SELinux and Solaris settings as well as tags, described below.  Once an
+     option is set for a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit
+     that option unless overridden by another option.
+
    SSEELLiinnuuxx__SSppeecc
      On systems with SELinux support, _s_u_d_o_e_r_s file entries may optionally have
      an SELinux role and/or type associated with a command.  If a role or type
@@ -2678,4 +2686,4 @@ DDIISSCCLLAAIIMMEERR
      file distributed with ssuuddoo or https://www.sudo.ws/license.html for
      complete details.
 
-Sudo 1.8.20                    February 5, 2017                    Sudo 1.8.20
+Sudo 1.8.20                    February 13, 2017                   Sudo 1.8.20
diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in
index 903b020cc..399e8432a 100644
--- a/doc/sudoers.man.in
+++ b/doc/sudoers.man.in
@@ -21,7 +21,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.TH "SUDOERS" "5" "February 5, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.TH "SUDOERS" "5" "February 13, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
 .nh
 .if n .ad l
 .SH "NAME"
@@ -982,10 +982,12 @@ User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
 Cmnd_Spec_List ::= Cmnd_Spec |
                    Cmnd_Spec ',' Cmnd_Spec_List
 
-Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Solaris_Priv_Spec? Tag_Spec* Cmnd
+Cmnd_Spec ::= Runas_Spec? Option_Spec* Cmnd
 
 Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
 
+Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Tag_Spec)
+
 SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
 
 Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
@@ -1185,6 +1187,17 @@ user
 \fBalan\fR
 may run any command as either user root or bin,
 optionally setting the group to operator or system.
+.SS "Option_Spec"
+A command may include zero or more options.
+These options include SELinux and Solaris settings as well
+as tags, described below.
+Once an option is set for a
+\fRCmnd\fR,
+subsequent
+\fRCmnd\fRs
+in the
+\fRCmnd_Spec_List\fR,
+inherit that option unless overridden by another option.
 .SS "SELinux_Spec"
 On systems with SELinux support,
 \fIsudoers\fR
diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
index 484204c4c..85eae4a52 100644
--- a/doc/sudoers.mdoc.in
+++ b/doc/sudoers.mdoc.in
@@ -19,7 +19,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd February 5, 2017
+.Dd February 13, 2017
 .Dt SUDOERS @mansectform@
 .Os Sudo @PACKAGE_VERSION@
 .Sh NAME
@@ -935,10 +935,12 @@ User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
 Cmnd_Spec_List ::= Cmnd_Spec |
                    Cmnd_Spec ',' Cmnd_Spec_List
 
-Cmnd_Spec ::= Runas_Spec? SELinux_Spec? Solaris_Priv_Spec? Tag_Spec* Cmnd
+Cmnd_Spec ::= Runas_Spec? Option_Spec* Cmnd
 
 Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
 
+Option_Spec ::= (SELinux_Spec | Solaris_Priv_Spec | Tag_Spec)
+
 SELinux_Spec ::= ('ROLE=role' | 'TYPE=type')
 
 Solaris_Priv_Spec ::= ('PRIVS=privset' | 'LIMITPRIVS=privset')
@@ -1113,6 +1115,17 @@ user
 .Sy alan
 may run any command as either user root or bin,
 optionally setting the group to operator or system.
+.Ss Option_Spec
+A command may include zero or more options.
+These options include SELinux and Solaris settings as well
+as tags, described below.
+Once an option is set for a
+.Li Cmnd ,
+subsequent
+.Li Cmnd Ns s
+in the
+.Li Cmnd_Spec_List ,
+inherit that option unless overridden by another option.
 .Ss SELinux_Spec
 On systems with SELinux support,
 .Em sudoers
diff --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c
index e622bdd37..59996acc6 100644
--- a/plugins/sudoers/gram.c
+++ b/plugins/sudoers/gram.c
@@ -120,14 +120,12 @@ typedef union {
     struct privilege *privilege;
     struct sudo_digest *digest;
     struct sudo_command command;
-    struct cmndtag tag;
-    struct selinux_info seinfo;
-    struct solaris_privs_info privinfo;
+    struct command_options options;
     char *string;
     int tok;
 } YYSTYPE;
 #endif /* YYSTYPE_DEFINED */
-#line 130 "gram.c"
+#line 128 "gram.c"
 #define COMMAND 257
 #define ALIAS 258
 #define DEFVAR 259
@@ -178,18 +176,17 @@ const short sudoerslhs[] =
 short sudoerslhs[] =
 #endif
 	{                                        -1,
-    0,    0,   30,   30,   31,   31,   31,   31,   31,   31,
-   31,   31,   31,   31,   31,   31,    4,    4,    3,    3,
+    0,    0,   28,   28,   29,   29,   29,   29,   29,   29,
+   29,   29,   29,   29,   29,   29,    4,    4,    3,    3,
     3,    3,    3,   21,   21,   20,   11,   11,    9,    9,
-    9,    9,    9,    2,    2,    1,   29,   29,   29,   29,
-    7,    7,    6,    6,   24,   25,   23,   23,   23,   23,
-   23,   27,   28,   26,   26,   26,   26,   26,   18,   18,
+    9,    9,    9,    2,    2,    1,   27,   27,   27,   27,
+    7,    7,    6,    6,   23,   24,   25,   26,   18,   18,
    19,   19,   19,   19,   19,   22,   22,   22,   22,   22,
    22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
-    5,    5,    5,   33,   33,   36,   10,   10,   34,   34,
-   37,    8,    8,   35,   35,   38,   32,   32,   39,   14,
-   14,   12,   12,   13,   13,   13,   13,   13,   17,   17,
-   15,   15,   16,   16,   16,
+   22,   22,   22,   22,    5,    5,    5,   31,   31,   34,
+   10,   10,   32,   32,   35,    8,    8,   33,   33,   36,
+   30,   30,   37,   14,   14,   12,   12,   13,   13,   13,
+   13,   13,   17,   17,   15,   15,   16,   16,   16,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoerslen[] =
@@ -200,15 +197,14 @@ short sudoerslen[] =
     0,    1,    1,    2,    1,    2,    2,    2,    2,    2,
     2,    2,    3,    3,    3,    3,    1,    3,    1,    2,
     3,    3,    3,    1,    3,    3,    1,    2,    1,    1,
-    1,    1,    1,    1,    3,    5,    3,    3,    3,    3,
-    1,    2,    1,    2,    3,    3,    0,    1,    1,    2,
-    2,    3,    3,    0,    1,    1,    2,    2,    0,    3,
+    1,    1,    1,    1,    3,    3,    3,    3,    3,    3,
+    1,    2,    1,    2,    3,    3,    3,    3,    0,    3,
     0,    1,    3,    2,    1,    0,    2,    2,    2,    2,
     2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-    1,    1,    1,    1,    3,    3,    1,    3,    1,    3,
-    3,    1,    3,    1,    3,    3,    1,    3,    3,    1,
-    3,    1,    2,    1,    1,    1,    1,    1,    1,    3,
-    1,    2,    1,    1,    1,
+    2,    2,    2,    2,    1,    1,    1,    1,    3,    3,
+    1,    3,    1,    3,    3,    1,    3,    1,    3,    3,
+    1,    3,    3,    1,    3,    1,    2,    1,    1,    1,
+    1,    1,    1,    3,    1,    2,    1,    1,    1,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoersdefred[] =
@@ -216,24 +212,24 @@ const short sudoersdefred[] =
 short sudoersdefred[] =
 #endif
 	{                                      0,
-    0,  104,  106,  107,  108,    0,    0,    0,    0,    0,
-  105,    5,    0,    0,    0,    0,    0,    0,  100,  102,
+    0,   98,  100,  101,  102,    0,    0,    0,    0,    0,
+   99,    5,    0,    0,    0,    0,    0,    0,   94,   96,
     0,    0,    3,    6,    0,    0,   17,    0,   29,   32,
-   31,   33,   30,    0,   27,    0,   87,    0,    0,   83,
-   82,   81,    0,    0,    0,    0,    0,   43,   41,   92,
-    0,    0,    0,    0,   84,    0,    0,   89,    0,    0,
-   97,    0,    0,   94,  103,    0,    0,   24,    0,    4,
+   31,   33,   30,    0,   27,    0,   81,    0,    0,   77,
+   76,   75,    0,    0,    0,    0,    0,   43,   41,   86,
+    0,    0,    0,    0,   78,    0,    0,   83,    0,    0,
+   91,    0,    0,   88,   97,    0,    0,   24,    0,    4,
     0,    0,    0,   20,    0,   28,    0,    0,    0,    0,
    44,    0,    0,    0,    0,    0,    0,   42,    0,    0,
-    0,    0,    0,    0,    0,    0,  101,    0,    0,   21,
-   22,   23,   18,   88,   37,   38,   39,   40,   93,    0,
-   85,    0,   90,    0,   98,    0,   95,    0,   34,    0,
-    0,   25,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,  113,  115,  114,    0,  109,  111,    0,    0,   60,
-   35,    0,    0,    0,    0,   66,    0,    0,   50,   51,
-  112,    0,    0,   46,   45,    0,    0,    0,   57,   58,
-  110,   52,   53,   67,   68,   69,   70,   71,   72,   73,
-   74,   75,   76,   79,   80,   77,   78,   36,
+    0,    0,    0,    0,    0,    0,   95,    0,    0,   21,
+   22,   23,   18,   82,   37,   38,   39,   40,   87,    0,
+   79,    0,   84,    0,   92,    0,   89,    0,   34,    0,
+   56,   25,    0,    0,    0,    0,    0,  107,  109,  108,
+    0,  103,  105,    0,    0,   50,   35,   57,   58,   59,
+   60,   61,   62,   63,   64,   65,   66,   69,   70,   67,
+   68,    0,    0,    0,    0,   36,   71,   72,   73,   74,
+  106,    0,    0,    0,    0,    0,    0,  104,   46,   45,
+   47,   48,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoersdgoto[] =
@@ -242,92 +238,92 @@ short sudoersdgoto[] =
 #endif
 	{                                      18,
   119,  120,   27,   28,   48,   49,   50,   51,   35,   67,
-   37,   19,   20,   21,  136,  137,  138,  121,  125,   68,
-   69,  158,  129,  130,  131,  146,  147,  148,   52,   22,
-   23,   60,   54,   57,   63,   55,   58,   64,   61,
+   37,   19,   20,   21,  132,  133,  134,  121,  125,   68,
+   69,  127,  157,  158,  159,  160,   52,   22,   23,   60,
+   54,   57,   63,   55,   58,   64,   61,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoerssindex[] =
 #else
 short sudoerssindex[] =
 #endif
-	{                                    686,
- -272,    0,    0,    0,    0,  -23,  227,  -19,  -19,   -5,
-    0,    0, -239, -236, -234, -232, -231,    0,    0,    0,
-  -33,  686,    0,    0,   -3, -220,    0,    3,    0,    0,
+	{                                    478,
+ -266,    0,    0,    0,    0,  -23,  289,  -19,  -19,   -5,
+    0,    0, -233, -232, -221, -219, -231,    0,    0,    0,
+  -33,  478,    0,    0,   -3, -216,    0,    3,    0,    0,
     0,    0,    0, -225,    0,  -28,    0,  -24,  -24,    0,
-    0,    0, -240,  -15,   -8,    2,    8,    0,    0,    0,
-  -21,  -12,   -9,   10,    0,    9,   13,    0,   11,   16,
-    0,   14,   19,    0,    0,  -19,  -36,    0,   20,    0,
- -208, -187, -183,    0,  -23,    0,  227,    3,    3,    3,
-    0, -181, -180, -179, -178,   -5,    3,    0,  227, -239,
-   -5, -236,  -19, -234,  -19, -232,    0,   41,  227,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,   46,
-    0,   47,    0,   48,    0,   48,    0,  -29,    0,   50,
- -230,    0,  289,   -7,   52,   41,   34,   37, -229, -192,
- -191,    0,    0,    0, -217,    0,    0,   56,  289,    0,
-    0, -161, -160,   43,   44,    0, -188, -185,    0,    0,
-    0,  289,   56,    0,    0, -154, -153,  533,    0,    0,
+    0,    0, -240,   -8,   -7,   -2,    2,    0,    0,    0,
+  -21,  -12,   -9,    8,    0,   -4,   10,    0,    9,   11,
+    0,   13,   14,    0,    0,  -19,  -37,    0,   17,    0,
+ -208, -202, -192,    0,  -23,    0,  289,    3,    3,    3,
+    0, -188, -186, -185, -184,   -5,    3,    0,  289, -233,
+   -5, -232,  -19, -221,  -19, -219,    0,   41,  289,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,   39,
+    0,   40,    0,   42,    0,   42,    0,  -29,    0,   46,
+    0,    0,  405,  -36,   44,   41,  404,    0,    0,    0,
+ -217,    0,    0,   47,  405,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,};
+    0,   31,   32,   33,   34,    0,    0,    0,    0,    0,
+    0,  405,   47, -165, -164, -163, -162,    0,    0,    0,
+    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoersrindex[] =
 #else
 short sudoersrindex[] =
 #endif
-	{                                    113,
+	{                                    102,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,  114,    0,    0,    1,    0,    0,  145,    0,    0,
+    0,  103,    0,    0,    1,    0,    0,  145,    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,  159,    0,    0,  193,    0,    0,  207,
     0,    0,  241,    0,    0,    0,    0,    0,  275,    0,
     0,    0,    0,    0,    0,    0,    0,  309,  323,  357,
     0,    0,    0,    0,    0,    0,  371,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,  404,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  434,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,   15,
-    0,   49,    0,   63,    0,   97,    0,   74,    0,  111,
-  434,    0,   75,   76,    0,  404,    0,    0,  566,  465,
-  499,    0,    0,    0,    0,    0,    0,   77,    0,    0,
-    0,    0,    0,    0,    0,    0,  597,  630,    0,    0,
-    0,    0,   78,    0,    0,    0,    0,    0,    0,    0,
+    0,   49,    0,   63,    0,   97,    0,   64,    0,  111,
+    0,    0,   65,   67,    0,  434,    0,    0,    0,    0,
+    0,    0,    0,   68,    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,   69,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoersgindex[] =
 #else
 short sudoersgindex[] =
 #endif
 	{                                      0,
-   -4,    0,   45,   18,   80,   72,  -79,   35,   91,   -1,
-   51,   61,  112,   -6,  -20,   -2,    4,    0,    0,   32,
-    0,    0,    0,    5,    7,    0,  -14,    6,    0,    0,
-  116,    0,    0,    0,    0,   57,   54,   39,   55,
+  -22,    0,   38,   26,   71,   66,  -73,   24,   82,   -1,
+   43,   51,  105,   -6,  -43,    4,  -11,    0,    0,   27,
+    0,    0,    0,    0,    0,    0,    0,    0,  101,    0,
+    0,    0,    0,   35,   36,   37,   45,
 };
-#define YYTABLESIZE 975
+#define YYTABLESIZE 767
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoerstable[] =
 #else
 short sudoerstable[] =
 #endif
 	{                                      34,
-   19,   38,   39,   17,   26,   36,  109,   77,   26,   26,
-   66,   26,   24,   17,   86,   77,   40,   41,   53,   66,
-   43,   56,   86,   59,   98,   62,    2,   43,  123,    3,
-    4,    5,   29,   19,   30,   31,   66,   32,   74,   72,
-  132,   73,   82,   42,   19,  133,   75,   86,   91,   83,
-  139,   89,   11,   78,  100,   79,   80,   71,   33,   84,
-  127,  128,   99,  144,  145,   85,  134,   90,   87,   91,
-   92,   93,   86,   94,   95,  101,   96,   99,  178,  102,
-  118,   91,  105,  106,  107,  108,  114,  110,  116,   77,
-   86,   66,  140,  126,  142,   99,   96,  143,  127,  152,
-  128,  154,  155,  156,  157,  145,   91,  144,  162,  163,
-   26,  124,    1,    2,   61,   65,   62,   64,   63,  103,
-   99,  141,   81,   88,   76,  112,   97,  104,   65,   96,
-  122,  161,  151,  160,  117,  150,  149,   70,    0,    0,
-    0,    0,  153,   26,   12,  113,  111,    0,  115,    0,
-    0,    0,  159,    0,   96,    0,    0,    0,    9,    0,
+   19,   38,   39,   17,   26,   36,   77,   66,   26,   26,
+   66,   26,  109,   17,   80,   77,   40,   41,   24,   66,
+   43,  135,   86,   98,   53,   56,    2,   43,  123,    3,
+    4,    5,   29,   19,   30,   31,   59,   32,   62,   72,
+  128,   73,   74,   42,   19,  129,   75,   80,   85,   82,
+   83,   89,   11,  156,  100,   84,   91,   71,   33,   85,
+  101,   78,   93,   79,   80,   90,  130,   92,   94,   93,
+  102,   96,   80,   95,   99,  105,   87,  106,  107,  108,
+  118,   85,   77,   86,  136,   66,  114,  110,  116,  126,
+  162,  164,  165,  166,  167,   93,   90,  169,  170,  171,
+  172,    1,    2,  137,   51,   55,   85,   52,   54,   53,
+   26,  124,  103,   81,  112,   76,   97,   88,  168,  104,
+   93,   65,   70,  163,  111,  122,    0,  113,    0,   90,
+    0,    0,  117,    0,  161,    0,    0,    0,  115,    0,
+    0,    0,    0,   26,   12,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,   90,    0,    0,    0,    9,    0,
     0,    0,    0,    0,    0,    0,    0,    0,   26,    0,
     0,    0,    0,    0,    0,    0,    0,   12,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
@@ -337,79 +333,58 @@ short sudoerstable[] =
     0,    0,    0,    0,   29,   10,   30,   31,    2,   32,
    25,    3,    4,    5,   25,   25,    0,   25,    2,    8,
    11,    3,    4,    5,   40,   41,    0,    0,    0,    0,
-   33,   40,   41,    0,   11,    0,   19,    0,   19,   34,
+   33,   40,   41,    0,   11,    0,   19,    0,   19,    0,
     0,   19,   19,   19,   11,   19,   19,   19,   19,   19,
-   86,   42,   86,   11,    7,   86,   86,   86,   42,   86,
-   86,   86,   86,   86,   19,   19,   19,   19,   19,   19,
-   44,   45,   46,   47,    0,    0,    0,    0,   86,   86,
-   86,   86,   86,   86,   91,    0,   91,    7,   15,   91,
-   91,   91,    0,   91,   91,   91,   91,   91,   99,    0,
-   99,  135,   13,   99,   99,   99,    0,   99,   99,   99,
-   99,   99,   91,   91,   91,   91,   91,   91,    0,    0,
-    0,   15,    0,    0,    0,    0,   99,   99,   99,   99,
-   99,   99,   96,    0,   96,   13,   14,   96,   96,   96,
-    0,   96,   96,   96,   96,   96,   26,    0,   26,    0,
+   80,   42,   80,   11,    7,   80,   80,   80,   42,   80,
+   80,   80,   80,   80,   19,   19,   19,   19,   19,   19,
+   44,   45,   46,   47,    0,    0,    0,    0,   80,   80,
+   80,   80,   80,   80,   85,    0,   85,    7,   15,   85,
+   85,   85,    0,   85,   85,   85,   85,   85,   93,    0,
+   93,   34,   13,   93,   93,   93,    0,   93,   93,   93,
+   93,   93,   85,   85,   85,   85,   85,   85,    0,    0,
+    0,   15,    0,    0,    0,    0,   93,   93,   93,   93,
+   93,   93,   90,    0,   90,   13,   14,   90,   90,   90,
+    0,   90,   90,   90,   90,   90,   26,    0,   26,    0,
    16,   26,   26,   26,    0,   26,   26,   26,   26,   26,
-   96,   96,   96,   96,   96,   96,    0,    0,    0,   14,
+   90,   90,   90,   90,   90,   90,    0,    0,    0,   14,
     0,    0,    0,    0,   26,   26,   26,   26,   26,   26,
    12,    0,   12,   16,    0,   12,   12,   12,    0,   12,
    12,   12,   12,   12,    9,    0,    9,    0,    0,    9,
     9,    9,    0,    9,    9,    9,    9,    9,   12,   12,
-   12,   12,   12,   12,    0,    0,   59,    0,    0,    0,
+   12,   12,   12,   12,    0,    0,   43,  131,    0,    0,
     0,    0,    9,    9,    9,    9,    9,    9,   10,    0,
    10,    0,    0,   10,   10,   10,    0,   10,   10,   10,
-   10,   10,    8,    0,    8,    0,   47,    8,    8,    8,
+   10,   10,    8,    0,    8,    0,   49,    8,    8,    8,
     0,    8,    8,    8,    8,    8,   10,   10,   10,   10,
-   10,   10,    0,    0,   29,    0,   30,   31,    0,   32,
-    8,    8,    8,    8,    8,    8,   11,   48,   11,    0,
+   10,   10,    0,    0,    0,    0,    0,    0,    0,    0,
+    8,    8,    8,    8,    8,    8,   11,    0,   11,    0,
     0,   11,   11,   11,    0,   11,   11,   11,   11,   11,
-   33,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+   17,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,   11,   11,   11,   11,   11,   11,
-    7,   49,    7,    0,    0,    7,    7,    7,    0,    7,
-    7,    7,    7,    7,    0,    0,  132,    0,    0,    0,
-    0,  133,    0,    0,    0,    0,    0,    0,    7,    7,
-    7,    7,    7,    7,   15,   43,   15,    0,    0,   15,
-   15,   15,  134,   15,   15,   15,   15,   15,   13,    0,
+    7,    0,    7,    0,    0,    7,    7,    7,    0,    7,
+    7,    7,    7,    7,    0,    0,   29,    0,   30,   31,
+    0,   32,    0,    0,    0,    0,    0,    0,    7,    7,
+    7,    7,    7,    7,   15,    0,   15,    0,    0,   15,
+   15,   15,   33,   15,   15,   15,   15,   15,   13,    0,
    13,    0,    0,   13,   13,   13,    0,   13,   13,   13,
-   13,   13,   15,   15,   15,   15,   15,   15,   54,    0,
+   13,   13,   15,   15,   15,   15,   15,   15,    0,    0,
     0,    0,    0,    0,    0,    0,   13,   13,   13,   13,
    13,   13,   14,    0,   14,    0,    0,   14,   14,   14,
-    0,   14,   14,   14,   14,   14,   16,    0,   16,   55,
+    0,   14,   14,   14,   14,   14,   16,    0,   16,    0,
     0,   16,   16,   16,    0,   16,   16,   16,   16,   16,
    14,   14,   14,   14,   14,   14,    0,    0,    0,    0,
     0,    0,    0,    0,   16,   16,   16,   16,   16,   16,
-   59,   59,   56,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,   59,   59,   59,   59,   59,   59,   59,
-   59,   59,   59,   59,   59,   59,   59,   59,    0,    0,
-   47,   47,    0,    0,   59,   59,   59,   59,    0,   59,
-   59,   59,   59,   47,   47,   47,   47,   47,   47,   47,
-   47,   47,   47,   47,   47,   47,   47,   47,   17,    0,
-    0,   48,   48,    0,    0,    0,   47,   47,    0,   47,
-   47,   47,   47,    0,   48,   48,   48,   48,   48,   48,
-   48,   48,   48,   48,   48,   48,   48,   48,   48,    0,
-    0,    0,    0,    0,    0,   49,   49,   48,   48,    0,
-   48,   48,   48,   48,    0,    0,    0,    0,   49,   49,
-   49,   49,   49,   49,   49,   49,   49,   49,   49,   49,
-   49,   49,   49,    0,    0,    0,    0,    0,    0,   40,
-   41,   49,   49,    0,   49,   49,   49,   49,    0,    0,
-    0,    0,  164,  165,  166,  167,  168,  169,  170,  171,
-  172,  173,  174,  175,  176,  177,   42,    0,    0,    0,
-    0,    0,   54,   54,    0,    0,    0,    0,   44,   45,
-   46,   47,    0,    0,    0,   54,   54,   54,   54,   54,
-   54,   54,   54,   54,   54,   54,   54,   54,   54,   54,
-    0,    0,    0,   55,   55,    0,    0,    0,    0,    0,
-    0,   54,   54,   54,   54,    0,   55,   55,   55,   55,
-   55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
-   55,    0,    0,    0,    0,    0,   56,   56,    0,    0,
-    0,    0,   55,   55,   55,   55,    0,    0,    0,   56,
-   56,   56,   56,   56,   56,   56,   56,   56,   56,   56,
-   56,   56,   56,   56,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   56,   56,   56,   56,    0,
+   40,   41,  128,    0,    0,    0,    0,  129,    0,    0,
+    0,    0,    0,  138,  139,  140,  141,  142,  143,  144,
+  145,  146,  147,  148,  149,  150,  151,   42,  130,    0,
+   49,   49,    0,    0,  152,  153,  154,  155,    0,   44,
+   45,   46,   47,   49,   49,   49,   49,   49,   49,   49,
+   49,   49,   49,   49,   49,   49,   49,   49,    0,    0,
+    0,    0,    0,    0,   49,   49,   49,   49,    0,   49,
+   49,   49,   49,    1,    0,    2,    0,    0,    3,    4,
+    5,    0,    6,    7,    8,    9,   10,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    1,    0,    2,    0,    0,    3,    4,    5,    0,
-    6,    7,    8,    9,   10,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,    0,    0,   11,
-   12,   13,   14,   15,   16,
+    0,   11,   12,   13,   14,   15,   16,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short sudoerscheck[] =
@@ -417,22 +392,22 @@ const short sudoerscheck[] =
 short sudoerscheck[] =
 #endif
 	{                                      33,
-    0,    8,    9,   33,   33,    7,   86,   44,   33,   33,
-   44,   33,  285,   33,    0,   44,  257,  258,  258,   44,
-   33,  258,   44,  258,   61,  258,  258,   33,   58,  261,
-  262,  263,  258,   33,  260,  261,   44,  263,  259,   43,
-  258,   45,   58,  284,   44,  263,   44,   33,    0,   58,
-   58,   61,  284,   36,  263,   38,   39,   61,  284,   58,
-  291,  292,    0,  293,  294,   58,  284,   58,   51,   61,
-   58,   61,   58,   58,   61,  263,   58,   58,  158,  263,
-   40,   33,  264,  264,  264,  264,   93,   89,   95,   44,
-   44,   44,   41,   44,   61,   33,    0,   61,  291,   44,
-  292,  263,  263,   61,   61,  294,   58,  293,  263,  263,
-    0,  118,    0,    0,   41,   41,   41,   41,   41,   75,
-   58,  126,   43,   52,   34,   91,   66,   77,   17,   33,
-   99,  152,  135,  148,   96,  131,  130,   22,   -1,   -1,
-   -1,   -1,  139,   33,    0,   92,   90,   -1,   94,   -1,
-   -1,   -1,  147,   -1,   58,   -1,   -1,   -1,    0,   -1,
+    0,    8,    9,   33,   33,    7,   44,   44,   33,   33,
+   44,   33,   86,   33,    0,   44,  257,  258,  285,   44,
+   33,   58,   44,   61,  258,  258,  258,   33,   58,  261,
+  262,  263,  258,   33,  260,  261,  258,  263,  258,   43,
+  258,   45,  259,  284,   44,  263,   44,   33,    0,   58,
+   58,   61,  284,  127,  263,   58,   61,   61,  284,   58,
+  263,   36,    0,   38,   39,   58,  284,   58,   58,   61,
+  263,   58,   58,   61,   58,  264,   51,  264,  264,  264,
+   40,   33,   44,   44,   41,   44,   93,   89,   95,   44,
+   44,   61,   61,   61,   61,   33,    0,  263,  263,  263,
+  263,    0,    0,  126,   41,   41,   58,   41,   41,   41,
+    0,  118,   75,   43,   91,   34,   66,   52,  162,   77,
+   58,   17,   22,  135,   90,   99,   -1,   92,   -1,   33,
+   -1,   -1,   96,   -1,  131,   -1,   -1,   -1,   94,   -1,
+   -1,   -1,   -1,   33,    0,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   58,   -1,   -1,   -1,    0,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   58,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
@@ -442,7 +417,7 @@ short sudoerscheck[] =
    -1,   -1,   -1,   -1,  258,   33,  260,  261,  258,  263,
   259,  261,  262,  263,  259,  259,   -1,  259,  258,   33,
     0,  261,  262,  263,  257,  258,   -1,   -1,   -1,   -1,
-  284,  257,  258,   -1,  284,   -1,  256,   -1,  258,   33,
+  284,  257,  258,   -1,  284,   -1,  256,   -1,  258,   -1,
    -1,  261,  262,  263,  284,  265,  266,  267,  268,  269,
   256,  284,  258,   33,    0,  261,  262,  263,  284,  265,
   266,  267,  268,  269,  284,  285,  286,  287,  288,  289,
@@ -460,61 +435,40 @@ short sudoerscheck[] =
   256,   -1,  258,   33,   -1,  261,  262,  263,   -1,  265,
   266,  267,  268,  269,  256,   -1,  258,   -1,   -1,  261,
   262,  263,   -1,  265,  266,  267,  268,  269,  284,  285,
-  286,  287,  288,  289,   -1,   -1,   33,   -1,   -1,   -1,
+  286,  287,  288,  289,   -1,   -1,   33,   33,   -1,   -1,
    -1,   -1,  284,  285,  286,  287,  288,  289,  256,   -1,
   258,   -1,   -1,  261,  262,  263,   -1,  265,  266,  267,
   268,  269,  256,   -1,  258,   -1,   33,  261,  262,  263,
    -1,  265,  266,  267,  268,  269,  284,  285,  286,  287,
-  288,  289,   -1,   -1,  258,   -1,  260,  261,   -1,  263,
-  284,  285,  286,  287,  288,  289,  256,   33,  258,   -1,
+  288,  289,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  284,  285,  286,  287,  288,  289,  256,   -1,  258,   -1,
    -1,  261,  262,  263,   -1,  265,  266,  267,  268,  269,
-  284,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,  284,  285,  286,  287,  288,  289,
-  256,   33,  258,   -1,   -1,  261,  262,  263,   -1,  265,
-  266,  267,  268,  269,   -1,   -1,  258,   -1,   -1,   -1,
+  256,   -1,  258,   -1,   -1,  261,  262,  263,   -1,  265,
+  266,  267,  268,  269,   -1,   -1,  258,   -1,  260,  261,
    -1,  263,   -1,   -1,   -1,   -1,   -1,   -1,  284,  285,
-  286,  287,  288,  289,  256,   33,  258,   -1,   -1,  261,
+  286,  287,  288,  289,  256,   -1,  258,   -1,   -1,  261,
   262,  263,  284,  265,  266,  267,  268,  269,  256,   -1,
   258,   -1,   -1,  261,  262,  263,   -1,  265,  266,  267,
-  268,  269,  284,  285,  286,  287,  288,  289,   33,   -1,
+  268,  269,  284,  285,  286,  287,  288,  289,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,  284,  285,  286,  287,
   288,  289,  256,   -1,  258,   -1,   -1,  261,  262,  263,
-   -1,  265,  266,  267,  268,  269,  256,   -1,  258,   33,
+   -1,  265,  266,  267,  268,  269,  256,   -1,  258,   -1,
    -1,  261,  262,  263,   -1,  265,  266,  267,  268,  269,
   284,  285,  286,  287,  288,  289,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,  284,  285,  286,  287,  288,  289,
-  257,  258,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  257,  258,  258,   -1,   -1,   -1,   -1,  263,   -1,   -1,
    -1,   -1,   -1,  270,  271,  272,  273,  274,  275,  276,
-  277,  278,  279,  280,  281,  282,  283,  284,   -1,   -1,
+  277,  278,  279,  280,  281,  282,  283,  284,  284,   -1,
   257,  258,   -1,   -1,  291,  292,  293,  294,   -1,  296,
   297,  298,  299,  270,  271,  272,  273,  274,  275,  276,
-  277,  278,  279,  280,  281,  282,  283,  284,   33,   -1,
-   -1,  257,  258,   -1,   -1,   -1,  293,  294,   -1,  296,
-  297,  298,  299,   -1,  270,  271,  272,  273,  274,  275,
-  276,  277,  278,  279,  280,  281,  282,  283,  284,   -1,
-   -1,   -1,   -1,   -1,   -1,  257,  258,  293,  294,   -1,
-  296,  297,  298,  299,   -1,   -1,   -1,   -1,  270,  271,
-  272,  273,  274,  275,  276,  277,  278,  279,  280,  281,
-  282,  283,  284,   -1,   -1,   -1,   -1,   -1,   -1,  257,
-  258,  293,  294,   -1,  296,  297,  298,  299,   -1,   -1,
-   -1,   -1,  270,  271,  272,  273,  274,  275,  276,  277,
-  278,  279,  280,  281,  282,  283,  284,   -1,   -1,   -1,
-   -1,   -1,  257,  258,   -1,   -1,   -1,   -1,  296,  297,
-  298,  299,   -1,   -1,   -1,  270,  271,  272,  273,  274,
-  275,  276,  277,  278,  279,  280,  281,  282,  283,  284,
-   -1,   -1,   -1,  257,  258,   -1,   -1,   -1,   -1,   -1,
-   -1,  296,  297,  298,  299,   -1,  270,  271,  272,  273,
-  274,  275,  276,  277,  278,  279,  280,  281,  282,  283,
-  284,   -1,   -1,   -1,   -1,   -1,  257,  258,   -1,   -1,
-   -1,   -1,  296,  297,  298,  299,   -1,   -1,   -1,  270,
-  271,  272,  273,  274,  275,  276,  277,  278,  279,  280,
-  281,  282,  283,  284,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  296,  297,  298,  299,   -1,
+  277,  278,  279,  280,  281,  282,  283,  284,   -1,   -1,
+   -1,   -1,   -1,   -1,  291,  292,  293,  294,   -1,  296,
+  297,  298,  299,  256,   -1,  258,   -1,   -1,  261,  262,
+  263,   -1,  265,  266,  267,  268,  269,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,  256,   -1,  258,   -1,   -1,  261,  262,  263,   -1,
-  265,  266,  267,  268,  269,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  284,
-  285,  286,  287,  288,  289,
+   -1,  284,  285,  286,  287,  288,  289,
 };
 #define YYFINAL 18
 #ifndef YYDEBUG
@@ -584,7 +538,7 @@ char *sudoersrule[] =
 "host : WORD",
 "cmndspeclist : cmndspec",
 "cmndspeclist : cmndspeclist ',' cmndspec",
-"cmndspec : runasspec selinux solarisprivs cmndtag digcmnd",
+"cmndspec : runasspec options digcmnd",
 "digest : SHA224_TOK ':' DIGEST",
 "digest : SHA256_TOK ':' DIGEST",
 "digest : SHA384_TOK ':' DIGEST",
@@ -595,18 +549,8 @@ char *sudoersrule[] =
 "opcmnd : '!' cmnd",
 "rolespec : ROLE '=' WORD",
 "typespec : TYPE '=' WORD",
-"selinux :",
-"selinux : rolespec",
-"selinux : typespec",
-"selinux : rolespec typespec",
-"selinux : typespec rolespec",
 "privsspec : PRIVS '=' WORD",
 "limitprivsspec : LIMITPRIVS '=' WORD",
-"solarisprivs :",
-"solarisprivs : privsspec",
-"solarisprivs : limitprivsspec",
-"solarisprivs : privsspec limitprivsspec",
-"solarisprivs : limitprivsspec privsspec",
 "runasspec :",
 "runasspec : '(' runaslist ')'",
 "runaslist :",
@@ -614,21 +558,25 @@ char *sudoersrule[] =
 "runaslist : userlist ':' grouplist",
 "runaslist : ':' grouplist",
 "runaslist : ':'",
-"cmndtag :",
-"cmndtag : cmndtag NOPASSWD",
-"cmndtag : cmndtag PASSWD",
-"cmndtag : cmndtag NOEXEC",
-"cmndtag : cmndtag EXEC",
-"cmndtag : cmndtag SETENV",
-"cmndtag : cmndtag NOSETENV",
-"cmndtag : cmndtag LOG_INPUT",
-"cmndtag : cmndtag NOLOG_INPUT",
-"cmndtag : cmndtag LOG_OUTPUT",
-"cmndtag : cmndtag NOLOG_OUTPUT",
-"cmndtag : cmndtag FOLLOW",
-"cmndtag : cmndtag NOFOLLOW",
-"cmndtag : cmndtag MAIL",
-"cmndtag : cmndtag NOMAIL",
+"options :",
+"options : options NOPASSWD",
+"options : options PASSWD",
+"options : options NOEXEC",
+"options : options EXEC",
+"options : options SETENV",
+"options : options NOSETENV",
+"options : options LOG_INPUT",
+"options : options NOLOG_INPUT",
+"options : options LOG_OUTPUT",
+"options : options NOLOG_OUTPUT",
+"options : options FOLLOW",
+"options : options NOFOLLOW",
+"options : options MAIL",
+"options : options NOMAIL",
+"options : options rolespec",
+"options : options typespec",
+"options : options privsspec",
+"options : options limitprivsspec",
 "cmnd : ALL",
 "cmnd : ALIAS",
 "cmnd : COMMAND",
@@ -692,7 +640,7 @@ short *yysslim;
 YYSTYPE *yyvs;
 unsigned int yystacksize;
 int yyparse(void);
-#line 856 "gram.y"
+#line 834 "gram.y"
 void
 sudoerserror(const char *s)
 {
@@ -1007,7 +955,7 @@ init_parser(const char *path, bool quiet)
 
     debug_return_bool(ret);
 }
-#line 958 "gram.c"
+#line 906 "gram.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1216,23 +1164,23 @@ yyreduce:
     switch (yyn)
     {
 case 1:
-#line 170 "gram.y"
+#line 166 "gram.y"
 { ; }
 break;
 case 5:
-#line 178 "gram.y"
+#line 174 "gram.y"
 {
 			    ;
 			}
 break;
 case 6:
-#line 181 "gram.y"
+#line 177 "gram.y"
 {
 			    yyerrok;
 			}
 break;
 case 7:
-#line 184 "gram.y"
+#line 180 "gram.y"
 {
 			    if (!add_userspec(yyvsp[-1].member, yyvsp[0].privilege)) {
 				sudoerserror(N_("unable to allocate memory"));
@@ -1241,73 +1189,73 @@ case 7:
 			}
 break;
 case 8:
-#line 190 "gram.y"
+#line 186 "gram.y"
 {
 			    ;
 			}
 break;
 case 9:
-#line 193 "gram.y"
+#line 189 "gram.y"
 {
 			    ;
 			}
 break;
 case 10:
-#line 196 "gram.y"
+#line 192 "gram.y"
 {
 			    ;
 			}
 break;
 case 11:
-#line 199 "gram.y"
+#line 195 "gram.y"
 {
 			    ;
 			}
 break;
 case 12:
-#line 202 "gram.y"
+#line 198 "gram.y"
 {
 			    if (!add_defaults(DEFAULTS, NULL, yyvsp[0].defaults))
 				YYERROR;
 			}
 break;
 case 13:
-#line 206 "gram.y"
+#line 202 "gram.y"
 {
 			    if (!add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults))
 				YYERROR;
 			}
 break;
 case 14:
-#line 210 "gram.y"
+#line 206 "gram.y"
 {
 			    if (!add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults))
 				YYERROR;
 			}
 break;
 case 15:
-#line 214 "gram.y"
+#line 210 "gram.y"
 {
 			    if (!add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults))
 				YYERROR;
 			}
 break;
 case 16:
-#line 218 "gram.y"
+#line 214 "gram.y"
 {
 			    if (!add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults))
 				YYERROR;
 			}
 break;
 case 18:
-#line 225 "gram.y"
+#line 221 "gram.y"
 {
 			    HLTQ_CONCAT(yyvsp[-2].defaults, yyvsp[0].defaults, entries);
 			    yyval.defaults = yyvsp[-2].defaults;
 			}
 break;
 case 19:
-#line 231 "gram.y"
+#line 227 "gram.y"
 {
 			    yyval.defaults = new_default(yyvsp[0].string, NULL, true);
 			    if (yyval.defaults == NULL) {
@@ -1317,7 +1265,7 @@ case 19:
 			}
 break;
 case 20:
-#line 238 "gram.y"
+#line 234 "gram.y"
 {
 			    yyval.defaults = new_default(yyvsp[0].string, NULL, false);
 			    if (yyval.defaults == NULL) {
@@ -1327,7 +1275,7 @@ case 20:
 			}
 break;
 case 21:
-#line 245 "gram.y"
+#line 241 "gram.y"
 {
 			    yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, true);
 			    if (yyval.defaults == NULL) {
@@ -1337,7 +1285,7 @@ case 21:
 			}
 break;
 case 22:
-#line 252 "gram.y"
+#line 248 "gram.y"
 {
 			    yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+');
 			    if (yyval.defaults == NULL) {
@@ -1347,7 +1295,7 @@ case 22:
 			}
 break;
 case 23:
-#line 259 "gram.y"
+#line 255 "gram.y"
 {
 			    yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-');
 			    if (yyval.defaults == NULL) {
@@ -1357,14 +1305,14 @@ case 23:
 			}
 break;
 case 25:
-#line 269 "gram.y"
+#line 265 "gram.y"
 {
 			    HLTQ_CONCAT(yyvsp[-2].privilege, yyvsp[0].privilege, entries);
 			    yyval.privilege = yyvsp[-2].privilege;
 			}
 break;
 case 26:
-#line 275 "gram.y"
+#line 271 "gram.y"
 {
 			    struct privilege *p = calloc(1, sizeof(*p));
 			    if (p == NULL) {
@@ -1378,21 +1326,21 @@ case 26:
 			}
 break;
 case 27:
-#line 288 "gram.y"
+#line 284 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = false;
 			}
 break;
 case 28:
-#line 292 "gram.y"
+#line 288 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = true;
 			}
 break;
 case 29:
-#line 298 "gram.y"
+#line 294 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
 			    if (yyval.member == NULL) {
@@ -1402,7 +1350,7 @@ case 29:
 			}
 break;
 case 30:
-#line 305 "gram.y"
+#line 301 "gram.y"
 {
 			    yyval.member = new_member(NULL, ALL);
 			    if (yyval.member == NULL) {
@@ -1412,7 +1360,7 @@ case 30:
 			}
 break;
 case 31:
-#line 312 "gram.y"
+#line 308 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, NETGROUP);
 			    if (yyval.member == NULL) {
@@ -1422,7 +1370,7 @@ case 31:
 			}
 break;
 case 32:
-#line 319 "gram.y"
+#line 315 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, NTWKADDR);
 			    if (yyval.member == NULL) {
@@ -1432,7 +1380,7 @@ case 32:
 			}
 break;
 case 33:
-#line 326 "gram.y"
+#line 322 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, WORD);
 			    if (yyval.member == NULL) {
@@ -1442,7 +1390,7 @@ case 33:
 			}
 break;
 case 35:
-#line 336 "gram.y"
+#line 332 "gram.y"
 {
 			    struct cmndspec *prev;
 			    prev = HLTQ_LAST(yyvsp[-2].cmndspec, cmndspec, entries);
@@ -1488,15 +1436,15 @@ case 35:
 			}
 break;
 case 36:
-#line 381 "gram.y"
+#line 377 "gram.y"
 {
 			    struct cmndspec *cs = calloc(1, sizeof(*cs));
 			    if (cs == NULL) {
 				sudoerserror(N_("unable to allocate memory"));
 				YYERROR;
 			    }
-			    if (yyvsp[-4].runas != NULL) {
-				if (yyvsp[-4].runas->runasusers != NULL) {
+			    if (yyvsp[-2].runas != NULL) {
+				if (yyvsp[-2].runas->runasusers != NULL) {
 				    cs->runasuserlist =
 					malloc(sizeof(*cs->runasuserlist));
 				    if (cs->runasuserlist == NULL) {
@@ -1504,9 +1452,9 @@ case 36:
 					YYERROR;
 				    }
 				    HLTQ_TO_TAILQ(cs->runasuserlist,
-					yyvsp[-4].runas->runasusers, entries);
+					yyvsp[-2].runas->runasusers, entries);
 				}
-				if (yyvsp[-4].runas->runasgroups != NULL) {
+				if (yyvsp[-2].runas->runasgroups != NULL) {
 				    cs->runasgrouplist =
 					malloc(sizeof(*cs->runasgrouplist));
 				    if (cs->runasgrouplist == NULL) {
@@ -1514,19 +1462,19 @@ case 36:
 					YYERROR;
 				    }
 				    HLTQ_TO_TAILQ(cs->runasgrouplist,
-					yyvsp[-4].runas->runasgroups, entries);
+					yyvsp[-2].runas->runasgroups, entries);
 				}
-				free(yyvsp[-4].runas);
+				free(yyvsp[-2].runas);
 			    }
 #ifdef HAVE_SELINUX
-			    cs->role = yyvsp[-3].seinfo.role;
-			    cs->type = yyvsp[-3].seinfo.type;
+			    cs->role = yyvsp[-1].options.role;
+			    cs->type = yyvsp[-1].options.type;
 #endif
 #ifdef HAVE_PRIV_SET
-			    cs->privs = yyvsp[-2].privinfo.privs;
-			    cs->limitprivs = yyvsp[-2].privinfo.limitprivs;
+			    cs->privs = yyvsp[-1].options.privs;
+			    cs->limitprivs = yyvsp[-1].options.limitprivs;
 #endif
-			    cs->tags = yyvsp[-1].tag;
+			    cs->tags = yyvsp[-1].options.tags;
 			    cs->cmnd = yyvsp[0].member;
 			    HLTQ_INIT(cs, entries);
 			    /* sudo "ALL" implies the SETENV tag */
@@ -1537,7 +1485,7 @@ case 36:
 			}
 break;
 case 37:
-#line 429 "gram.y"
+#line 425 "gram.y"
 {
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA224, yyvsp[0].string);
 			    if (yyval.digest == NULL) {
@@ -1547,7 +1495,7 @@ case 37:
 			}
 break;
 case 38:
-#line 436 "gram.y"
+#line 432 "gram.y"
 {
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA256, yyvsp[0].string);
 			    if (yyval.digest == NULL) {
@@ -1557,7 +1505,7 @@ case 38:
 			}
 break;
 case 39:
-#line 443 "gram.y"
+#line 439 "gram.y"
 {
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA384, yyvsp[0].string);
 			    if (yyval.digest == NULL) {
@@ -1567,7 +1515,7 @@ case 39:
 			}
 break;
 case 40:
-#line 450 "gram.y"
+#line 446 "gram.y"
 {
 			    yyval.digest = new_digest(SUDO_DIGEST_SHA512, yyvsp[0].string);
 			    if (yyval.digest == NULL) {
@@ -1577,13 +1525,13 @@ case 40:
 			}
 break;
 case 41:
-#line 459 "gram.y"
+#line 455 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			}
 break;
 case 42:
-#line 462 "gram.y"
+#line 458 "gram.y"
 {
 			    if (yyvsp[0].member->type != COMMAND) {
 				sudoerserror(N_("a digest requires a path name"));
@@ -1595,127 +1543,57 @@ case 42:
 			}
 break;
 case 43:
-#line 473 "gram.y"
+#line 469 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = false;
 			}
 break;
 case 44:
-#line 477 "gram.y"
+#line 473 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = true;
 			}
 break;
 case 45:
-#line 483 "gram.y"
+#line 479 "gram.y"
 {
 			    yyval.string = yyvsp[0].string;
 			}
 break;
 case 46:
-#line 488 "gram.y"
+#line 484 "gram.y"
 {
 			    yyval.string = yyvsp[0].string;
 			}
 break;
 case 47:
-#line 493 "gram.y"
+#line 489 "gram.y"
 {
-			    yyval.seinfo.role = NULL;
-			    yyval.seinfo.type = NULL;
+			    yyval.string = yyvsp[0].string;
 			}
 break;
 case 48:
-#line 497 "gram.y"
+#line 493 "gram.y"
 {
-			    yyval.seinfo.role = yyvsp[0].string;
-			    yyval.seinfo.type = NULL;
+			    yyval.string = yyvsp[0].string;
 			}
 break;
 case 49:
-#line 501 "gram.y"
-{
-			    yyval.seinfo.type = yyvsp[0].string;
-			    yyval.seinfo.role = NULL;
-			}
-break;
-case 50:
-#line 505 "gram.y"
-{
-			    yyval.seinfo.role = yyvsp[-1].string;
-			    yyval.seinfo.type = yyvsp[0].string;
-			}
-break;
-case 51:
-#line 509 "gram.y"
-{
-			    yyval.seinfo.type = yyvsp[-1].string;
-			    yyval.seinfo.role = yyvsp[0].string;
-			}
-break;
-case 52:
-#line 515 "gram.y"
-{
-			    yyval.string = yyvsp[0].string;
-			}
-break;
-case 53:
-#line 519 "gram.y"
-{
-			    yyval.string = yyvsp[0].string;
-			}
-break;
-case 54:
-#line 524 "gram.y"
-{
-			    yyval.privinfo.privs = NULL;
-			    yyval.privinfo.limitprivs = NULL;
-			}
-break;
-case 55:
-#line 528 "gram.y"
-{
-			    yyval.privinfo.privs = yyvsp[0].string;
-			    yyval.privinfo.limitprivs = NULL;
-			}
-break;
-case 56:
-#line 532 "gram.y"
-{
-			    yyval.privinfo.privs = NULL;
-			    yyval.privinfo.limitprivs = yyvsp[0].string;
-			}
-break;
-case 57:
-#line 536 "gram.y"
-{
-			    yyval.privinfo.privs = yyvsp[-1].string;
-			    yyval.privinfo.limitprivs = yyvsp[0].string;
-			}
-break;
-case 58:
-#line 540 "gram.y"
-{
-			    yyval.privinfo.limitprivs = yyvsp[-1].string;
-			    yyval.privinfo.privs = yyvsp[0].string;
-			}
-break;
-case 59:
-#line 546 "gram.y"
+#line 498 "gram.y"
 {
 			    yyval.runas = NULL;
 			}
 break;
-case 60:
-#line 549 "gram.y"
+case 50:
+#line 501 "gram.y"
 {
 			    yyval.runas = yyvsp[-1].runas;
 			}
 break;
-case 61:
-#line 554 "gram.y"
+case 51:
+#line 506 "gram.y"
 {
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
 			    if (yyval.runas != NULL) {
@@ -1732,8 +1610,8 @@ case 61:
 			    }
 			}
 break;
-case 62:
-#line 569 "gram.y"
+case 52:
+#line 521 "gram.y"
 {
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
 			    if (yyval.runas == NULL) {
@@ -1744,8 +1622,8 @@ case 62:
 			    /* $$->runasgroups = NULL; */
 			}
 break;
-case 63:
-#line 578 "gram.y"
+case 53:
+#line 530 "gram.y"
 {
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
 			    if (yyval.runas == NULL) {
@@ -1756,8 +1634,8 @@ case 63:
 			    yyval.runas->runasgroups = yyvsp[0].member;
 			}
 break;
-case 64:
-#line 587 "gram.y"
+case 54:
+#line 539 "gram.y"
 {
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
 			    if (yyval.runas == NULL) {
@@ -1768,8 +1646,8 @@ case 64:
 			    yyval.runas->runasgroups = yyvsp[0].member;
 			}
 break;
-case 65:
-#line 596 "gram.y"
+case 55:
+#line 548 "gram.y"
 {
 			    yyval.runas = calloc(1, sizeof(struct runascontainer));
 			    if (yyval.runas != NULL) {
@@ -1786,98 +1664,136 @@ case 65:
 			    }
 			}
 break;
-case 66:
-#line 613 "gram.y"
+case 56:
+#line 565 "gram.y"
 {
-			    TAGS_INIT(yyval.tag);
+			    TAGS_INIT(yyval.options.tags);
+#ifdef HAVE_SELINUX
+			    yyval.options.role = NULL, yyval.options.type = NULL;
+#endif
+#ifdef HAVE_PRIV_SET
+			    yyval.options.privs = NULL, yyval.options.limitprivs = NULL;
+#endif
+			}
+break;
+case 57:
+#line 574 "gram.y"
+{
+			    yyval.options.tags.nopasswd = true;
+			}
+break;
+case 58:
+#line 577 "gram.y"
+{
+			    yyval.options.tags.nopasswd = false;
+			}
+break;
+case 59:
+#line 580 "gram.y"
+{
+			    yyval.options.tags.noexec = true;
+			}
+break;
+case 60:
+#line 583 "gram.y"
+{
+			    yyval.options.tags.noexec = false;
+			}
+break;
+case 61:
+#line 586 "gram.y"
+{
+			    yyval.options.tags.setenv = true;
+			}
+break;
+case 62:
+#line 589 "gram.y"
+{
+			    yyval.options.tags.setenv = false;
+			}
+break;
+case 63:
+#line 592 "gram.y"
+{
+			    yyval.options.tags.log_input = true;
+			}
+break;
+case 64:
+#line 595 "gram.y"
+{
+			    yyval.options.tags.log_input = false;
+			}
+break;
+case 65:
+#line 598 "gram.y"
+{
+			    yyval.options.tags.log_output = true;
+			}
+break;
+case 66:
+#line 601 "gram.y"
+{
+			    yyval.options.tags.log_output = false;
 			}
 break;
 case 67:
-#line 616 "gram.y"
+#line 604 "gram.y"
 {
-			    yyval.tag.nopasswd = true;
+			    yyval.options.tags.follow = true;
 			}
 break;
 case 68:
-#line 619 "gram.y"
+#line 607 "gram.y"
 {
-			    yyval.tag.nopasswd = false;
+			    yyval.options.tags.follow = false;
 			}
 break;
 case 69:
-#line 622 "gram.y"
+#line 610 "gram.y"
 {
-			    yyval.tag.noexec = true;
+			    yyval.options.tags.send_mail = true;
 			}
 break;
 case 70:
-#line 625 "gram.y"
+#line 613 "gram.y"
 {
-			    yyval.tag.noexec = false;
+			    yyval.options.tags.send_mail = false;
 			}
 break;
 case 71:
-#line 628 "gram.y"
+#line 616 "gram.y"
 {
-			    yyval.tag.setenv = true;
+#ifdef HAVE_SELINUX
+			    yyval.options.role = yyvsp[0].string;
+#endif
 			}
 break;
 case 72:
-#line 631 "gram.y"
+#line 621 "gram.y"
 {
-			    yyval.tag.setenv = false;
+#ifdef HAVE_SELINUX
+			    yyval.options.type = yyvsp[0].string;
+#endif
 			}
 break;
 case 73:
-#line 634 "gram.y"
+#line 626 "gram.y"
 {
-			    yyval.tag.log_input = true;
+#ifdef HAVE_PRIV_SET
+			    yyval.options.privs = yyvsp[0].string;
+#endif
 			}
 break;
 case 74:
-#line 637 "gram.y"
+#line 631 "gram.y"
 {
-			    yyval.tag.log_input = false;
+#ifdef HAVE_PRIV_SET
+			    yyval.options.limitprivs = yyvsp[0].string;
+#endif
 			}
 break;
 case 75:
-#line 640 "gram.y"
-{
-			    yyval.tag.log_output = true;
-			}
-break;
-case 76:
-#line 643 "gram.y"
-{
-			    yyval.tag.log_output = false;
-			}
-break;
-case 77:
-#line 646 "gram.y"
-{
-			    yyval.tag.follow = true;
-			}
-break;
-case 78:
-#line 649 "gram.y"
-{
-			    yyval.tag.follow = false;
-			}
-break;
-case 79:
-#line 652 "gram.y"
-{
-			    yyval.tag.send_mail = true;
-			}
-break;
-case 80:
-#line 655 "gram.y"
-{
-			    yyval.tag.send_mail = false;
-			}
-break;
-case 81:
-#line 660 "gram.y"
+#line 638 "gram.y"
 {
 			    yyval.member = new_member(NULL, ALL);
 			    if (yyval.member == NULL) {
@@ -1886,8 +1802,8 @@ case 81:
 			    }
 			}
 break;
-case 82:
-#line 667 "gram.y"
+case 76:
+#line 645 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
 			    if (yyval.member == NULL) {
@@ -1896,8 +1812,8 @@ case 82:
 			    }
 			}
 break;
-case 83:
-#line 674 "gram.y"
+case 77:
+#line 652 "gram.y"
 {
 			    struct sudo_command *c = calloc(1, sizeof(*c));
 			    if (c == NULL) {
@@ -1914,8 +1830,8 @@ case 83:
 			    }
 			}
 break;
-case 86:
-#line 695 "gram.y"
+case 80:
+#line 673 "gram.y"
 {
 			    const char *s;
 			    s = alias_add(yyvsp[-2].string, HOSTALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1925,15 +1841,15 @@ case 86:
 			    }
 			}
 break;
-case 88:
-#line 706 "gram.y"
+case 82:
+#line 684 "gram.y"
 {
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
 			    yyval.member = yyvsp[-2].member;
 			}
 break;
-case 91:
-#line 716 "gram.y"
+case 85:
+#line 694 "gram.y"
 {
 			    const char *s;
 			    s = alias_add(yyvsp[-2].string, CMNDALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1943,15 +1859,15 @@ case 91:
 			    }
 			}
 break;
-case 93:
-#line 727 "gram.y"
+case 87:
+#line 705 "gram.y"
 {
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
 			    yyval.member = yyvsp[-2].member;
 			}
 break;
-case 96:
-#line 737 "gram.y"
+case 90:
+#line 715 "gram.y"
 {
 			    const char *s;
 			    s = alias_add(yyvsp[-2].string, RUNASALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1961,8 +1877,8 @@ case 96:
 			    }
 			}
 break;
-case 99:
-#line 751 "gram.y"
+case 93:
+#line 729 "gram.y"
 {
 			    const char *s;
 			    s = alias_add(yyvsp[-2].string, USERALIAS, sudoers, this_lineno, yyvsp[0].member);
@@ -1972,29 +1888,29 @@ case 99:
 			    }
 			}
 break;
-case 101:
-#line 762 "gram.y"
+case 95:
+#line 740 "gram.y"
 {
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
 			    yyval.member = yyvsp[-2].member;
 			}
 break;
-case 102:
-#line 768 "gram.y"
+case 96:
+#line 746 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = false;
 			}
 break;
-case 103:
-#line 772 "gram.y"
+case 97:
+#line 750 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = true;
 			}
 break;
-case 104:
-#line 778 "gram.y"
+case 98:
+#line 756 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
 			    if (yyval.member == NULL) {
@@ -2003,8 +1919,8 @@ case 104:
 			    }
 			}
 break;
-case 105:
-#line 785 "gram.y"
+case 99:
+#line 763 "gram.y"
 {
 			    yyval.member = new_member(NULL, ALL);
 			    if (yyval.member == NULL) {
@@ -2013,8 +1929,8 @@ case 105:
 			    }
 			}
 break;
-case 106:
-#line 792 "gram.y"
+case 100:
+#line 770 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, NETGROUP);
 			    if (yyval.member == NULL) {
@@ -2023,8 +1939,8 @@ case 106:
 			    }
 			}
 break;
-case 107:
-#line 799 "gram.y"
+case 101:
+#line 777 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, USERGROUP);
 			    if (yyval.member == NULL) {
@@ -2033,8 +1949,8 @@ case 107:
 			    }
 			}
 break;
-case 108:
-#line 806 "gram.y"
+case 102:
+#line 784 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, WORD);
 			    if (yyval.member == NULL) {
@@ -2043,29 +1959,29 @@ case 108:
 			    }
 			}
 break;
-case 110:
-#line 816 "gram.y"
+case 104:
+#line 794 "gram.y"
 {
 			    HLTQ_CONCAT(yyvsp[-2].member, yyvsp[0].member, entries);
 			    yyval.member = yyvsp[-2].member;
 			}
 break;
-case 111:
-#line 822 "gram.y"
+case 105:
+#line 800 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = false;
 			}
 break;
-case 112:
-#line 826 "gram.y"
+case 106:
+#line 804 "gram.y"
 {
 			    yyval.member = yyvsp[0].member;
 			    yyval.member->negated = true;
 			}
 break;
-case 113:
-#line 832 "gram.y"
+case 107:
+#line 810 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, ALIAS);
 			    if (yyval.member == NULL) {
@@ -2074,8 +1990,8 @@ case 113:
 			    }
 			}
 break;
-case 114:
-#line 839 "gram.y"
+case 108:
+#line 817 "gram.y"
 {
 			    yyval.member = new_member(NULL, ALL);
 			    if (yyval.member == NULL) {
@@ -2084,8 +2000,8 @@ case 114:
 			    }
 			}
 break;
-case 115:
-#line 846 "gram.y"
+case 109:
+#line 824 "gram.y"
 {
 			    yyval.member = new_member(yyvsp[0].string, WORD);
 			    if (yyval.member == NULL) {
@@ -2094,7 +2010,7 @@ case 115:
 			    }
 			}
 break;
-#line 2045 "gram.c"
+#line 1961 "gram.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
diff --git a/plugins/sudoers/gram.h b/plugins/sudoers/gram.h
index c0a8e45c3..e2ccaeec2 100644
--- a/plugins/sudoers/gram.h
+++ b/plugins/sudoers/gram.h
@@ -51,9 +51,7 @@ typedef union {
     struct privilege *privilege;
     struct sudo_digest *digest;
     struct sudo_command command;
-    struct cmndtag tag;
-    struct selinux_info seinfo;
-    struct solaris_privs_info privinfo;
+    struct command_options options;
     char *string;
     int tok;
 } YYSTYPE;
diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y
index 2f68a4254..2b1a98a4e 100644
--- a/plugins/sudoers/gram.y
+++ b/plugins/sudoers/gram.y
@@ -81,9 +81,7 @@ static struct sudo_digest *new_digest(int, const char *);
     struct privilege *privilege;
     struct sudo_digest *digest;
     struct sudo_command command;
-    struct cmndtag tag;
-    struct selinux_info seinfo;
-    struct solaris_privs_info privinfo;
+    struct command_options options;
     char *string;
     int tok;
 }
@@ -156,11 +154,9 @@ static struct sudo_digest *new_digest(int, const char *);
 %type <runas>	  runaslist
 %type <privilege> privilege
 %type <privilege> privileges
-%type <tag>	  cmndtag
-%type <seinfo>	  selinux
+%type <options>	  options
 %type <string>	  rolespec
 %type <string>	  typespec
-%type <privinfo>  solarisprivs
 %type <string>	  privsspec
 %type <string>	  limitprivsspec
 %type <digest>	  digest
@@ -378,7 +374,7 @@ cmndspeclist	:	cmndspec
 			}
 		;
 
-cmndspec	:	runasspec selinux solarisprivs cmndtag digcmnd {
+cmndspec	:	runasspec options digcmnd {
 			    struct cmndspec *cs = calloc(1, sizeof(*cs));
 			    if (cs == NULL) {
 				sudoerserror(N_("unable to allocate memory"));
@@ -412,11 +408,11 @@ cmndspec	:	runasspec selinux solarisprivs cmndtag digcmnd {
 			    cs->type = $2.type;
 #endif
 #ifdef HAVE_PRIV_SET
-			    cs->privs = $3.privs;
-			    cs->limitprivs = $3.limitprivs;
+			    cs->privs = $2.privs;
+			    cs->limitprivs = $2.limitprivs;
 #endif
-			    cs->tags = $4;
-			    cs->cmnd = $5;
+			    cs->tags = $2.tags;
+			    cs->cmnd = $3;
 			    HLTQ_INIT(cs, entries);
 			    /* sudo "ALL" implies the SETENV tag */
 			    if (cs->cmnd->type == ALL && !cs->cmnd->negated &&
@@ -490,28 +486,6 @@ typespec	:	TYPE '=' WORD {
 			}
 		;
 
-selinux		:	/* empty */ {
-			    $$.role = NULL;
-			    $$.type = NULL;
-			}
-		|	rolespec {
-			    $$.role = $1;
-			    $$.type = NULL;
-			}
-		|	typespec {
-			    $$.type = $1;
-			    $$.role = NULL;
-			}
-		|	rolespec typespec {
-			    $$.role = $1;
-			    $$.type = $2;
-			}
-		|	typespec rolespec {
-			    $$.type = $1;
-			    $$.role = $2;
-			}
-		;
-
 privsspec	:	PRIVS '=' WORD {
 			    $$ = $3;
 			}
@@ -521,28 +495,6 @@ limitprivsspec	:	LIMITPRIVS '=' WORD {
 			}
 		;
 
-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;
 			}
@@ -610,50 +562,76 @@ runaslist	:	/* empty */ {
 			}
 		;
 
-cmndtag		:	/* empty */ {
-			    TAGS_INIT($$);
+options		:	/* empty */ {
+			    TAGS_INIT($$.tags);
+#ifdef HAVE_SELINUX
+			    $$.role = NULL, $$.type = NULL;
+#endif
+#ifdef HAVE_PRIV_SET
+			    $$.privs = NULL, $$.limitprivs = NULL;
+#endif
 			}
-		|	cmndtag NOPASSWD {
-			    $$.nopasswd = true;
+		|	options NOPASSWD {
+			    $$.tags.nopasswd = true;
 			}
-		|	cmndtag PASSWD {
-			    $$.nopasswd = false;
+		|	options PASSWD {
+			    $$.tags.nopasswd = false;
 			}
-		|	cmndtag NOEXEC {
-			    $$.noexec = true;
+		|	options NOEXEC {
+			    $$.tags.noexec = true;
 			}
-		|	cmndtag EXEC {
-			    $$.noexec = false;
+		|	options EXEC {
+			    $$.tags.noexec = false;
 			}
-		|	cmndtag SETENV {
-			    $$.setenv = true;
+		|	options SETENV {
+			    $$.tags.setenv = true;
 			}
-		|	cmndtag NOSETENV {
-			    $$.setenv = false;
+		|	options NOSETENV {
+			    $$.tags.setenv = false;
 			}
-		|	cmndtag LOG_INPUT {
-			    $$.log_input = true;
+		|	options LOG_INPUT {
+			    $$.tags.log_input = true;
 			}
-		|	cmndtag NOLOG_INPUT {
-			    $$.log_input = false;
+		|	options NOLOG_INPUT {
+			    $$.tags.log_input = false;
 			}
-		|	cmndtag LOG_OUTPUT {
-			    $$.log_output = true;
+		|	options LOG_OUTPUT {
+			    $$.tags.log_output = true;
 			}
-		|	cmndtag NOLOG_OUTPUT {
-			    $$.log_output = false;
+		|	options NOLOG_OUTPUT {
+			    $$.tags.log_output = false;
 			}
-		|	cmndtag FOLLOW {
-			    $$.follow = true;
+		|	options FOLLOW {
+			    $$.tags.follow = true;
 			}
-		|	cmndtag NOFOLLOW {
-			    $$.follow = false;
+		|	options NOFOLLOW {
+			    $$.tags.follow = false;
 			}
-		|	cmndtag MAIL {
-			    $$.send_mail = true;
+		|	options MAIL {
+			    $$.tags.send_mail = true;
 			}
-		|	cmndtag NOMAIL {
-			    $$.send_mail = false;
+		|	options NOMAIL {
+			    $$.tags.send_mail = false;
+			}
+		|	options rolespec {
+#ifdef HAVE_SELINUX
+			    $$.role = $2;
+#endif
+			}
+		|	options typespec {
+#ifdef HAVE_SELINUX
+			    $$.type = $2;
+#endif
+			}
+		|	options privsspec {
+#ifdef HAVE_PRIV_SET
+			    $$.privs = $2;
+#endif
+			}
+		|	options limitprivsspec {
+#ifdef HAVE_PRIV_SET
+			    $$.limitprivs = $2;
+#endif
 			}
 		;
 
diff --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
index e9cf62404..6450e2a29 100644
--- a/plugins/sudoers/parse.h
+++ b/plugins/sudoers/parse.h
@@ -110,22 +110,16 @@ struct cmndtag {
 };
 
 /*
- * SELinux-specific container struct.
- * Currently just contains a role and type.
+ * Per-command option container struct.
  */
-struct selinux_info {
-    char *role;
-    char *type;
-};
-
-/*
- * Solaris privileges container struct
- * Currently just contains permitted and limit privileges.
- * It could have PFEXEC and PRIV_AWARE flags added in the future.
- */
-struct solaris_privs_info {
-    char *privs;
-    char *limitprivs;
+struct command_options {
+    struct cmndtag tags;		/* Command tags */
+#ifdef HAVE_SELINUX
+    char *role, *type;			/* SELinux role and type */
+#endif
+#ifdef HAVE_PRIV_SET
+    char *privs, *limitprivs;		/* Solaris privilege sets */
+#endif
 };
 
 /*
