From dfc90ff0b1de9c848fe5b5af694c6feea2717091 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Wed, 11 Apr 2012 19:51:56 -0400 Subject: [PATCH] Instead of treating ^C from tgetpass() specially, always return AUTH_INTR if tgetpass() returned NULL. Treat PAM_AUTHINFO_UNAVAIL like PAM_AUTH_ERR which Mac OS X returns this when there is no tty. --- plugins/sudoers/auth/pam.c | 51 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c index 64ac30a80..0de9af212 100644 --- a/plugins/sudoers/auth/pam.c +++ b/plugins/sudoers/auth/pam.c @@ -71,7 +71,7 @@ static int converse(int, PAM_CONST struct pam_message **, struct pam_response **, void *); static char *def_prompt = "Password:"; -static int gotintr; +static int getpass_error; #ifndef PAM_DATA_SILENT #define PAM_DATA_SILENT 0 @@ -166,10 +166,12 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth) } /* FALLTHROUGH */ case PAM_AUTH_ERR: - if (gotintr) { + case PAM_AUTHINFO_UNAVAIL: + if (getpass_error) { /* error or ^C from tgetpass() */ debug_return_int(AUTH_INTR); } + /* FALLTHROUGH */ case PAM_MAXTRIES: case PAM_PERM_DENIED: debug_return_int(AUTH_FAILURE); @@ -297,6 +299,7 @@ converse(int num_msg, PAM_CONST struct pam_message **msg, const char *prompt; char *pass; int n, type, std_prompt; + int ret = PAM_AUTH_ERR; debug_decl(converse, SUDO_DEBUG_AUTH) if ((*response = malloc(num_msg * sizeof(struct pam_response))) == NULL) @@ -308,12 +311,13 @@ converse(int num_msg, PAM_CONST struct pam_message **msg, switch (pm->msg_style) { case PAM_PROMPT_ECHO_ON: type = SUDO_CONV_PROMPT_ECHO_ON; + /* FALLTHROUGH */ case PAM_PROMPT_ECHO_OFF: prompt = def_prompt; /* Error out if the last password read was interrupted. */ - if (gotintr) - goto err; + if (getpass_error) + goto done; /* Is the sudo prompt standard? (If so, we'l just use PAM's) */ std_prompt = strncmp(def_prompt, "Password:", 9) == 0 && @@ -335,13 +339,12 @@ converse(int num_msg, PAM_CONST struct pam_message **msg, /* Read the password unless interrupted. */ pass = auth_getpass(prompt, def_passwd_timeout * 60, type); if (pass == NULL) { - /* We got ^C instead of a password; abort quickly. */ - if (errno == EINTR) - gotintr = 1; -#if defined(__darwin__) || defined(__APPLE__) + /* Error (or ^C) reading password, don't try again. */ + getpass_error = 1; +#if (defined(__darwin__) || defined(__APPLE__)) && !defined(OPENPAM_VERSION) pass = ""; #else - goto err; + goto done; #endif } pr->resp = estrdup(pass); @@ -358,23 +361,25 @@ converse(int num_msg, PAM_CONST struct pam_message **msg, } break; default: - goto err; + ret = PAM_CONV_ERR; + goto done; } } + ret = PAM_SUCCESS; - debug_return_int(PAM_SUCCESS); - -err: - /* Zero and free allocated memory and return an error. */ - for (pr = *response, n = num_msg; n--; pr++) { - if (pr->resp != NULL) { - zero_bytes(pr->resp, strlen(pr->resp)); - free(pr->resp); - pr->resp = NULL; +done: + if (ret != PAM_SUCCESS) { + /* Zero and free allocated memory and return an error. */ + for (pr = *response, n = num_msg; n--; pr++) { + if (pr->resp != NULL) { + zero_bytes(pr->resp, strlen(pr->resp)); + free(pr->resp); + pr->resp = NULL; + } } + zero_bytes(*response, num_msg * sizeof(struct pam_response)); + free(*response); + *response = NULL; } - zero_bytes(*response, num_msg * sizeof(struct pam_response)); - free(*response); - *response = NULL; - debug_return_int(gotintr ? PAM_AUTH_ERR : PAM_CONV_ERR); + debug_return_int(ret); } -- 2.50.0