]> granicus.if.org Git - sudo/commitdiff
Add iolog_flush option.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 20 Mar 2017 16:25:58 +0000 (10:25 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Mon, 20 Mar 2017 16:25:58 +0000 (10:25 -0600)
doc/sudoers.cat
doc/sudoers.man.in
doc/sudoers.mdoc.in
plugins/sudoers/def_data.c
plugins/sudoers/def_data.h
plugins/sudoers/def_data.in
plugins/sudoers/iolog.c

index 39752453c8161b7a0edab86c0772ebde6ed4c1f3..b0caee9344a3c9239a1f17d949fab73d2b4059b4 100644 (file)
@@ -1615,6 +1615,16 @@ S\bSU\bUD\bDO\bOE\bER\bRS\bS O\bOP\bPT\bTI\bIO\bON\bNS\bS
                        will be truncated and overwritten unless _\bi_\bo_\bl_\bo_\bg_\b__\bf_\bi_\bl_\be
                        ends in six or more Xs.
 
+     iolog_flush       If set, s\bsu\bud\bdo\bo will flush I/O log data to disk after each
+                       write instead of buffering it.  This makes it possible
+                       to view the logs in real-time as the program is
+                       executing but may significantly reduce the
+                       effectiveness of I/O log compression.  This flag is _\bo_\bf_\bf
+                       by default.
+
+                       This setting is only supported by version 1.8.20 or
+                       higher.
+
      iolog_group       The group name to look up when setting the group ID on
                        new I/O log files and directories.  By default, I/O log
                        files and directories inherit the group ID of the
@@ -2241,12 +2251,14 @@ I\bI/\b/O\bO L\bLO\bOG\bG F\bFI\bIL\bLE\bES\bS
      _\bs_\bt_\bd_\be_\br_\br    standard error to a pipe or redirected to a file
 
      All files other than _\bl_\bo_\bg are compressed in gzip format unless the
-     _\bc_\bo_\bm_\bp_\br_\be_\bs_\bs_\b__\bi_\bo option has been disabled.  Due to buffering, it is not
-     possible to display the I/O logs in real-time as the program is
-     executing.  The I/O log data will not be complete until the program run
-     by s\bsu\bud\bdo\bo has exited or has been terminated by a signal.  The output
-     portion of an I/O log file can be viewed with the sudoreplay(1m) utility,
-     which can also be used to list or search the available logs.
+     _\bc_\bo_\bm_\bp_\br_\be_\bs_\bs_\b__\bi_\bo flag has been disabled.  Due to buffering, it is not normally
+     possible to display the I/O logs in real-time as the program is executing
+     The I/O log data will not be complete until the program run by s\bsu\bud\bdo\bo has
+     exited or has been terminated by a signal.  The _\bi_\bo_\bl_\bo_\bg_\b__\bf_\bl_\bu_\bs_\bh flag can be
+     used to disable buffering, in which case I/O log data is written to disk
+     as soon as it is available.  The output portion of an I/O log file can be
+     viewed with the sudoreplay(1m) utility, which can also be used to list or
+     search the available logs.
 
      Note that user input may contain sensitive information such as passwords
      (even if they are not echoed to the screen), which will be stored in the
@@ -2748,4 +2760,4 @@ D\bDI\bIS\bSC\bCL\bLA\bAI\bIM\bME\bER\bR
      file distributed with s\bsu\bud\bdo\bo or https://www.sudo.ws/license.html for
      complete details.
 
-Sudo 1.8.20                     March 17, 2017                     Sudo 1.8.20
+Sudo 1.8.20                     March 20, 2017                     Sudo 1.8.20
index a9ff7541542a6d160b8425c4698476194befd35a..49dbd77ad555720e493610b5ab20568084387ff6 100644 (file)
@@ -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" "March 17, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
+.TH "SUDOERS" "5" "March 20, 2017" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
 .nh
 .if n .ad l
 .SH "NAME"
@@ -3315,6 +3315,19 @@ ends in six or
 more
 \fRX\fRs.
 .TP 18n
+iolog_flush
+If set,
+\fBsudo\fR
+will flush I/O log data to disk after each write instead of buffering it.
+This makes it possible to view the logs in real-time as the program
+is executing but may significantly reduce the effectiveness of I/O
+log compression.
+This flag is
+\fIoff\fR
+by default.
+.sp
+This setting is only supported by version 1.8.20 or higher.
+.TP 18n
 iolog_group
 The group name to look up when setting the group ID on new I/O log
 files and directories.
@@ -4467,12 +4480,16 @@ All files other than
 \fIlog\fR
 are compressed in gzip format unless the
 \fIcompress_io\fR
-option has been disabled.
-Due to buffering, it is not possible to display the I/O logs in
-real-time as the program is executing.
+flag has been disabled.
+Due to buffering, it is not normally possible to display the I/O logs in
+real-time as the program is executing
 The I/O log data will not be complete until the program run by
 \fBsudo\fR
 has exited or has been terminated by a signal.
+The
+\fIiolog_flush\fR
+flag can be used to disable buffering, in which case I/O log data
+is written to disk as soon as it is available.
 The output portion of an I/O log file can be viewed with the
 sudoreplay(@mansectsu@)
 utility, which can also be used to list or search the available logs.
index 97ac155c7126536cbea82b54cb5496ce4e3223b0..e872b7c6aa72bc5d6aaae0b9cf0d75eb5e0fbd45 100644 (file)
@@ -19,7 +19,7 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd March 17, 2017
+.Dd March 20, 2017
 .Dt SUDOERS @mansectform@
 .Os Sudo @PACKAGE_VERSION@
 .Sh NAME
@@ -3109,6 +3109,18 @@ overwritten unless
 ends in six or
 more
 .Li X Ns s .
+.It iolog_flush
+If set,
+.Nm sudo
+will flush I/O log data to disk after each write instead of buffering it.
+This makes it possible to view the logs in real-time as the program
+is executing but may significantly reduce the effectiveness of I/O
+log compression.
+This flag is
+.Em off
+by default.
+.Pp
+This setting is only supported by version 1.8.20 or higher.
 .It iolog_group
 The group name to look up when setting the group ID on new I/O log
 files and directories.
@@ -4148,12 +4160,16 @@ All files other than
 .Pa log
 are compressed in gzip format unless the
 .Em compress_io
-option has been disabled.
-Due to buffering, it is not possible to display the I/O logs in
-real-time as the program is executing.
+flag has been disabled.
+Due to buffering, it is not normally possible to display the I/O logs in
+real-time as the program is executing
 The I/O log data will not be complete until the program run by
 .Nm sudo
 has exited or has been terminated by a signal.
+The
+.Em iolog_flush
+flag can be used to disable buffering, in which case I/O log data
+is written to disk as soon as it is available.
 The output portion of an I/O log file can be viewed with the
 .Xr sudoreplay @mansectsu@
 utility, which can also be used to list or search the available logs.
index 501d7804e2c96e56466796d704f32fbcabbf9b76..331a6b4286e4ee0c6718fe0cef0efd03623ea488 100644 (file)
@@ -457,6 +457,10 @@ struct sudo_defs_types sudo_defs_table[] = {
        "user_command_timeouts", T_FLAG,
        N_("Allow the user to specify a timeout on the command line"),
        NULL,
+    }, {
+       "iolog_flush", T_FLAG,
+       N_("Flush I/O log data to disk immediately instead of buffering it"),
+       NULL,
     }, {
        NULL, 0, NULL
     }
index 2f749b53bb3b5d630e81e967b898c1731bab7366..c523352360508a60d0c2d348eb9259d5f12f5a23 100644 (file)
 #define def_command_timeout     (sudo_defs_table[I_COMMAND_TIMEOUT].sd_un.ival)
 #define I_USER_COMMAND_TIMEOUTS 106
 #define def_user_command_timeouts (sudo_defs_table[I_USER_COMMAND_TIMEOUTS].sd_un.flag)
+#define I_IOLOG_FLUSH           107
+#define def_iolog_flush         (sudo_defs_table[I_IOLOG_FLUSH].sd_un.flag)
 
 enum def_tuple {
        never,
index b5fb4d92e0358fdb1a9dcbf34e0d6dc9dad4898f..a005a6c0137ad39939c4ac1542742c49c9407006 100644 (file)
@@ -335,3 +335,6 @@ command_timeout
 user_command_timeouts
        T_FLAG
        "Allow the user to specify a timeout on the command line"
+iolog_flush
+       T_FLAG
+       "Flush I/O log data to disk immediately instead of buffering it"
index f1ab3c406e2f62bad2efecadb3103f25ace0cad9..058659d51e3f7126a31dd541cf0bd4d4253799ab 100644 (file)
@@ -710,6 +710,7 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
 
 /*
  * Write the "/log" file that contains the user and command info.
+ * This file is not compressed.
  */
 static bool
 write_info_log(char *pathbuf, size_t len, struct iolog_details *details,
@@ -748,6 +749,57 @@ write_info_log(char *pathbuf, size_t len, struct iolog_details *details,
     debug_return_bool(ret);
 }
 
+#ifdef HAVE_ZLIB_H
+static const char *
+gzstrerror(gzFile file)
+{
+    int errnum;
+
+    return gzerror(file, &errnum);
+}
+#endif /* HAVE_ZLIB_H */
+
+/*
+ * Write to an I/O log, compressing if iolog_compress is enabled.
+ * If def_iolog_flush is true, flush the buffer immediately.
+ */
+static const char *
+iolog_write(const void *buf, unsigned int len, int idx)
+{
+    const char *errstr = NULL;
+    debug_decl(iolog_write, SUDOERS_DEBUG_PLUGIN)
+
+#ifdef HAVE_ZLIB_H
+    if (iolog_compress) {
+       if (gzwrite(io_log_files[idx].fd.g, buf, len) != (int)len) {
+           errstr = gzstrerror(io_log_files[idx].fd.g);
+           goto done;
+       }
+       if (def_iolog_flush) {
+           if (gzflush(io_log_files[idx].fd.g, Z_SYNC_FLUSH) != Z_OK) {
+               errstr = gzstrerror(io_log_files[idx].fd.g);
+               goto done;
+           }
+       }
+    } else
+#endif
+    {
+       if (fwrite(buf, 1, len, io_log_files[idx].fd.f) != len) {
+           errstr = strerror(errno);
+           goto done;
+       }
+       if (def_iolog_flush) {
+           if (fflush(io_log_files[idx].fd.f) != 0) {
+               errstr = strerror(errno);
+               goto done;
+           }
+       }
+    }
+
+done:
+    debug_return_const_str(errstr);
+}
+
 static int
 sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     sudo_printf_t plugin_printf, char * const settings[],
@@ -915,13 +967,15 @@ sudoers_io_version(int verbose)
 
 /*
  * Generic I/O logging function.  Called by the I/O logging entry points.
+ * Returns 1 on success and -1 on error.
  */
 static int
 sudoers_io_log(const char *buf, unsigned int len, int idx)
 {
     struct timeval now, delay;
+    char tbuf[1024];
     const char *errstr = NULL;
-    int ret = true;
+    int ret = -1;
     debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN)
 
     if (io_log_files[idx].fd.v == NULL) {
@@ -932,41 +986,28 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
 
     gettimeofday(&now, NULL);
 
-#ifdef HAVE_ZLIB_H
-    if (iolog_compress) {
-       if (gzwrite(io_log_files[idx].fd.g, (const voidp)buf, len) != (int)len) {
-           int errnum;
+    /* Write I/O log file entry. */
+    errstr = iolog_write(buf, len, idx);
+    if (errstr != NULL)
+       goto done;
 
-           errstr = gzerror(io_log_files[idx].fd.g, &errnum);
-           ret = -1;
-       }
-    } else
-#endif
-    {
-       if (fwrite(buf, 1, len, io_log_files[idx].fd.f) != len) {
-           errstr = strerror(errno);
-           ret = -1;
-       }
-    }
+    /* Write timing file entry. */
     sudo_timevalsub(&now, &last_time, &delay);
-#ifdef HAVE_ZLIB_H
-    if (iolog_compress) {
-       if (gzprintf(io_log_files[IOFD_TIMING].fd.g, "%d %f %u\n", idx,
-           delay.tv_sec + ((double)delay.tv_usec / 1000000), len) == 0) {
-           int errnum;
-
-           errstr = gzerror(io_log_files[IOFD_TIMING].fd.g, &errnum);
-           ret = -1;
-       }
-    } else
-#endif
-    {
-       if (fprintf(io_log_files[IOFD_TIMING].fd.f, "%d %f %u\n", idx,
-           delay.tv_sec + ((double)delay.tv_usec / 1000000), len) < 0) {
-           errstr = strerror(errno);
-           ret = -1;
-       }
+    len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %f %u\n", idx,
+       delay.tv_sec + ((double)delay.tv_usec / 1000000), len);
+    if (len >= sizeof(tbuf)) {
+       /* Not actually possible due to the size of tbuf[]. */
+       errstr = strerror(EOVERFLOW);
+       goto done;
     }
+    errstr = iolog_write(tbuf, len, IOFD_TIMING);
+    if (errstr != NULL)
+       goto done;
+
+    /* Success. */
+    ret = 1;
+
+done:
     last_time.tv_sec = now.tv_sec;
     last_time.tv_usec = now.tv_usec;
 
@@ -980,7 +1021,7 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
 
        /* Ignore errors if they occur if the policy says so. */
        if (iolog_details.ignore_iolog_errors)
-           ret = true;
+           ret = 1;
     }
 
     debug_return_int(ret);