diff --git a/plugins/sudoers/auth/pam.c b/plugins/sudoers/auth/pam.c index 69fd5ac92..e5afad9fd 100644 --- a/plugins/sudoers/auth/pam.c +++ b/plugins/sudoers/auth/pam.c @@ -174,6 +174,23 @@ conv_filter_init(void) debug_return; } +/* + * Like pam_strerror() but never returns NULL and uses strerror(errno) + * for PAM_SYSTEM_ERR. + */ +static const char * +sudo_pam_strerror(pam_handle_t *handle, int errnum) +{ + const char *errstr; + static char errbuf[32]; + + if (errnum == PAM_SYSTEM_ERR) + return strerror(errno); + if ((errstr = pam_strerror(handle, errnum)) == NULL) + (void)snprintf(errbuf, sizeof(errbuf), "PAM error %d", errnum); + return errstr; +} + static int sudo_pam_init2(struct passwd *pw, sudo_auth *auth, bool quiet) { @@ -198,8 +215,7 @@ sudo_pam_init2(struct passwd *pw, sudo_auth *auth, bool quiet) def_pam_login_service : def_pam_service; pam_status = pam_start(pam_service, pw->pw_name, &pam_conv, &pamh); if (pam_status != PAM_SUCCESS) { - if ((errstr = pam_strerror(NULL, pam_status)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(NULL, pam_status); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_start(%s, %s, %p, %p): %s", pam_service, pw->pw_name, &pam_conv, &pamh, errstr); @@ -217,16 +233,14 @@ sudo_pam_init2(struct passwd *pw, sudo_auth *auth, bool quiet) */ rc = pam_set_item(pamh, PAM_RUSER, user_name); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_set_item(pamh, PAM_RUSER, %s): %s", user_name, errstr); } #ifdef __sun__ rc = pam_set_item(pamh, PAM_RHOST, user_host); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_set_item(pamh, PAM_RHOST, %s): %s", user_host, errstr); } @@ -243,8 +257,7 @@ sudo_pam_init2(struct passwd *pw, sudo_auth *auth, bool quiet) if (tty != NULL) { rc = pam_set_item(pamh, PAM_TTY, tty); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_set_item(pamh, PAM_TTY, %s): %s", tty, errstr); } @@ -302,8 +315,8 @@ sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_co "pam_authenticate: %d", *pam_status); debug_return_int(AUTH_FAILURE); default: - if ((s = pam_strerror(pamh, *pam_status)) != NULL) - log_warningx(0, N_("PAM authentication error: %s"), s); + s = sudo_pam_strerror(pamh, *pam_status); + log_warningx(0, N_("PAM authentication error: %s"), s); debug_return_int(AUTH_FATAL); } } @@ -338,10 +351,8 @@ sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt) rc = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); if (rc == PAM_SUCCESS) break; - if ((s = pam_strerror(pamh, rc)) == NULL) - s = "unknown error"; - log_warningx(0, - N_("unable to change expired password: %s"), s); + s = pam_strerror(pamh, rc); + log_warningx(0, N_("unable to change expired password: %s"), s); status = AUTH_FAILURE; break; case PAM_AUTHTOK_EXPIRED: @@ -364,15 +375,13 @@ sudo_pam_approval(struct passwd *pw, sudo_auth *auth, bool exempt) case PAM_AUTHINFO_UNAVAIL: case PAM_MAXTRIES: case PAM_PERM_DENIED: - s = pam_strerror(pamh, rc); - log_warningx(0, N_("PAM account management error: %s"), - s ? s : "unknown error"); + s = sudo_pam_strerror(pamh, rc); + log_warningx(0, N_("PAM account management error: %s"), s); status = AUTH_FAILURE; break; default: - s = pam_strerror(pamh, rc); - log_warningx(0, N_("PAM account management error: %s"), - s ? s : "unknown error"); + s = sudo_pam_strerror(pamh, rc); + log_warningx(0, N_("PAM account management error: %s"), s); status = AUTH_FATAL; break; } @@ -412,8 +421,7 @@ sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth) if (pamh != NULL) { rc = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_end: %s", errstr); } @@ -428,8 +436,7 @@ sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth) */ rc = pam_set_item(pamh, PAM_USER, pw->pw_name); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_set_item(pamh, PAM_USER, %s): %s", pw->pw_name, errstr); } @@ -445,8 +452,7 @@ sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth) if (def_pam_setcred) { rc = pam_setcred(pamh, PAM_REINITIALIZE_CRED); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_setcred: %s", errstr); } @@ -464,8 +470,7 @@ sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth) break; case PAM_SESSION_ERR: /* Treat PAM_SESSION_ERR as a non-fatal error. */ - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_open_session: %s", errstr); /* Avoid closing session that was not opened. */ @@ -474,13 +479,11 @@ sudo_pam_begin_session(struct passwd *pw, char **user_envp[], sudo_auth *auth) default: /* Unexpected session failure, treat as fatal error. */ *pam_status = rc; - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); log_warningx(0, N_("%s: %s"), "pam_open_session", errstr); rc = pam_end(pamh, *pam_status | PAM_DATA_SILENT); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_end: %s", errstr); } @@ -529,16 +532,14 @@ sudo_pam_end_session(struct passwd *pw, sudo_auth *auth) */ rc = pam_set_item(pamh, PAM_USER, pw->pw_name); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_set_item(pamh, PAM_USER, %s): %s", pw->pw_name, errstr); } if (def_pam_session) { rc = pam_close_session(pamh, PAM_SILENT); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_close_session: %s", errstr); } @@ -546,16 +547,14 @@ sudo_pam_end_session(struct passwd *pw, sudo_auth *auth) if (def_pam_setcred) { rc = pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_setcred: %s", errstr); } } rc = pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT); if (rc != PAM_SUCCESS) { - if ((errstr = pam_strerror(pamh, rc)) == NULL) - errstr = "unknown error"; + errstr = sudo_pam_strerror(pamh, rc); sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "pam_end: %s", errstr); status = AUTH_FATAL;