]> granicus.if.org Git - sudo/commitdiff
Instead of treating ^C from tgetpass() specially, always
authorTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 11 Apr 2012 23:51:56 +0000 (19:51 -0400)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Wed, 11 Apr 2012 23:51:56 +0000 (19:51 -0400)
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

index 64ac30a80a363d615ffbd34e3bddd3f0064351ff..0de9af2127fc001fd5f3c888fa6eb016260de7e1 100644 (file)
@@ -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);
 }