summaryrefslogtreecommitdiff
path: root/usr.bin/sudo/auth/pam.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2007-07-26 16:10:17 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2007-07-26 16:10:17 +0000
commit828fe35b0dee0a24eae19e816e9f6bc05c720bc0 (patch)
tree2adb27efde016e50eadcf2e74892e19861268a25 /usr.bin/sudo/auth/pam.c
parenteb13f7f0aa17caa3bf79e5518751b3f095fb2445 (diff)
Update to sudo 1.6.9p1. Note that the environment handling in sudo
1.6.9 has changed relative to older versions. Sudo now starts commands with a minimal environment containing the variables in the env_keep and env_check lists. This behavior is configurable in the sudoers file. Please see the "SECURITY NOTES" section in the sudo manual.
Diffstat (limited to 'usr.bin/sudo/auth/pam.c')
-rw-r--r--usr.bin/sudo/auth/pam.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/usr.bin/sudo/auth/pam.c b/usr.bin/sudo/auth/pam.c
index d289a06ef5c..f4693f08e08 100644
--- a/usr.bin/sudo/auth/pam.c
+++ b/usr.bin/sudo/auth/pam.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2004 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 1999-2005 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -18,7 +18,7 @@
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
-#include "config.h"
+#include <config.h>
#include <sys/types.h>
#include <sys/param.h>
@@ -56,14 +56,14 @@
#include "sudo_auth.h"
/* Only OpenPAM and Linux PAM use const qualifiers. */
-#if defined(_OPENPAM) || defined(__LIBPAM_VERSION)
+#if defined(_OPENPAM) || defined(__LIBPAM_VERSION) || defined(__LINUX_PAM__)
# define PAM_CONST const
#else
# define PAM_CONST
#endif
#ifndef lint
-static const char rcsid[] = "$Sudo: pam.c,v 1.43 2004/06/28 14:51:50 millert Exp $";
+__unused static const char rcsid[] = "$Sudo: pam.c,v 1.43.2.4 2007/07/22 12:14:53 millert Exp $";
#endif /* lint */
static int sudo_conv __P((int, PAM_CONST struct pam_message **,
@@ -94,7 +94,14 @@ pam_init(pw, promptp, auth)
log_error(USE_ERRNO|NO_EXIT|NO_MAIL, "unable to initialize PAM");
return(AUTH_FATAL);
}
- if (strcmp(user_tty, "unknown"))
+ /*
+ * Some versions of pam_lastlog have a bug that
+ * will cause a crash if PAM_TTY is not set so if
+ * there is no tty, set PAM_TTY to the empty string.
+ */
+ if (strcmp(user_tty, "unknown") == 0)
+ (void) pam_set_item(pamh, PAM_TTY, "");
+ else
(void) pam_set_item(pamh, PAM_TTY, user_tty);
return(AUTH_SUCCESS);
@@ -175,6 +182,8 @@ int
pam_prep_user(pw)
struct passwd *pw;
{
+ int eval;
+
if (pamh == NULL)
pam_init(pw, NULL, NULL);
@@ -195,6 +204,18 @@ pam_prep_user(pw)
*/
(void) pam_setcred(pamh, PAM_ESTABLISH_CRED);
+ /*
+ * To fully utilize PAM sessions we would need to keep a
+ * sudo process around until the command exits. However, we
+ * can at least cause pam_limits to be run by opening and then
+ * immediately closing the session.
+ */
+ if ((eval = pam_open_session(pamh, 0)) != PAM_SUCCESS) {
+ (void) pam_end(pamh, eval | PAM_DATA_SILENT);
+ return(AUTH_FAILURE);
+ }
+ (void) pam_close_session(pamh, 0);
+
if (pam_end(pamh, PAM_SUCCESS | PAM_DATA_SILENT) == PAM_SUCCESS)
return(AUTH_SUCCESS);
else
@@ -235,7 +256,12 @@ sudo_conv(num_msg, msg, response, appdata_ptr)
p = pm->msg;
/* Read the password. */
pass = tgetpass(p, def_passwd_timeout * 60, flags);
- pr->resp = estrdup(pass ? pass : "");
+ if (pass == NULL) {
+ /* We got ^C instead of a password; abort quickly. */
+ nil_pw = 1;
+ goto err;
+ }
+ pr->resp = estrdup(pass);
if (*pr->resp == '\0')
nil_pw = 1; /* empty password */
else
@@ -252,20 +278,23 @@ sudo_conv(num_msg, msg, response, appdata_ptr)
}
break;
default:
- /* 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;
- return(PAM_CONV_ERR);
+ goto err;
}
}
return(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;
+ }
+ }
+ zero_bytes(*response, num_msg * sizeof(struct pam_response));
+ free(*response);
+ *response = NULL;
+ return(PAM_CONV_ERR);
}