New (correct) PAM code
Tgetpass now takes an echo flag for use with PAM_PROMPT_ECHO_ON Block SIGINT and SIGTSTP during auth remove a useless umask setting Change error from BAD_ALLOCATION -> BAD_AUTH_INIT (for use with sia/PAM) Some cosmetic changes to auth.c for consistency
This commit is contained in:
233
auth.c
233
auth.c
@@ -92,8 +92,7 @@ static int sudo_krb5_validate_user __P((struct passwd *, char *));
|
|||||||
static int verify_krb_v5_tgt __P((krb5_ccache));
|
static int verify_krb_v5_tgt __P((krb5_ccache));
|
||||||
#endif /* HAVE_KERB5 */
|
#endif /* HAVE_KERB5 */
|
||||||
#ifdef HAVE_PAM
|
#ifdef HAVE_PAM
|
||||||
static int pam_auth __P((char *, char *));
|
static int sudo_conv __P((int,
|
||||||
static int PAM_conv __P((int,
|
|
||||||
PAM_CONST struct pam_message **,
|
PAM_CONST struct pam_message **,
|
||||||
struct pam_response **, void *));
|
struct pam_response **, void *));
|
||||||
#endif /* HAVE_PAM */
|
#endif /* HAVE_PAM */
|
||||||
@@ -150,9 +149,7 @@ check_passwd()
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* You get TRIES_FOR_PASSWORD times to guess your password */
|
||||||
* you get TRIES_FOR_PASSWORD times to guess your password
|
|
||||||
*/
|
|
||||||
while (counter > 0) {
|
while (counter > 0) {
|
||||||
if (sd_auth(sd) == ACM_OK) {
|
if (sd_auth(sd) == ACM_OK) {
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_USER, 0);
|
||||||
@@ -164,14 +161,8 @@ check_passwd()
|
|||||||
}
|
}
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_USER, 0);
|
||||||
|
|
||||||
if (counter > 0) {
|
log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
log_error(PASSWORD_NOT_CORRECT);
|
inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
inform_user(PASSWORD_NOT_CORRECT);
|
|
||||||
} else {
|
|
||||||
log_error(PASSWORDS_NOT_CORRECT);
|
|
||||||
inform_user(PASSWORDS_NOT_CORRECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#else /* !HAVE_SECURID */
|
#else /* !HAVE_SECURID */
|
||||||
@@ -207,9 +198,7 @@ check_passwd()
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* You get TRIES_FOR_PASSWORD times to guess your password */
|
||||||
* you get TRIES_FOR_PASSWORD times to guess your password
|
|
||||||
*/
|
|
||||||
while (counter > 0) {
|
while (counter > 0) {
|
||||||
|
|
||||||
sprintf(cbuf,"authorize %s sudo",user_name);
|
sprintf(cbuf,"authorize %s sudo",user_name);
|
||||||
@@ -219,9 +208,9 @@ check_passwd()
|
|||||||
|
|
||||||
if (!strncmp(cbuf, "challenge ", 10)) {
|
if (!strncmp(cbuf, "challenge ", 10)) {
|
||||||
sprintf(buf, "Challenge \"%s\": ", &cbuf[10]);
|
sprintf(buf, "Challenge \"%s\": ", &cbuf[10]);
|
||||||
pass = GETPASS(buf, PASSWORD_TIMEOUT * 60);
|
pass = GETPASS(buf, PASSWORD_TIMEOUT * 60, 1);
|
||||||
} else if (!strncmp(cbuf, "password", 8)) {
|
} else if (!strncmp(cbuf, "password", 8)) {
|
||||||
pass = GETPASS(buf, PASSWORD_TIMEOUT * 60);
|
pass = GETPASS(buf, PASSWORD_TIMEOUT * 60, 1);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Server sent %s\n", cbuf);
|
fprintf(stderr, "Server sent %s\n", cbuf);
|
||||||
auth_close();
|
auth_close();
|
||||||
@@ -249,13 +238,8 @@ check_passwd()
|
|||||||
|
|
||||||
auth_close();
|
auth_close();
|
||||||
|
|
||||||
if (counter > 0) {
|
log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
log_error(PASSWORD_NOT_CORRECT);
|
inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
inform_user(PASSWORD_NOT_CORRECT);
|
|
||||||
} else {
|
|
||||||
log_error(PASSWORDS_NOT_CORRECT);
|
|
||||||
inform_user(PASSWORDS_NOT_CORRECT);
|
|
||||||
}
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,14 +265,12 @@ check_passwd()
|
|||||||
(void) memset((VOID *)&opie, 0, sizeof(opie));
|
(void) memset((VOID *)&opie, 0, sizeof(opie));
|
||||||
#endif /* HAVE_OPIE */
|
#endif /* HAVE_OPIE */
|
||||||
|
|
||||||
/*
|
/* You get TRIES_FOR_PASSWORD times to guess your password */
|
||||||
* you get TRIES_FOR_PASSWORD times to guess your password
|
|
||||||
*/
|
|
||||||
while (counter > 0) {
|
while (counter > 0) {
|
||||||
|
|
||||||
#ifdef HAVE_AUTHENTICATE
|
#ifdef HAVE_AUTHENTICATE
|
||||||
/* use AIX authenticate() function */
|
/* use AIX authenticate() function */
|
||||||
pass = GETPASS(prompt, PASSWORD_TIMEOUT * 60);
|
pass = GETPASS(prompt, PASSWORD_TIMEOUT * 60, 1);
|
||||||
reenter = 1;
|
reenter = 1;
|
||||||
if (authenticate(user_name, pass, &reenter, &message) == 0)
|
if (authenticate(user_name, pass, &reenter, &message) == 0)
|
||||||
return; /* valid password */
|
return; /* valid password */
|
||||||
@@ -311,7 +293,7 @@ check_passwd()
|
|||||||
(void) des_read_pw_string(kpass, sizeof(kpass) - 1, prompt, 0);
|
(void) des_read_pw_string(kpass, sizeof(kpass) - 1, prompt, 0);
|
||||||
pass = kpass;
|
pass = kpass;
|
||||||
# else
|
# else
|
||||||
pass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60);
|
pass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60, 1);
|
||||||
# endif /* HAVE_KERB4 */
|
# endif /* HAVE_KERB4 */
|
||||||
|
|
||||||
# ifdef HAVE_SKEY
|
# ifdef HAVE_SKEY
|
||||||
@@ -399,14 +381,8 @@ check_passwd()
|
|||||||
pass_warn(stderr);
|
pass_warn(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (counter > 0) {
|
log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
log_error(PASSWORD_NOT_CORRECT);
|
inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
inform_user(PASSWORD_NOT_CORRECT);
|
|
||||||
} else {
|
|
||||||
log_error(PASSWORDS_NOT_CORRECT);
|
|
||||||
inform_user(PASSWORDS_NOT_CORRECT);
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_AUTHSRV */
|
#endif /* HAVE_AUTHSRV */
|
||||||
@@ -496,7 +472,7 @@ sudo_krb5_validate_user(pw, pass)
|
|||||||
|
|
||||||
princ_name = emalloc(strlen(pw->pw_name) + strlen(realm) + 2);
|
princ_name = emalloc(strlen(pw->pw_name) + strlen(realm) + 2);
|
||||||
|
|
||||||
sprintf(princ_name, "%s@%s", pw->pw_name, realm);
|
(void) sprintf(princ_name, "%s@%s", pw->pw_name, realm);
|
||||||
if (retval = krb5_parse_name(sudo_context, princ_name, &princ))
|
if (retval = krb5_parse_name(sudo_context, princ_name, &princ))
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
@@ -613,118 +589,109 @@ cleanup:
|
|||||||
* pam_attempt_auth()
|
* pam_attempt_auth()
|
||||||
*
|
*
|
||||||
* Try to authenticate the user using Pluggable Authentication
|
* Try to authenticate the user using Pluggable Authentication
|
||||||
* Modules (PAM). Added 9/11/98 by Gary J. Calvin
|
* Modules (PAM).
|
||||||
* Reworked for stock PAM by Amos Elberg and Todd Miller
|
|
||||||
*/
|
*/
|
||||||
static char *PAM_username;
|
|
||||||
static char *PAM_password;
|
|
||||||
|
|
||||||
static int
|
|
||||||
PAM_conv(num_msg, msg, resp, appdata_ptr)
|
|
||||||
int num_msg;
|
|
||||||
PAM_CONST struct pam_message **msg;
|
|
||||||
struct pam_response **resp;
|
|
||||||
void *appdata_ptr;
|
|
||||||
{
|
|
||||||
int replies = 0;
|
|
||||||
struct pam_response *reply = NULL;
|
|
||||||
|
|
||||||
if ((reply = malloc(sizeof(struct pam_response) * num_msg)) == NULL)
|
|
||||||
return(PAM_CONV_ERR);
|
|
||||||
|
|
||||||
for (replies = 0; replies < num_msg; replies++) {
|
|
||||||
switch (msg[replies]->msg_style) {
|
|
||||||
case PAM_PROMPT_ECHO_ON:
|
|
||||||
reply[replies].resp_retcode = PAM_SUCCESS;
|
|
||||||
reply[replies].resp = estrdup(PAM_username);
|
|
||||||
/* PAM frees resp */
|
|
||||||
break;
|
|
||||||
case PAM_PROMPT_ECHO_OFF:
|
|
||||||
reply[replies].resp_retcode = PAM_SUCCESS;
|
|
||||||
reply[replies].resp = estrdup(PAM_password);
|
|
||||||
/* PAM frees resp */
|
|
||||||
break;
|
|
||||||
case PAM_TEXT_INFO:
|
|
||||||
/* fall through */
|
|
||||||
case PAM_ERROR_MSG:
|
|
||||||
/* ignore it... */
|
|
||||||
reply[replies].resp_retcode = PAM_SUCCESS;
|
|
||||||
reply[replies].resp = NULL;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Must be an error of some sort... */
|
|
||||||
free(reply);
|
|
||||||
return(PAM_CONV_ERR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reply)
|
|
||||||
*resp = reply;
|
|
||||||
|
|
||||||
return(PAM_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
pam_auth(user, password)
|
|
||||||
char *user;
|
|
||||||
char *password;
|
|
||||||
{
|
|
||||||
struct pam_conv PAM_conversation;
|
|
||||||
pam_handle_t *pamh;
|
|
||||||
|
|
||||||
/* Initialize our variables for PAM */
|
|
||||||
PAM_conversation.conv = PAM_conv;
|
|
||||||
PAM_conversation.appdata_ptr = NULL;
|
|
||||||
PAM_password = password;
|
|
||||||
PAM_username = user;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Setting PAM_SILENT stops generation of error messages to syslog
|
|
||||||
* to enable debugging on Red Hat Linux set:
|
|
||||||
* /etc/pam.d/sudo:
|
|
||||||
* auth required /lib/security/pam_pwdb.so shadow nullok audit
|
|
||||||
* _OR_ change PAM_SILENT to 0 to force detailed reporting (logging)
|
|
||||||
*/
|
|
||||||
if (pam_start("sudo", user, &PAM_conversation, &pamh) != PAM_SUCCESS ||
|
|
||||||
pam_authenticate(pamh, PAM_SILENT) != PAM_SUCCESS) {
|
|
||||||
pam_end(pamh, 0);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* User authenticated successfully */
|
|
||||||
pam_end(pamh, PAM_SUCCESS);
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pam_attempt_auth()
|
pam_attempt_auth()
|
||||||
{
|
{
|
||||||
int i = TRIES_FOR_PASSWORD;
|
int counter = TRIES_FOR_PASSWORD;
|
||||||
|
int null_pw = 0;
|
||||||
|
static struct pam_conv pam_conv;
|
||||||
|
static pam_handle_t *pamh;
|
||||||
|
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_ROOT, 0);
|
||||||
while (i > 0) {
|
|
||||||
char *pamPass = (char *) GETPASS(prompt, PASSWORD_TIMEOUT * 60);
|
|
||||||
|
|
||||||
if (pam_auth(user_name, pamPass)) {
|
/* Initial PAM setup + use our default prompt */
|
||||||
|
pam_conv.conv = sudo_conv;
|
||||||
|
pam_conv.appdata_ptr = &null_pw;
|
||||||
|
if (pam_start("sudo", user_name, &pam_conv, &pamh) != PAM_SUCCESS ||
|
||||||
|
pam_set_item(pamh, PAM_USER_PROMPT, (void *) prompt) != PAM_SUCCESS) {
|
||||||
|
set_perms(PERM_USER, 0);
|
||||||
|
log_error(BAD_AUTH_INIT);
|
||||||
|
inform_user(BAD_AUTH_INIT);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* You get TRIES_FOR_PASSWORD times to guess your password */
|
||||||
|
while (counter > 0) {
|
||||||
|
|
||||||
|
/* PAM_SILENT prevents error messages from going to syslog(3) */
|
||||||
|
if (pam_authenticate(pamh, PAM_SILENT) == PAM_SUCCESS) {
|
||||||
|
pam_end(pamh, PAM_SUCCESS);
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_USER, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
--i;
|
if (null_pw)
|
||||||
|
break;
|
||||||
|
|
||||||
|
--counter; /* otherwise, try again */
|
||||||
pass_warn(stderr);
|
pass_warn(stderr);
|
||||||
}
|
}
|
||||||
|
pam_end(pamh, 0);
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_USER, 0);
|
||||||
|
|
||||||
if (i == 0) {
|
log_error(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
log_error(PASSWORD_NOT_CORRECT);
|
inform_user(counter ? PASSWORD_NOT_CORRECT : PASSWORDS_NOT_CORRECT);
|
||||||
inform_user(PASSWORD_NOT_CORRECT);
|
|
||||||
} else {
|
|
||||||
log_error(PASSWORDS_NOT_CORRECT);
|
|
||||||
inform_user(PASSWORDS_NOT_CORRECT);
|
|
||||||
}
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* sudo_conv()
|
||||||
|
*
|
||||||
|
* ``Conversation function'' for PAM.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
sudo_conv(num_msg, msg, response, appdata_ptr)
|
||||||
|
int num_msg;
|
||||||
|
PAM_CONST struct pam_message **msg;
|
||||||
|
struct pam_response **response;
|
||||||
|
void *appdata_ptr;
|
||||||
|
{
|
||||||
|
struct pam_response *pr;
|
||||||
|
struct pam_message *pm;
|
||||||
|
int echo = 0;
|
||||||
|
|
||||||
|
if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL)
|
||||||
|
return(PAM_CONV_ERR);
|
||||||
|
(void) memset((VOID *)*response, 0, num_msg * sizeof(struct pam_response));
|
||||||
|
|
||||||
|
for (pr = *response, pm = *msg; num_msg--; pr++, pm++) {
|
||||||
|
switch (pm->msg_style) {
|
||||||
|
case PAM_PROMPT_ECHO_ON:
|
||||||
|
echo = 1;
|
||||||
|
case PAM_PROMPT_ECHO_OFF:
|
||||||
|
pr->resp = estrdup((char *) GETPASS(pm->msg,
|
||||||
|
PASSWORD_TIMEOUT * 60, !echo));
|
||||||
|
/* Solaris PAM does not pass through appdata_ptr! */
|
||||||
|
if (pr->resp[0] == '\0' && appdata_ptr != NULL)
|
||||||
|
*((int *) appdata_ptr) = 1; /* indicate an empty password */
|
||||||
|
break;
|
||||||
|
case PAM_TEXT_INFO:
|
||||||
|
if (pm->msg)
|
||||||
|
(void) puts(pm->msg);
|
||||||
|
break;
|
||||||
|
case PAM_ERROR_MSG:
|
||||||
|
if (pm->msg) {
|
||||||
|
(void) fputs(pm->msg, stderr);
|
||||||
|
(void) fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Something odd happened */
|
||||||
|
/* XXX - should free non-NULL response members */
|
||||||
|
free(*response);
|
||||||
|
*response = NULL;
|
||||||
|
return(PAM_CONV_ERR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(PAM_SUCCESS);
|
||||||
|
}
|
||||||
#endif /* HAVE_PAM */
|
#endif /* HAVE_PAM */
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_SKEY
|
#ifdef HAVE_SKEY
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
*
|
*
|
||||||
|
31
check.c
31
check.c
@@ -45,6 +45,7 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#endif /* HAVE_STRINGS_H */
|
#endif /* HAVE_STRINGS_H */
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@@ -96,13 +97,28 @@ static char timestampfile[MAXPATHLEN];
|
|||||||
void
|
void
|
||||||
check_user()
|
check_user()
|
||||||
{
|
{
|
||||||
register int rtn;
|
int rtn;
|
||||||
mode_t oldmask;
|
#ifdef POSIX_SIGNALS
|
||||||
|
sigset_t set, oset;
|
||||||
|
#else
|
||||||
|
int omask;
|
||||||
|
#endif /* POSIX_SIGNALS */
|
||||||
|
|
||||||
if (user_is_exempt()) /* some users don't need to enter a passwd */
|
if (user_is_exempt()) /* some users don't need to enter a passwd */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
oldmask = umask(077); /* make sure the timestamp files are private */
|
/*
|
||||||
|
* Block SIGINT and SIGTSTP during authentication so the user
|
||||||
|
* can't abort the logging.
|
||||||
|
*/
|
||||||
|
#ifdef POSIX_SIGNALS
|
||||||
|
(void) sigemptyset(&set);
|
||||||
|
(void) sigaddset(&set, SIGINT);
|
||||||
|
(void) sigaddset(&set, SIGTSTP);
|
||||||
|
(void) sigprocmask(SIG_BLOCK, &set, &oset);
|
||||||
|
#else
|
||||||
|
omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
|
||||||
|
#endif /* POSIX_SIGNALS */
|
||||||
|
|
||||||
rtn = check_timestamp();
|
rtn = check_timestamp();
|
||||||
if (rtn && user_uid) { /* if timestamp is not current... */
|
if (rtn && user_uid) { /* if timestamp is not current... */
|
||||||
@@ -123,9 +139,14 @@ check_user()
|
|||||||
#endif /* HAVE_SIA */
|
#endif /* HAVE_SIA */
|
||||||
}
|
}
|
||||||
|
|
||||||
update_timestamp();
|
/* Unblock signals */
|
||||||
(void) umask(oldmask); /* want a real umask to exec() the command */
|
#ifdef POSIX_SIGNALS
|
||||||
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
#else
|
||||||
|
(void) sigsetmask(omask);
|
||||||
|
#endif /* POSIX_SIGNALS */
|
||||||
|
|
||||||
|
update_timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -113,8 +113,8 @@ sia_attempt_auth()
|
|||||||
1, NULL);
|
1, NULL);
|
||||||
if (retval != SIASUCCESS) {
|
if (retval != SIASUCCESS) {
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_USER, 0);
|
||||||
log_error(BAD_ALLOCATION);
|
log_error(BAD_AUTH_INIT);
|
||||||
inform_user(BAD_ALLOCATION);
|
inform_user(BAD_AUTH_INIT);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* XXX - need a way to detect user hitting return or EOF at prompt */
|
/* XXX - need a way to detect user hitting return or EOF at prompt */
|
||||||
|
10
logging.c
10
logging.c
@@ -264,9 +264,9 @@ log_error(code)
|
|||||||
tty, cwd, runas_user);
|
tty, cwd, runas_user);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BAD_ALLOCATION:
|
case BAD_AUTH_INIT:
|
||||||
(void) sprintf(p,
|
(void) sprintf(p,
|
||||||
"allocation failure; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=",
|
"unable to initialize authentication scheme; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=",
|
||||||
tty, cwd, runas_user);
|
tty, cwd, runas_user);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -668,9 +668,9 @@ inform_user(code)
|
|||||||
"Your timestamp file has a preposterous date, ignoring.\n");
|
"Your timestamp file has a preposterous date, ignoring.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BAD_ALLOCATION:
|
case BAD_AUTH_INIT:
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"Resource allocation failure.\n");
|
"Unable to initialize authentication scheme.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NO_CMND_SAFE:
|
case NO_CMND_SAFE:
|
||||||
@@ -736,7 +736,7 @@ appropriate(code)
|
|||||||
case NO_SUDOERS_FILE:
|
case NO_SUDOERS_FILE:
|
||||||
case BAD_STAMPDIR:
|
case BAD_STAMPDIR:
|
||||||
case BAD_STAMPFILE:
|
case BAD_STAMPFILE:
|
||||||
case BAD_ALLOCATION:
|
case BAD_AUTH_INIT:
|
||||||
case NO_CMND_SAFE:
|
case NO_CMND_SAFE:
|
||||||
default:
|
default:
|
||||||
return (1);
|
return (1);
|
||||||
|
8
sudo.h
8
sudo.h
@@ -152,7 +152,7 @@ struct generic_alias {
|
|||||||
#define SUDOERS_NOT_FILE ( 0x0B | GLOBAL_PROBLEM )
|
#define SUDOERS_NOT_FILE ( 0x0B | GLOBAL_PROBLEM )
|
||||||
#define BAD_STAMPDIR 0x0C
|
#define BAD_STAMPDIR 0x0C
|
||||||
#define BAD_STAMPFILE 0x0D
|
#define BAD_STAMPFILE 0x0D
|
||||||
#define BAD_ALLOCATION 0x0E
|
#define BAD_AUTH_INIT 0x0E
|
||||||
#define NO_CMND_SAFE 0x0F
|
#define NO_CMND_SAFE 0x0F
|
||||||
#ifdef HAVE_KERB5
|
#ifdef HAVE_KERB5
|
||||||
#define GLOBAL_KRB5_INIT_ERR ( 0x10 | GLOBAL_PROBLEM )
|
#define GLOBAL_KRB5_INIT_ERR ( 0x10 | GLOBAL_PROBLEM )
|
||||||
@@ -209,9 +209,9 @@ struct generic_alias {
|
|||||||
* Use either tgetpass() or system getpass()
|
* Use either tgetpass() or system getpass()
|
||||||
*/
|
*/
|
||||||
#ifdef USE_GETPASS
|
#ifdef USE_GETPASS
|
||||||
#define GETPASS(p, t) getpass(p)
|
#define GETPASS(p, t, e) getpass(p)
|
||||||
#else
|
#else
|
||||||
#define GETPASS(p, t) tgetpass(p, t)
|
#define GETPASS(p, t, e) tgetpass(p, t, e)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -235,7 +235,7 @@ int putenv __P((const char *));
|
|||||||
#endif
|
#endif
|
||||||
char *sudo_goodpath __P((const char *));
|
char *sudo_goodpath __P((const char *));
|
||||||
int sudo_setenv __P((char *, char *));
|
int sudo_setenv __P((char *, char *));
|
||||||
char *tgetpass __P((const char *, int));
|
char *tgetpass __P((const char *, int, int));
|
||||||
int find_path __P((char *, char **));
|
int find_path __P((char *, char **));
|
||||||
void log_error __P((int));
|
void log_error __P((int));
|
||||||
void inform_user __P((int));
|
void inform_user __P((int));
|
||||||
|
73
tgetpass.c
73
tgetpass.c
@@ -88,9 +88,10 @@ static const char rcsid[] = "$Sudo$";
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
char *
|
char *
|
||||||
tgetpass(prompt, timeout)
|
tgetpass(prompt, timeout, echo_off)
|
||||||
const char *prompt;
|
const char *prompt;
|
||||||
int timeout;
|
int timeout;
|
||||||
|
int echo_off;
|
||||||
{
|
{
|
||||||
#ifdef HAVE_TERMIOS_H
|
#ifdef HAVE_TERMIOS_H
|
||||||
struct termios term;
|
struct termios term;
|
||||||
@@ -102,12 +103,11 @@ tgetpass(prompt, timeout)
|
|||||||
#endif /* HAVE_TERMIO_H */
|
#endif /* HAVE_TERMIO_H */
|
||||||
#endif /* HAVE_TERMIOS_H */
|
#endif /* HAVE_TERMIOS_H */
|
||||||
#ifdef POSIX_SIGNALS
|
#ifdef POSIX_SIGNALS
|
||||||
sigset_t oldmask;
|
sigset_t set, oset;
|
||||||
sigset_t mask;
|
|
||||||
#else
|
#else
|
||||||
int oldmask;
|
int omask;
|
||||||
#endif /* POSIX_SIGNALS */
|
#endif /* POSIX_SIGNALS */
|
||||||
int n, echo, input, output;
|
int n, input, output;
|
||||||
static char buf[SUDO_PASS_MAX + 1];
|
static char buf[SUDO_PASS_MAX + 1];
|
||||||
fd_set *readfds;
|
fd_set *readfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@@ -116,13 +116,13 @@ tgetpass(prompt, timeout)
|
|||||||
* mask out SIGINT and SIGTSTP, should probably just catch and deal.
|
* mask out SIGINT and SIGTSTP, should probably just catch and deal.
|
||||||
*/
|
*/
|
||||||
#ifdef POSIX_SIGNALS
|
#ifdef POSIX_SIGNALS
|
||||||
(void) sigemptyset(&mask);
|
(void) sigemptyset(&set);
|
||||||
(void) sigaddset(&mask, SIGINT);
|
(void) sigaddset(&set, SIGINT);
|
||||||
(void) sigaddset(&mask, SIGTSTP);
|
(void) sigaddset(&set, SIGTSTP);
|
||||||
(void) sigprocmask(SIG_BLOCK, &mask, &oldmask);
|
(void) sigprocmask(SIG_BLOCK, &set, &oset);
|
||||||
#else
|
#else
|
||||||
oldmask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
|
omask = sigblock(sigmask(SIGINT)|sigmask(SIGTSTP));
|
||||||
#endif
|
#endif /* POSIX_SIGNALS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open /dev/tty for reading/writing if possible or use
|
* open /dev/tty for reading/writing if possible or use
|
||||||
@@ -138,29 +138,31 @@ tgetpass(prompt, timeout)
|
|||||||
(void) write(output, prompt, strlen(prompt) + 1);
|
(void) write(output, prompt, strlen(prompt) + 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* turn off echo
|
* turn off echo unless asked to keep it on
|
||||||
*/
|
*/
|
||||||
|
if (echo_off) {
|
||||||
#ifdef HAVE_TERMIOS_H
|
#ifdef HAVE_TERMIOS_H
|
||||||
(void) tcgetattr(input, &term);
|
(void) tcgetattr(input, &term);
|
||||||
if ((echo = (term.c_lflag & ECHO))) {
|
if ((echo_off = (term.c_lflag & ECHO))) {
|
||||||
term.c_lflag &= ~ECHO;
|
term.c_lflag &= ~ECHO;
|
||||||
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
|
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_TERMIO_H
|
#ifdef HAVE_TERMIO_H
|
||||||
(void) ioctl(input, TCGETA, &term);
|
(void) ioctl(input, TCGETA, &term);
|
||||||
if ((echo = (term.c_lflag & ECHO))) {
|
if ((echo_off = (term.c_lflag & ECHO))) {
|
||||||
term.c_lflag &= ~ECHO;
|
term.c_lflag &= ~ECHO;
|
||||||
(void) ioctl(input, TCSETA, &term);
|
(void) ioctl(input, TCSETA, &term);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
(void) ioctl(input, TIOCGETP, &ttyb);
|
(void) ioctl(input, TIOCGETP, &ttyb);
|
||||||
if ((echo = (ttyb.sg_flags & ECHO))) {
|
if ((echo_off = (ttyb.sg_flags & ECHO))) {
|
||||||
ttyb.sg_flags &= ~ECHO;
|
ttyb.sg_flags &= ~ECHO;
|
||||||
(void) ioctl(input, TIOCSETP, &ttyb);
|
(void) ioctl(input, TIOCSETP, &ttyb);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_TERMIO_H */
|
#endif /* HAVE_TERMIO_H */
|
||||||
#endif /* HAVE_TERMIOS_H */
|
#endif /* HAVE_TERMIOS_H */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timeout of <= 0 means no timeout
|
* Timeout of <= 0 means no timeout
|
||||||
@@ -198,20 +200,20 @@ tgetpass(prompt, timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* turn on echo */
|
/* turn on echo if we turned it off above */
|
||||||
#ifdef HAVE_TERMIOS_H
|
#ifdef HAVE_TERMIOS_H
|
||||||
if (echo) {
|
if (echo_off) {
|
||||||
term.c_lflag |= ECHO;
|
term.c_lflag |= ECHO;
|
||||||
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
|
(void) tcsetattr(input, TCSAFLUSH|TCSASOFT, &term);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#ifdef HAVE_TERMIO_H
|
#ifdef HAVE_TERMIO_H
|
||||||
if (echo) {
|
if (echo_off) {
|
||||||
term.c_lflag |= ECHO;
|
term.c_lflag |= ECHO;
|
||||||
(void) ioctl(input, TCSETA, &term);
|
(void) ioctl(input, TCSETA, &term);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (echo) {
|
if (echo_off) {
|
||||||
ttyb.sg_flags |= ECHO;
|
ttyb.sg_flags |= ECHO;
|
||||||
(void) ioctl(input, TIOCSETP, &ttyb);
|
(void) ioctl(input, TIOCSETP, &ttyb);
|
||||||
}
|
}
|
||||||
@@ -219,14 +221,15 @@ tgetpass(prompt, timeout)
|
|||||||
#endif /* HAVE_TERMIOS_H */
|
#endif /* HAVE_TERMIOS_H */
|
||||||
|
|
||||||
/* print a newline since echo is turned off */
|
/* print a newline since echo is turned off */
|
||||||
(void) write(output, "\n", 1);
|
if (echo_off)
|
||||||
|
(void) write(output, "\n", 1);
|
||||||
|
|
||||||
/* restore old signal mask */
|
/* restore old signal mask */
|
||||||
#ifdef POSIX_SIGNALS
|
#ifdef POSIX_SIGNALS
|
||||||
(void) sigprocmask(SIG_SETMASK, &oldmask, NULL);
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
#else
|
#else
|
||||||
(void) sigsetmask(oldmask);
|
(void) sigsetmask(omask);
|
||||||
#endif
|
#endif /* POSIX_SIGNALS */
|
||||||
|
|
||||||
/* close /dev/tty if that's what we opened */
|
/* close /dev/tty if that's what we opened */
|
||||||
if (input != STDIN_FILENO)
|
if (input != STDIN_FILENO)
|
||||||
|
Reference in New Issue
Block a user