Break sudoers transcript feature up into log_input and log_output.

This commit is contained in:
Todd C. Miller
2010-05-30 10:31:38 -04:00
parent 1a217bcc22
commit 2dd29bf64d
18 changed files with 515 additions and 444 deletions

13
INSTALL
View File

@@ -557,11 +557,10 @@ The following options are also configurable at runtime:
prompt as an argument and print the received password to prompt as an argument and print the received password to
the standard output. the standard output.
--with-transcript[=DIR] --with-iologdir[=DIR]
By default, sudo stores transcript files in either By default, sudo stores I/O log files in either /var/log/sudo-io,
/var/log/sudo-transcript, /var/adm/sudo-transcript, or /var/adm/sudo-io, or /usr/log/sudo-io. If this option is
/usr/log/sudo-transcript. If this option is specified, specified, I/O logs will be stored in the indicated directory
transcripts will be stored in the indicated directory
instead. instead.
--disable-authentication --disable-authentication
@@ -607,13 +606,13 @@ The following options are also configurable at runtime:
--enable-zlib[=DIR] --enable-zlib[=DIR]
Enable the use of the zlib compress library when storing Enable the use of the zlib compress library when storing
transcript files. If specified, DIR is the base directory I/O log files. If specified, DIR is the base directory
containing the zlib include and lib directories. By default containing the zlib include and lib directories. By default
zlib is used if it is found on the system. zlib is used if it is found on the system.
--disable-zlib --disable-zlib
Disable the use of the zlib compress library when storing Disable the use of the zlib compress library when storing
transcript files. I/O log files.
Shadow password and C2 support Shadow password and C2 support
============================== ==============================

View File

@@ -8,9 +8,10 @@ What's new in Sudo 1.8.0?
What's new in Sudo 1.7.3? What's new in Sudo 1.7.3?
* Support for logging a transcript of the command being run. * Support for logging I/O for the command being run.
For more information, see the documentation for the "transcript" For more information, see the documentation for the "log_input"
Defaults option in the sudoers manual and the sudoreplay manual. and "log_output" Defaults options in the sudoers manual. Also
see the sudoreplay manual for how to replay I/O log sessions.
* The passwd_timeout and timestamp_timeout options may now be * The passwd_timeout and timestamp_timeout options may now be
specified as floating point numbers for more granular timeout specified as floating point numbers for more granular timeout

20
aclocal.m4 vendored
View File

@@ -158,22 +158,22 @@ fi
])dnl ])dnl
dnl dnl
dnl Where the transcript files go, use /var/log/sudo-transcript if dnl Where the I/O log files go, use /var/log/sudo-io if
dnl /var/log exists, else /{var,usr}/adm/sudo-transcript dnl /var/log exists, else /{var,usr}/adm/sudo-io
dnl dnl
AC_DEFUN(SUDO_TRANSCRIPT, [ AC_DEFUN(SUDO_IO_LOGDIR, [
AC_MSG_CHECKING(for transcript dir location) AC_MSG_CHECKING(for I/O log dir location)
if test "${with_transcript-yes}" != "yes"; then if test "${with_iologdir-yes}" != "yes"; then
: :
elif test -d "/var/log"; then elif test -d "/var/log"; then
with_transcript="/var/log/sudo-transcript" with_iologdir="/var/log/sudo-io"
elif test -d "/var/adm"; then elif test -d "/var/adm"; then
with_transcript="/var/adm/sudo-transcript" with_iologdir="/var/adm/sudo-io"
else else
with_transcript="/usr/adm/sudo-transcript" with_iologdir="/usr/adm/sudo-io"
fi fi
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_TRANSCRIPT, "$with_transcript") SUDO_DEFINE_UNQUOTED(_PATH_SUDO_IO_LOGDIR, "$with_iologdir")
AC_MSG_RESULT($with_transcript) AC_MSG_RESULT($with_iologdir)
])dnl ])dnl
dnl dnl

30
configure vendored
View File

@@ -945,7 +945,7 @@ with_passprompt
with_badpass_message with_badpass_message
with_fqdn with_fqdn
with_timedir with_timedir
with_transcript with_iologdir
with_sendmail with_sendmail
with_sudoers_mode with_sudoers_mode
with_sudoers_uid with_sudoers_uid
@@ -1699,7 +1699,7 @@ Optional Packages:
--with-badpass-message message the user sees when the password is wrong --with-badpass-message message the user sees when the password is wrong
--with-fqdn expect fully qualified hosts in sudoers --with-fqdn expect fully qualified hosts in sudoers
--with-timedir path to the sudo timestamp dir --with-timedir path to the sudo timestamp dir
--with-transcript=DIR directory to store sudo transcript files in --with-iologdir=DIR directory to store sudo I/O log files in
--with-sendmail set path to sendmail --with-sendmail set path to sendmail
--without-sendmail do not send mail at all --without-sendmail do not send mail at all
--with-sudoers-mode mode of sudoers file (defaults to 0440) --with-sudoers-mode mode of sudoers file (defaults to 0440)
@@ -3665,11 +3665,11 @@ fi
# Check whether --with-transcript was given. # Check whether --with-iologdir was given.
if test "${with_transcript+set}" = set; then : if test "${with_iologdir+set}" = set; then :
withval=$with_transcript; case $with_transcript in withval=$with_iologdir; case $with_iologdir in
yes) ;; yes) ;;
no) as_fn_error "\"--without-transcript not supported.\"" "$LINENO" 5 no) as_fn_error "\"--without-iologfir not supported.\"" "$LINENO" 5
;; ;;
esac esac
fi fi
@@ -17935,23 +17935,23 @@ EOF
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for transcript dir location" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for I/O log dir location" >&5
$as_echo_n "checking for transcript dir location... " >&6; } $as_echo_n "checking for I/O log dir location... " >&6; }
if test "${with_transcript-yes}" != "yes"; then if test "${with_iologdir-yes}" != "yes"; then
: :
elif test -d "/var/log"; then elif test -d "/var/log"; then
with_transcript="/var/log/sudo-transcript" with_iologdir="/var/log/sudo-io"
elif test -d "/var/adm"; then elif test -d "/var/adm"; then
with_transcript="/var/adm/sudo-transcript" with_iologdir="/var/adm/sudo-io"
else else
with_transcript="/usr/adm/sudo-transcript" with_iologdir="/usr/adm/sudo-io"
fi fi
cat >>confdefs.h <<EOF cat >>confdefs.h <<EOF
#define _PATH_SUDO_TRANSCRIPT "$with_transcript" #define _PATH_SUDO_IO_LOGDIR "$with_iologdir"
EOF EOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_transcript" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_iologdir" >&5
$as_echo "$with_transcript" >&6; } $as_echo "$with_iologdir" >&6; }
case "$with_passwd" in case "$with_passwd" in

View File

@@ -704,11 +704,11 @@ AC_ARG_WITH(timedir, [AS_HELP_STRING([--with-timedir], [path to the sudo timesta
;; ;;
esac]) esac])
AC_ARG_WITH(transcript, [AS_HELP_STRING([--with-transcript=DIR], [directory AC_ARG_WITH(iologdir, [AS_HELP_STRING([--with-iologdir=DIR], [directory
to store sudo transcript files in])], to store sudo I/O log files in])],
[case $with_transcript in [case $with_iologdir in
yes) ;; yes) ;;
no) AC_MSG_ERROR(["--without-transcript not supported."]) no) AC_MSG_ERROR(["--without-iologfir not supported."])
;; ;;
esac]) esac])
@@ -2663,11 +2663,11 @@ if test -n "$blibpath"; then
fi fi
dnl dnl
dnl Check for log file, timestamp and transcript locations dnl Check for log file, timestamp and iolog locations
dnl dnl
SUDO_LOGFILE SUDO_LOGFILE
SUDO_TIMEDIR SUDO_TIMEDIR
SUDO_TRANSCRIPT SUDO_IOLOGDIR
dnl dnl
dnl Use passwd (and secureware) auth modules? dnl Use passwd (and secureware) auth modules?

View File

@@ -74,12 +74,12 @@
#endif /* _PATH_SUDO_TIMEDIR */ #endif /* _PATH_SUDO_TIMEDIR */
/* /*
* Where to put the session files. Defaults to /var/log/sudo-session, * Where to put the I/O log files. Defaults to /var/log/sudo-io,
* /var/adm/sudo-session or /usr/adm/sudo-session depending on what exists. * /var/adm/sudo-io or /usr/adm/sudo-io depending on what exists.
*/ */
#ifndef _PATH_SUDO_TRANSCRIPT #ifndef _PATH_SUDO_IO_LOGDIR
#undef _PATH_SUDO_TRANSCRIPT #undef _PATH_SUDO_IO_LOGDIR
#endif /* _PATH_SUDO_TRANSCRIPT */ #endif /* _PATH_SUDO_IO_LOGDIR */
/* /*
* Where to put the sudo log file when logging to a file. Defaults to * Where to put the sudo log file when logging to a file. Defaults to

View File

@@ -315,12 +315,16 @@ struct sudo_defs_types sudo_defs_table[] = {
"The umask specified in sudoers will override the user's, even if it is more permissive", "The umask specified in sudoers will override the user's, even if it is more permissive",
NULL, NULL,
}, { }, {
"transcript", T_FLAG, "log_input", T_FLAG,
"Log a transcript of the command being run", "Log user's input for the command being run",
NULL, NULL,
}, { }, {
"compress_transcript", T_FLAG, "log_output", T_FLAG,
"Compress session transcripts with zlib", "Log the output of the command being run",
NULL,
}, {
"compress_io", T_FLAG,
"Compress I/O logs using zlib",
NULL, NULL,
}, { }, {
NULL, 0, NULL NULL, 0, NULL

View File

@@ -144,10 +144,12 @@
#define I_FAST_GLOB 71 #define I_FAST_GLOB 71
#define def_umask_override (sudo_defs_table[72].sd_un.flag) #define def_umask_override (sudo_defs_table[72].sd_un.flag)
#define I_UMASK_OVERRIDE 72 #define I_UMASK_OVERRIDE 72
#define def_transcript (sudo_defs_table[73].sd_un.flag) #define def_log_input (sudo_defs_table[73].sd_un.flag)
#define I_TRANSCRIPT 73 #define I_LOG_INPUT 73
#define def_compress_transcript (sudo_defs_table[74].sd_un.flag) #define def_log_output (sudo_defs_table[74].sd_un.flag)
#define I_COMPRESS_TRANSCRIPT 74 #define I_LOG_OUTPUT 74
#define def_compress_io (sudo_defs_table[75].sd_un.flag)
#define I_COMPRESS_IO 75
enum def_tupple { enum def_tupple {
never, never,

View File

@@ -232,9 +232,12 @@ fast_glob
umask_override umask_override
T_FLAG T_FLAG
"The umask specified in sudoers will override the user's, even if it is more permissive" "The umask specified in sudoers will override the user's, even if it is more permissive"
transcript log_input
T_FLAG T_FLAG
"Log a transcript of the command being run" "Log user's input for the command being run"
compress_transcript log_output
T_FLAG T_FLAG
"Compress session transcripts with zlib" "Log the output of the command being run"
compress_io
T_FLAG
"Compress I/O logs using zlib"

View File

@@ -477,7 +477,7 @@ init_defaults(void)
def_passwd_timeout = PASSWORD_TIMEOUT; def_passwd_timeout = PASSWORD_TIMEOUT;
def_passwd_tries = TRIES_FOR_PASSWORD; def_passwd_tries = TRIES_FOR_PASSWORD;
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
def_compress_transcript = TRUE; def_compress_io = TRUE;
#endif #endif
/* Now do the strings */ /* Now do the strings */

File diff suppressed because it is too large Load Diff

View File

@@ -16,17 +16,19 @@
#define EXEC 272 #define EXEC 272
#define SETENV 273 #define SETENV 273
#define NOSETENV 274 #define NOSETENV 274
#define TRANSCRIPT 275 #define LOG_INPUT 275
#define NOTRANSCRIPT 276 #define NOLOG_INPUT 276
#define ALL 277 #define LOG_OUTPUT 277
#define COMMENT 278 #define NOLOG_OUTPUT 278
#define HOSTALIAS 279 #define ALL 279
#define CMNDALIAS 280 #define COMMENT 280
#define USERALIAS 281 #define HOSTALIAS 281
#define RUNASALIAS 282 #define CMNDALIAS 282
#define ERROR 283 #define USERALIAS 283
#define TYPE 284 #define RUNASALIAS 284
#define ROLE 285 #define ERROR 285
#define TYPE 286
#define ROLE 287
#ifndef YYSTYPE_DEFINED #ifndef YYSTYPE_DEFINED
#define YYSTYPE_DEFINED #define YYSTYPE_DEFINED
typedef union { typedef union {

View File

@@ -142,8 +142,10 @@ yyerror(s)
%token <tok> EXEC /* don't preload dummy execve() */ %token <tok> EXEC /* don't preload dummy execve() */
%token <tok> SETENV /* user may set environment for cmnd */ %token <tok> SETENV /* user may set environment for cmnd */
%token <tok> NOSETENV /* user may not set environment */ %token <tok> NOSETENV /* user may not set environment */
%token <tok> TRANSCRIPT /* log a transcript of the cmnd */ %token <tok> LOG_INPUT /* log user's cmnd input */
%token <tok> NOTRANSCRIPT /* don't log a transcript of the cmnd */ %token <tok> NOLOG_INPUT /* don't log user's cmnd input */
%token <tok> LOG_OUTPUT /* log cmnd output */
%token <tok> NOLOG_OUTPUT /* don't log cmnd output */
%token <tok> ALL /* ALL keyword */ %token <tok> ALL /* ALL keyword */
%token <tok> COMMENT /* comment and/or carriage return */ %token <tok> COMMENT /* comment and/or carriage return */
%token <tok> HOSTALIAS /* Host_Alias keyword */ %token <tok> HOSTALIAS /* Host_Alias keyword */
@@ -315,8 +317,10 @@ cmndspeclist : cmndspec
if ($3->tags.setenv == UNSPEC && if ($3->tags.setenv == UNSPEC &&
$3->prev->tags.setenv != IMPLIED) $3->prev->tags.setenv != IMPLIED)
$3->tags.setenv = $3->prev->tags.setenv; $3->tags.setenv = $3->prev->tags.setenv;
if ($3->tags.transcript == UNSPEC) if ($3->tags.log_input == UNSPEC)
$3->tags.transcript = $3->prev->tags.transcript; $3->tags.log_input = $3->prev->tags.log_input;
if ($3->tags.log_output == UNSPEC)
$3->tags.log_output = $3->prev->tags.log_output;
if ((tq_empty(&$3->runasuserlist) && if ((tq_empty(&$3->runasuserlist) &&
tq_empty(&$3->runasgrouplist)) && tq_empty(&$3->runasgrouplist)) &&
(!tq_empty(&$3->prev->runasuserlist) || (!tq_empty(&$3->prev->runasuserlist) ||
@@ -422,7 +426,8 @@ runaslist : userlist {
; ;
cmndtag : /* empty */ { cmndtag : /* empty */ {
$$.nopasswd = $$.noexec = $$.setenv = $$.transcript = UNSPEC; $$.nopasswd = $$.noexec = $$.setenv =
$$.log_input = $$.log_output = UNSPEC;
} }
| cmndtag NOPASSWD { | cmndtag NOPASSWD {
$$.nopasswd = TRUE; $$.nopasswd = TRUE;
@@ -442,11 +447,17 @@ cmndtag : /* empty */ {
| cmndtag NOSETENV { | cmndtag NOSETENV {
$$.setenv = FALSE; $$.setenv = FALSE;
} }
| cmndtag TRANSCRIPT { | cmndtag LOG_INPUT {
$$.transcript = TRUE; $$.log_input = TRUE;
} }
| cmndtag NOTRANSCRIPT { | cmndtag NOLOG_INPUT {
$$.transcript = FALSE; $$.log_input = FALSE;
}
| cmndtag LOG_OUTPUT {
$$.log_output = TRUE;
}
| cmndtag NOLOG_OUTPUT {
$$.log_output = FALSE;
} }
; ;

View File

@@ -91,20 +91,20 @@ io_nextid(void)
char pathbuf[PATH_MAX]; char pathbuf[PATH_MAX];
/* /*
* Create _PATH_SUDO_TRANSCRIPT if it doesn't already exist. * Create _PATH_SUDO_IO_LOGDIR if it doesn't already exist.
*/ */
if (stat(_PATH_SUDO_TRANSCRIPT, &sb) != 0) { if (stat(_PATH_SUDO_IO_LOGDIR, &sb) != 0) {
if (mkdir(_PATH_SUDO_TRANSCRIPT, S_IRWXU) != 0) if (mkdir(_PATH_SUDO_IO_LOGDIR, S_IRWXU) != 0)
log_error(USE_ERRNO, "Can't mkdir %s", _PATH_SUDO_TRANSCRIPT); log_error(USE_ERRNO, "Can't mkdir %s", _PATH_SUDO_IO_LOGDIR);
} else if (!S_ISDIR(sb.st_mode)) { } else if (!S_ISDIR(sb.st_mode)) {
log_error(0, "%s exists but is not a directory (0%o)", log_error(0, "%s exists but is not a directory (0%o)",
_PATH_SUDO_TRANSCRIPT, (unsigned int) sb.st_mode); _PATH_SUDO_IO_LOGDIR, (unsigned int) sb.st_mode);
} }
/* /*
* Open sequence file * Open sequence file
*/ */
len = snprintf(pathbuf, sizeof(pathbuf), "%s/seq", _PATH_SUDO_TRANSCRIPT); len = snprintf(pathbuf, sizeof(pathbuf), "%s/seq", _PATH_SUDO_IO_LOGDIR);
if (len <= 0 || len >= sizeof(pathbuf)) { if (len <= 0 || len >= sizeof(pathbuf)) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
log_error(USE_ERRNO, "%s/seq", pathbuf); log_error(USE_ERRNO, "%s/seq", pathbuf);
@@ -158,12 +158,12 @@ build_idpath(char *pathbuf, size_t pathsize)
/* /*
* Path is of the form /var/log/sudo-session/00/00/01. * Path is of the form /var/log/sudo-session/00/00/01.
*/ */
len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", _PATH_SUDO_TRANSCRIPT, len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", _PATH_SUDO_IO_LOGDIR,
sudo_user.sessid[0], sudo_user.sessid[1], sudo_user.sessid[2], sudo_user.sessid[0], sudo_user.sessid[1], sudo_user.sessid[2],
sudo_user.sessid[3], sudo_user.sessid[4], sudo_user.sessid[5]); sudo_user.sessid[3], sudo_user.sessid[4], sudo_user.sessid[5]);
if (len <= 0 && len >= pathsize) { if (len <= 0 && len >= pathsize) {
errno = ENAMETOOLONG; errno = ENAMETOOLONG;
log_error(USE_ERRNO, "%s/%s", _PATH_SUDO_TRANSCRIPT, sudo_user.sessid); log_error(USE_ERRNO, "%s/%s", _PATH_SUDO_IO_LOGDIR, sudo_user.sessid);
} }
/* /*
@@ -223,7 +223,7 @@ static sudoers_io_open(unsigned int version, sudo_conv_t conversation,
if (argc == 0) if (argc == 0)
return TRUE; return TRUE;
if (!def_transcript) if (!def_log_input && !def_log_output)
return FALSE; return FALSE;
/* /*
@@ -244,27 +244,27 @@ static sudoers_io_open(unsigned int version, sudo_conv_t conversation,
if (io_logfile == NULL) if (io_logfile == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
io_fds[IOFD_TIMING].v = open_io_fd(pathbuf, len, "/timing", def_compress_transcript); io_fds[IOFD_TIMING].v = open_io_fd(pathbuf, len, "/timing", def_compress_io);
if (io_fds[IOFD_TIMING].v == NULL) if (io_fds[IOFD_TIMING].v == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
io_fds[IOFD_TTYIN].v = open_io_fd(pathbuf, len, "/ttyin", def_compress_transcript); io_fds[IOFD_TTYIN].v = open_io_fd(pathbuf, len, "/ttyin", def_compress_io);
if (io_fds[IOFD_TTYIN].v == NULL) if (io_fds[IOFD_TTYIN].v == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
io_fds[IOFD_TTYOUT].v = open_io_fd(pathbuf, len, "/ttyout", def_compress_transcript); io_fds[IOFD_TTYOUT].v = open_io_fd(pathbuf, len, "/ttyout", def_compress_io);
if (io_fds[IOFD_TTYOUT].v == NULL) if (io_fds[IOFD_TTYOUT].v == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
io_fds[IOFD_STDIN].v = open_io_fd(pathbuf, len, "/stdin", def_compress_transcript); io_fds[IOFD_STDIN].v = open_io_fd(pathbuf, len, "/stdin", def_compress_io);
if (io_fds[IOFD_STDIN].v == NULL) if (io_fds[IOFD_STDIN].v == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
io_fds[IOFD_STDOUT].v = open_io_fd(pathbuf, len, "/stdout", def_compress_transcript); io_fds[IOFD_STDOUT].v = open_io_fd(pathbuf, len, "/stdout", def_compress_io);
if (io_fds[IOFD_STDOUT].v == NULL) if (io_fds[IOFD_STDOUT].v == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
io_fds[IOFD_STDERR].v = open_io_fd(pathbuf, len, "/stderr", def_compress_transcript); io_fds[IOFD_STDERR].v = open_io_fd(pathbuf, len, "/stderr", def_compress_io);
if (io_fds[IOFD_STDERR].v == NULL) if (io_fds[IOFD_STDERR].v == NULL)
log_error(USE_ERRNO, "Can't create %s", pathbuf); log_error(USE_ERRNO, "Can't create %s", pathbuf);
@@ -297,7 +297,7 @@ static sudoers_io_close(int exit_status, int error)
for (i = 0; i < IOFD_MAX; i++) { for (i = 0; i < IOFD_MAX; i++) {
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
if (def_compress_transcript) if (def_compress_io)
gzclose(io_fds[i].g); gzclose(io_fds[i].g);
else else
#endif #endif
@@ -336,14 +336,14 @@ sudoers_io_log(const char *buf, unsigned int len, int idx)
sigprocmask(SIG_BLOCK, &ttyblock, &omask); sigprocmask(SIG_BLOCK, &ttyblock, &omask);
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
if (def_compress_transcript) if (def_compress_io)
gzwrite(io_fds[idx].g, buf, len); gzwrite(io_fds[idx].g, buf, len);
else else
#endif #endif
fwrite(buf, 1, len, io_fds[idx].f); fwrite(buf, 1, len, io_fds[idx].f);
timersub(&now, &last_time, &tv); timersub(&now, &last_time, &tv);
#ifdef HAVE_ZLIB #ifdef HAVE_ZLIB
if (def_compress_transcript) if (def_compress_io)
gzprintf(io_fds[IOFD_TIMING].g, "%d %f %d\n", idx, gzprintf(io_fds[IOFD_TIMING].g, "%d %f %d\n", idx,
tv.tv_sec + ((double)tv.tv_usec / 1000000), len); tv.tv_sec + ((double)tv.tv_usec / 1000000), len);
else else

View File

@@ -243,8 +243,10 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
def_noexec = tags->noexec; def_noexec = tags->noexec;
if (tags->setenv != UNSPEC) if (tags->setenv != UNSPEC)
def_setenv = tags->setenv; def_setenv = tags->setenv;
if (tags->transcript != UNSPEC) if (tags->log_input != UNSPEC)
def_transcript = tags->transcript; def_log_input = tags->log_input;
if (tags->log_output != UNSPEC)
def_log_output = tags->log_output;
} }
} else if (match == DENY) { } else if (match == DENY) {
SET(validated, VALIDATE_NOT_OK); SET(validated, VALIDATE_NOT_OK);
@@ -284,10 +286,15 @@ sudo_file_append_cmnd(struct cmndspec *cs, struct cmndtag *tags,
"PASSWD: ", NULL); "PASSWD: ", NULL);
tags->nopasswd = cs->tags.nopasswd; tags->nopasswd = cs->tags.nopasswd;
} }
if (TAG_CHANGED(transcript)) { if (TAG_CHANGED(log_input)) {
lbuf_append(lbuf, cs->tags.transcript ? "SCRIPT: " : lbuf_append(lbuf, cs->tags.log_input ? "LOG_INPUT: " :
"NOSCRIPT: ", NULL); "NOLOG_INPUT: ", NULL);
tags->transcript = cs->tags.transcript; tags->log_input = cs->tags.log_input;
}
if (TAG_CHANGED(log_output)) {
lbuf_append(lbuf, cs->tags.log_output ? "LOG_OUTPUT: " :
"NOLOG_OUTPUT: ", NULL);
tags->log_output = cs->tags.log_output;
} }
m = cs->cmnd; m = cs->cmnd;
print_member(lbuf, m->name, m->type, m->negated, print_member(lbuf, m->name, m->type, m->negated,
@@ -310,7 +317,8 @@ sudo_file_display_priv_short(struct passwd *pw, struct userspec *us,
tags.noexec = UNSPEC; tags.noexec = UNSPEC;
tags.setenv = UNSPEC; tags.setenv = UNSPEC;
tags.nopasswd = UNSPEC; tags.nopasswd = UNSPEC;
tags.transcript = UNSPEC; tags.log_input = UNSPEC;
tags.log_output = UNSPEC;
lbuf_append(lbuf, " ", NULL); lbuf_append(lbuf, " ", NULL);
tq_foreach_fwd(&priv->cmndlist, cs) { tq_foreach_fwd(&priv->cmndlist, cs) {
if (cs != tq_first(&priv->cmndlist)) if (cs != tq_first(&priv->cmndlist))
@@ -362,7 +370,8 @@ sudo_file_display_priv_long(struct passwd *pw, struct userspec *us,
tags.noexec = UNSPEC; tags.noexec = UNSPEC;
tags.setenv = UNSPEC; tags.setenv = UNSPEC;
tags.nopasswd = UNSPEC; tags.nopasswd = UNSPEC;
tags.transcript = UNSPEC; tags.log_input = UNSPEC;
tags.log_output = UNSPEC;
lbuf_append(lbuf, "\nSudoers entry:\n", NULL); lbuf_append(lbuf, "\nSudoers entry:\n", NULL);
tq_foreach_fwd(&priv->cmndlist, cs) { tq_foreach_fwd(&priv->cmndlist, cs) {
lbuf_append(lbuf, " RunAsUsers: ", NULL); lbuf_append(lbuf, " RunAsUsers: ", NULL);

View File

@@ -40,10 +40,11 @@ struct sudo_command {
* Possible valus: TRUE, FALSE, UNSPEC. * Possible valus: TRUE, FALSE, UNSPEC.
*/ */
struct cmndtag { struct cmndtag {
__signed char nopasswd; __signed int nopasswd: 3;
__signed char noexec; __signed int noexec: 3;
__signed char setenv; __signed int setenv: 3;
__signed char transcript; __signed int log_input: 3;
__signed int log_output: 3;
}; };
/* /*

View File

@@ -518,7 +518,7 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
validate_env_vars(sudo_user.env_vars); validate_env_vars(sudo_user.env_vars);
} }
if (def_transcript && (sudo_mode & (MODE_RUN | MODE_EDIT))) if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output))
io_nextid(); io_nextid();
log_allowed(validated); log_allowed(validated);
if (ISSET(sudo_mode, MODE_CHECK)) if (ISSET(sudo_mode, MODE_CHECK))

View File

@@ -110,7 +110,7 @@ union io_fd {
}; };
/* /*
* Info present in the transcript log file * Info present in the I/O log file
*/ */
struct log_info { struct log_info {
char *cwd; char *cwd;
@@ -161,7 +161,7 @@ struct search_node {
static struct search_node *node_stack[32]; static struct search_node *node_stack[32];
static int stack_top; static int stack_top;
static const char *session_dir = _PATH_SUDO_TRANSCRIPT; static const char *session_dir = _PATH_SUDO_IO_LOGDIR;
static union io_fd io_fds[IOFD_MAX]; static union io_fd io_fds[IOFD_MAX];
static const char *io_fnames[IOFD_MAX] = { static const char *io_fnames[IOFD_MAX] = {
@@ -642,7 +642,11 @@ list_session_dir(char *pathbuf, REGEX_T *re, const char *user, const char *tty)
pathbuf[plen + 0] = '/'; pathbuf[plen + 0] = '/';
pathbuf[plen + 1] = dp->d_name[0]; pathbuf[plen + 1] = dp->d_name[0];
pathbuf[plen + 2] = dp->d_name[1]; pathbuf[plen + 2] = dp->d_name[1];
pathbuf[plen + 3] = '\0'; pathbuf[plen + 3] = '/';
pathbuf[plen + 4] = 'l';
pathbuf[plen + 5] = 'o';
pathbuf[plen + 6] = 'g';
pathbuf[plen + 7] = '\0';
fp = fopen(pathbuf, "r"); fp = fopen(pathbuf, "r");
if (fp == NULL) { if (fp == NULL) {
warning("unable to open %s", pathbuf); warning("unable to open %s", pathbuf);
@@ -744,6 +748,10 @@ list_sessions(int argc, char **argv, const char *pattern, const char *user,
#endif /* HAVE_REGCOMP */ #endif /* HAVE_REGCOMP */
sdlen = strlcpy(pathbuf, session_dir, sizeof(pathbuf)); sdlen = strlcpy(pathbuf, session_dir, sizeof(pathbuf));
if (sdlen + sizeof("/00/00/00/log") >= sizeof(pathbuf)) {
errno = ENAMETOOLONG;
error(1, "%s/00/00/00/log", session_dir);
}
/* /*
* Three levels of directory, e.g. 00/00/00 .. ZZ/ZZ/ZZ * Three levels of directory, e.g. 00/00/00 .. ZZ/ZZ/ZZ