Move the ignoring of I/O log plugin errors into the I/O log plugin

itself.
This commit is contained in:
Todd C. Miller
2016-08-17 14:38:00 -06:00
parent ed18d0d5f8
commit 3e4c7eed31
4 changed files with 39 additions and 41 deletions

View File

@@ -63,9 +63,12 @@ struct iolog_details {
struct group *runas_gr; struct group *runas_gr;
int lines; int lines;
int cols; int cols;
bool ignore_iolog_errors;
}; };
static struct iolog_details iolog_details;
static bool iolog_compress = false; static bool iolog_compress = false;
static bool warned = false;
static struct timeval last_time; static struct timeval last_time;
static unsigned int sessid_max = SESSID_MAX; 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) { if (lseek(fd, 0, SEEK_SET) == -1 || write(fd, buf, 7) != 7) {
#endif #endif
log_warning(SLOG_SEND_MAIL, N_("unable to write to %s"), pathbuf); log_warning(SLOG_SEND_MAIL, N_("unable to write to %s"), pathbuf);
warned = true;
goto done; goto done;
} }
rval = true; rval = true;
@@ -448,6 +452,11 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
} }
break; break;
case 'i': 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) { if (strncmp(*cur, "iolog_path=", sizeof("iolog_path=") - 1) == 0) {
details->iolog_path = *cur + sizeof("iolog_path=") - 1; details->iolog_path = *cur + sizeof("iolog_path=") - 1;
continue; 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[]) 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 sudo_conf_debug_file_list debug_files = TAILQ_HEAD_INITIALIZER(debug_files);
struct iolog_details details;
char pathbuf[PATH_MAX], sessid[7]; char pathbuf[PATH_MAX], sessid[7];
char *tofree = NULL; char *tofree = NULL;
char * const *cur; char * const *cur;
@@ -615,8 +623,6 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
if (argc == 0) if (argc == 0)
debug_return_int(true); debug_return_int(true);
memset(&details, 0, sizeof(details));
bindtextdomain("sudoers", LOCALEDIR); bindtextdomain("sudoers", LOCALEDIR);
/* Initialize the debug subsystem. */ /* 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. * 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; rval = false;
goto done; goto done;
} }
/* If no I/O log path defined we need to figure it out ourselves. */ /* 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. */ /* Get next session ID and convert it into a path. */
tofree = malloc(sizeof(_PATH_SUDO_IO_LOGDIR) + sizeof(sessid) + 2); tofree = malloc(sizeof(_PATH_SUDO_IO_LOGDIR) + sizeof(sessid) + 2);
if (tofree == NULL) { 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, snprintf(tofree + sizeof(_PATH_SUDO_IO_LOGDIR), sizeof(sessid) + 2,
"%c%c/%c%c/%c%c", sessid[0], sessid[1], sessid[2], sessid[3], "%c%c/%c%c/%c%c", sessid[0], sessid[1], sessid[2], sessid[3],
sessid[4], sessid[5]); 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 * Make local copy of I/O log path and create it, along with any
* intermediate subdirs. Calls mkdtemp() if iolog_path ends in XXXXXX. * 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)) if (len >= sizeof(pathbuf))
goto done; goto done;
/* Write log file with user and command details. */ /* Write log file with user and command details. */
if (gettimeofday(&last_time, NULL) == -1) if (gettimeofday(&last_time, NULL) == -1)
goto done; 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. */ /* Create the timing and I/O log files. */
for (i = 0; i < IOFD_MAX; i++) { for (i = 0; i < IOFD_MAX; i++) {
@@ -698,13 +704,17 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
done: done:
free(tofree); free(tofree);
if (details.runas_pw) if (iolog_details.runas_pw)
sudo_pw_delref(details.runas_pw); sudo_pw_delref(iolog_details.runas_pw);
if (details.runas_gr) if (iolog_details.runas_gr)
sudo_gr_delref(details.runas_gr); sudo_gr_delref(iolog_details.runas_gr);
sudo_freepwcache(); sudo_freepwcache();
sudo_freegrcache(); 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); debug_return_int(rval);
} }
@@ -730,8 +740,12 @@ sudoers_io_close(int exit_status, int error)
errstr = strerror(errno); errstr = strerror(errno);
} }
if (errstr != NULL) if (errstr != NULL && !warned) {
sudo_warnx(U_("unable to write to I/O log file: %s"), errstr); /* 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(); sudoers_debug_deregister();
@@ -756,7 +770,6 @@ static int
sudoers_io_log(const char *buf, unsigned int len, int idx) sudoers_io_log(const char *buf, unsigned int len, int idx)
{ {
struct timeval now, delay; struct timeval now, delay;
static bool warned = false;
const char *errstr = NULL; const char *errstr = NULL;
int rval = true; int rval = true;
debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN) debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN)
@@ -807,12 +820,19 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
last_time.tv_sec = now.tv_sec; last_time.tv_sec = now.tv_sec;
last_time.tv_usec = now.tv_usec; last_time.tv_usec = now.tv_usec;
if (rval == -1) {
if (errstr != NULL && !warned) { if (errstr != NULL && !warned) {
/* Only warn about I/O log file errors once. */ /* Only warn about I/O log file errors once. */
sudo_warnx(U_("unable to write to I/O log file: %s"), errstr); log_warning(SLOG_SEND_MAIL,
N_("unable to write to I/O log file: %s"), errstr);
warned = true; warned = true;
} }
/* Ignore errors if they occur if the policy says so. */
if (iolog_details.ignore_iolog_errors)
rval = true;
}
debug_return_int(rval); debug_return_int(rval);
} }

View File

@@ -89,7 +89,6 @@ static int ttymode = TERM_COOKED;
static pid_t ppgrp, cmnd_pgrp, mon_pgrp; static pid_t ppgrp, cmnd_pgrp, mon_pgrp;
static sigset_t ttyblock; static sigset_t ttyblock;
static struct io_buffer_list iobufs; static struct io_buffer_list iobufs;
static bool ignore_iolog_errors;
static void del_io_events(bool nonblocking); static void del_io_events(bool nonblocking);
static int exec_monitor(struct command_details *details, int backchannel); 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. */ /* Error: disable plugin's I/O function. */
plugin->u.io->log_ttyin = NULL; plugin->u.io->log_ttyin = NULL;
} }
if (!ignore_iolog_errors)
rval = false;
break; break;
} }
} }
@@ -252,8 +249,6 @@ log_stdin(const char *buf, unsigned int n, struct io_buffer *iob)
/* Error: disable plugin's I/O function. */ /* Error: disable plugin's I/O function. */
plugin->u.io->log_stdin = NULL; plugin->u.io->log_stdin = NULL;
} }
if (!ignore_iolog_errors)
rval = false;
break; break;
} }
} }
@@ -285,8 +280,6 @@ log_ttyout(const char *buf, unsigned int n, struct io_buffer *iob)
/* Error: disable plugin's I/O function. */ /* Error: disable plugin's I/O function. */
plugin->u.io->log_ttyout = NULL; plugin->u.io->log_ttyout = NULL;
} }
if (!ignore_iolog_errors)
rval = false;
break; break;
} }
} }
@@ -330,8 +323,6 @@ log_stdout(const char *buf, unsigned int n, struct io_buffer *iob)
/* Error: disable plugin's I/O function. */ /* Error: disable plugin's I/O function. */
plugin->u.io->log_stdout = NULL; plugin->u.io->log_stdout = NULL;
} }
if (!ignore_iolog_errors)
rval = false;
break; break;
} }
} }
@@ -375,8 +366,6 @@ log_stderr(const char *buf, unsigned int n, struct io_buffer *iob)
/* Error: disable plugin's I/O function. */ /* Error: disable plugin's I/O function. */
plugin->u.io->log_stderr = NULL; plugin->u.io->log_stderr = NULL;
} }
if (!ignore_iolog_errors)
rval = false;
break; break;
} }
} }
@@ -749,13 +738,6 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask)
sigaddset(&ttyblock, SIGTTIN); sigaddset(&ttyblock, SIGTTIN);
sigaddset(&ttyblock, SIGTTOU); 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. * Setup stdin/stdout/stderr for child, to be duped after forking.
* In background mode there is no stdin. * In background mode there is no stdin.

View File

@@ -675,9 +675,6 @@ command_info_to_details(char * const info[], struct command_details *details)
break; break;
} }
break; break;
case 'i':
SET_FLAG("ignore_iolog_errors=", CD_IGNORE_IOLOG_ERRS)
break;
case 'l': case 'l':
SET_STRING("login_class=", login_class) SET_STRING("login_class=", login_class)
break; break;

View File

@@ -130,7 +130,6 @@ struct user_details {
#define CD_SUDOEDIT_FOLLOW 0x10000 #define CD_SUDOEDIT_FOLLOW 0x10000
#define CD_SUDOEDIT_CHECKDIR 0x20000 #define CD_SUDOEDIT_CHECKDIR 0x20000
#define CD_SET_GROUPS 0x40000 #define CD_SET_GROUPS 0x40000
#define CD_IGNORE_IOLOG_ERRS 0x80000
struct preserved_fd { struct preserved_fd {
TAILQ_ENTRY(preserved_fd) entries; TAILQ_ENTRY(preserved_fd) entries;