]> granicus.if.org Git - sudo/commitdiff
Give the policy module fine-grained control over what the I/O plugin
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 21 Dec 2010 22:43:18 +0000 (17:43 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 21 Dec 2010 22:43:18 +0000 (17:43 -0500)
logs.

doc/sudo_plugin.pod
plugins/sudoers/iolog.c
plugins/sudoers/sudoers.c

index 701f82a45327b4f1b9c94dda6fa4d8a5103cb7d6..89536ed3a6e85e5291851c1cd7364435d4e5689f 100644 (file)
@@ -535,15 +535,50 @@ enable I<sudoedit> when the user attempts to run an editor.
 If specified, B<sudo> will close all files descriptors with a value
 of I<number> or higher.
 
+=item iolog_stdin=bool
+
+Set to true if the I/O logging plugins, if any, should log the
+standard input if it is not connected to a terminal device.  This
+is a hint to the I/O logging plugin which may choose to ignore it.
+
+=item iolog_stdout=bool
+
+Set to true if the I/O logging plugins, if any, should log the
+standard output if it is not connected to a terminal device.  This
+is a hint to the I/O logging plugin which may choose to ignore it.
+
+=item iolog_stderr=bool
+
+Set to true if the I/O logging plugins, if any, should log the
+standard error if it is not connected to a terminal device.  This
+is a hint to the I/O logging plugin which may choose to ignore it.
+
+=item iolog_ttyin=bool
+
+Set to true if the I/O logging plugins, if any, should log all
+terminal input.  This only includes input typed by the user and not
+from a pipe or redirected from a file.  This is a hint to the I/O
+logging plugin which may choose to ignore it.
+
+=item iolog_ttyout=bool
+
+Set to true if the I/O logging plugins, if any, should log all
+terminal output.  This only includes output to the screen, not
+output to a pipe or file.  This is a hint to the I/O logging plugin
+which may choose to ignore it.
+
 =item iolog_dir=string
 
-Fully qualified path to the directory in which I/O logs are
-to be stored.  This value may be used by the I/O logging plugin.
+Fully qualified path to the directory in which I/O logs are to be
+stored.  This is a hint to the I/O logging plugin which may choose
+to ignore it.  If no I/O logging plugin is loaded, this setting has
+no effect.
 
 =item iolog_file=string
 
 File name to use when I/O logging is enabled, relative to I<iolog_dir>.
-This value may be used by the I/O logging plugin.
+This is a hint to the I/O logging plugin which may choose to ignore
+it.  If no I/O logging plugin is loaded, this setting has no effect.
 
 =item use_pty=bool
 
index 955e88087b88fe68c2a88237275e07f8c4c96690..98a642b056e5e3c9d39af377270d958f99ca5d89 100644 (file)
@@ -246,10 +246,10 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     int argc, char * const argv[], char * const user_env[])
 {
     char pathbuf[PATH_MAX];
-    const char *iolog_dir, *iolog_file = NULL;
+    const char *iolog_dir, *iolog_file;
     char * const *cur;
     FILE *io_logfile;
-    int len;
+    int len, iolog_stdin, iolog_stdout, iolog_stderr, iolog_ttyin, iolog_ttyout;
 
     if (!sudo_conv)
        sudo_conv = conversation;
@@ -261,26 +261,60 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
        return TRUE;
 
     /*
-     * Pull iolog_dir and iolog_file out of command_info, if present,
-     * falling back to policy module info if not.
+     * Pull iolog settings out of command_info, if any.
      */
     iolog_dir = def_iolog_dir;
+    iolog_file = sudo_user.sessid;
+    iolog_stdin = iolog_ttyin = def_log_input;
+    iolog_stdout = iolog_stderr = iolog_ttyout = def_log_output;
     for (cur = command_info; *cur != NULL; cur++) {
        if (**cur != 'i')
            continue;
        if (strncmp(*cur, "iolog_file=", sizeof("iolog_file=") - 1) == 0) {
            iolog_file = *cur + sizeof("iolog_file=") - 1;
-       } else if (strncmp(*cur, "iolog_dir=", sizeof("iolog_dir=") - 1) == 0) {
+           continue;
+       }
+       if (strncmp(*cur, "iolog_dir=", sizeof("iolog_dir=") - 1) == 0) {
            iolog_dir = *cur + sizeof("iolog_dir=") - 1;
+           continue;
+       }
+       if (strncmp(*cur, "iolog_stdin=", sizeof("iolog_stdin=") - 1) == 0) {
+           if (atobool(*cur + sizeof("iolog_stdin=") - 1) == TRUE)
+               iolog_stdin = TRUE;
+           continue;
+       }
+       if (strncmp(*cur, "iolog_stdout=", sizeof("iolog_stdout=") - 1) == 0) {
+           if (atobool(*cur + sizeof("iolog_stdout=") - 1) == TRUE)
+               iolog_stdout = TRUE;
+           continue;
+       }
+       if (strncmp(*cur, "iolog_stderr=", sizeof("iolog_stderr=") - 1) == 0) {
+           if (atobool(*cur + sizeof("iolog_stderr=") - 1) == TRUE)
+               iolog_stderr = TRUE;
+           continue;
+       }
+       if (strncmp(*cur, "iolog_ttyin=", sizeof("iolog_ttyin=") - 1) == 0) {
+           if (atobool(*cur + sizeof("iolog_ttyin=") - 1) == TRUE)
+               iolog_ttyin = TRUE;
+           continue;
+       }
+       if (strncmp(*cur, "iolog_ttyout=", sizeof("iolog_ttyout=") - 1) == 0) {
+           if (atobool(*cur + sizeof("iolog_ttyout=") - 1) == TRUE)
+               iolog_ttyout = TRUE;
+           continue;
        }
     }
+    /* Did policy module disable I/O logging? */
+    if (!iolog_stdin && !iolog_ttyin && !iolog_stdout && !iolog_stderr &&
+       !iolog_ttyout)
+       return FALSE;
 
     /* If no I/O log file defined there is nothing to do. */
     if (iolog_file == NULL)
        return FALSE;
 
     /*
-     * Build a path containing the session id split into two-digit subdirs,
+     * Build a path containing the session ID split into two-digit subdirs,
      * so ID 000001 becomes /var/log/sudo-io/00/00/01.
      */
     len = build_idpath(iolog_dir, iolog_file, pathbuf, sizeof(pathbuf));
@@ -301,42 +335,46 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
     if (io_fds[IOFD_TIMING].v == NULL)
        log_error(USE_ERRNO, "Can't create %s", pathbuf);
 
-    if (def_log_input) {
+    if (iolog_ttyin) {
        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);
-
+    } else {
+       sudoers_io.log_ttyin = NULL;
+    }
+    if (iolog_stdin) {
        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);
     } else {
-       /* No input logging. */
-       sudoers_io.log_ttyin = NULL;
        sudoers_io.log_stdin = NULL;
     }
-
-    if (def_log_output) {
+    if (iolog_ttyout) {
        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);
-
+    } else {
+       sudoers_io.log_ttyout = NULL;
+    }
+    if (iolog_stdout) {
        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);
-
+    } else {
+       sudoers_io.log_stdout = NULL;
+    }
+    if (iolog_stderr) {
        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);
     } else {
-       /* No output logging. */
-       sudoers_io.log_ttyout = NULL;
-       sudoers_io.log_stdout = NULL;
        sudoers_io.log_stderr = NULL;
     }
 
     gettimeofday(&last_time, NULL);
 
     /* XXX - log more stuff?  window size? environment? */
+    /* XXX - don't rely on policy module globals */
     fprintf(io_logfile, "%ld:%s:%s:%s:%s\n", (long)last_time.tv_sec, user_name,
         runas_pw->pw_name, runas_gr ? runas_gr->gr_name : "", user_tty);
     fprintf(io_logfile, "%s\n", user_cwd);
index bdc32296abd368c53d7664ee854eeddee0c3bcc2..08933fca44362bd183542474b522b477f49b13c8 100644 (file)
@@ -499,10 +499,19 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
            validate_env_vars(sudo_user.env_vars);
     }
 
-    if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output)) {
+    if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT)) && (def_log_input || def_log_output)) {
        io_nextid();
        command_info[info_len++] = fmt_string("iolog_dir", def_iolog_dir);
        command_info[info_len++] = fmt_string("iolog_file", sudo_user.sessid);
+       if (def_log_input) {
+           command_info[info_len++] = estrdup("iolog_stdin=true");
+           command_info[info_len++] = estrdup("iolog_ttyin=true");
+       }
+       if (def_log_output) {
+           command_info[info_len++] = estrdup("iolog_stdout=true");
+           command_info[info_len++] = estrdup("iolog_stderr=true");
+           command_info[info_len++] = estrdup("iolog_ttyout=true");
+       }
     }
 
     log_allowed(validated);