]> granicus.if.org Git - sudo/commitdiff
First pass at zlib support for transcript data files
authorTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 22 Oct 2009 23:50:16 +0000 (23:50 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Thu, 22 Oct 2009 23:50:16 +0000 (23:50 +0000)
INSTALL
configure
configure.in
script.c
sudoreplay.c

diff --git a/INSTALL b/INSTALL
index 38e0e981cb47676dee8230d5f47af10a00d04283..6cfd6e12bae91cdb16fb7cead547bbe29e019b4c 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -601,6 +601,17 @@ The following options are also configurable at runtime:
        /usr/log/sudo-transcript.  If DIR is specified, transcripts
        will be stored in the indicated directory instead.
 
+  --disable-zlib
+        Disable the use of the zlib compress library when storing
+        transcript files.
+
+  --enable-zlib[=DIR]
+        Enable the use of the zlib compress library when storing
+        transcript 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 and transcript
+        support is not disabled.
+
 Shadow password and C2 support
 ==============================
 
index d5f2a1a6cafba810e146df10a25efcb3d44673ca..16f7221d76ea10ec9fe6093283e92aa96cedc149 100755 (executable)
--- a/configure
+++ b/configure
@@ -839,6 +839,7 @@ LDAP
 REPLAY
 LOGINCAP_USAGE
 NONUNIX_GROUPS_IMPL
+ZLIB
 timedir
 timeout
 password_timeout
@@ -1513,6 +1514,7 @@ Optional Features:
   --disable-libtool-lock  avoid locking (might break parallel builds)
   --disable-sia           Disable SIA on Digital UNIX
   --disable-pam-session   Disable PAM session support
+  --enable-zlib=PATH      Whether to enable or disable zlib
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -2124,6 +2126,7 @@ echo "$as_me: Configuring Sudo version $PACKAGE_VERSION" >&6;}
 
 
 
+
 
 
 timeout=5
@@ -2166,6 +2169,7 @@ REPLAY="#"
 BAMAN='.\" '
 LCMAN='.\" '
 SEMAN='.\" '
+ZLIB=
 AUTH_OBJS=
 AUTH_REG=
 AUTH_EXCL=
@@ -6467,7 +6471,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6470 "configure"' > conftest.$ac_ext
+  echo '#line 6474 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -8331,11 +8335,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8334: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8338: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8338: \$? = $ac_status" >&5
+   echo "$as_me:8342: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8621,11 +8625,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8624: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8628: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8628: \$? = $ac_status" >&5
+   echo "$as_me:8632: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8725,11 +8729,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8728: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8732: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8732: \$? = $ac_status" >&5
+   echo "$as_me:8736: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -11085,7 +11089,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 11088 "configure"
+#line 11092 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11185,7 +11189,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 11188 "configure"
+#line 11192 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -25806,6 +25810,111 @@ _ACEOF
        PROGS="$PROGS sudoreplay"
        REPLAY=""
 
+       # Check whether --enable-zlib was given.
+if test "${enable_zlib+set}" = set; then
+  enableval=$enable_zlib;  case "$enableval" in
+           yes)    cat >>confdefs.h <<\_ACEOF
+#define HAVE_ZLIB 1
+_ACEOF
+
+                   ZLIB="-lz"
+                   ;;
+           no)     ;;
+           *)      cat >>confdefs.h <<\_ACEOF
+#define HAVE_ZLIB 1
+_ACEOF
+
+                   CPPFLAGS="${CPPFLAGS} -I${enableval}/include"
+
+    if test X"$with_rpath" = X"yes"; then
+       ZLIB="${ZLIB} -L$enableval/lib -R$enableval/lib"
+    else
+       ZLIB="${ZLIB} -L$enableval/lib"
+    fi
+    if test X"$blibpath" != X"" -a "ZLIB" = "SUDO_LDFLAGS"; then
+       blibpath_add="${blibpath_add}:$enableval/lib"
+    fi
+
+                   ZLIB="${ZLIB} -lz"
+                   ;;
+         esac
+
+fi
+
+       if test X"$enable_zlib" = X""; then
+           { echo "$as_me:$LINENO: checking for gzdopen in -lz" >&5
+echo $ECHO_N "checking for gzdopen in -lz... $ECHO_C" >&6; }
+if test "${ac_cv_lib_z_gzdopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char gzdopen ();
+int
+main ()
+{
+return gzdopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_z_gzdopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_z_gzdopen=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzdopen" >&5
+echo "${ECHO_T}$ac_cv_lib_z_gzdopen" >&6; }
+if test $ac_cv_lib_z_gzdopen = yes; then
+
+               cat >>confdefs.h <<\_ACEOF
+#define HAVE_ZLIB 1
+_ACEOF
+
+               ZLIB="-lz"
+
+fi
+
+       fi
+
 else
 
        { echo "$as_me:$LINENO: WARNING: Disabling transcript support due to lack of tcsetpgrp function" >&5
@@ -26582,6 +26691,7 @@ LDAP!$LDAP$ac_delim
 REPLAY!$REPLAY$ac_delim
 LOGINCAP_USAGE!$LOGINCAP_USAGE$ac_delim
 NONUNIX_GROUPS_IMPL!$NONUNIX_GROUPS_IMPL$ac_delim
+ZLIB!$ZLIB$ac_delim
 timedir!$timedir$ac_delim
 timeout!$timeout$ac_delim
 password_timeout!$password_timeout$ac_delim
@@ -26603,7 +26713,6 @@ badpass_message!$badpass_message$ac_delim
 fqdn!$fqdn$ac_delim
 runas_default!$runas_default$ac_delim
 env_editor!$env_editor$ac_delim
-passwd_tries!$passwd_tries$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -26645,6 +26754,7 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+passwd_tries!$passwd_tries$ac_delim
 tty_tickets!$tty_tickets$ac_delim
 insults!$insults$ac_delim
 root_sudo!$root_sudo$ac_delim
@@ -26689,7 +26799,7 @@ KRB5CONFIG!$KRB5CONFIG$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 42; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 43; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -27314,6 +27424,8 @@ fi
 
 
 
+
+
 
 
 
index e36805c1227a7ad8839d2c6142f495754452ab57..d085e37c8195e8b5f40c1da2057c25bbb6356a01 100644 (file)
@@ -52,6 +52,7 @@ AC_SUBST(LDAP)
 AC_SUBST(REPLAY)
 AC_SUBST(LOGINCAP_USAGE)
 AC_SUBST(NONUNIX_GROUPS_IMPL)
+AC_SUBST(ZLIB)
 dnl
 dnl Variables that get substituted in docs (not overridden by environment)
 dnl
@@ -133,6 +134,7 @@ REPLAY="#"
 BAMAN='.\" '
 LCMAN='.\" '
 SEMAN='.\" '
+ZLIB=
 AUTH_OBJS=
 AUTH_REG=
 AUTH_EXCL=
@@ -2604,6 +2606,27 @@ if test "${enable_transcript-yes}" != "no"; then
        SUDO_OBJS="${SUDO_OBJS} pty.o script.o"
        PROGS="$PROGS sudoreplay"
        REPLAY=""
+
+       AC_ARG_ENABLE(zlib,
+       [AS_HELP_STRING([--enable-zlib[[=PATH]]], [Whether to enable or disable zlib])],
+       [ case "$enableval" in
+           yes)    AC_DEFINE(HAVE_ZLIB)
+                   ZLIB="-lz"
+                   ;;
+           no)     ;;
+           *)      AC_DEFINE(HAVE_ZLIB)
+                   CPPFLAGS="${CPPFLAGS} -I${enableval}/include"
+                   SUDO_APPEND_LIBPATH(ZLIB, [$enableval/lib])
+                   ZLIB="${ZLIB} -lz"
+                   ;;
+         esac
+       ])
+       if test X"$enable_zlib" = X""; then
+           AC_CHECK_LIB(z, gzdopen, [
+               AC_DEFINE(HAVE_ZLIB)
+               ZLIB="-lz"
+           ])
+       fi
     ], [
        AC_MSG_WARN([Disabling transcript support due to lack of tcsetpgrp function])
        enable_transcript=no
@@ -2772,6 +2795,7 @@ AH_TEMPLATE(WITHOUT_PASSWD, [Define to avoid using the passwd/shadow file for au
 AH_TEMPLATE(sig_atomic_t, [Define to `int' if <signal.h> does not define.])
 AH_TEMPLATE(__signed, [Define to `signed' or nothing if compiler does not support a signed type qualifier.])
 AH_TEMPLATE(USING_NONUNIX_GROUPS, [Define to 1 if using a non-Unix group lookup implementation.])
+AH_TEMPLATE(HAVE_ZLIB, [Define to 1 if you the `zlib' library.])
 
 dnl
 dnl Bits to copy verbatim into config.h.in
index 0f57ece5b7708eaefde8b497ebc071d2ec42b587..017172375c150f3b467779094008dba883b1b391 100644 (file)
--- a/script.c
+++ b/script.c
@@ -67,6 +67,9 @@
 #ifdef HAVE_SELINUX
 # include <selinux/selinux.h>
 #endif
+#ifdef HAVE_ZLIB
+# include <zlib.h>
+#endif
 
 #include "sudo.h"
 
@@ -104,7 +107,7 @@ static void sigchild __P((int s));
 static void sigtstp __P((int s));
 static void sigwinch __P((int s));
 static void flush_output __P((struct script_buf *output, struct timeval *then,
-    struct timeval *now, FILE *ofile, FILE *tfile));
+    struct timeval *now, void *ofile, void *tfile));
 
 extern int get_pty __P((int *master, int *slave, char *name, size_t namesz));
 
@@ -315,15 +318,29 @@ log_output(buf, n, then, now, ofile, tfile)
     int n;
     struct timeval *then;
     struct timeval *now;
+#ifdef HAVE_ZLIB
+    gzFile ofile;
+    gzFile tfile;
+#else
     FILE *ofile;
     FILE *tfile;
+#endif
 {
     struct timeval tv;
 
+#ifdef HAVE_ZLIB
+    gzwrite(ofile, buf, n);
+#else
     fwrite(buf, 1, n, ofile);
+#endif
     timersub(now, then, &tv);
+#ifdef HAVE_ZLIB
+    gzprintf(tfile, "%f %d\n",
+       tv.tv_sec + ((double)tv.tv_usec / 1000000), n);
+#else
     fprintf(tfile, "%f %d\n",
        tv.tv_sec + ((double)tv.tv_usec / 1000000), n);
+#endif
     then->tv_sec = now->tv_sec;
     then->tv_usec = now->tv_usec;
 }
@@ -352,7 +369,12 @@ script_execv(path, argv)
     struct timeval now, then;
     int n, nready, exitcode = 1;
     fd_set *fdsr, *fdsw;
+    FILE *idfile;
+#ifdef HAVE_ZLIB
+    gzFile ofile, tfile;
+#else
     FILE *idfile, *ofile, *tfile;
+#endif
     int rbac_enabled = 0;
 
 #ifdef HAVE_SELINUX
@@ -402,10 +424,17 @@ script_execv(path, argv)
 
     if ((idfile = fdopen(script_fds[SFD_LOG], "w")) == NULL)
        log_error(USE_ERRNO, "fdopen");
+#ifdef HAVE_ZLIB
+    if ((ofile = gzdopen(script_fds[SFD_OUTPUT], "w")) == NULL)
+       log_error(USE_ERRNO, "gzdopen");
+    if ((tfile = gzdopen(script_fds[SFD_TIMING], "w")) == NULL)
+       log_error(USE_ERRNO, "gzdopen");
+#else
     if ((ofile = fdopen(script_fds[SFD_OUTPUT], "w")) == NULL)
        log_error(USE_ERRNO, "fdopen");
     if ((tfile = fdopen(script_fds[SFD_TIMING], "w")) == NULL)
        log_error(USE_ERRNO, "fdopen");
+#endif
 
     gettimeofday(&then, NULL);
 
@@ -452,8 +481,19 @@ script_execv(path, argv)
 
        zero_bytes(fdsw, howmany(script_fds[SFD_MASTER] + 1, NFDBITS) * sizeof(fd_mask));
        zero_bytes(fdsr, howmany(script_fds[SFD_MASTER] + 1, NFDBITS) * sizeof(fd_mask));
-       if (input.len != sizeof(input.buf))
-           FD_SET(script_fds[SFD_USERTTY], fdsr);
+       if (input.len != sizeof(input.buf)) {
+           /* Only check for input if master pty is writable. */
+           struct timeval tv;
+           tv.tv_sec = 0;
+           tv.tv_usec = 0;
+           FD_SET(script_fds[SFD_MASTER], fdsw);
+           do {
+               n = select(script_fds[SFD_MASTER] + 1, NULL, fdsw, NULL, &tv);
+           } while (n == -1 && errno == EINTR);
+           if (n == 1)
+               FD_SET(script_fds[SFD_USERTTY], fdsr);
+           FD_CLR(script_fds[SFD_MASTER], fdsw);
+       }
        if (output.len != sizeof(output.buf))
            FD_SET(script_fds[SFD_MASTER], fdsr);
        if (output.len > output.off)
@@ -556,6 +596,14 @@ script_execv(path, argv)
     }
     flush_output(&output, &then, &now, ofile, tfile);
 
+#ifdef HAVE_ZLIB
+    gzclose(ofile);
+    gzclose(tfile);
+#else
+    fclose(ofile);
+    fclose(tfile);
+#endif
+
     do {
        n = term_restore(script_fds[SFD_USERTTY]);
     } while (!n && errno == EINTR);
@@ -687,8 +735,8 @@ flush_output(output, then, now, ofile, tfile)
     struct script_buf *output;
     struct timeval *then;
     struct timeval *now;
-    FILE *ofile;
-    FILE *tfile;
+    void *ofile;
+    void *tfile;
 {
     int n;
 
index e99302361685a3b792fcf003137f008fab670627..eae9d43f53e1050272465144cff70f7992361582 100644 (file)
@@ -76,6 +76,9 @@
 #ifdef HAVE_REGCOMP
 # include <regex.h>
 #endif
+#ifdef HAVE_ZLIB
+# include <zlib.h>
+#endif
 #include <signal.h>
 
 #include <pathnames.h>
@@ -179,7 +182,12 @@ main(argc, argv)
     int ch, plen, ttyfd, interactive = 0, listonly = 0;
     const char *id, *user = NULL, *pattern = NULL, *tty = NULL;
     char path[PATH_MAX], buf[LINE_MAX], *cp, *ep;
-    FILE *tfile, *sfile, *lfile;
+    FILE *lfile;
+#ifdef HAVE_ZLIB
+    gzFile tfile, sfile;
+#else
+    FILE *tfile, *sfile;
+#endif
     sigaction_t sa;
     unsigned long nbytes;
     size_t len, nread;
@@ -242,13 +250,21 @@ main(argc, argv)
            id, &id[2], &id[4], strerror(ENAMETOOLONG));
 
     /* timing file */
+#ifdef HAVE_ZLIB
+    tfile = gzopen(path, "r");
+#else
     tfile = fopen(path, "r");
+#endif
     if (tfile == NULL)
        error(1, "unable to open %s", path);
 
     /* script file */
     memcpy(&path[plen - 3], "scr", 3);
+#ifdef HAVE_ZLIB
+    sfile = gzopen(path, "r");
+#else
     sfile = fopen(path, "r");
+#endif
     if (sfile == NULL)
        error(1, "unable to open %s", path);
 
@@ -290,7 +306,11 @@ main(argc, argv)
     /*
      * Timing file consists of line of the format: "%f %d\n"
      */
+#ifdef HAVE_ZLIB
+    while (gzgets(tfile, buf, sizeof(buf)) != NULL) {
+#else
     while (fgets(buf, sizeof(buf), tfile) != NULL) {
+#endif
        errno = 0;
        seconds = strtod(buf, &ep);
        if (errno != 0 || !isspace((unsigned char) *ep))
@@ -316,7 +336,11 @@ main(argc, argv)
                len = sizeof(buf);
            else
                len = nbytes;
+#ifdef HAVE_ZLIB
+           nread = gzread(sfile, buf, len);
+#else
            nread = fread(buf, 1, len, sfile);
+#endif
            nbytes -= nread;
            do {
                /* no stdio, must be unbuffered */