]> granicus.if.org Git - sudo/commitdiff
Break sudoers transcript feature up into log_input and log_output.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 30 May 2010 14:31:38 +0000 (10:31 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 30 May 2010 14:31:38 +0000 (10:31 -0400)
18 files changed:
INSTALL
WHATSNEW
aclocal.m4
configure
configure.in
pathnames.h.in
plugins/sudoers/def_data.c
plugins/sudoers/def_data.h
plugins/sudoers/def_data.in
plugins/sudoers/defaults.c
plugins/sudoers/gram.c
plugins/sudoers/gram.h
plugins/sudoers/gram.y
plugins/sudoers/iolog.c
plugins/sudoers/parse.c
plugins/sudoers/parse.h
plugins/sudoers/sudoers.c
plugins/sudoers/sudoreplay.c

diff --git a/INSTALL b/INSTALL
index 7a534f14929b4c990c31d2ba0a7966f1a0ada884..61ca720e77fd284fd83eaa9626d0faa8b721b28e 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -557,11 +557,10 @@ The following options are also configurable at runtime:
         prompt as an argument and print the received password to
         the standard output.
 
-  --with-transcript[=DIR]
-        By default, sudo stores transcript files in either
-        /var/log/sudo-transcript, /var/adm/sudo-transcript, or
-        /usr/log/sudo-transcript.  If this option is specified,
-        transcripts will be stored in the indicated directory
+  --with-iologdir[=DIR]
+        By default, sudo stores I/O log files in either /var/log/sudo-io,
+        /var/adm/sudo-io, or /usr/log/sudo-io.  If this option is
+        specified, I/O logs will be stored in the indicated directory
         instead.
 
   --disable-authentication
@@ -607,13 +606,13 @@ The following options are also configurable at runtime:
 
   --enable-zlib[=DIR]
         Enable the use of the zlib compress library when storing
-        transcript files.  If specified, DIR is the base directory
+        I/O log files.  If specified, DIR is the base directory
         containing the zlib include and lib directories.  By default
         zlib is used if it is found on the system.
 
   --disable-zlib
         Disable the use of the zlib compress library when storing
-        transcript files.
+        I/O log files.
 
 Shadow password and C2 support
 ==============================
index 576b6d2438a8f86a39b8d6c715f1e6d2b1f06564..1797d308ce5c7008a824d081b7e261d5a9ba350d 100644 (file)
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -8,9 +8,10 @@ What's new in Sudo 1.8.0?
 
 What's new in Sudo 1.7.3?
 
- * Support for logging a transcript of the command being run.
-   For more information, see the documentation for the "transcript"
-   Defaults option in the sudoers manual and the sudoreplay manual.
+ * Support for logging I/O for the command being run.
+   For more information, see the documentation for the "log_input"
+   and "log_output" Defaults options in the sudoers manual.  Also
+   see the sudoreplay manual for how to replay I/O log sessions.
 
  * The passwd_timeout and timestamp_timeout options may now be
    specified as floating point numbers for more granular timeout
index 5246810ce551fdbd25dd0cb1e79b47aee782ceeb..46d66a05a073b5f66c92d3c53ea36864ee8da66b 100644 (file)
@@ -158,22 +158,22 @@ fi
 ])dnl
 
 dnl
-dnl Where the transcript files go, use /var/log/sudo-transcript if
-dnl /var/log exists, else /{var,usr}/adm/sudo-transcript
+dnl Where the I/O log files go, use /var/log/sudo-io if
+dnl /var/log exists, else /{var,usr}/adm/sudo-io
 dnl
-AC_DEFUN(SUDO_TRANSCRIPT, [
-    AC_MSG_CHECKING(for transcript dir location)
-    if test "${with_transcript-yes}" != "yes"; then
+AC_DEFUN(SUDO_IO_LOGDIR, [
+    AC_MSG_CHECKING(for I/O log dir location)
+    if test "${with_iologdir-yes}" != "yes"; then
        :
     elif test -d "/var/log"; then
-       with_transcript="/var/log/sudo-transcript"
+       with_iologdir="/var/log/sudo-io"
     elif test -d "/var/adm"; then
-       with_transcript="/var/adm/sudo-transcript"
+       with_iologdir="/var/adm/sudo-io"
     else
-       with_transcript="/usr/adm/sudo-transcript"
+       with_iologdir="/usr/adm/sudo-io"
     fi
-    SUDO_DEFINE_UNQUOTED(_PATH_SUDO_TRANSCRIPT, "$with_transcript")
-    AC_MSG_RESULT($with_transcript)
+    SUDO_DEFINE_UNQUOTED(_PATH_SUDO_IO_LOGDIR, "$with_iologdir")
+    AC_MSG_RESULT($with_iologdir)
 ])dnl
 
 dnl
index e24cdd9841723d141ec4acd85e1ce257c1a1e7ff..7fb4a3efb94ff9939c3ce2063a2632ea6b13b3ad 100755 (executable)
--- a/configure
+++ b/configure
@@ -945,7 +945,7 @@ with_passprompt
 with_badpass_message
 with_fqdn
 with_timedir
-with_transcript
+with_iologdir
 with_sendmail
 with_sudoers_mode
 with_sudoers_uid
@@ -1699,7 +1699,7 @@ Optional Packages:
   --with-badpass-message  message the user sees when the password is wrong
   --with-fqdn             expect fully qualified hosts in sudoers
   --with-timedir          path to the sudo timestamp dir
-  --with-transcript=DIR   directory to store sudo transcript files in
+  --with-iologdir=DIR     directory to store sudo I/O log files in
   --with-sendmail         set path to sendmail
   --without-sendmail      do not send mail at all
   --with-sudoers-mode     mode of sudoers file (defaults to 0440)
@@ -3665,11 +3665,11 @@ fi
 
 
 
-# Check whether --with-transcript was given.
-if test "${with_transcript+set}" = set; then :
-  withval=$with_transcript; case $with_transcript in
+# Check whether --with-iologdir was given.
+if test "${with_iologdir+set}" = set; then :
+  withval=$with_iologdir; case $with_iologdir in
     yes)    ;;
-    no)     as_fn_error "\"--without-transcript not supported.\"" "$LINENO" 5
+    no)     as_fn_error "\"--without-iologfir not supported.\"" "$LINENO" 5
            ;;
 esac
 fi
@@ -17935,23 +17935,23 @@ EOF
 fi
 
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for transcript dir location" >&5
-$as_echo_n "checking for transcript dir location... " >&6; }
-    if test "${with_transcript-yes}" != "yes"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for I/O log dir location" >&5
+$as_echo_n "checking for I/O log dir location... " >&6; }
+    if test "${with_iologdir-yes}" != "yes"; then
        :
     elif test -d "/var/log"; then
-       with_transcript="/var/log/sudo-transcript"
+       with_iologdir="/var/log/sudo-io"
     elif test -d "/var/adm"; then
-       with_transcript="/var/adm/sudo-transcript"
+       with_iologdir="/var/adm/sudo-io"
     else
-       with_transcript="/usr/adm/sudo-transcript"
+       with_iologdir="/usr/adm/sudo-io"
     fi
     cat >>confdefs.h <<EOF
-#define _PATH_SUDO_TRANSCRIPT "$with_transcript"
+#define _PATH_SUDO_IO_LOGDIR "$with_iologdir"
 EOF
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_transcript" >&5
-$as_echo "$with_transcript" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_iologdir" >&5
+$as_echo "$with_iologdir" >&6; }
 
 
 case "$with_passwd" in
index fce653e0a69a407bdbfcdfeb36ad370f26a7bc0f..8ea0d7373b8c8c1aee8185e8b81050940f3c184e 100644 (file)
@@ -704,11 +704,11 @@ AC_ARG_WITH(timedir, [AS_HELP_STRING([--with-timedir], [path to the sudo timesta
                ;;
 esac])
 
-AC_ARG_WITH(transcript, [AS_HELP_STRING([--with-transcript=DIR], [directory
-to store sudo transcript files in])],
-[case $with_transcript in
+AC_ARG_WITH(iologdir, [AS_HELP_STRING([--with-iologdir=DIR], [directory
+to store sudo I/O log files in])],
+[case $with_iologdir in
     yes)    ;;
-    no)     AC_MSG_ERROR(["--without-transcript not supported."])
+    no)     AC_MSG_ERROR(["--without-iologfir not supported."])
            ;;
 esac])
 
@@ -2663,11 +2663,11 @@ if test -n "$blibpath"; then
 fi
 
 dnl
-dnl Check for log file, timestamp and transcript locations
+dnl Check for log file, timestamp and iolog locations
 dnl
 SUDO_LOGFILE
 SUDO_TIMEDIR
-SUDO_TRANSCRIPT
+SUDO_IOLOGDIR
 
 dnl
 dnl Use passwd (and secureware) auth modules?
index 8402c1585d0be4423fbc0677e1bd8fd32e05e647..88ba6abfa6ebe9cc72611b2ec1ea56067dca49bf 100644 (file)
 #endif /* _PATH_SUDO_TIMEDIR */
 
 /*
- * Where to put the session files.  Defaults to /var/log/sudo-session,
- * /var/adm/sudo-session or /usr/adm/sudo-session depending on what exists.
+ * Where to put the I/O log files.  Defaults to /var/log/sudo-io,
+ * /var/adm/sudo-io or /usr/adm/sudo-io depending on what exists.
  */
-#ifndef _PATH_SUDO_TRANSCRIPT
-#undef _PATH_SUDO_TRANSCRIPT
-#endif /* _PATH_SUDO_TRANSCRIPT */
+#ifndef _PATH_SUDO_IO_LOGDIR
+#undef _PATH_SUDO_IO_LOGDIR
+#endif /* _PATH_SUDO_IO_LOGDIR */
 
 /*
  * Where to put the sudo log file when logging to a file.  Defaults to
index b16d128bb6aaae510b340d01d3dcd20482462192..fe46789862a8ec466edeb6c66e6f388be736e869 100644 (file)
@@ -315,12 +315,16 @@ struct sudo_defs_types sudo_defs_table[] = {
        "The umask specified in sudoers will override the user's, even if it is more permissive",
        NULL,
     }, {
-       "transcript", T_FLAG,
-       "Log a transcript of the command being run",
+       "log_input", T_FLAG,
+       "Log user's input for the command being run",
        NULL,
     }, {
-       "compress_transcript", T_FLAG,
-       "Compress session transcripts with zlib",
+       "log_output", T_FLAG,
+       "Log the output of the command being run",
+       NULL,
+    }, {
+       "compress_io", T_FLAG,
+       "Compress I/O logs using zlib",
        NULL,
     }, {
        NULL, 0, NULL
index 9e9e80d378f3587ad39ee2ab5efcb416a0727989..96652af2c48c46dfdd1bbbe004f5bd9109c07b91 100644 (file)
 #define I_FAST_GLOB             71
 #define def_umask_override      (sudo_defs_table[72].sd_un.flag)
 #define I_UMASK_OVERRIDE        72
-#define def_transcript          (sudo_defs_table[73].sd_un.flag)
-#define I_TRANSCRIPT            73
-#define def_compress_transcript (sudo_defs_table[74].sd_un.flag)
-#define I_COMPRESS_TRANSCRIPT   74
+#define def_log_input           (sudo_defs_table[73].sd_un.flag)
+#define I_LOG_INPUT             73
+#define def_log_output          (sudo_defs_table[74].sd_un.flag)
+#define I_LOG_OUTPUT            74
+#define def_compress_io         (sudo_defs_table[75].sd_un.flag)
+#define I_COMPRESS_IO           75
 
 enum def_tupple {
        never,
index a5b8e9d4117950457a2903707f40931319f18008..56418397dc0cf2cbaec1f80a0906e7c0981710de 100644 (file)
@@ -232,9 +232,12 @@ fast_glob
 umask_override
        T_FLAG
        "The umask specified in sudoers will override the user's, even if it is more permissive"
-transcript
+log_input
        T_FLAG
-       "Log a transcript of the command being run"
-compress_transcript
+       "Log user's input for the command being run"
+log_output
        T_FLAG
-       "Compress session transcripts with zlib"
+       "Log the output of the command being run"
+compress_io
+       T_FLAG
+       "Compress I/O logs using zlib"
index b2f5fac3a252c30d4d97b8b37c4e8c34dc27ffe3..5be5dfe5fa928e7acbe18e340e0a3124242d2525 100644 (file)
@@ -477,7 +477,7 @@ init_defaults(void)
     def_passwd_timeout = PASSWORD_TIMEOUT;
     def_passwd_tries = TRIES_FOR_PASSWORD;
 #ifdef HAVE_ZLIB
-    def_compress_transcript = TRUE;
+    def_compress_io = TRUE;
 #endif
 
     /* Now do the strings */
index 05c1029cec4856b73117cec8932c3d554958b1bd..39e0bc606c3d384ec4269d909d71d93ff1af3439 100644 (file)
@@ -9,7 +9,7 @@
 #define yyerrok (yyerrflag=0)
 #define YYRECOVERING() (yyerrflag!=0)
 #define YYPREFIX "yy"
-#line 2 "./gram.y"
+#line 2 "gram.y"
 /*
  * Copyright (c) 1996, 1998-2005, 2007-2009
  *     Todd C. Miller <Todd.Miller@courtesan.com>
@@ -119,7 +119,7 @@ yyerror(s)
     }
     parse_error = TRUE;
 }
-#line 113 "./gram.y"
+#line 113 "gram.y"
 #ifndef YYSTYPE_DEFINED
 #define YYSTYPE_DEFINED
 typedef union {
@@ -154,17 +154,19 @@ typedef union {
 #define EXEC 272
 #define SETENV 273
 #define NOSETENV 274
-#define TRANSCRIPT 275
-#define NOTRANSCRIPT 276
-#define ALL 277
-#define COMMENT 278
-#define HOSTALIAS 279
-#define CMNDALIAS 280
-#define USERALIAS 281
-#define RUNASALIAS 282
-#define ERROR 283
-#define TYPE 284
-#define ROLE 285
+#define LOG_INPUT 275
+#define NOLOG_INPUT 276
+#define LOG_OUTPUT 277
+#define NOLOG_OUTPUT 278
+#define ALL 279
+#define COMMENT 280
+#define HOSTALIAS 281
+#define CMNDALIAS 282
+#define USERALIAS 283
+#define RUNASALIAS 284
+#define ERROR 285
+#define TYPE 286
+#define ROLE 287
 #define YYERRCODE 256
 #if defined(__cplusplus) || defined(__STDC__)
 const short yylhs[] =
@@ -177,11 +179,11 @@ short yylhs[] =
     3,    3,    3,   20,   20,   19,   10,   10,    8,    8,
     8,    8,    8,    2,    2,    1,    6,    6,   23,   24,
    22,   22,   22,   22,   22,   17,   17,   18,   18,   18,
-   21,   21,   21,   21,   21,   21,   21,   21,   21,    5,
-    5,    5,   28,   28,   31,    9,    9,   29,   29,   32,
-    7,    7,   30,   30,   33,   27,   27,   34,   13,   13,
-   11,   11,   12,   12,   12,   12,   12,   16,   16,   14,
-   14,   15,   15,   15,
+   21,   21,   21,   21,   21,   21,   21,   21,   21,   21,
+   21,    5,    5,    5,   28,   28,   31,    9,    9,   29,
+   29,   32,    7,    7,   30,   30,   33,   27,   27,   34,
+   13,   13,   11,   11,   12,   12,   12,   12,   12,   16,
+   16,   14,   14,   15,   15,   15,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yylen[] =
@@ -194,11 +196,11 @@ short yylen[] =
     3,    3,    3,    1,    3,    3,    1,    2,    1,    1,
     1,    1,    1,    1,    3,    4,    1,    2,    3,    3,
     0,    1,    1,    2,    2,    0,    3,    1,    3,    2,
-    0,    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,
+    0,    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,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yydefred[] =
@@ -206,21 +208,21 @@ const short yydefred[] =
 short yydefred[] =
 #endif
        {                                      0,
-    0,   83,   85,   86,   87,    0,    0,    0,    0,    0,
-   84,    5,    0,    0,    0,    0,    0,    0,   79,   81,
+    0,   85,   87,   88,   89,    0,    0,    0,    0,    0,
+   86,    5,    0,    0,    0,    0,    0,    0,   81,   83,
     0,    0,    3,    6,    0,    0,   17,    0,   29,   32,
-   31,   33,   30,    0,   27,    0,   66,    0,    0,   62,
-   61,   60,    0,   37,   71,    0,    0,    0,   63,    0,
-    0,   68,    0,    0,   76,    0,    0,   73,   82,    0,
+   31,   33,   30,    0,   27,    0,   68,    0,    0,   64,
+   63,   62,    0,   37,   73,    0,    0,    0,   65,    0,
+    0,   70,    0,    0,   78,    0,    0,   75,   84,    0,
     0,   24,    0,    4,    0,    0,    0,   20,    0,   28,
     0,    0,    0,    0,   38,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   80,    0,    0,   21,   22,
-   23,   18,   67,   72,    0,   64,    0,   69,    0,   77,
-    0,   74,    0,   34,    0,    0,   25,    0,    0,    0,
-    0,    0,    0,   51,    0,    0,   92,   94,   93,    0,
-   88,   90,    0,    0,   47,   35,    0,    0,    0,   44,
-   45,   91,    0,    0,   40,   39,   52,   53,   54,   55,
-   56,   57,   58,   59,   36,   89,
+    0,    0,    0,    0,    0,   82,    0,    0,   21,   22,
+   23,   18,   69,   74,    0,   66,    0,   71,    0,   79,
+    0,   76,    0,   34,    0,    0,   25,    0,    0,    0,
+    0,    0,    0,   51,    0,    0,   94,   96,   95,    0,
+   90,   92,    0,    0,   47,   35,    0,    0,    0,   44,
+   45,   93,    0,    0,   40,   39,   52,   53,   54,   55,
+   56,   57,   58,   59,   60,   61,   36,   91,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yydgoto[] =
@@ -238,238 +240,250 @@ const short yysindex[] =
 #else
 short yysindex[] =
 #endif
-       {                                    -26,
- -272,    0,    0,    0,    0,  -16,  481,  485,  485,  -31,
-    0,    0, -237, -232, -228, -227, -238,    0,    0,    0,
-  417,  -26,    0,    0,   -2, -217,    0,    7,    0,    0,
-    0,    0,    0, -223,    0,  -28,    0,  -25,  -25,    0,
-    0,    0, -248,    0,    0,  -11,  -14,   -6,    0,   -3,
-   -5,    0,   -1,    4,    0,    2,    6,    0,    0,  485,
-  -17,    0,    8,    0, -198, -196, -195,    0,  -16,    0,
-  481,    7,    7,    7,    0,  -31,    7,  481, -237,  -31,
- -232,  485, -228,  485, -227,    0,   29,  481,    0,    0,
-    0,    0,    0,    0,   26,    0,   30,    0,   31,    0,
-   31,    0,  457,    0,   32, -270,    0,  -30,   -8,   36,
-   29,   11,   12,    0, -206, -205,    0,    0,    0, -245,
-    0,    0,   35,  -30,    0,    0, -182, -180,  453,    0,
-    0,    0,  -30,   35,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,};
+       {                                    475,
+ -270,    0,    0,    0,    0,  -29,  567,  594,  594,   -2,
+    0,    0, -240, -222, -216, -212, -241,    0,    0,    0,
+  -25,  475,    0,    0,  -10, -207,    0,    9,    0,    0,
+    0,    0,    0, -235,    0,  -33,    0,  -31,  -31,    0,
+    0,    0, -242,    0,    0,  -30,   -7,    3,    0,   -6,
+    4,    0,   -5,    6,    0,   -1,    8,    0,    0,  594,
+  -20,    0,   10,    0, -205, -196, -194,    0,  -29,    0,
+  567,    9,    9,    9,    0,   -2,    9,  567, -240,   -2,
+ -222,  594, -216,  594, -212,    0,   31,  567,    0,    0,
+    0,    0,    0,    0,   26,    0,   28,    0,   29,    0,
+   29,    0,  541,    0,   32, -247,    0,   86,  -15,   33,
+   31,   14,   16,    0, -208, -204,    0,    0,    0, -231,
+    0,    0,   38,   86,    0,    0, -179, -178,  491,    0,
+    0,    0,   86,   38,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short yyrindex[] =
 #else
 short yyrindex[] =
 #endif
-       {                                     84,
+       {                                     87,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,   89,    0,    0,    1,    0,    0,  163,    0,    0,
+    0,   90,    0,    0,    1,    0,    0,  177,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,    0,  190,    0,    0,
-  217,    0,    0,  244,    0,    0,  271,    0,    0,    0,
-    0,    0,  298,    0,    0,    0,    0,    0,    0,    0,
-    0,  325,  352,  379,    0,    0,  406,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,  432,    0,    0,    0,
-    0,    0,    0,    0,   28,    0,   55,    0,   82,    0,
-  109,    0,    0,    0,  136,  480,    0,    0,   49,    0,
-  432,    0,    0,    0,  507,  534,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  207,    0,    0,
+  237,    0,    0,  271,    0,    0,  300,    0,    0,    0,
+    0,    0,  329,    0,    0,    0,    0,    0,    0,    0,
+    0,  358,  387,  417,    0,    0,  446,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  -26,    0,    0,    0,
+    0,    0,    0,    0,   30,    0,   59,    0,   89,    0,
+  118,    0,    0,    0,  148,  514,    0,    0,   45,    0,
+  -26,    0,    0,    0,  537,  565,    0,    0,    0,    0,
     0,    0,   50,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,   51,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,};
+    0,    0,    0,   52,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,};
 #if defined(__cplusplus) || defined(__STDC__)
 const short yygindex[] =
 #else
 short yygindex[] =
 #endif
        {                                      0,
-  -18,    0,   25,   10,   52,  -72,   16,   63,   -7,   27,
-   39,   83,    3,  -32,  -15,  -22,    0,    0,   15,    0,
-    0,    0,  -12,   -4,    0,   85,    0,    0,    0,    0,
-   33,   37,   23,   34,
+  -17,    0,   27,   11,   54,  -64,   15,   64,    2,   34,
+   39,   84,   -3,  -27,  -18,  -21,    0,    0,   19,    0,
+    0,    0,  -12,   -4,    0,   88,    0,    0,    0,    0,
+   35,   40,   23,   37,
 };
-#define YYTABLESIZE 811
+#define YYTABLESIZE 873
 #if defined(__cplusplus) || defined(__STDC__)
 const short yytable[] =
 #else
 short yytable[] =
 #endif
-       {                                      36,
-   19,   43,  120,   94,   26,   24,   17,   26,   40,   41,
-   38,   39,  117,  112,  113,   71,   26,  118,   60,    2,
-   47,   26,    3,    4,    5,   50,   71,   65,   42,   53,
-   56,  119,   76,   19,   29,   60,   30,   31,   11,   32,
-   66,   68,   67,   87,   19,   72,   78,   73,   74,  124,
-   69,   79,   81,   33,   70,   77,  145,   80,   65,   82,
-   65,   83,   84,   85,   89,   88,   90,   91,  103,   71,
-   95,  127,  128,   76,   60,  111,  125,  112,  133,  113,
-  135,   78,  136,    1,   99,   65,  101,   70,    2,   48,
-   50,   49,  126,   92,   75,   97,   70,   93,   86,   59,
-  146,  134,  107,  131,  132,  109,   64,  102,   75,    0,
-  130,   96,   70,    0,   78,    0,  100,   98,    0,    0,
+       {                                      26,
+   19,   26,   26,   26,   38,   39,   46,   34,   36,   24,
+   71,   94,   60,   76,   40,   41,    2,   47,   60,    3,
+    4,    5,   29,   71,   30,   31,  117,   32,   60,   67,
+   43,  118,   66,   19,   67,   50,   42,   11,  112,  113,
+   87,   53,  124,   33,   19,   56,   72,  119,   73,   74,
+   65,   68,   69,   78,   80,   82,   77,   89,   72,   84,
+   79,   81,   67,   83,  147,   85,   90,   88,   91,   71,
+  103,   76,   60,  125,  127,  111,  128,  112,   99,   95,
+  101,  133,  113,  135,  136,   48,    1,   67,   80,    2,
+   50,   72,   49,  126,   97,   92,   75,   70,   86,  109,
+   59,  132,  134,  131,   93,  148,  107,  102,    0,   64,
+  130,    0,    0,   96,    0,    0,   72,   77,  120,  100,
+   98,   80,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   26,    0,    0,    0,   78,
-    0,   75,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,   80,   26,    0,    0,
+   77,    0,    0,    0,    0,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   12,    0,    0,    0,   75,    0,   26,    0,
+    0,    0,    0,    0,    0,   77,   12,    0,    0,    0,
+   26,    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,    9,
-    0,    0,    0,   26,    0,   12,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   26,    9,    0,    0,   12,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,    0,   10,    0,    0,    0,
-    0,    0,    9,    0,    0,   40,   41,  117,    0,    1,
-   25,    2,  118,   25,    3,    4,    5,    6,    7,    8,
-    9,   10,   25,    8,    0,   42,  119,   25,    0,   10,
-   11,   12,   13,   14,   15,   16,   19,    0,   19,    0,
-    0,   19,   19,   19,   19,   19,   19,   19,   19,    0,
-   11,    0,    0,    0,    0,    0,    8,   19,   19,   19,
-   19,   19,   19,   65,    0,   65,    0,    0,   65,   65,
-   65,   65,   65,   65,   65,   65,    0,    7,    0,    0,
-    0,    0,    0,   11,   65,   65,   65,   65,   65,   65,
-   70,    0,   70,    0,    0,   70,   70,   70,   70,   70,
-   70,   70,   70,    0,   15,    0,    0,    0,    0,    0,
-    7,   70,   70,   70,   70,   70,   70,   78,    0,   78,
-    0,    0,   78,   78,   78,   78,   78,   78,   78,   78,
-    0,   13,    0,    0,    0,    0,    0,   15,   78,   78,
-   78,   78,   78,   78,   75,    0,   75,    0,    0,   75,
-   75,   75,   75,   75,   75,   75,   75,    0,   14,    0,
-    0,    0,    0,    0,   13,   75,   75,   75,   75,   75,
-   75,   26,    0,   26,    0,    0,   26,   26,   26,   26,
-   26,   26,   26,   26,    0,   16,    0,    0,    0,    0,
-    0,   14,   26,   26,   26,   26,   26,   26,   12,    0,
-   12,    0,    0,   12,   12,   12,   12,   12,   12,   12,
-   12,    0,    0,    0,    0,    0,    0,    0,   16,   12,
-   12,   12,   12,   12,   12,    9,    0,    9,    0,   34,
-    9,    9,    9,    9,    9,    9,    9,    9,    0,    0,
-   60,    0,    0,    0,   46,    0,    9,    9,    9,    9,
-    9,    9,   10,    0,   10,    0,    0,   10,   10,   10,
-   10,   10,   10,   10,   10,   43,    0,    0,    0,   17,
-    0,    0,    0,   10,   10,   10,   10,   10,   10,    8,
-    0,    8,    0,    0,    8,    8,    8,    8,    8,    8,
-    8,    8,   41,   34,  108,    0,    0,   17,    0,    0,
-    8,    8,    8,    8,    8,    8,   11,    0,   11,    0,
-    0,   11,   11,   11,   11,   11,   11,   11,   11,   42,
-    0,    0,    0,    0,    0,    0,    0,   11,   11,   11,
-   11,   11,   11,    7,    0,    7,    0,    0,    7,    7,
-    7,    7,    7,    7,    7,    7,   43,    0,    0,    0,
-    0,    0,    0,    0,    7,    7,    7,    7,    7,    7,
-   15,    0,   15,    0,    0,   15,   15,   15,   15,   15,
-   15,   15,   15,    0,    0,    0,    0,    0,    0,    0,
-    0,   15,   15,   15,   15,   15,   15,   13,    0,   13,
-    0,    0,   13,   13,   13,   13,   13,   13,   13,   13,
-    0,    0,    0,    0,    0,    0,    0,    0,   13,   13,
-   13,   13,   13,   13,   14,    0,   14,    0,    0,   14,
-   14,   14,   14,   14,   14,   14,   14,    0,    0,    0,
+    0,    0,    0,    0,    0,   25,    0,   25,   25,   25,
+   46,   46,   29,    0,   30,   31,   10,   32,    0,    9,
+    0,    0,   46,   46,   46,   46,   46,   46,   46,   46,
+   46,   46,   46,   33,   40,   41,   19,    0,   19,   46,
+   46,   19,   19,   19,   19,   19,   19,   19,   19,   10,
+    8,    0,    0,    0,    0,    0,   42,    0,    0,   19,
+   19,   19,   19,   19,   19,   67,    0,   67,    0,    0,
+   67,   67,   67,   67,   67,   67,   67,   67,    0,   11,
+    0,    0,    0,    8,    0,    0,    0,    0,   67,   67,
+   67,   67,   67,   67,   72,    0,   72,    0,    0,   72,
+   72,   72,   72,   72,   72,   72,   72,    0,    7,    0,
+    0,    0,   11,    0,    0,    0,    0,   72,   72,   72,
+   72,   72,   72,  117,   80,    0,   80,    0,  118,   80,
+   80,   80,   80,   80,   80,   80,   80,   15,    0,    0,
+    0,    7,    0,    0,  119,    0,    0,   80,   80,   80,
+   80,   80,   80,   77,    0,   77,    0,    0,   77,   77,
+   77,   77,   77,   77,   77,   77,   13,    0,    0,    0,
+   15,    0,    0,    0,    0,    0,   77,   77,   77,   77,
+   77,   77,    0,   26,    0,   26,    0,    0,   26,   26,
+   26,   26,   26,   26,   26,   26,   14,    0,    0,   13,
+    0,    0,    0,    0,    0,    0,   26,   26,   26,   26,
+   26,   26,   12,    0,   12,    0,    0,   12,   12,   12,
+   12,   12,   12,   12,   12,   16,    0,    0,    0,   14,
+    0,    0,    0,    0,    0,   12,   12,   12,   12,   12,
+   12,    0,    9,    0,    9,    0,    0,    9,    9,    9,
+    9,    9,    9,    9,    9,    0,    0,    0,   16,    0,
+    0,    0,    0,    0,    0,    9,    9,    9,    9,    9,
+    9,    0,   10,    0,   10,    0,    0,   10,   10,   10,
+   10,   10,   10,   10,   10,    0,    0,   17,    0,    0,
+    0,    0,    0,    0,    0,   10,   10,   10,   10,   10,
+   10,    0,    0,   43,    0,    0,    8,    0,    8,    0,
+    0,    8,    8,    8,    8,    8,    8,    8,    8,    0,
+    0,    0,    0,    0,    0,    0,   41,    0,    0,    8,
+    8,    8,    8,    8,    8,   11,    0,   11,    0,    0,
+   11,   11,   11,   11,   11,   11,   11,   11,    0,   42,
+    0,    0,    0,   17,    0,    0,    0,    0,   11,   11,
+   11,   11,   11,   11,    7,    0,    7,    0,    0,    7,
+    7,    7,    7,    7,    7,    7,    7,   43,  108,   34,
+    0,    0,    0,    0,    0,    0,    0,    7,    7,    7,
+    7,    7,    7,   15,    0,   15,    0,    0,   15,   15,
+   15,   15,   15,   15,   15,   15,   17,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,   15,   15,   15,   15,
+   15,   15,   13,    0,   13,    0,    0,   13,   13,   13,
+   13,   13,   13,   13,   13,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   13,   13,   13,   13,   13,
+   13,    0,   14,    0,   14,    0,    0,   14,   14,   14,
+   14,   14,   14,   14,   14,    0,    0,    0,    0,    0,
     0,    0,    0,    0,    0,   14,   14,   14,   14,   14,
    14,   16,    0,   16,    0,    0,   16,   16,   16,   16,
-   16,   16,   16,   16,   29,    0,   30,   31,    0,   32,
-    0,    0,   16,   16,   16,   16,   16,   16,   46,   46,
-    0,    0,    0,   33,    0,    0,    0,    0,    0,    0,
-   46,   46,   46,   46,   46,   46,   46,   46,   46,   40,
-   41,    0,    0,    0,    2,   46,   46,    3,    4,    5,
-    0,  137,  138,  139,  140,  141,  142,  143,  144,   42,
-    0,    0,    0,   11,    0,    0,   41,   41,   29,    0,
-   30,   31,    2,   32,    0,    3,    4,    5,   41,   41,
-   41,   41,   41,   41,   41,   41,   41,   33,    0,    0,
-    0,   11,    0,   42,   42,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    0,   42,   42,   42,   42,   42,
-   42,   42,   42,   42,    0,    0,    0,    0,    0,    0,
-   43,   43,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,   43,   43,   43,   43,   43,   43,   43,   43,
-   43,
+   16,   16,   16,   16,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,   16,   16,   16,   16,   16,   16,
+    1,    0,    2,    0,    0,    3,    4,    5,    6,    7,
+    8,    9,   10,    0,    0,    0,    0,   40,   41,    0,
+    0,    0,    0,   11,   12,   13,   14,   15,   16,  137,
+  138,  139,  140,  141,  142,  143,  144,  145,  146,   42,
+   41,   41,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   41,   41,   41,   41,   41,   41,   41,   41,
+   41,   41,   41,   42,   42,    0,    0,    0,    2,    0,
+    0,    3,    4,    5,    0,   42,   42,   42,   42,   42,
+   42,   42,   42,   42,   42,   42,    0,    0,    0,   11,
+    0,   43,   43,    0,   29,    0,   30,   31,    0,   32,
+    0,    0,    0,   43,   43,   43,   43,   43,   43,   43,
+   43,   43,   43,   43,    0,   33,    0,    0,    0,    0,
+    0,    2,    0,    0,    3,    4,    5,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,   11,
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const short yycheck[] =
 #else
 short yycheck[] =
 #endif
-       {                                       7,
-    0,   33,   33,   76,   33,  278,   33,   33,  257,  258,
-    8,    9,  258,  284,  285,   44,   33,  263,   44,  258,
-  258,   33,  261,  262,  263,  258,   44,    0,  277,  258,
-  258,  277,   44,   33,  258,   44,  260,  261,  277,  263,
-   43,  259,   45,   61,   44,   36,   61,   38,   39,   58,
-   44,   58,   58,  277,    0,   46,  129,   61,   61,   61,
-   33,   58,   61,   58,  263,   58,  263,  263,   40,   44,
-   78,   61,   61,   44,   44,   44,   41,  284,   44,  285,
-  263,    0,  263,    0,   82,   58,   84,   33,    0,   41,
-   41,   41,  111,   69,   43,   80,   34,   71,   60,   17,
-  133,  124,   88,  116,  120,  103,   22,   85,    0,   -1,
-  115,   79,   58,   -1,   33,   -1,   83,   81,   -1,   -1,
+       {                                      33,
+    0,   33,   33,   33,    8,    9,   33,   33,    7,  280,
+   44,   76,   44,   44,  257,  258,  258,  258,   44,  261,
+  262,  263,  258,   44,  260,  261,  258,  263,   44,    0,
+   33,  263,   43,   33,   45,  258,  279,  279,  286,  287,
+   61,  258,   58,  279,   44,  258,   36,  279,   38,   39,
+   61,  259,   44,   61,   61,   61,   46,  263,    0,   61,
+   58,   58,   33,   58,  129,   58,  263,   58,  263,   44,
+   40,   44,   44,   41,   61,   44,   61,  286,   82,   78,
+   84,   44,  287,  263,  263,   41,    0,   58,    0,    0,
+   41,   33,   41,  111,   80,   69,   43,   34,   60,  103,
+   17,  120,  124,  116,   71,  133,   88,   85,   -1,   22,
+  115,   -1,   -1,   79,   -1,   -1,   58,    0,   33,   83,
+   81,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   58,
-   -1,   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   58,    0,   -1,   -1,
+   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,    0,   -1,   -1,   -1,   58,   -1,   33,   -1,
+   -1,   -1,   -1,   -1,   -1,   58,    0,   -1,   -1,   -1,
+   33,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,    0,
-   -1,   -1,   -1,   58,   -1,   33,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   58,    0,   -1,   -1,   33,
    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,
-   -1,   -1,   33,   -1,   -1,  257,  258,  258,   -1,  256,
-  259,  258,  263,  259,  261,  262,  263,  264,  265,  266,
-  267,  268,  259,    0,   -1,  277,  277,  259,   -1,   33,
-  277,  278,  279,  280,  281,  282,  256,   -1,  258,   -1,
-   -1,  261,  262,  263,  264,  265,  266,  267,  268,   -1,
-    0,   -1,   -1,   -1,   -1,   -1,   33,  277,  278,  279,
-  280,  281,  282,  256,   -1,  258,   -1,   -1,  261,  262,
-  263,  264,  265,  266,  267,  268,   -1,    0,   -1,   -1,
-   -1,   -1,   -1,   33,  277,  278,  279,  280,  281,  282,
-  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,  265,
-  266,  267,  268,   -1,    0,   -1,   -1,   -1,   -1,   -1,
-   33,  277,  278,  279,  280,  281,  282,  256,   -1,  258,
-   -1,   -1,  261,  262,  263,  264,  265,  266,  267,  268,
-   -1,    0,   -1,   -1,   -1,   -1,   -1,   33,  277,  278,
-  279,  280,  281,  282,  256,   -1,  258,   -1,   -1,  261,
+   -1,   -1,   -1,   -1,   -1,  259,   -1,  259,  259,  259,
+  257,  258,  258,   -1,  260,  261,    0,  263,   -1,   33,
+   -1,   -1,  269,  270,  271,  272,  273,  274,  275,  276,
+  277,  278,  279,  279,  257,  258,  256,   -1,  258,  286,
+  287,  261,  262,  263,  264,  265,  266,  267,  268,   33,
+    0,   -1,   -1,   -1,   -1,   -1,  279,   -1,   -1,  279,
+  280,  281,  282,  283,  284,  256,   -1,  258,   -1,   -1,
+  261,  262,  263,  264,  265,  266,  267,  268,   -1,    0,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,  279,  280,
+  281,  282,  283,  284,  256,   -1,  258,   -1,   -1,  261,
   262,  263,  264,  265,  266,  267,  268,   -1,    0,   -1,
-   -1,   -1,   -1,   -1,   33,  277,  278,  279,  280,  281,
-  282,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
-  265,  266,  267,  268,   -1,    0,   -1,   -1,   -1,   -1,
-   -1,   33,  277,  278,  279,  280,  281,  282,  256,   -1,
-  258,   -1,   -1,  261,  262,  263,  264,  265,  266,  267,
-  268,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   33,  277,
-  278,  279,  280,  281,  282,  256,   -1,  258,   -1,   33,
-  261,  262,  263,  264,  265,  266,  267,  268,   -1,   -1,
-   44,   -1,   -1,   -1,   33,   -1,  277,  278,  279,  280,
-  281,  282,  256,   -1,  258,   -1,   -1,  261,  262,  263,
-  264,  265,  266,  267,  268,   33,   -1,   -1,   -1,   33,
-   -1,   -1,   -1,  277,  278,  279,  280,  281,  282,  256,
-   -1,  258,   -1,   -1,  261,  262,  263,  264,  265,  266,
-  267,  268,   33,   33,   58,   -1,   -1,   33,   -1,   -1,
-  277,  278,  279,  280,  281,  282,  256,   -1,  258,   -1,
-   -1,  261,  262,  263,  264,  265,  266,  267,  268,   33,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,  277,  278,  279,
-  280,  281,  282,  256,   -1,  258,   -1,   -1,  261,  262,
+   -1,   -1,   33,   -1,   -1,   -1,   -1,  279,  280,  281,
+  282,  283,  284,  258,  256,   -1,  258,   -1,  263,  261,
+  262,  263,  264,  265,  266,  267,  268,    0,   -1,   -1,
+   -1,   33,   -1,   -1,  279,   -1,   -1,  279,  280,  281,
+  282,  283,  284,  256,   -1,  258,   -1,   -1,  261,  262,
+  263,  264,  265,  266,  267,  268,    0,   -1,   -1,   -1,
+   33,   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,
+  283,  284,   -1,  256,   -1,  258,   -1,   -1,  261,  262,
+  263,  264,  265,  266,  267,  268,    0,   -1,   -1,   33,
+   -1,   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,
+  283,  284,  256,   -1,  258,   -1,   -1,  261,  262,  263,
+  264,  265,  266,  267,  268,    0,   -1,   -1,   -1,   33,
+   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,  283,
+  284,   -1,  256,   -1,  258,   -1,   -1,  261,  262,  263,
+  264,  265,  266,  267,  268,   -1,   -1,   -1,   33,   -1,
+   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,  283,
+  284,   -1,  256,   -1,  258,   -1,   -1,  261,  262,  263,
+  264,  265,  266,  267,  268,   -1,   -1,   33,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,  283,
+  284,   -1,   -1,   33,   -1,   -1,  256,   -1,  258,   -1,
+   -1,  261,  262,  263,  264,  265,  266,  267,  268,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   33,   -1,   -1,  279,
+  280,  281,  282,  283,  284,  256,   -1,  258,   -1,   -1,
+  261,  262,  263,  264,  265,  266,  267,  268,   -1,   33,
+   -1,   -1,   -1,   33,   -1,   -1,   -1,   -1,  279,  280,
+  281,  282,  283,  284,  256,   -1,  258,   -1,   -1,  261,
+  262,  263,  264,  265,  266,  267,  268,   33,   58,   33,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  279,  280,  281,
+  282,  283,  284,  256,   -1,  258,   -1,   -1,  261,  262,
   263,  264,  265,  266,  267,  268,   33,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,  277,  278,  279,  280,  281,  282,
+   -1,   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,
+  283,  284,  256,   -1,  258,   -1,   -1,  261,  262,  263,
+  264,  265,  266,  267,  268,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,  283,
+  284,   -1,  256,   -1,  258,   -1,   -1,  261,  262,  263,
+  264,  265,  266,  267,  268,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  279,  280,  281,  282,  283,
+  284,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
+  265,  266,  267,  268,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  279,  280,  281,  282,  283,  284,
   256,   -1,  258,   -1,   -1,  261,  262,  263,  264,  265,
-  266,  267,  268,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
-   -1,  277,  278,  279,  280,  281,  282,  256,   -1,  258,
-   -1,   -1,  261,  262,  263,  264,  265,  266,  267,  268,
-   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  277,  278,
-  279,  280,  281,  282,  256,   -1,  258,   -1,   -1,  261,
-  262,  263,  264,  265,  266,  267,  268,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  277,  278,  279,  280,  281,
-  282,  256,   -1,  258,   -1,   -1,  261,  262,  263,  264,
-  265,  266,  267,  268,  258,   -1,  260,  261,   -1,  263,
-   -1,   -1,  277,  278,  279,  280,  281,  282,  257,  258,
-   -1,   -1,   -1,  277,   -1,   -1,   -1,   -1,   -1,   -1,
-  269,  270,  271,  272,  273,  274,  275,  276,  277,  257,
-  258,   -1,   -1,   -1,  258,  284,  285,  261,  262,  263,
-   -1,  269,  270,  271,  272,  273,  274,  275,  276,  277,
-   -1,   -1,   -1,  277,   -1,   -1,  257,  258,  258,   -1,
-  260,  261,  258,  263,   -1,  261,  262,  263,  269,  270,
-  271,  272,  273,  274,  275,  276,  277,  277,   -1,   -1,
-   -1,  277,   -1,  257,  258,   -1,   -1,   -1,   -1,   -1,
-   -1,   -1,   -1,   -1,   -1,  269,  270,  271,  272,  273,
-  274,  275,  276,  277,   -1,   -1,   -1,   -1,   -1,   -1,
+  266,  267,  268,   -1,   -1,   -1,   -1,  257,  258,   -1,
+   -1,   -1,   -1,  279,  280,  281,  282,  283,  284,  269,
+  270,  271,  272,  273,  274,  275,  276,  277,  278,  279,
   257,  258,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
    -1,   -1,  269,  270,  271,  272,  273,  274,  275,  276,
-  277,
+  277,  278,  279,  257,  258,   -1,   -1,   -1,  258,   -1,
+   -1,  261,  262,  263,   -1,  269,  270,  271,  272,  273,
+  274,  275,  276,  277,  278,  279,   -1,   -1,   -1,  279,
+   -1,  257,  258,   -1,  258,   -1,  260,  261,   -1,  263,
+   -1,   -1,   -1,  269,  270,  271,  272,  273,  274,  275,
+  276,  277,  278,  279,   -1,  279,   -1,   -1,   -1,   -1,
+   -1,  258,   -1,   -1,  261,  262,  263,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  279,
 };
 #define YYFINAL 18
 #ifndef YYDEBUG
 #define YYDEBUG 0
 #endif
-#define YYMAXTOKEN 285
+#define YYMAXTOKEN 287
 #if YYDEBUG
 #if defined(__cplusplus) || defined(__STDC__)
 const char * const yyname[] =
@@ -486,9 +500,9 @@ 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,0,0,
 "COMMAND","ALIAS","DEFVAR","NTWKADDR","NETGROUP","USERGROUP","WORD","DEFAULTS",
 "DEFAULTS_HOST","DEFAULTS_USER","DEFAULTS_RUNAS","DEFAULTS_CMND","NOPASSWD",
-"PASSWD","NOEXEC","EXEC","SETENV","NOSETENV","TRANSCRIPT","NOTRANSCRIPT","ALL",
-"COMMENT","HOSTALIAS","CMNDALIAS","USERALIAS","RUNASALIAS","ERROR","TYPE",
-"ROLE",
+"PASSWD","NOEXEC","EXEC","SETENV","NOSETENV","LOG_INPUT","NOLOG_INPUT",
+"LOG_OUTPUT","NOLOG_OUTPUT","ALL","COMMENT","HOSTALIAS","CMNDALIAS","USERALIAS",
+"RUNASALIAS","ERROR","TYPE","ROLE",
 };
 #if defined(__cplusplus) || defined(__STDC__)
 const char * const yyrule[] =
@@ -553,8 +567,10 @@ char *yyrule[] =
 "cmndtag : cmndtag EXEC",
 "cmndtag : cmndtag SETENV",
 "cmndtag : cmndtag NOSETENV",
-"cmndtag : cmndtag TRANSCRIPT",
-"cmndtag : cmndtag NOTRANSCRIPT",
+"cmndtag : cmndtag LOG_INPUT",
+"cmndtag : cmndtag NOLOG_INPUT",
+"cmndtag : cmndtag LOG_OUTPUT",
+"cmndtag : cmndtag NOLOG_OUTPUT",
 "cmnd : ALL",
 "cmnd : ALIAS",
 "cmnd : COMMAND",
@@ -617,7 +633,7 @@ short *yyss;
 short *yysslim;
 YYSTYPE *yyvs;
 int yystacksize;
-#line 596 "./gram.y"
+#line 607 "gram.y"
 static struct defaults *
 new_default(var, val, op)
     char *var;
@@ -808,7 +824,7 @@ init_parser(path, quiet)
     sudolineno = 1;
     verbose = !quiet;
 }
-#line 760 "y.tab.c"
+#line 776 "y.tab.c"
 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
 #if defined(__cplusplus) || defined(__STDC__)
 static int yygrowstack(void)
@@ -1014,127 +1030,127 @@ yyreduce:
     switch (yyn)
     {
 case 1:
-#line 186 "./gram.y"
+#line 188 "gram.y"
 { ; }
 break;
 case 5:
-#line 194 "./gram.y"
+#line 196 "gram.y"
 {
                            ;
                        }
 break;
 case 6:
-#line 197 "./gram.y"
+#line 199 "gram.y"
 {
                            yyerrok;
                        }
 break;
 case 7:
-#line 200 "./gram.y"
+#line 202 "gram.y"
 {
                            add_userspec(yyvsp[-1].member, yyvsp[0].privilege);
                        }
 break;
 case 8:
-#line 203 "./gram.y"
+#line 205 "gram.y"
 {
                            ;
                        }
 break;
 case 9:
-#line 206 "./gram.y"
+#line 208 "gram.y"
 {
                            ;
                        }
 break;
 case 10:
-#line 209 "./gram.y"
+#line 211 "gram.y"
 {
                            ;
                        }
 break;
 case 11:
-#line 212 "./gram.y"
+#line 214 "gram.y"
 {
                            ;
                        }
 break;
 case 12:
-#line 215 "./gram.y"
+#line 217 "gram.y"
 {
                            add_defaults(DEFAULTS, NULL, yyvsp[0].defaults);
                        }
 break;
 case 13:
-#line 218 "./gram.y"
+#line 220 "gram.y"
 {
                            add_defaults(DEFAULTS_USER, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 14:
-#line 221 "./gram.y"
+#line 223 "gram.y"
 {
                            add_defaults(DEFAULTS_RUNAS, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 15:
-#line 224 "./gram.y"
+#line 226 "gram.y"
 {
                            add_defaults(DEFAULTS_HOST, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 16:
-#line 227 "./gram.y"
+#line 229 "gram.y"
 {
                            add_defaults(DEFAULTS_CMND, yyvsp[-1].member, yyvsp[0].defaults);
                        }
 break;
 case 18:
-#line 233 "./gram.y"
+#line 235 "gram.y"
 {
                            list_append(yyvsp[-2].defaults, yyvsp[0].defaults);
                            yyval.defaults = yyvsp[-2].defaults;
                        }
 break;
 case 19:
-#line 239 "./gram.y"
+#line 241 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[0].string, NULL, TRUE);
                        }
 break;
 case 20:
-#line 242 "./gram.y"
+#line 244 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[0].string, NULL, FALSE);
                        }
 break;
 case 21:
-#line 245 "./gram.y"
+#line 247 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, TRUE);
                        }
 break;
 case 22:
-#line 248 "./gram.y"
+#line 250 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '+');
                        }
 break;
 case 23:
-#line 251 "./gram.y"
+#line 253 "gram.y"
 {
                            yyval.defaults = new_default(yyvsp[-2].string, yyvsp[0].string, '-');
                        }
 break;
 case 25:
-#line 257 "./gram.y"
+#line 259 "gram.y"
 {
                            list_append(yyvsp[-2].privilege, yyvsp[0].privilege);
                            yyval.privilege = yyvsp[-2].privilege;
                        }
 break;
 case 26:
-#line 263 "./gram.y"
+#line 265 "gram.y"
 {
                            struct privilege *p = emalloc(sizeof(*p));
                            list2tq(&p->hostlist, yyvsp[-2].member);
@@ -1145,51 +1161,51 @@ case 26:
                        }
 break;
 case 27:
-#line 273 "./gram.y"
+#line 275 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = FALSE;
                        }
 break;
 case 28:
-#line 277 "./gram.y"
+#line 279 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = TRUE;
                        }
 break;
 case 29:
-#line 283 "./gram.y"
+#line 285 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
 case 30:
-#line 286 "./gram.y"
+#line 288 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
 case 31:
-#line 289 "./gram.y"
+#line 291 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, NETGROUP);
                        }
 break;
 case 32:
-#line 292 "./gram.y"
+#line 294 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, NTWKADDR);
                        }
 break;
 case 33:
-#line 295 "./gram.y"
+#line 297 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
 case 35:
-#line 301 "./gram.y"
+#line 303 "gram.y"
 {
                            list_append(yyvsp[-2].cmndspec, yyvsp[0].cmndspec);
 #ifdef HAVE_SELINUX
@@ -1207,8 +1223,10 @@ case 35:
                            if (yyvsp[0].cmndspec->tags.setenv == UNSPEC &&
                                yyvsp[0].cmndspec->prev->tags.setenv != IMPLIED)
                                yyvsp[0].cmndspec->tags.setenv = yyvsp[0].cmndspec->prev->tags.setenv;
-                           if (yyvsp[0].cmndspec->tags.transcript == UNSPEC)
-                               yyvsp[0].cmndspec->tags.transcript = yyvsp[0].cmndspec->prev->tags.transcript;
+                           if (yyvsp[0].cmndspec->tags.log_input == UNSPEC)
+                               yyvsp[0].cmndspec->tags.log_input = yyvsp[0].cmndspec->prev->tags.log_input;
+                           if (yyvsp[0].cmndspec->tags.log_output == UNSPEC)
+                               yyvsp[0].cmndspec->tags.log_output = yyvsp[0].cmndspec->prev->tags.log_output;
                            if ((tq_empty(&yyvsp[0].cmndspec->runasuserlist) &&
                                 tq_empty(&yyvsp[0].cmndspec->runasgrouplist)) &&
                                (!tq_empty(&yyvsp[0].cmndspec->prev->runasuserlist) ||
@@ -1220,7 +1238,7 @@ case 35:
                        }
 break;
 case 36:
-#line 331 "./gram.y"
+#line 335 "gram.y"
 {
                            struct cmndspec *cs = emalloc(sizeof(*cs));
                            if (yyvsp[-3].runas != NULL) {
@@ -1247,80 +1265,80 @@ case 36:
                        }
 break;
 case 37:
-#line 357 "./gram.y"
+#line 361 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = FALSE;
                        }
 break;
 case 38:
-#line 361 "./gram.y"
+#line 365 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = TRUE;
                        }
 break;
 case 39:
-#line 367 "./gram.y"
+#line 371 "gram.y"
 {
                            yyval.string = yyvsp[0].string;
                        }
 break;
 case 40:
-#line 372 "./gram.y"
+#line 376 "gram.y"
 {
                            yyval.string = yyvsp[0].string;
                        }
 break;
 case 41:
-#line 377 "./gram.y"
+#line 381 "gram.y"
 {
                            yyval.seinfo.role = NULL;
                            yyval.seinfo.type = NULL;
                        }
 break;
 case 42:
-#line 381 "./gram.y"
+#line 385 "gram.y"
 {
                            yyval.seinfo.role = yyvsp[0].string;
                            yyval.seinfo.type = NULL;
                        }
 break;
 case 43:
-#line 385 "./gram.y"
+#line 389 "gram.y"
 {
                            yyval.seinfo.type = yyvsp[0].string;
                            yyval.seinfo.role = NULL;
                        }
 break;
 case 44:
-#line 389 "./gram.y"
+#line 393 "gram.y"
 {
                            yyval.seinfo.role = yyvsp[-1].string;
                            yyval.seinfo.type = yyvsp[0].string;
                        }
 break;
 case 45:
-#line 393 "./gram.y"
+#line 397 "gram.y"
 {
                            yyval.seinfo.type = yyvsp[-1].string;
                            yyval.seinfo.role = yyvsp[0].string;
                        }
 break;
 case 46:
-#line 399 "./gram.y"
+#line 403 "gram.y"
 {
                            yyval.runas = NULL;
                        }
 break;
 case 47:
-#line 402 "./gram.y"
+#line 406 "gram.y"
 {
                            yyval.runas = yyvsp[-1].runas;
                        }
 break;
 case 48:
-#line 407 "./gram.y"
+#line 411 "gram.y"
 {
                            yyval.runas = emalloc(sizeof(struct runascontainer));
                            yyval.runas->runasusers = yyvsp[0].member;
@@ -1328,7 +1346,7 @@ case 48:
                        }
 break;
 case 49:
-#line 412 "./gram.y"
+#line 416 "gram.y"
 {
                            yyval.runas = emalloc(sizeof(struct runascontainer));
                            yyval.runas->runasusers = yyvsp[-2].member;
@@ -1336,7 +1354,7 @@ case 49:
                        }
 break;
 case 50:
-#line 417 "./gram.y"
+#line 421 "gram.y"
 {
                            yyval.runas = emalloc(sizeof(struct runascontainer));
                            yyval.runas->runasusers = NULL;
@@ -1344,73 +1362,86 @@ case 50:
                        }
 break;
 case 51:
-#line 424 "./gram.y"
+#line 428 "gram.y"
 {
-                           yyval.tag.nopasswd = yyval.tag.noexec = yyval.tag.setenv = yyval.tag.transcript = UNSPEC;
+                           yyval.tag.nopasswd = yyval.tag.noexec = yyval.tag.setenv =
+                               yyval.tag.log_input = yyval.tag.log_output = UNSPEC;
                        }
 break;
 case 52:
-#line 427 "./gram.y"
+#line 432 "gram.y"
 {
                            yyval.tag.nopasswd = TRUE;
                        }
 break;
 case 53:
-#line 430 "./gram.y"
+#line 435 "gram.y"
 {
                            yyval.tag.nopasswd = FALSE;
                        }
 break;
 case 54:
-#line 433 "./gram.y"
+#line 438 "gram.y"
 {
                            yyval.tag.noexec = TRUE;
                        }
 break;
 case 55:
-#line 436 "./gram.y"
+#line 441 "gram.y"
 {
                            yyval.tag.noexec = FALSE;
                        }
 break;
 case 56:
-#line 439 "./gram.y"
+#line 444 "gram.y"
 {
                            yyval.tag.setenv = TRUE;
                        }
 break;
 case 57:
-#line 442 "./gram.y"
+#line 447 "gram.y"
 {
                            yyval.tag.setenv = FALSE;
                        }
 break;
 case 58:
-#line 445 "./gram.y"
+#line 450 "gram.y"
 {
-                           yyval.tag.transcript = TRUE;
+                           yyval.tag.log_input = TRUE;
                        }
 break;
 case 59:
-#line 448 "./gram.y"
+#line 453 "gram.y"
 {
-                           yyval.tag.transcript = FALSE;
+                           yyval.tag.log_input = FALSE;
                        }
 break;
 case 60:
-#line 453 "./gram.y"
+#line 456 "gram.y"
 {
-                           yyval.member = new_member(NULL, ALL);
+                           yyval.tag.log_output = TRUE;
                        }
 break;
 case 61:
-#line 456 "./gram.y"
+#line 459 "gram.y"
 {
-                           yyval.member = new_member(yyvsp[0].string, ALIAS);
+                           yyval.tag.log_output = FALSE;
                        }
 break;
 case 62:
-#line 459 "./gram.y"
+#line 464 "gram.y"
+{
+                           yyval.member = new_member(NULL, ALL);
+                       }
+break;
+case 63:
+#line 467 "gram.y"
+{
+                           yyval.member = new_member(yyvsp[0].string, ALIAS);
+                       }
+break;
+case 64:
+#line 470 "gram.y"
 {
                            struct sudo_command *c = emalloc(sizeof(*c));
                            c->cmnd = yyvsp[0].command.cmnd;
@@ -1418,8 +1449,8 @@ case 62:
                            yyval.member = new_member((char *)c, COMMAND);
                        }
 break;
-case 65:
-#line 471 "./gram.y"
+case 67:
+#line 482 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, HOSTALIAS, yyvsp[0].member)) != NULL) {
@@ -1428,15 +1459,15 @@ case 65:
                            }
                        }
 break;
-case 67:
-#line 481 "./gram.y"
+case 69:
+#line 492 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
-case 70:
-#line 491 "./gram.y"
+case 72:
+#line 502 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, CMNDALIAS, yyvsp[0].member)) != NULL) {
@@ -1445,15 +1476,15 @@ case 70:
                            }
                        }
 break;
-case 72:
-#line 501 "./gram.y"
+case 74:
+#line 512 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
-case 75:
-#line 511 "./gram.y"
+case 77:
+#line 522 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, RUNASALIAS, yyvsp[0].member)) != NULL) {
@@ -1462,8 +1493,8 @@ case 75:
                            }
                        }
 break;
-case 78:
-#line 524 "./gram.y"
+case 80:
+#line 535 "gram.y"
 {
                            char *s;
                            if ((s = alias_add(yyvsp[-2].string, USERALIAS, yyvsp[0].member)) != NULL) {
@@ -1472,97 +1503,97 @@ case 78:
                            }
                        }
 break;
-case 80:
-#line 534 "./gram.y"
+case 82:
+#line 545 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
-case 81:
-#line 540 "./gram.y"
+case 83:
+#line 551 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = FALSE;
                        }
 break;
-case 82:
-#line 544 "./gram.y"
+case 84:
+#line 555 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = TRUE;
                        }
 break;
-case 83:
-#line 550 "./gram.y"
+case 85:
+#line 561 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
-case 84:
-#line 553 "./gram.y"
+case 86:
+#line 564 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
-case 85:
-#line 556 "./gram.y"
+case 87:
+#line 567 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, NETGROUP);
                        }
 break;
-case 86:
-#line 559 "./gram.y"
+case 88:
+#line 570 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, USERGROUP);
                        }
 break;
-case 87:
-#line 562 "./gram.y"
+case 89:
+#line 573 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
-case 89:
-#line 568 "./gram.y"
+case 91:
+#line 579 "gram.y"
 {
                            list_append(yyvsp[-2].member, yyvsp[0].member);
                            yyval.member = yyvsp[-2].member;
                        }
 break;
-case 90:
-#line 574 "./gram.y"
+case 92:
+#line 585 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = FALSE;
                        }
 break;
-case 91:
-#line 578 "./gram.y"
+case 93:
+#line 589 "gram.y"
 {
                            yyval.member = yyvsp[0].member;
                            yyval.member->negated = TRUE;
                        }
 break;
-case 92:
-#line 584 "./gram.y"
+case 94:
+#line 595 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, ALIAS);
                        }
 break;
-case 93:
-#line 587 "./gram.y"
+case 95:
+#line 598 "gram.y"
 {
                            yyval.member = new_member(NULL, ALL);
                        }
 break;
-case 94:
-#line 590 "./gram.y"
+case 96:
+#line 601 "gram.y"
 {
                            yyval.member = new_member(yyvsp[0].string, WORD);
                        }
 break;
-#line 1514 "y.tab.c"
+#line 1545 "y.tab.c"
     }
     yyssp -= yym;
     yystate = *yyssp;
index 1d1c6d590064c4597f844390ecb92f67ec93f748..2bec420543b137625617894d715d6127e9cbc906 100644 (file)
 #define EXEC 272
 #define SETENV 273
 #define NOSETENV 274
-#define TRANSCRIPT 275
-#define NOTRANSCRIPT 276
-#define ALL 277
-#define COMMENT 278
-#define HOSTALIAS 279
-#define CMNDALIAS 280
-#define USERALIAS 281
-#define RUNASALIAS 282
-#define ERROR 283
-#define TYPE 284
-#define ROLE 285
+#define LOG_INPUT 275
+#define NOLOG_INPUT 276
+#define LOG_OUTPUT 277
+#define NOLOG_OUTPUT 278
+#define ALL 279
+#define COMMENT 280
+#define HOSTALIAS 281
+#define CMNDALIAS 282
+#define USERALIAS 283
+#define RUNASALIAS 284
+#define ERROR 285
+#define TYPE 286
+#define ROLE 287
 #ifndef YYSTYPE_DEFINED
 #define YYSTYPE_DEFINED
 typedef union {
index 5682f90e35dd3537a83fc11cecd37251a5fc033e..0e55a71133faad94c565c5cff4a2d141826c42ce 100644 (file)
@@ -142,8 +142,10 @@ yyerror(s)
 %token <tok>    EXEC                   /* don't preload dummy execve() */
 %token <tok>    SETENV                 /* user may set environment for cmnd */
 %token <tok>    NOSETENV               /* user may not set environment */
-%token <tok>    TRANSCRIPT             /* log a transcript of the cmnd */
-%token <tok>    NOTRANSCRIPT           /* don't log a transcript of the cmnd */
+%token <tok>    LOG_INPUT              /* log user's cmnd input */
+%token <tok>    NOLOG_INPUT            /* don't log user's cmnd input */
+%token <tok>    LOG_OUTPUT             /* log cmnd output */
+%token <tok>    NOLOG_OUTPUT           /* don't log cmnd output */
 %token <tok>    ALL                    /* ALL keyword */
 %token <tok>    COMMENT                /* comment and/or carriage return */
 %token <tok>    HOSTALIAS              /* Host_Alias keyword */
@@ -315,8 +317,10 @@ cmndspeclist       :       cmndspec
                            if ($3->tags.setenv == UNSPEC &&
                                $3->prev->tags.setenv != IMPLIED)
                                $3->tags.setenv = $3->prev->tags.setenv;
-                           if ($3->tags.transcript == UNSPEC)
-                               $3->tags.transcript = $3->prev->tags.transcript;
+                           if ($3->tags.log_input == UNSPEC)
+                               $3->tags.log_input = $3->prev->tags.log_input;
+                           if ($3->tags.log_output == UNSPEC)
+                               $3->tags.log_output = $3->prev->tags.log_output;
                            if ((tq_empty(&$3->runasuserlist) &&
                                 tq_empty(&$3->runasgrouplist)) &&
                                (!tq_empty(&$3->prev->runasuserlist) ||
@@ -422,7 +426,8 @@ runaslist   :       userlist {
                ;
 
 cmndtag                :       /* empty */ {
-                           $$.nopasswd = $$.noexec = $$.setenv = $$.transcript = UNSPEC;
+                           $$.nopasswd = $$.noexec = $$.setenv =
+                               $$.log_input = $$.log_output = UNSPEC;
                        }
                |       cmndtag NOPASSWD {
                            $$.nopasswd = TRUE;
@@ -442,11 +447,17 @@ cmndtag           :       /* empty */ {
                |       cmndtag NOSETENV {
                            $$.setenv = FALSE;
                        }
-               |       cmndtag TRANSCRIPT {
-                           $$.transcript = TRUE;
+               |       cmndtag LOG_INPUT {
+                           $$.log_input = TRUE;
                        }
-               |       cmndtag NOTRANSCRIPT {
-                           $$.transcript = FALSE;
+               |       cmndtag NOLOG_INPUT {
+                           $$.log_input = FALSE;
+                       }
+               |       cmndtag LOG_OUTPUT {
+                           $$.log_output = TRUE;
+                       }
+               |       cmndtag NOLOG_OUTPUT {
+                           $$.log_output = FALSE;
                        }
                ;
 
index cf29692b9b86f7f6fbec10a216a7dcbe3d61b14e..54eb3cd749b85b47f4d7fb97107f23e472f28200 100644 (file)
@@ -91,20 +91,20 @@ io_nextid(void)
     char pathbuf[PATH_MAX];
 
     /*
-     * Create _PATH_SUDO_TRANSCRIPT if it doesn't already exist.
+     * Create _PATH_SUDO_IO_LOGDIR if it doesn't already exist.
      */
-    if (stat(_PATH_SUDO_TRANSCRIPT, &sb) != 0) {
-       if (mkdir(_PATH_SUDO_TRANSCRIPT, S_IRWXU) != 0)
-           log_error(USE_ERRNO, "Can't mkdir %s", _PATH_SUDO_TRANSCRIPT);
+    if (stat(_PATH_SUDO_IO_LOGDIR, &sb) != 0) {
+       if (mkdir(_PATH_SUDO_IO_LOGDIR, S_IRWXU) != 0)
+           log_error(USE_ERRNO, "Can't mkdir %s", _PATH_SUDO_IO_LOGDIR);
     } else if (!S_ISDIR(sb.st_mode)) {
        log_error(0, "%s exists but is not a directory (0%o)",
-           _PATH_SUDO_TRANSCRIPT, (unsigned int) sb.st_mode);
+           _PATH_SUDO_IO_LOGDIR, (unsigned int) sb.st_mode);
     }
 
     /*
      * Open sequence file
      */
-    len = snprintf(pathbuf, sizeof(pathbuf), "%s/seq", _PATH_SUDO_TRANSCRIPT);
+    len = snprintf(pathbuf, sizeof(pathbuf), "%s/seq", _PATH_SUDO_IO_LOGDIR);
     if (len <= 0 || len >= sizeof(pathbuf)) {
        errno = ENAMETOOLONG;
        log_error(USE_ERRNO, "%s/seq", pathbuf);
@@ -158,12 +158,12 @@ build_idpath(char *pathbuf, size_t pathsize)
     /*
      * Path is of the form /var/log/sudo-session/00/00/01.
      */
-    len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", _PATH_SUDO_TRANSCRIPT,
+    len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", _PATH_SUDO_IO_LOGDIR,
        sudo_user.sessid[0], sudo_user.sessid[1], sudo_user.sessid[2],
        sudo_user.sessid[3], sudo_user.sessid[4], sudo_user.sessid[5]);
     if (len <= 0 && len >= pathsize) {
        errno = ENAMETOOLONG;
-       log_error(USE_ERRNO, "%s/%s", _PATH_SUDO_TRANSCRIPT, sudo_user.sessid);
+       log_error(USE_ERRNO, "%s/%s", _PATH_SUDO_IO_LOGDIR, sudo_user.sessid);
     }
 
     /*
@@ -223,7 +223,7 @@ static sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     if (argc == 0)
        return TRUE;
 
-    if (!def_transcript)
+    if (!def_log_input && !def_log_output)
        return FALSE;
 
     /*
@@ -244,27 +244,27 @@ static sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     if (io_logfile == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    io_fds[IOFD_TIMING].v = open_io_fd(pathbuf, len, "/timing", def_compress_transcript);
+    io_fds[IOFD_TIMING].v = open_io_fd(pathbuf, len, "/timing", def_compress_io);
     if (io_fds[IOFD_TIMING].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    io_fds[IOFD_TTYIN].v = open_io_fd(pathbuf, len, "/ttyin", def_compress_transcript);
+    io_fds[IOFD_TTYIN].v = open_io_fd(pathbuf, len, "/ttyin", def_compress_io);
     if (io_fds[IOFD_TTYIN].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    io_fds[IOFD_TTYOUT].v = open_io_fd(pathbuf, len, "/ttyout", def_compress_transcript);
+    io_fds[IOFD_TTYOUT].v = open_io_fd(pathbuf, len, "/ttyout", def_compress_io);
     if (io_fds[IOFD_TTYOUT].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    io_fds[IOFD_STDIN].v = open_io_fd(pathbuf, len, "/stdin", def_compress_transcript);
+    io_fds[IOFD_STDIN].v = open_io_fd(pathbuf, len, "/stdin", def_compress_io);
     if (io_fds[IOFD_STDIN].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    io_fds[IOFD_STDOUT].v = open_io_fd(pathbuf, len, "/stdout", def_compress_transcript);
+    io_fds[IOFD_STDOUT].v = open_io_fd(pathbuf, len, "/stdout", def_compress_io);
     if (io_fds[IOFD_STDOUT].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    io_fds[IOFD_STDERR].v = open_io_fd(pathbuf, len, "/stderr", def_compress_transcript);
+    io_fds[IOFD_STDERR].v = open_io_fd(pathbuf, len, "/stderr", def_compress_io);
     if (io_fds[IOFD_STDERR].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
@@ -297,7 +297,7 @@ static sudoers_io_close(int exit_status, int error)
 
     for (i = 0; i < IOFD_MAX; i++) {
 #ifdef HAVE_ZLIB
-       if (def_compress_transcript)
+       if (def_compress_io)
            gzclose(io_fds[i].g);
        else
 #endif
@@ -336,14 +336,14 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
     sigprocmask(SIG_BLOCK, &ttyblock, &omask);
 
 #ifdef HAVE_ZLIB
-    if (def_compress_transcript)
+    if (def_compress_io)
        gzwrite(io_fds[idx].g, buf, len);
     else
 #endif
        fwrite(buf, 1, len, io_fds[idx].f);
     timersub(&now, &last_time, &tv);
 #ifdef HAVE_ZLIB
-    if (def_compress_transcript)
+    if (def_compress_io)
        gzprintf(io_fds[IOFD_TIMING].g, "%d %f %d\n", idx,
            tv.tv_sec + ((double)tv.tv_usec / 1000000), len);
     else
index b2905c7caabe36c808c73c604582ee88bb2095b6..c8eca8c2116eea96259ad153dfed80ad02794c36 100644 (file)
@@ -243,8 +243,10 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
                def_noexec = tags->noexec;
            if (tags->setenv != UNSPEC)
                def_setenv = tags->setenv;
-           if (tags->transcript != UNSPEC)
-               def_transcript = tags->transcript;
+           if (tags->log_input != UNSPEC)
+               def_log_input = tags->log_input;
+           if (tags->log_output != UNSPEC)
+               def_log_output = tags->log_output;
        }
     } else if (match == DENY) {
        SET(validated, VALIDATE_NOT_OK);
@@ -284,10 +286,15 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
            "PASSWD: ", NULL);
        tags->nopasswd = cs->tags.nopasswd;
     }
-    if (TAG_CHANGED(transcript)) {
-       lbuf_append(lbuf, cs->tags.transcript ? "SCRIPT: " :
-           "NOSCRIPT: ", NULL);
-       tags->transcript = cs->tags.transcript;
+    if (TAG_CHANGED(log_input)) {
+       lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " :
+           "NOLOG_INPUT: ", NULL);
+       tags->log_input = cs->tags.log_input;
+    }
+    if (TAG_CHANGED(log_output)) {
+       lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " :
+           "NOLOG_OUTPUT: ", NULL);
+       tags->log_output = cs->tags.log_output;
     }
     m = cs->cmnd;
     print_member(lbuf, m->name, m->type, m->negated,
@@ -310,7 +317,8 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
        tags.noexec = UNSPEC;
        tags.setenv = UNSPEC;
        tags.nopasswd = UNSPEC;
-       tags.transcript = UNSPEC;
+       tags.log_input = UNSPEC;
+       tags.log_output = UNSPEC;
        lbuf_append(lbuf, "    ", NULL);
        tq_foreach_fwd(&priv->cmndlist, cs) {
            if (cs != tq_first(&priv->cmndlist))
@@ -362,7 +370,8 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
        tags.noexec = UNSPEC;
        tags.setenv = UNSPEC;
        tags.nopasswd = UNSPEC;
-       tags.transcript = UNSPEC;
+       tags.log_input = UNSPEC;
+       tags.log_output = UNSPEC;
        lbuf_append(lbuf, "\nSudoers entry:\n", NULL);
        tq_foreach_fwd(&priv->cmndlist, cs) {
            lbuf_append(lbuf, "    RunAsUsers: ", NULL);
index 17578f0e28c08195edd0ec36d7225b70b2fea224..ee250daeed8dcbf4a2a0544083bbc103d6b07f0a 100644 (file)
@@ -40,10 +40,11 @@ struct sudo_command {
  * Possible valus: TRUE, FALSE, UNSPEC.
  */
 struct cmndtag {
-    __signed char nopasswd;
-    __signed char noexec;
-    __signed char setenv;
-    __signed char transcript;
+    __signed int nopasswd: 3;
+    __signed int noexec: 3;
+    __signed int setenv: 3;
+    __signed int log_input: 3;
+    __signed int log_output: 3;
 };
 
 /*
index 9cfd81da9d57961ae6a89f6ed87b83f2f6786497..d62923a3a4a417353b28c0ec3a8f92b829da40b2 100644 (file)
@@ -518,7 +518,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
            validate_env_vars(sudo_user.env_vars);
     }
 
-    if (def_transcript && (sudo_mode & (MODE_RUN | MODE_EDIT)))
+    if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output))
        io_nextid();
     log_allowed(validated);
     if (ISSET(sudo_mode, MODE_CHECK))
index dc87a2ba947899e5d1b91bdb1d5e1e97a1c28b54..4ff45c44a7150b4eae28e334318af295da5562b6 100644 (file)
@@ -110,7 +110,7 @@ union io_fd {
 };
 
 /*
- * Info present in the transcript log file
+ * Info present in the I/O log file
  */
 struct log_info {
     char *cwd;
@@ -161,7 +161,7 @@ struct search_node {
 static struct search_node *node_stack[32];
 static int stack_top;
 
-static const char *session_dir = _PATH_SUDO_TRANSCRIPT;
+static const char *session_dir = _PATH_SUDO_IO_LOGDIR;
 
 static union io_fd io_fds[IOFD_MAX];
 static const char *io_fnames[IOFD_MAX] = {
@@ -642,7 +642,11 @@ list_session_dir(char *pathbuf, REGEX_T *re, const char *user, const char *tty)
        pathbuf[plen + 0] = '/';
        pathbuf[plen + 1] = dp->d_name[0];
        pathbuf[plen + 2] = dp->d_name[1];
-       pathbuf[plen + 3] = '\0';
+       pathbuf[plen + 3] = '/';
+       pathbuf[plen + 4] = 'l';
+       pathbuf[plen + 5] = 'o';
+       pathbuf[plen + 6] = 'g';
+       pathbuf[plen + 7] = '\0';
        fp = fopen(pathbuf, "r");
        if (fp == NULL) {
            warning("unable to open %s", pathbuf);
@@ -744,6 +748,10 @@ list_sessions(int argc, char **argv, const char *pattern, const char *user,
 #endif /* HAVE_REGCOMP */
 
     sdlen = strlcpy(pathbuf, session_dir, sizeof(pathbuf));
+    if (sdlen + sizeof("/00/00/00/log") >= sizeof(pathbuf)) {
+       errno = ENAMETOOLONG;
+       error(1, "%s/00/00/00/log", session_dir);
+    }
 
     /*
      * Three levels of directory, e.g. 00/00/00 .. ZZ/ZZ/ZZ