- don't re-use the va list twice, leads to coredumps.

- introduce and use a "safe" version of pam_strerror(3) that does not return
   NULL
This commit is contained in:
christos 2013-06-20 20:54:02 +00:00
parent d4c14d49dd
commit f9bc1aff9f
1 changed files with 23 additions and 9 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: su_pam.c,v 1.17 2012/03/15 02:02:23 joerg Exp $ */
/* $NetBSD: su_pam.c,v 1.18 2013/06/20 20:54:02 christos Exp $ */
/*
* Copyright (c) 1988 The Regents of the University of California.
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1988\
#if 0
static char sccsid[] = "@(#)su.c 8.3 (Berkeley) 4/2/94";*/
#else
__RCSID("$NetBSD: su_pam.c,v 1.17 2012/03/15 02:02:23 joerg Exp $");
__RCSID("$NetBSD: su_pam.c,v 1.18 2013/06/20 20:54:02 christos Exp $");
#endif
#endif /* not lint */
@ -83,6 +83,18 @@ static const struct pam_conv pamc = { &openpam_ttyconv, NULL };
static void logit(const char *, ...) __printflike(1, 2);
static const char *
safe_pam_strerror(pam_handle_t *pamh, int pam_err) {
const char *msg;
if ((msg = pam_strerror(pamh, pam_err)) != NULL)
return msg;
static char buf[1024];
snprintf(buf, sizeof(buf), "Unknown pam error %d", pam_err);
return buf;
}
int
main(int argc, char **argv)
{
@ -215,7 +227,7 @@ main(int argc, char **argv)
PAM_END("pam_start");
/* Things went really bad... */
syslog(LOG_ERR, "pam_start failed: %s",
pam_strerror(pamh, pam_err));
safe_pam_strerror(pamh, pam_err));
errx(EXIT_FAILURE, "pam_start failed");
}
@ -239,9 +251,9 @@ main(int argc, char **argv)
*/
if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
syslog(LOG_WARNING, "BAD SU %s to %s%s: %s",
username, user, ontty(), pam_strerror(pamh, pam_err));
username, user, ontty(), safe_pam_strerror(pamh, pam_err));
(void)pam_end(pamh, pam_err);
errx(EXIT_FAILURE, "Sorry: %s", pam_strerror(pamh, pam_err));
errx(EXIT_FAILURE, "Sorry: %s", safe_pam_strerror(pamh, pam_err));
}
/*
@ -267,7 +279,7 @@ main(int argc, char **argv)
pam_err = pam_get_item(pamh, PAM_USER, &newuser);
if (pam_err != PAM_SUCCESS) {
syslog(LOG_WARNING,
"pam_get_item(PAM_USER): %s", pam_strerror(pamh, pam_err));
"pam_get_item(PAM_USER): %s", safe_pam_strerror(pamh, pam_err));
} else {
user = (char *)__UNCONST(newuser);
if (getpwnam_r(user, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 ||
@ -423,11 +435,11 @@ out:
pam_err = pam_setcred(pamh, PAM_DELETE_CRED);
if (pam_err != PAM_SUCCESS)
logit("pam_setcred: %s",
pam_strerror(pamh, pam_err));
safe_pam_strerror(pamh, pam_err));
pam_err = pam_close_session(pamh, 0);
if (pam_err != PAM_SUCCESS)
logit("pam_close_session: %s",
pam_strerror(pamh, pam_err));
safe_pam_strerror(pamh, pam_err));
(void)pam_end(pamh, pam_err);
exit(WEXITSTATUS(status));
break;
@ -543,7 +555,7 @@ out:
(void)execv(shell, np);
err(EXIT_FAILURE, "%s", shell);
done:
logit("%s: %s", func, pam_strerror(pamh, pam_err));
logit("%s: %s", func, safe_pam_strerror(pamh, pam_err));
(void)pam_end(pamh, pam_err);
return EXIT_FAILURE;
}
@ -555,6 +567,8 @@ logit(const char *fmt, ...)
va_start(ap, fmt);
vwarnx(fmt, ap);
va_end(ap);
va_start(ap, fmt);
vsyslog(LOG_ERR, fmt, ap);
va_end(ap);
}