Make user_details extern so tgetpass can get at the uid and gid.

Set uid/gid to user before executing askpass program.
Check environment for SUDO_ASKPASS and use that if set.
TODO: a way for the policy to set the askpass program itself
This commit is contained in:
Todd C. Miller
2010-02-24 19:53:45 -05:00
parent f3b2c9ac1d
commit 9e5ff964ad
2 changed files with 37 additions and 27 deletions

View File

@@ -103,6 +103,9 @@ extern const char *list_user, *runas_user, *runas_group;
int Argc; int Argc;
char **Argv; char **Argv;
/* Needed by tgetpass when executing askpass helper */
struct user_details user_details;
#if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL)
static struct rlimit corelimit; static struct rlimit corelimit;
#endif /* RLIMIT_CORE && !SUDO_DEVEL */ #endif /* RLIMIT_CORE && !SUDO_DEVEL */
@@ -116,7 +119,6 @@ main(int argc, char *argv[], char *envp[])
char **nargv, **settings, **env_add; char **nargv, **settings, **env_add;
char **user_info, **command_info, **argv_out, **user_env_out; char **user_info, **command_info, **argv_out, **user_env_out;
struct plugin_container *plugin; struct plugin_container *plugin;
struct user_details user_details;
struct command_details command_details; struct command_details command_details;
int ok; int ok;
#if defined(SUDO_DEVEL) && defined(__OpenBSD__) #if defined(SUDO_DEVEL) && defined(__OpenBSD__)

View File

@@ -56,35 +56,42 @@
#include "sudo.h" #include "sudo.h"
/* XXX */
char *user_askpass = NULL;
static volatile sig_atomic_t signo; static volatile sig_atomic_t signo;
static void handler __P((int)); static void handler(int);
static char *getln __P((int, char *, size_t, int)); static char *getln(int, char *, size_t, int);
static char *sudo_askpass __P((const char *)); static char *sudo_askpass(const char *, const char *);
extern struct user_details user_details; /* XXX */
/* /*
* Like getpass(3) but with timeout and echo flags. * Like getpass(3) but with timeout and echo flags.
*/ */
char * char *
tgetpass(prompt, timeout, flags) tgetpass(const char *prompt, int timeout, int flags)
const char *prompt;
int timeout;
int flags;
{ {
sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm; sigaction_t sa, savealrm, saveint, savehup, savequit, saveterm;
sigaction_t savetstp, savettin, savettou; sigaction_t savetstp, savettin, savettou;
char *pass; char *pass;
static char *askpass;
static char buf[SUDO_PASS_MAX + 1]; static char buf[SUDO_PASS_MAX + 1];
int input, output, save_errno, neednl;; int input, output, save_errno, neednl;;
(void) fflush(stdout); (void) fflush(stdout);
/* If using a helper program to get the password, run it instead. */ /* If using a helper program to get the password, run it instead. */
if (ISSET(flags, TGP_ASKPASS) && user_askpass) /* XXX - askpass may be set by policy */
return(sudo_askpass(prompt)); if (ISSET(flags, TGP_ASKPASS)) {
if (!askpass) {
askpass = getenv("SUDO_ASKPASS");
#ifdef _PATH_SUDO_ASKPASS
if (!askpass)
askpass = _PATH_SUDO_ASKPASS;
#endif
}
if (askpass && *askpass)
return(sudo_askpass(askpass, prompt));
}
restart: restart:
signo = 0; signo = 0;
@@ -170,8 +177,7 @@ restart:
* Fork a child and exec sudo-askpass to get the password from the user. * Fork a child and exec sudo-askpass to get the password from the user.
*/ */
static char * static char *
sudo_askpass(prompt) sudo_askpass(const char *askpass, const char *prompt)
const char *prompt;
{ {
static char buf[SUDO_PASS_MAX + 1], *pass; static char buf[SUDO_PASS_MAX + 1], *pass;
sigaction_t sa, saved_sa_pipe; sigaction_t sa, saved_sa_pipe;
@@ -187,11 +193,18 @@ sudo_askpass(prompt)
if (pid == 0) { if (pid == 0) {
/* child, point stdout to output side of the pipe and exec askpass */ /* child, point stdout to output side of the pipe and exec askpass */
(void) dup2(pfd[1], STDOUT_FILENO); (void) dup2(pfd[1], STDOUT_FILENO);
//XXX - set real and effective uid to user (void) setuid(ROOT_UID);
//set_perms(PERM_FULL_USER); if (setgid(user_details.gid)) {
warning("unable to set gid to %u", (unsigned int)user_details.gid);
_exit(255);
}
if (setuid(user_details.uid)) {
warning("unable to set uid to %u", (unsigned int)user_details.uid);
_exit(255);
}
closefrom(STDERR_FILENO + 1); closefrom(STDERR_FILENO + 1);
execl(user_askpass, user_askpass, prompt, (char *)NULL); execl(askpass, askpass, prompt, (char *)NULL);
warning("unable to run %s", user_askpass); warning("unable to run %s", askpass);
_exit(255); _exit(255);
} }
@@ -214,11 +227,7 @@ sudo_askpass(prompt)
extern int term_erase, term_kill; extern int term_erase, term_kill;
static char * static char *
getln(fd, buf, bufsiz, feedback) getln(int fd, char *buf, size_t bufsiz, int feedback)
int fd;
char *buf;
size_t bufsiz;
int feedback;
{ {
size_t left = bufsiz; size_t left = bufsiz;
ssize_t nr = -1; ssize_t nr = -1;
@@ -267,15 +276,14 @@ getln(fd, buf, bufsiz, feedback)
} }
static void static void
handler(s) handler(int s)
int s;
{ {
if (s != SIGALRM) if (s != SIGALRM)
signo = s; signo = s;
} }
int int
tty_present() tty_present(void)
{ {
int fd; int fd;