|
version 1.1.1.3, 2012/10/09 09:29:52
|
version 1.1.1.5, 2013/10/14 07:56:35
|
|
Line 1
|
Line 1
|
| /* |
/* |
| * Copyright (c) 1996, 1998-2005, 2007-2011 | * Copyright (c) 1996, 1998-2005, 2007-2013 |
| * 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 |
|
Line 26
|
Line 26
|
| #include <config.h> |
#include <config.h> |
| |
|
| #include <sys/types.h> |
#include <sys/types.h> |
| #include <sys/param.h> |
|
| #include <stdio.h> |
#include <stdio.h> |
| #ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
| # include <stdlib.h> |
# include <stdlib.h> |
|
Line 54
|
Line 53
|
| #include <fcntl.h> |
#include <fcntl.h> |
| |
|
| #include "sudo.h" |
#include "sudo.h" |
| |
#include "sudo_plugin.h" |
| |
|
| static volatile sig_atomic_t signo[NSIG]; |
static volatile sig_atomic_t signo[NSIG]; |
| |
|
| static void handler(int); | static void tgetpass_handler(int); |
| static char *getln(int, char *, size_t, int); |
static char *getln(int, char *, size_t, int); |
| static char *sudo_askpass(const char *, const char *); |
static char *sudo_askpass(const char *, const char *); |
| |
|
|
Line 71 tgetpass(const char *prompt, int timeout, int flags)
|
Line 71 tgetpass(const char *prompt, int timeout, int flags)
|
| sigaction_t savetstp, savettin, savettou, savepipe; |
sigaction_t savetstp, savettin, savettou, savepipe; |
| char *pass; |
char *pass; |
| static const char *askpass; |
static const char *askpass; |
| static char buf[SUDO_PASS_MAX + 1]; | static char buf[SUDO_CONV_REPL_MAX + 1]; |
| int i, input, output, save_errno, neednl = 0, need_restart; |
int i, input, output, save_errno, neednl = 0, need_restart; |
| debug_decl(tgetpass, SUDO_DEBUG_CONV) |
debug_decl(tgetpass, SUDO_DEBUG_CONV) |
| |
|
|
Line 96 tgetpass(const char *prompt, int timeout, int flags)
|
Line 96 tgetpass(const char *prompt, int timeout, int flags)
|
| /* 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)) { |
if (ISSET(flags, TGP_ASKPASS)) { |
| if (askpass == NULL || *askpass == '\0') |
if (askpass == NULL || *askpass == '\0') |
| errorx(1, _("no askpass program specified, try setting SUDO_ASKPASS")); | fatalx(_("no askpass program specified, try setting SUDO_ASKPASS")); |
| debug_return_str_masked(sudo_askpass(askpass, prompt)); |
debug_return_str_masked(sudo_askpass(askpass, prompt)); |
| } |
} |
| |
|
|
Line 128 restart:
|
Line 128 restart:
|
| * Catch signals that would otherwise cause the user to end |
* Catch signals that would otherwise cause the user to end |
| * up with echo turned off in the shell. |
* up with echo turned off in the shell. |
| */ |
*/ |
| zero_bytes(&sa, sizeof(sa)); | memset(&sa, 0, sizeof(sa)); |
| sigemptyset(&sa.sa_mask); |
sigemptyset(&sa.sa_mask); |
| sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */ |
sa.sa_flags = SA_INTERRUPT; /* don't restart system calls */ |
| sa.sa_handler = handler; | sa.sa_handler = tgetpass_handler; |
| (void) sigaction(SIGALRM, &sa, &savealrm); |
(void) sigaction(SIGALRM, &sa, &savealrm); |
| (void) sigaction(SIGINT, &sa, &saveint); |
(void) sigaction(SIGINT, &sa, &saveint); |
| (void) sigaction(SIGHUP, &sa, &savehup); |
(void) sigaction(SIGHUP, &sa, &savehup); |
|
Line 208 restore:
|
Line 208 restore:
|
| static char * |
static char * |
| sudo_askpass(const char *askpass, const char *prompt) |
sudo_askpass(const char *askpass, const char *prompt) |
| { |
{ |
| static char buf[SUDO_PASS_MAX + 1], *pass; | static char buf[SUDO_CONV_REPL_MAX + 1], *pass; |
| sigaction_t sa, saved_sa_pipe; |
sigaction_t sa, saved_sa_pipe; |
| int pfd[2]; |
int pfd[2]; |
| pid_t pid; |
pid_t pid; |
| debug_decl(sudo_askpass, SUDO_DEBUG_CONV) |
debug_decl(sudo_askpass, SUDO_DEBUG_CONV) |
| |
|
| if (pipe(pfd) == -1) |
if (pipe(pfd) == -1) |
| error(1, _("unable to create pipe")); | fatal(_("unable to create pipe")); |
| |
|
| if ((pid = fork()) == -1) |
if ((pid = fork()) == -1) |
| error(1, _("unable to fork")); | fatal(_("unable to fork")); |
| |
|
| 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 */ |
|
Line 226 sudo_askpass(const char *askpass, const char *prompt)
|
Line 226 sudo_askpass(const char *askpass, const char *prompt)
|
| warning("dup2"); |
warning("dup2"); |
| _exit(255); |
_exit(255); |
| } |
} |
| (void) setuid(ROOT_UID); | if (setuid(ROOT_UID) == -1) |
| | warning("setuid(%d)", ROOT_UID); |
| if (setgid(user_details.gid)) { |
if (setgid(user_details.gid)) { |
| warning(_("unable to set gid to %u"), (unsigned int)user_details.gid); |
warning(_("unable to set gid to %u"), (unsigned int)user_details.gid); |
| _exit(255); |
_exit(255); |
|
Line 242 sudo_askpass(const char *askpass, const char *prompt)
|
Line 243 sudo_askpass(const char *askpass, const char *prompt)
|
| } |
} |
| |
|
| /* Ignore SIGPIPE in case child exits prematurely */ |
/* Ignore SIGPIPE in case child exits prematurely */ |
| zero_bytes(&sa, sizeof(sa)); | memset(&sa, 0, sizeof(sa)); |
| sigemptyset(&sa.sa_mask); |
sigemptyset(&sa.sa_mask); |
| sa.sa_flags = SA_INTERRUPT; |
sa.sa_flags = SA_INTERRUPT; |
| sa.sa_handler = SIG_IGN; |
sa.sa_handler = SIG_IGN; |
|
Line 316 getln(int fd, char *buf, size_t bufsiz, int feedback)
|
Line 317 getln(int fd, char *buf, size_t bufsiz, int feedback)
|
| } |
} |
| |
|
| static void |
static void |
| handler(int s) | tgetpass_handler(int s) |
| { |
{ |
| if (s != SIGALRM) |
if (s != SIGALRM) |
| signo[s] = 1; |
signo[s] = 1; |