First cut at session logging for sudo. Still need to write get_pty()

for Unix 98 and old-style BSD ptys.  Also needs documentation and
general cleanup.
This commit is contained in:
Todd C. Miller
2009-08-06 00:04:14 +00:00
parent 334c19a405
commit 3bfce30a85
19 changed files with 788 additions and 385 deletions

View File

@@ -106,7 +106,7 @@ SRCS = aix.c alias.c alloc.c audit.c bsm_audit.c check.c closefrom.c \
def_data.c defaults.c env.c error.c fileops.c find_path.c fnmatch.c \
getcwd.c getprogname.c getspwuid.c gettime.c glob.c goodpath.c gram.c \
gram.y interfaces.c isblank.c lbuf.c ldap.c list.c logging.c match.c \
mkstemp.c memrchr.c parse.c pwutil.c set_perms.c sigaction.c \
mkstemp.c memrchr.c parse.c pwutil.c script.c set_perms.c sigaction.c \
snprintf.c strcasecmp.c strerror.c strlcat.c strlcpy.c sudo.c \
sudo_noexec.c sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c \
toke.c toke.l tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c \
@@ -131,8 +131,8 @@ COMMON_OBJS = gram.o alias.o alloc.o defaults.o error.o list.o match.o \
SUDO_OBJS = $(COMMON_OBJS) $(AUTH_OBJS) @SUDO_OBJS@ audit.o check.o env.o \
getspwuid.o gettime.o goodpath.o fileops.o find_path.o \
interfaces.o lbuf.o logging.o parse.o pwutil.o set_perms.o \
sudo.o sudo_edit.o sudo_nss.o term.o tgetpass.o
interfaces.o lbuf.o logging.o parse.o pwutil.o script.o \
set_perms.o sudo.o sudo_edit.o sudo_nss.o term.o tgetpass.o
VISUDO_OBJS = $(COMMON_OBJS) visudo.o fileops.o gettime.o goodpath.o \
find_path.o pwutil.o
@@ -285,6 +285,8 @@ pwutil.o: $(srcdir)/pwutil.c $(SUDODEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/pwutil.c
redblack.o: $(srcdir)/redblack.c $(SUDODEP) $(srcdir)/redblack.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/redblack.c
script.o: $(srcdir)/script.c $(SUDODEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/script.c
set_perms.o: $(srcdir)/set_perms.c $(SUDODEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/set_perms.c
sigaction.o: $(srcdir)/sigaction.c $(srcdir)/compat.h

27
aclocal.m4 vendored
View File

@@ -134,7 +134,8 @@ fi
])dnl
dnl
dnl Where the log file goes, use /var/log if it exists, else /{var,usr}/adm
dnl Where the timestamp files go, use /var/run/sudo if /var/run exists,
dnl else /{var,usr}/adm/sudo
dnl
AC_DEFUN(SUDO_TIMEDIR, [AC_MSG_CHECKING(for timestamp file location)
if test -n "$with_timedir"; then
@@ -156,6 +157,30 @@ else
fi
])dnl
dnl
dnl Where the session files go, use /var/log/sudo-session if /var/log exists,
dnl else /{var,usr}/adm/sudo-session
dnl
AC_DEFUN(SUDO_SESSDIR, [AC_MSG_CHECKING(for session file location)
if test -n "$with_sessdir"; then
AC_MSG_RESULT($with_sessdir)
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_SESSDIR, "$with_sessdir")
sessdir="$with_sessdir"
elif test -d "/var/log"; then
AC_MSG_RESULT(/var/log/sudo-session)
SUDO_DEFINE(_PATH_SUDO_SESSDIR, "/var/log/sudo-session")
sessdir="/var/log/sudo-session"
elif test -d "/var/adm"; then
AC_MSG_RESULT(/var/adm/sudo-session)
SUDO_DEFINE(_PATH_SUDO_SESSDIR, "/var/adm/sudo-session")
sessdir="/var/adm/sudo-session"
else
AC_MSG_RESULT(/usr/adm/sudo-session)
SUDO_DEFINE(_PATH_SUDO_SESSDIR, "/usr/adm/sudo-session")
sessdir="/usr/adm/sudo-session"
fi
])dnl
dnl
dnl SUDO_CHECK_TYPE(TYPE, DEFAULT)
dnl XXX - should require the check for unistd.h...

View File

@@ -198,6 +198,7 @@ int isblank __P((int));
# define SA_ONSTACK SV_ONSTACK
# define SA_RESTART SV_INTERRUPT /* opposite effect */
# define SA_RESETHAND SV_RESETHAND
# define SA_NOCLDSTOP SV_NOCLDSTOP
# define sa_handler sv_handler
# define sa_mask sv_mask
# define sa_flags sv_flags

View File

@@ -318,6 +318,9 @@
/* Define to 1 if you have the <netgroup.h> header file. */
#undef HAVE_NETGROUP_H
/* Define to 1 if you have the `openpty' function. */
#undef HAVE_OPENPTY
/* Define to 1 if you use NRL OPIE. */
#undef HAVE_OPIE

220
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for sudo 1.7.2.
# Generated by GNU Autoconf 2.61 for sudo 1.7.3.
#
# Report bugs to <http://www.sudo.ws/bugs/>.
#
@@ -724,8 +724,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='sudo'
PACKAGE_TARNAME='sudo'
PACKAGE_VERSION='1.7.2'
PACKAGE_STRING='sudo 1.7.2'
PACKAGE_VERSION='1.7.3'
PACKAGE_STRING='sudo 1.7.3'
PACKAGE_BUGREPORT='http://www.sudo.ws/bugs/'
# Factoring default headers for most tests.
@@ -1416,7 +1416,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sudo 1.7.2 to adapt to many kinds of systems.
\`configure' configures sudo 1.7.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1481,7 +1481,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sudo 1.7.2:";;
short | recursive ) echo "Configuration of sudo 1.7.3:";;
esac
cat <<\_ACEOF
@@ -1683,7 +1683,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sudo configure 1.7.2
sudo configure 1.7.3
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1697,7 +1697,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sudo $as_me 1.7.2, which was
It was created by sudo $as_me 1.7.3, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -15921,6 +15921,172 @@ fi
done
for ac_func in openpty
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$ac_func || defined __stub___$ac_func
choke me
#endif
int
main ()
{
return $ac_func ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
fi
ac_res=`eval echo '${'$as_ac_var'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
else
{ echo "$as_me:$LINENO: checking for openpty in -lutil" >&5
echo $ECHO_N "checking for openpty in -lutil... $ECHO_C" >&6; }
if test "${ac_cv_lib_util_openpty+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lutil $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char openpty ();
int
main ()
{
return openpty ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
ac_cv_lib_util_openpty=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_util_openpty=no
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_util_openpty" >&5
echo "${ECHO_T}$ac_cv_lib_util_openpty" >&6; }
if test $ac_cv_lib_util_openpty = yes; then
SUDO_LIBS="${SUDO_LIBS} -lutil"
cat >>confdefs.h <<\_ACEOF
#define HAVE_OPENPTY 1
_ACEOF
fi
fi
done
for ac_func in unsetenv
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
@@ -23997,6 +24163,42 @@ EOF
timedir="/usr/adm/sudo"
fi
{ echo "$as_me:$LINENO: checking for session file location" >&5
echo $ECHO_N "checking for session file location... $ECHO_C" >&6; }
if test -n "$with_sessdir"; then
{ echo "$as_me:$LINENO: result: $with_sessdir" >&5
echo "${ECHO_T}$with_sessdir" >&6; }
cat >>confdefs.h <<EOF
#define _PATH_SUDO_SESSDIR "$with_sessdir"
EOF
sessdir="$with_sessdir"
elif test -d "/var/log"; then
{ echo "$as_me:$LINENO: result: /var/log/sudo-session" >&5
echo "${ECHO_T}/var/log/sudo-session" >&6; }
cat >>confdefs.h <<\EOF
#define _PATH_SUDO_SESSDIR "/var/log/sudo-session"
EOF
sessdir="/var/log/sudo-session"
elif test -d "/var/adm"; then
{ echo "$as_me:$LINENO: result: /var/adm/sudo-session" >&5
echo "${ECHO_T}/var/adm/sudo-session" >&6; }
cat >>confdefs.h <<\EOF
#define _PATH_SUDO_SESSDIR "/var/adm/sudo-session"
EOF
sessdir="/var/adm/sudo-session"
else
{ echo "$as_me:$LINENO: result: /usr/adm/sudo-session" >&5
echo "${ECHO_T}/usr/adm/sudo-session" >&6; }
cat >>confdefs.h <<\EOF
#define _PATH_SUDO_SESSDIR "/usr/adm/sudo-session"
EOF
sessdir="/usr/adm/sudo-session"
fi
case "$with_passwd" in
yes|maybe)
@@ -24462,7 +24664,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sudo $as_me 1.7.2, which was
This file was extended by sudo $as_me 1.7.3, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -24511,7 +24713,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
sudo config.status 1.7.2
sudo config.status 1.7.3
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@@ -4,7 +4,7 @@ dnl $Sudo$
dnl
dnl Copyright (c) 1994-1996,1998-2009 Todd C. Miller <Todd.Miller@courtesan.com>
dnl
AC_INIT([sudo], [1.7.2], [http://www.sudo.ws/bugs/], [sudo])
AC_INIT([sudo], [1.7.3], [http://www.sudo.ws/bugs/], [sudo])
AC_CONFIG_HEADER(config.h pathnames.h)
dnl
dnl This won't work before AC_INIT
@@ -1837,6 +1837,10 @@ AC_FUNC_GETGROUPS
AC_CHECK_FUNCS(strchr strrchr memchr memcpy memset sysconf tzset \
strftime setrlimit initgroups getgroups fstat gettimeofday \
setlocale getaddrinfo setsid setenv)
AC_CHECK_FUNCS(openpty, [], [AC_CHECK_LIB(util, openpty, [
SUDO_LIBS="${SUDO_LIBS} -lutil"
AC_DEFINE(HAVE_OPENPTY)
])])
AC_CHECK_FUNCS(unsetenv, SUDO_FUNC_UNSETENV_VOID)
SUDO_FUNC_PUTENV_CONST
if test -z "$SKIP_SETRESUID"; then
@@ -2543,6 +2547,7 @@ dnl Check for log file and timestamp locations
dnl
SUDO_LOGFILE
SUDO_TIMEDIR
SUDO_SESSDIR
dnl
dnl Use passwd (and secureware) auth modules?

View File

@@ -314,6 +314,10 @@ struct sudo_defs_types sudo_defs_table[] = {
"umask_override", T_FLAG,
"The umask specified in sudoers will override the user's, even if it is more permissive",
NULL,
}, {
"script", T_FLAG,
"Log a transcript of the command being run",
NULL,
}, {
NULL, 0, NULL
}

View File

@@ -144,6 +144,8 @@
#define I_FAST_GLOB 71
#define def_umask_override (sudo_defs_table[72].sd_un.flag)
#define I_UMASK_OVERRIDE 72
#define def_script (sudo_defs_table[73].sd_un.flag)
#define I_SCRIPT 73
enum def_tupple {
never,

View File

@@ -232,3 +232,6 @@ fast_glob
umask_override
T_FLAG
"The umask specified in sudoers will override the user's, even if it is more permissive"
script
T_FLAG
"Log a transcript of the command being run"

737
gram.c

File diff suppressed because it is too large Load Diff

20
gram.h
View File

@@ -16,15 +16,17 @@
#define EXEC 272
#define SETENV 273
#define NOSETENV 274
#define ALL 275
#define COMMENT 276
#define HOSTALIAS 277
#define CMNDALIAS 278
#define USERALIAS 279
#define RUNASALIAS 280
#define ERROR 281
#define TYPE 282
#define ROLE 283
#define SCRIPT 275
#define NOSCRIPT 276
#define ALL 277
#define COMMENT 278
#define HOSTALIAS 279
#define CMNDALIAS 280
#define USERALIAS 281
#define RUNASALIAS 282
#define ERROR 283
#define TYPE 284
#define ROLE 285
#ifndef YYSTYPE_DEFINED
#define YYSTYPE_DEFINED
typedef union {

12
gram.y
View File

@@ -146,6 +146,8 @@ yyerror(s)
%token <tok> EXEC /* don't preload dummy execve() */
%token <tok> SETENV /* user may set environment for cmnd */
%token <tok> NOSETENV /* user may not set environment */
%token <tok> SCRIPT /* log a transcript of the cmnd */
%token <tok> NOSCRIPT /* don't log a transcript of the cmnd */
%token <tok> ALL /* ALL keyword */
%token <tok> COMMENT /* comment and/or carriage return */
%token <tok> HOSTALIAS /* Host_Alias keyword */
@@ -317,6 +319,8 @@ cmndspeclist : cmndspec
if ($3->tags.setenv == UNSPEC &&
$3->prev->tags.setenv != IMPLIED)
$3->tags.setenv = $3->prev->tags.setenv;
if ($3->tags.script == UNSPEC)
$3->tags.script = $3->prev->tags.script;
if ((tq_empty(&$3->runasuserlist) &&
tq_empty(&$3->runasgrouplist)) &&
(!tq_empty(&$3->prev->runasuserlist) ||
@@ -422,7 +426,7 @@ runaslist : userlist {
;
cmndtag : /* empty */ {
$$.nopasswd = $$.noexec = $$.setenv = UNSPEC;
$$.nopasswd = $$.noexec = $$.setenv = $$.script = UNSPEC;
}
| cmndtag NOPASSWD {
$$.nopasswd = TRUE;
@@ -442,6 +446,12 @@ cmndtag : /* empty */ {
| cmndtag NOSETENV {
$$.setenv = FALSE;
}
| cmndtag SCRIPT {
$$.script = TRUE;
}
| cmndtag NOSCRIPT {
$$.script = FALSE;
}
;
cmnd : ALL {

View File

@@ -254,6 +254,8 @@ sudo_file_lookup(nss, validated, pwflag)
def_noexec = tags->noexec;
if (tags->setenv != UNSPEC)
def_setenv = tags->setenv;
if (tags->script != UNSPEC)
def_script = tags->script;
}
} else if (match == DENY) {
SET(validated, VALIDATE_NOT_OK);
@@ -295,6 +297,11 @@ sudo_file_append_cmnd(cs, tags, lbuf)
"PASSWD: ", NULL);
tags->nopasswd = cs->tags.nopasswd;
}
if (TAG_CHANGED(script)) {
lbuf_append(lbuf, cs->tags.script ? "SCRIPT: " :
"NOSCRIPT: ", NULL);
tags->script = cs->tags.script;
}
m = cs->cmnd;
print_member(lbuf, m->name, m->type, m->negated,
CMNDALIAS);
@@ -316,6 +323,7 @@ sudo_file_display_priv_short(pw, us, lbuf)
tags.noexec = UNSPEC;
tags.setenv = UNSPEC;
tags.nopasswd = UNSPEC;
tags.script = UNSPEC;
lbuf_append(lbuf, " ", NULL);
tq_foreach_fwd(&priv->cmndlist, cs) {
if (cs != tq_first(&priv->cmndlist))
@@ -367,6 +375,7 @@ sudo_file_display_priv_long(pw, us, lbuf)
tags.noexec = UNSPEC;
tags.setenv = UNSPEC;
tags.nopasswd = UNSPEC;
tags.script = UNSPEC;
lbuf_print(lbuf); /* force a newline */
lbuf_append(lbuf, "Sudoers entry:", NULL);
lbuf_print(lbuf);

View File

@@ -45,7 +45,7 @@ struct cmndtag {
__signed char nopasswd;
__signed char noexec;
__signed char setenv;
__signed char extra;
__signed char script;
};
/*

View File

@@ -68,6 +68,14 @@
#undef _PATH_SUDO_TIMEDIR
#endif /* _PATH_SUDO_TIMEDIR */
/*
* Where to put the session files. Defaults to /var/log/sudo-session,
* /var/adm/sudo-session or /usr/adm/sudo-session depending on what exists.
*/
#ifndef _PATH_SUDO_SESSDIR
#undef _PATH_SUDO_SESSDIR
#endif /* _PATH_SUDO_SESSDIR */
/*
* Where to put the sudo log file when logging to a file. Defaults to
* /var/log/sudo.log if /var/log exists, else /var/adm/sudo.log.

27
sudo.c
View File

@@ -165,6 +165,10 @@ static struct sudo_nss_list *snl;
extern char *optarg;
extern int optind;
/* XXX - script.c */
extern int script_fds[5];
extern void term_restore __P((int));
int
main(argc, argv, envp)
int argc;
@@ -498,6 +502,10 @@ main(argc, argv, envp)
/* Must audit before uid change. */
audit_success(NewArgv);
/* Open tty as needed */
if (def_script)
script_setup();
/* Become specified user or root if executing a command. */
if (ISSET(sudo_mode, MODE_RUN))
set_perms(PERM_FULL_RUNAS);
@@ -540,7 +548,16 @@ main(argc, argv, envp)
sudo_endpwent();
sudo_endgrent();
closefrom(def_closefrom);
/* Move pty master/slave to low numbered fd and close the rest. */
fd = def_closefrom;
if (def_script) {
int i;
for (i = 0; i < 5; i++) {
dup2(script_fds[i], fd);
script_fds[i] = fd++;
}
}
closefrom(fd);
#ifndef PROFILING
if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) {
@@ -548,11 +565,15 @@ main(argc, argv, envp)
exit(0);
} else {
#ifdef HAVE_SELINUX
/* XXX - script support */
if (is_selinux_enabled() > 0 && user_role != NULL)
selinux_exec(user_role, user_type, NewArgv,
ISSET(sudo_mode, MODE_LOGIN_SHELL));
#endif
execv(safe_cmnd, NewArgv);
if (def_script)
script_execv(safe_cmnd, NewArgv);
else
execv(safe_cmnd, NewArgv);
}
#else
exit(0);
@@ -1446,6 +1467,8 @@ cleanup(gotsignal)
sudo_endpwent();
sudo_endgrent();
}
if (def_script)
term_restore(STDIN_FILENO);
}
static void

2
sudo.h
View File

@@ -324,6 +324,8 @@ void selinux_exec __P((char *, char *, char **, int));
#ifdef HAVE_GETUSERATTR
void aix_setlimits __P((char *));
#endif
int script_execv __P((const char *, char * const *));
void script_setup __P((void));
YY_DECL;
/* Only provide extern declarations outside of sudo.c. */

77
term.c
View File

@@ -132,9 +132,32 @@ term_noecho(fd)
}
#if defined(HAVE_TERMIOS_H) || defined(HAVE_TERMIO_H)
int
term_raw(fd)
int fd;
{
struct termios term;
if (!changed && tcgetattr(fd, &oterm) != 0)
return(0);
(void) memcpy(&term, &oterm, sizeof(term));
/* Set terminal to raw mode */
term.c_iflag &= ~(BRKINT|ICRNL|IGNCR|INLCR|IXON|PARMRK);
term.c_oflag &= ~OPOST;
term.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 0;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term) == 0) {
changed = 1;
return(1);
}
return(0);
}
int
term_cbreak(fd)
int fd;
{
if (!changed && tcgetattr(fd, &oterm) != 0)
return(0);
@@ -156,11 +179,42 @@ term_raw(fd)
return(0);
}
int
term_copy(src, dst)
int src;
int dst;
{
struct termios tt;
if (tcgetattr(src, &tt) != 0)
return(0);
if (tcsetattr(dst, TCSAFLUSH, &tt) != 0)
return(0);
return(1);
}
#else /* SGTTY */
int
term_raw(fd)
int fd;
{
if (!changed && ioctl(fd, TIOCGETP, &oterm) != 0)
return(0);
(void) memcpy(&term, &oterm, sizeof(term));
/* Set terminal to raw mode */
CLR(term.c_lflag, ECHO);
SET(term.sg_flags, RAW);
if (ioctl(fd, TIOCSETP, &term) == 0) {
changed = 1;
return(1);
}
return(0);
}
int
term_cbreak(fd)
int fd;
{
if (!changed && ioctl(fd, TIOCGETP, &oterm) != 0)
return(0);
@@ -177,4 +231,27 @@ term_raw(fd)
return(0);
}
int
term_copy(src, dst)
int src;
int dst;
{
struct sgttyb b;
struct tchars tc;
struct ltchars lc;
int l, lb;
if (ioctl(src, TIOCGETP, &b) != 0 || ioctl(src, TIOCGETC, &tc) != 0 ||
ioctl(src, TIOCGETD, &l) != 0 || ioctl(src, TIOCGLTC, &lc) != 0 ||
ioctl(src, TIOCLGET, &lb)) {
return(0);
}
if (ioctl(dst, TIOCSETP, &b) != 0 || ioctl(dst, TIOCSETC, &tc) != 0 ||
ioctl(dst, TIOCSLTC, &lc) != 0 || ioctl(dst, TIOCLSET, &lb) != 0 ||
ioctl(dst, TIOCSETD, &l) != 0) {
return(0);
}
return(1);
}
#endif

View File

@@ -68,7 +68,7 @@ static char *sudo_askpass __P((const char *));
extern int term_restore __P((int));
extern int term_noecho __P((int));
extern int term_raw __P((int));
extern int term_cbreak __P((int));
/*
* Like getpass(3) but with timeout and echo flags.
@@ -120,7 +120,7 @@ restart:
(void) sigaction(SIGTTOU, &sa, &savettou);
if (def_pwfeedback)
neednl = term_raw(input);
neednl = term_cbreak(input);
else
neednl = term_noecho(input);