Add sudo_pam_strerror(), like pam_strerror() but never returns NULL.

It also uses strerror(errno) for PAM_SYSTEM_ERR.
This commit is contained in:
Todd C. Miller
2019-08-29 17:30:13 -06:00
parent 60862b4d07
commit 5138ed9bec

View File

@@ -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,7 +315,7 @@ 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)
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;