]> granicus.if.org Git - sudo/commitdiff
Move the ignoring of I/O log plugin errors into the I/O log plugin
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 17 Aug 2016 20:38:00 +0000 (14:38 -0600)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 17 Aug 2016 20:38:00 +0000 (14:38 -0600)
itself.

plugins/sudoers/iolog.c
src/exec_pty.c
src/sudo.c
src/sudo.h

index d4db4ce3cb4afdf020827a25cd8bd1d8428478c2..36b2330010351d84c975043fbb6698bed908bbac 100644 (file)
@@ -63,9 +63,12 @@ struct iolog_details {
     struct group *runas_gr;
     int lines;
     int cols;
+    bool ignore_iolog_errors;
 };
 
+static struct iolog_details iolog_details;
 static bool iolog_compress = false;
+static bool warned = false;
 static struct timeval last_time;
 static unsigned int sessid_max = SESSID_MAX;
 
@@ -301,6 +304,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
     if (lseek(fd, 0, SEEK_SET) == -1 || write(fd, buf, 7) != 7) {
 #endif
        log_warning(SLOG_SEND_MAIL, N_("unable to write to %s"), pathbuf);
+       warned = true;
        goto done;
     }
     rval = true;
@@ -448,6 +452,11 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
            }
            break;
        case 'i':
+           if (strncmp(*cur, "ignore_iolog_errors=", sizeof("ignore_iolog_errors=") - 1) == 0) {
+               if (sudo_strtobool(*cur + sizeof("ignore_iolog_errors=") - 1) == true)
+                   details->ignore_iolog_errors = true;
+               continue;
+           }
            if (strncmp(*cur, "iolog_path=", sizeof("iolog_path=") - 1) == 0) {
                details->iolog_path = *cur + sizeof("iolog_path=") - 1;
                continue;
@@ -599,7 +608,6 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     int argc, char * const argv[], char * const user_env[], char * const args[])
 {
     struct sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files);
-    struct iolog_details details;
     char pathbuf[PATH_MAX], sessid[7];
     char *tofree = NULL;
     char * const *cur;
@@ -615,8 +623,6 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     if (argc == 0)
        debug_return_int(true);
 
-    memset(&details, 0, sizeof(details));
-
     bindtextdomain("sudoers", LOCALEDIR);
 
     /* Initialize the debug subsystem.  */
@@ -637,13 +643,13 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     /*
      * Pull iolog settings out of command_info.
      */
-    if (!iolog_deserialize_info(&details, user_info, command_info)) {
+    if (!iolog_deserialize_info(&iolog_details, user_info, command_info)) {
        rval = false;
        goto done;
     }
 
     /* If no I/O log path defined we need to figure it out ourselves. */
-    if (details.iolog_path == NULL) {
+    if (iolog_details.iolog_path == NULL) {
        /* Get next session ID and convert it into a path. */
        tofree = malloc(sizeof(_PATH_SUDO_IO_LOGDIR) + sizeof(sessid) + 2);
        if (tofree == NULL) {
@@ -658,21 +664,21 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        snprintf(tofree + sizeof(_PATH_SUDO_IO_LOGDIR), sizeof(sessid) + 2,
            "%c%c/%c%c/%c%c", sessid[0], sessid[1], sessid[2], sessid[3],
            sessid[4], sessid[5]);
-       details.iolog_path = tofree;
+       iolog_details.iolog_path = tofree;
     }
 
     /*
      * Make local copy of I/O log path and create it, along with any
      * intermediate subdirs.  Calls mkdtemp() if iolog_path ends in XXXXXX.
      */
-    len = mkdir_iopath(details.iolog_path, pathbuf, sizeof(pathbuf));
+    len = mkdir_iopath(iolog_details.iolog_path, pathbuf, sizeof(pathbuf));
     if (len >= sizeof(pathbuf))
        goto done;
 
     /* Write log file with user and command details. */
     if (gettimeofday(&last_time, NULL) == -1)
        goto done;
-    write_info_log(pathbuf, len, &details, argv, &last_time);
+    write_info_log(pathbuf, len, &iolog_details, argv, &last_time);
 
     /* Create the timing and I/O log files. */
     for (i = 0; i < IOFD_MAX; i++) {
@@ -698,13 +704,17 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
 
 done:
     free(tofree);
-    if (details.runas_pw)
-       sudo_pw_delref(details.runas_pw);
-    if (details.runas_gr)
-       sudo_gr_delref(details.runas_gr);
+    if (iolog_details.runas_pw)
+       sudo_pw_delref(iolog_details.runas_pw);
+    if (iolog_details.runas_gr)
+       sudo_gr_delref(iolog_details.runas_gr);
     sudo_freepwcache();
     sudo_freegrcache();
 
+    /* Ignore errors if they occur if the policy says so. */
+    if (rval == -1 && iolog_details.ignore_iolog_errors)
+       rval = 0;
+
     debug_return_int(rval);
 }
 
@@ -730,8 +740,12 @@ sudoers_io_close(int exit_status, int error)
            errstr = strerror(errno);
     }
 
-    if (errstr != NULL)
-       sudo_warnx(U_("unable to write to I/O log file: %s"), errstr);
+    if (errstr != NULL && !warned) {
+       /* Only warn about I/O log file errors once. */
+       log_warning(SLOG_SEND_MAIL,
+           N_("unable to write to I/O log file: %s"), errstr);
+       warned = true;
+    }
 
     sudoers_debug_deregister();
 
@@ -756,7 +770,6 @@ static int
 sudoers_io_log(const char *buf, unsigned int len, int idx)
 {
     struct timeval now, delay;
-    static bool warned = false;
     const char *errstr = NULL;
     int rval = true;
     debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN)
@@ -807,10 +820,17 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
     last_time.tv_sec = now.tv_sec;
     last_time.tv_usec = now.tv_usec;
 
-    if (errstr != NULL && !warned) {
-       /* Only warn about I/O log file errors once. */
-       sudo_warnx(U_("unable to write to I/O log file: %s"), errstr);
-       warned = true;
+    if (rval == -1) {
+       if (errstr != NULL && !warned) {
+           /* Only warn about I/O log file errors once. */
+           log_warning(SLOG_SEND_MAIL,
+               N_("unable to write to I/O log file: %s"), errstr);
+           warned = true;
+       }
+
+       /* Ignore errors if they occur if the policy says so. */
+       if (iolog_details.ignore_iolog_errors)
+           rval = true;
     }
 
     debug_return_int(rval);
index 8035920389e93a65cbfd6af499718b24d5aaef31..a22bee6cfdc5f4b2052d83f8149b5104fbb2a055 100644 (file)
@@ -89,7 +89,6 @@ static int ttymode = TERM_COOKED;
 static pid_t ppgrp, cmnd_pgrp, mon_pgrp;
 static sigset_t ttyblock;
 static struct io_buffer_list iobufs;
-static bool ignore_iolog_errors;
 
 static void del_io_events(bool nonblocking);
 static int exec_monitor(struct command_details *details, int backchannel);
@@ -219,8 +218,6 @@ log_ttyin(const char *buf, unsigned int n, struct io_buffer *iob)
                    /* Error: disable plugin's I/O function. */
                    plugin->u.io->log_ttyin = NULL;
                }
-               if (!ignore_iolog_errors)
-                   rval = false;
                break;
            }
        }
@@ -252,8 +249,6 @@ log_stdin(const char *buf, unsigned int n, struct io_buffer *iob)
                    /* Error: disable plugin's I/O function. */
                    plugin->u.io->log_stdin = NULL;
                }
-               if (!ignore_iolog_errors)
-                   rval = false;
                break;
            }
        }
@@ -285,8 +280,6 @@ log_ttyout(const char *buf, unsigned int n, struct io_buffer *iob)
                    /* Error: disable plugin's I/O function. */
                    plugin->u.io->log_ttyout = NULL;
                }
-               if (!ignore_iolog_errors)
-                   rval = false;
                break;
            }
        }
@@ -330,8 +323,6 @@ log_stdout(const char *buf, unsigned int n, struct io_buffer *iob)
                    /* Error: disable plugin's I/O function. */
                    plugin->u.io->log_stdout = NULL;
                }
-               if (!ignore_iolog_errors)
-                   rval = false;
                break;
            }
        }
@@ -375,8 +366,6 @@ log_stderr(const char *buf, unsigned int n, struct io_buffer *iob)
                    /* Error: disable plugin's I/O function. */
                    plugin->u.io->log_stderr = NULL;
                }
-               if (!ignore_iolog_errors)
-                   rval = false;
                break;
            }
        }
@@ -749,13 +738,6 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask)
     sigaddset(&ttyblock, SIGTTIN);
     sigaddset(&ttyblock, SIGTTOU);
 
-    /*
-     * The security policy may tell us to ignore errors from the
-     * I/O log functions.
-     */
-    if (!ISSET(details->flags, CD_IGNORE_IOLOG_ERRS))
-       ignore_iolog_errors = true;
-
     /*
      * Setup stdin/stdout/stderr for child, to be duped after forking.
      * In background mode there is no stdin.
index b711c0bd31e58317d5d0d5fcc3145ae0b24625c6..58085e9e73e5b0a44765b271ef52a8dcc9185d4e 100644 (file)
@@ -675,9 +675,6 @@ command_info_to_details(char * const info[], struct command_details *details)
                    break;
                }
                break;
-           case 'i':
-               SET_FLAG("ignore_iolog_errors=", CD_IGNORE_IOLOG_ERRS)
-               break;
            case 'l':
                SET_STRING("login_class=", login_class)
                break;
index 490f1d437f081040dddd7923aee7ad852167ddd6..e871acde4e019a2e41bf14072e47c3f8cc6fb703 100644 (file)
@@ -130,7 +130,6 @@ struct user_details {
 #define CD_SUDOEDIT_FOLLOW     0x10000
 #define CD_SUDOEDIT_CHECKDIR   0x20000
 #define CD_SET_GROUPS          0x40000
-#define CD_IGNORE_IOLOG_ERRS   0x80000
 
 struct preserved_fd {
     TAILQ_ENTRY(preserved_fd) entries;