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;
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);

View 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.

View 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;

View 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;