Add support for running a helper program to read the password when
no tty is present (or when specified with the -A flag). TODO: docs.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1999-2005 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 1999-2005, 2008 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -195,7 +195,8 @@ verify_user(pw, prompt)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_warn(stderr);
|
if (!ISSET(tgetpass_flags, TGP_ASKPASS))
|
||||||
|
pass_warn(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
6
check.c
6
check.c
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1993-1996,1998-2005 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 1993-1996,1998-2005, 2007-2008
|
||||||
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -98,7 +99,8 @@ check_user(validated)
|
|||||||
status = timestamp_status(timestampdir, timestampfile, user_name,
|
status = timestamp_status(timestampdir, timestampfile, user_name,
|
||||||
TS_MAKE_DIRS);
|
TS_MAKE_DIRS);
|
||||||
if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) {
|
if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) {
|
||||||
lecture(status);
|
if (!ISSET(tgetpass_flags, TGP_ASKPASS))
|
||||||
|
lecture(status);
|
||||||
|
|
||||||
/* Expand any escapes in the prompt. */
|
/* Expand any escapes in the prompt. */
|
||||||
prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
|
prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
|
||||||
|
41
configure
vendored
41
configure
vendored
@@ -1581,6 +1581,7 @@ Optional Packages:
|
|||||||
--with-secure-path override the user's path with a built-in one
|
--with-secure-path override the user's path with a built-in one
|
||||||
--without-interfaces don't try to read the ip addr of ether interfaces
|
--without-interfaces don't try to read the ip addr of ether interfaces
|
||||||
--with-stow properly handle GNU stow packaging
|
--with-stow properly handle GNU stow packaging
|
||||||
|
--with-askpass=PATH Fully qualified pathname of sudo-askpass
|
||||||
--with-selinux enable SELinux support
|
--with-selinux enable SELinux support
|
||||||
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
|
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
|
||||||
--with-pic try to use only PIC/non-PIC objects [default=use
|
--with-pic try to use only PIC/non-PIC objects [default=use
|
||||||
@@ -3740,6 +3741,28 @@ echo "${ECHO_T}no" >&6; }
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
{ echo "$as_me:$LINENO: checking path to sudo-askpass" >&5
|
||||||
|
echo $ECHO_N "checking path to sudo-askpass... $ECHO_C" >&6; }
|
||||||
|
|
||||||
|
# Check whether --with-askpass was given.
|
||||||
|
if test "${with_askpass+set}" = set; then
|
||||||
|
withval=$with_askpass; case $with_askpass in
|
||||||
|
yes) with_askpass="$libexecdir/sudo-askpass"
|
||||||
|
;;
|
||||||
|
no) ;;
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
with_askpass="$libexecdir/sudo-askpass"
|
||||||
|
fi
|
||||||
|
|
||||||
|
{ echo "$as_me:$LINENO: result: $with_askpass" >&5
|
||||||
|
echo "${ECHO_T}$with_askpass" >&6; }
|
||||||
|
cat >>confdefs.h <<EOF
|
||||||
|
#define _PATH_SUDO_ASKPASS "$with_askpass"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{ echo "$as_me:$LINENO: checking whether to do user authentication by default" >&5
|
{ echo "$as_me:$LINENO: checking whether to do user authentication by default" >&5
|
||||||
echo $ECHO_N "checking whether to do user authentication by default... $ECHO_C" >&6; }
|
echo $ECHO_N "checking whether to do user authentication by default... $ECHO_C" >&6; }
|
||||||
@@ -6180,7 +6203,7 @@ ia64-*-hpux*)
|
|||||||
;;
|
;;
|
||||||
*-*-irix6*)
|
*-*-irix6*)
|
||||||
# Find out which ABI we are using.
|
# Find out which ABI we are using.
|
||||||
echo '#line 6183 "configure"' > conftest.$ac_ext
|
echo '#line 6206 "configure"' > conftest.$ac_ext
|
||||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||||
(eval $ac_compile) 2>&5
|
(eval $ac_compile) 2>&5
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
@@ -7724,11 +7747,11 @@ else
|
|||||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||||
-e 's:$: $lt_compiler_flag:'`
|
-e 's:$: $lt_compiler_flag:'`
|
||||||
(eval echo "\"\$as_me:7727: $lt_compile\"" >&5)
|
(eval echo "\"\$as_me:7750: $lt_compile\"" >&5)
|
||||||
(eval "$lt_compile" 2>conftest.err)
|
(eval "$lt_compile" 2>conftest.err)
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
cat conftest.err >&5
|
cat conftest.err >&5
|
||||||
echo "$as_me:7731: \$? = $ac_status" >&5
|
echo "$as_me:7754: \$? = $ac_status" >&5
|
||||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||||
# The compiler can only warn and ignore the option if not recognized
|
# The compiler can only warn and ignore the option if not recognized
|
||||||
# So say no if there are warnings other than the usual output.
|
# So say no if there are warnings other than the usual output.
|
||||||
@@ -8014,11 +8037,11 @@ else
|
|||||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||||
-e 's:$: $lt_compiler_flag:'`
|
-e 's:$: $lt_compiler_flag:'`
|
||||||
(eval echo "\"\$as_me:8017: $lt_compile\"" >&5)
|
(eval echo "\"\$as_me:8040: $lt_compile\"" >&5)
|
||||||
(eval "$lt_compile" 2>conftest.err)
|
(eval "$lt_compile" 2>conftest.err)
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
cat conftest.err >&5
|
cat conftest.err >&5
|
||||||
echo "$as_me:8021: \$? = $ac_status" >&5
|
echo "$as_me:8044: \$? = $ac_status" >&5
|
||||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||||
# The compiler can only warn and ignore the option if not recognized
|
# The compiler can only warn and ignore the option if not recognized
|
||||||
# So say no if there are warnings other than the usual output.
|
# So say no if there are warnings other than the usual output.
|
||||||
@@ -8118,11 +8141,11 @@ else
|
|||||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||||
-e 's:$: $lt_compiler_flag:'`
|
-e 's:$: $lt_compiler_flag:'`
|
||||||
(eval echo "\"\$as_me:8121: $lt_compile\"" >&5)
|
(eval echo "\"\$as_me:8144: $lt_compile\"" >&5)
|
||||||
(eval "$lt_compile" 2>out/conftest.err)
|
(eval "$lt_compile" 2>out/conftest.err)
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
cat out/conftest.err >&5
|
cat out/conftest.err >&5
|
||||||
echo "$as_me:8125: \$? = $ac_status" >&5
|
echo "$as_me:8148: \$? = $ac_status" >&5
|
||||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||||
then
|
then
|
||||||
# The compiler can only warn and ignore the option if not recognized
|
# The compiler can only warn and ignore the option if not recognized
|
||||||
@@ -10463,7 +10486,7 @@ else
|
|||||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||||
lt_status=$lt_dlunknown
|
lt_status=$lt_dlunknown
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 10466 "configure"
|
#line 10489 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#if HAVE_DLFCN_H
|
#if HAVE_DLFCN_H
|
||||||
@@ -10563,7 +10586,7 @@ else
|
|||||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||||
lt_status=$lt_dlunknown
|
lt_status=$lt_dlunknown
|
||||||
cat > conftest.$ac_ext <<EOF
|
cat > conftest.$ac_ext <<EOF
|
||||||
#line 10566 "configure"
|
#line 10589 "configure"
|
||||||
#include "confdefs.h"
|
#include "confdefs.h"
|
||||||
|
|
||||||
#if HAVE_DLFCN_H
|
#if HAVE_DLFCN_H
|
||||||
|
11
configure.in
11
configure.in
@@ -1010,6 +1010,17 @@ AC_ARG_WITH(stow, [ --with-stow properly handle GNU stow packaging]
|
|||||||
;;
|
;;
|
||||||
esac], AC_MSG_RESULT(no))
|
esac], AC_MSG_RESULT(no))
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(path to sudo-askpass)
|
||||||
|
AC_ARG_WITH(askpass, [ --with-askpass=PATH Fully qualified pathname of sudo-askpass],
|
||||||
|
[case $with_askpass in
|
||||||
|
yes) with_askpass="$libexecdir/sudo-askpass"
|
||||||
|
;;
|
||||||
|
no) ;;
|
||||||
|
*) ;;
|
||||||
|
esac], [with_askpass="$libexecdir/sudo-askpass"])
|
||||||
|
AC_MSG_RESULT($with_askpass)
|
||||||
|
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_ASKPASS, "$with_askpass")
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl Options for --enable
|
dnl Options for --enable
|
||||||
dnl
|
dnl
|
||||||
|
@@ -282,6 +282,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
|||||||
"type", T_STR,
|
"type", T_STR,
|
||||||
"SELinux type to use in the new security context: %s",
|
"SELinux type to use in the new security context: %s",
|
||||||
NULL,
|
NULL,
|
||||||
|
}, {
|
||||||
|
"askpass", T_STR|T_PATH,
|
||||||
|
"Path to the askpass helper program: %s",
|
||||||
|
NULL,
|
||||||
}, {
|
}, {
|
||||||
NULL, 0, NULL
|
NULL, 0, NULL
|
||||||
}
|
}
|
||||||
|
@@ -128,6 +128,8 @@
|
|||||||
#define I_ROLE 63
|
#define I_ROLE 63
|
||||||
#define def_type (sudo_defs_table[64].sd_un.str)
|
#define def_type (sudo_defs_table[64].sd_un.str)
|
||||||
#define I_TYPE 64
|
#define I_TYPE 64
|
||||||
|
#define def_askpass (sudo_defs_table[65].sd_un.str)
|
||||||
|
#define I_ASKPASS 65
|
||||||
|
|
||||||
enum def_tupple {
|
enum def_tupple {
|
||||||
never,
|
never,
|
||||||
|
@@ -208,3 +208,6 @@ role
|
|||||||
type
|
type
|
||||||
T_STR
|
T_STR
|
||||||
"SELinux type to use in the new security context: %s"
|
"SELinux type to use in the new security context: %s"
|
||||||
|
askpass
|
||||||
|
T_STR|T_PATH
|
||||||
|
"Path to the askpass helper program: %s"
|
||||||
|
@@ -422,6 +422,9 @@ init_defaults()
|
|||||||
#endif
|
#endif
|
||||||
#ifdef ENV_EDITOR
|
#ifdef ENV_EDITOR
|
||||||
def_env_editor = TRUE;
|
def_env_editor = TRUE;
|
||||||
|
#endif
|
||||||
|
#ifdef _PATH_SUDO_ASKPASS
|
||||||
|
def_askpass = _PATH_SUDO_ASKPASS;
|
||||||
#endif
|
#endif
|
||||||
def_env_reset = TRUE;
|
def_env_reset = TRUE;
|
||||||
def_set_logname = TRUE;
|
def_set_logname = TRUE;
|
||||||
|
@@ -84,6 +84,10 @@
|
|||||||
#undef _PATH_SUDO_NOEXEC
|
#undef _PATH_SUDO_NOEXEC
|
||||||
#endif /* _PATH_SUDO_NOEXEC */
|
#endif /* _PATH_SUDO_NOEXEC */
|
||||||
|
|
||||||
|
#ifndef _PATH_SUDO_ASKPASS
|
||||||
|
#undef _PATH_SUDO_ASKPASS
|
||||||
|
#endif /* _PATH_SUDO_ASKPASS */
|
||||||
|
|
||||||
#ifndef _PATH_VI
|
#ifndef _PATH_VI
|
||||||
#undef _PATH_VI
|
#undef _PATH_VI
|
||||||
#endif /* _PATH_VI */
|
#endif /* _PATH_VI */
|
||||||
|
20
sudo.c
20
sudo.c
@@ -384,6 +384,15 @@ main(argc, argv, envp)
|
|||||||
(void) close(fd);
|
(void) close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Use askpass value from sudoers unless specified by the user. */
|
||||||
|
if (def_askpass && !user_askpass)
|
||||||
|
user_askpass = def_askpass;
|
||||||
|
|
||||||
|
/* If no tty is present but DISPLAY is set, use askpass if we have it. */
|
||||||
|
if (user_askpass && !ISSET(tgetpass_flags, TGP_STDIN) &&
|
||||||
|
user_ttypath == NULL && user_display != NULL && *user_display != '\0')
|
||||||
|
SET(tgetpass_flags, TGP_ASKPASS);
|
||||||
|
|
||||||
/* User may have overriden environment resetting via the -E flag. */
|
/* User may have overriden environment resetting via the -E flag. */
|
||||||
if (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)
|
if (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)
|
||||||
def_env_reset = FALSE;
|
def_env_reset = FALSE;
|
||||||
@@ -599,7 +608,12 @@ init_vars(sudo_mode, envp)
|
|||||||
user_tty = "unknown";
|
user_tty = "unknown";
|
||||||
|
|
||||||
for (ep = envp; *ep; ep++) {
|
for (ep = envp; *ep; ep++) {
|
||||||
|
/* XXX - don't fill in if empty string */
|
||||||
switch (**ep) {
|
switch (**ep) {
|
||||||
|
case 'D':
|
||||||
|
if (strncmp("DISPLAY=", *ep, 8) == 0)
|
||||||
|
user_display = *ep + 8;
|
||||||
|
break;
|
||||||
case 'K':
|
case 'K':
|
||||||
if (strncmp("KRB5CCNAME=", *ep, 11) == 0)
|
if (strncmp("KRB5CCNAME=", *ep, 11) == 0)
|
||||||
user_ccname = *ep + 11;
|
user_ccname = *ep + 11;
|
||||||
@@ -615,8 +629,9 @@ init_vars(sudo_mode, envp)
|
|||||||
user_prompt = *ep + 12;
|
user_prompt = *ep + 12;
|
||||||
else if (strncmp("SUDO_USER=", *ep, 10) == 0)
|
else if (strncmp("SUDO_USER=", *ep, 10) == 0)
|
||||||
prev_user = *ep + 10;
|
prev_user = *ep + 10;
|
||||||
|
else if (strncmp("SUDO_ASKPASS=", *ep, 13) == 0)
|
||||||
|
user_askpass = *ep + 13;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -810,6 +825,9 @@ parse_args(argc, argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (NewArgv[0][1]) {
|
switch (NewArgv[0][1]) {
|
||||||
|
case 'A':
|
||||||
|
SET(tgetpass_flags, TGP_ASKPASS);
|
||||||
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
/* Must have an associated prompt. */
|
/* Must have an associated prompt. */
|
||||||
if (NewArgv[1] == NULL)
|
if (NewArgv[1] == NULL)
|
||||||
|
7
sudo.h
7
sudo.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1993-1996, 1998-2005, 2007
|
* Copyright (c) 1993-1996, 1998-2005, 2007-2008
|
||||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
@@ -54,6 +54,8 @@ struct sudo_user {
|
|||||||
char *cmnd_safe;
|
char *cmnd_safe;
|
||||||
char *class_name;
|
char *class_name;
|
||||||
char *krb5_ccname;
|
char *krb5_ccname;
|
||||||
|
char *display;
|
||||||
|
char *askpass;
|
||||||
int ngroups;
|
int ngroups;
|
||||||
GETGROUPS_T *groups;
|
GETGROUPS_T *groups;
|
||||||
struct list_member *env_vars;
|
struct list_member *env_vars;
|
||||||
@@ -147,6 +149,8 @@ struct sudo_user {
|
|||||||
#define user_host (sudo_user.host)
|
#define user_host (sudo_user.host)
|
||||||
#define user_shost (sudo_user.shost)
|
#define user_shost (sudo_user.shost)
|
||||||
#define user_ccname (sudo_user.krb5_ccname)
|
#define user_ccname (sudo_user.krb5_ccname)
|
||||||
|
#define user_display (sudo_user.display)
|
||||||
|
#define user_askpass (sudo_user.askpass)
|
||||||
#define safe_cmnd (sudo_user.cmnd_safe)
|
#define safe_cmnd (sudo_user.cmnd_safe)
|
||||||
#define login_class (sudo_user.class_name)
|
#define login_class (sudo_user.class_name)
|
||||||
#define runas_pw (sudo_user._runas_pw)
|
#define runas_pw (sudo_user._runas_pw)
|
||||||
@@ -174,6 +178,7 @@ struct sudo_user {
|
|||||||
*/
|
*/
|
||||||
#define TGP_ECHO 0x01 /* leave echo on when reading passwd */
|
#define TGP_ECHO 0x01 /* leave echo on when reading passwd */
|
||||||
#define TGP_STDIN 0x02 /* read from stdin, not /dev/tty */
|
#define TGP_STDIN 0x02 /* read from stdin, not /dev/tty */
|
||||||
|
#define TGP_ASKPASS 0x03 /* read from askpass helper program */
|
||||||
|
|
||||||
struct lbuf;
|
struct lbuf;
|
||||||
struct passwd;
|
struct passwd;
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
* Usage strings for sudo. These are here because we
|
* Usage strings for sudo. These are here because we
|
||||||
* need to be able to substitute values from configure.
|
* need to be able to substitute values from configure.
|
||||||
*/
|
*/
|
||||||
#define SUDO_USAGE1 " -h | -K | -k | -L | -V | -v"
|
#define SUDO_USAGE1 " [-A] -h | -K | -k | -L | -V | -v"
|
||||||
#define SUDO_USAGE2 " -l[l] [-g groupname|#gid] [-U username] [-u username|#uid] [-g groupname|#gid] [command]"
|
#define SUDO_USAGE2 " -l[l] [-A] [-g groupname|#gid] [-U username] [-u username|#uid] [-g groupname|#gid] [command]"
|
||||||
#define SUDO_USAGE3 " [-bEHPS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] [<command>]"
|
#define SUDO_USAGE3 " [-AbEHPS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] [-g groupname|#gid] [VAR=value] [-i|-s] [<command>]"
|
||||||
#define SUDO_USAGE4 " -e [-S] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] file ..."
|
#define SUDO_USAGE4 " -e [-AS] @BSDAUTH_USAGE@@SELINUX_USAGE@[-C fd] @LOGINCAP_USAGE@[-g groupname|#gid] [-p prompt] [-u username|#uid] file ..."
|
||||||
|
|
||||||
#endif /* _SUDO_USAGE_H */
|
#endif /* _SUDO_USAGE_H */
|
||||||
|
52
tgetpass.c
52
tgetpass.c
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1996, 1998-2005 Todd C. Miller <Todd.Miller@courtesan.com>
|
* Copyright (c) 1996, 1998-2005, 2007-2008
|
||||||
|
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -122,6 +123,7 @@ static volatile sig_atomic_t signo;
|
|||||||
|
|
||||||
static void handler __P((int));
|
static void handler __P((int));
|
||||||
static char *getln __P((int, char *, size_t));
|
static char *getln __P((int, char *, size_t));
|
||||||
|
static char *sudo_askpass(const char *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like getpass(3) but with timeout and echo flags.
|
* Like getpass(3) but with timeout and echo flags.
|
||||||
@@ -140,6 +142,11 @@ tgetpass(prompt, timeout, flags)
|
|||||||
int input, output, save_errno;
|
int input, output, save_errno;
|
||||||
|
|
||||||
(void) fflush(stdout);
|
(void) fflush(stdout);
|
||||||
|
|
||||||
|
/* If using a helper program to get the password, run it instead. */
|
||||||
|
if (ISSET(flags, TGP_ASKPASS) && user_askpass)
|
||||||
|
return(sudo_askpass(prompt));
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
signo = 0;
|
signo = 0;
|
||||||
pass = NULL;
|
pass = NULL;
|
||||||
@@ -232,6 +239,49 @@ restart:
|
|||||||
return(pass);
|
return(pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fork a child and exec sudo-askpass to get the password from the user.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
sudo_askpass(prompt)
|
||||||
|
const char *prompt;
|
||||||
|
{
|
||||||
|
static char buf[SUDO_PASS_MAX + 1], *pass;
|
||||||
|
sigaction_t sa, saved_sa_pipe;
|
||||||
|
int pfd[2];
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (pipe(pfd) == -1)
|
||||||
|
error(1, "unable to create pipe");
|
||||||
|
|
||||||
|
if ((pid = fork()) == -1)
|
||||||
|
error(1, "unable to fork");
|
||||||
|
|
||||||
|
if (pid == 0) {
|
||||||
|
/* child, point stdout to output side of the pipe and exec askpass */
|
||||||
|
(void) dup2(pfd[1], STDOUT_FILENO);
|
||||||
|
set_perms(PERM_FULL_USER);
|
||||||
|
closefrom(STDERR_FILENO + 1);
|
||||||
|
execl(user_askpass, user_askpass, prompt, (char *)NULL);
|
||||||
|
warning("unable to run %s", user_askpass);
|
||||||
|
_exit(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore SIGPIPE in case child exits prematurely */
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
sa.sa_flags = 0;
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
|
(void) sigaction(SIGPIPE, &sa, &saved_sa_pipe);
|
||||||
|
|
||||||
|
/* Get response from child (askpass) and restore SIGPIPE handler */
|
||||||
|
(void) close(pfd[1]);
|
||||||
|
pass = getln(pfd[0], buf, sizeof(buf));
|
||||||
|
(void) close(pfd[0]);
|
||||||
|
(void) sigaction(SIGPIPE, &saved_sa_pipe, NULL);
|
||||||
|
|
||||||
|
return(pass);
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
getln(fd, buf, bufsiz)
|
getln(fd, buf, bufsiz)
|
||||||
int fd;
|
int fd;
|
||||||
|
Reference in New Issue
Block a user