- (dtucker) [auth-pam.c auth-pam.h auth1.c auth2.c monitor.c monitor_wrap.c
monitor_wrap.h] Bug #808: Ensure force_pwchange is correctly initialized
even if keyboard-interactive is not used by the client. Prevents segfaults
in some cases where the user's password is expired (note this is not
considered a security exposure). ok djm@
diff --git a/ChangeLog b/ChangeLog
index 24afd75..cfedf89 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,14 @@
20040308
- (dtucker) [sshd.c] Back out rev 1.270 as it caused problems on some
- platforms (eg SCO, HP-UX) with logging in the wrong TZ.
+ platforms (eg SCO, HP-UX) with logging in the wrong TZ. ok djm@
+ - (dtucker) [configure.ac sshd.c openbsd-compat/bsd-misc.h
+ openbsd-compat/setenv.c] Unset KRB5CCNAME on AIX to prevent it from being
+ inherited by the child. ok djm@
+ - (dtucker) [auth-pam.c auth-pam.h auth1.c auth2.c monitor.c monitor_wrap.c
+ monitor_wrap.h] Bug #808: Ensure force_pwchange is correctly initialized
+ even if keyboard-interactive is not used by the client. Prevents segfaults
+ in some cases where the user's password is expired (note this is not
+ considered a security exposure). ok djm@
20040307
- (tim) [regress/login-timeout.sh] fix building outside of source tree.
@@ -861,4 +869,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
-$Id: ChangeLog,v 1.3278 2004/03/08 11:13:12 dtucker Exp $
+$Id: ChangeLog,v 1.3279 2004/03/08 12:04:06 dtucker Exp $
diff --git a/auth-pam.c b/auth-pam.c
index ea361f1..6f2264c 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -31,7 +31,7 @@
/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.97 2004/03/04 09:03:54 dtucker Exp $");
+RCSID("$Id: auth-pam.c,v 1.98 2004/03/08 12:04:06 dtucker Exp $");
#ifdef USE_PAM
#if defined(HAVE_SECURITY_PAM_APPL_H)
@@ -160,7 +160,7 @@
static int sshpam_cred_established = 0;
static int sshpam_account_status = -1;
static char **sshpam_env = NULL;
-static int *force_pwchange;
+static Authctxt *the_authctxt = NULL;
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
@@ -180,7 +180,9 @@
pam_password_change_required(int reqd)
{
debug3("%s %d", __func__, reqd);
- *force_pwchange = reqd;
+ if (the_authctxt == NULL)
+ fatal("%s: PAM authctxt not initialized", __func__);
+ the_authctxt->force_pwchange = reqd;
if (reqd) {
no_port_forwarding_flag |= 2;
no_agent_forwarding_flag |= 2;
@@ -339,6 +341,9 @@
sshpam_conv.conv = sshpam_thread_conv;
sshpam_conv.appdata_ptr = ctxt;
+ if (the_authctxt == NULL)
+ fatal("%s: PAM authctxt not initialized", __func__);
+
buffer_init(&buffer);
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&sshpam_conv);
@@ -351,7 +356,7 @@
if (compat20) {
if (!do_pam_account())
goto auth_fail;
- if (*force_pwchange) {
+ if (the_authctxt->force_pwchange) {
sshpam_err = pam_chauthtok(sshpam_handle,
PAM_CHANGE_EXPIRED_AUTHTOK);
if (sshpam_err != PAM_SUCCESS)
@@ -365,7 +370,7 @@
#ifndef USE_POSIX_THREADS
/* Export variables set by do_pam_account */
buffer_put_int(&buffer, sshpam_account_status);
- buffer_put_int(&buffer, *force_pwchange);
+ buffer_put_int(&buffer, the_authctxt->force_pwchange);
/* Export any environment strings set in child */
for(i = 0; environ[i] != NULL; i++)
@@ -446,11 +451,11 @@
}
static int
-sshpam_init(const char *user)
+sshpam_init(Authctxt *authctxt)
{
extern u_int utmp_len;
extern char *__progname;
- const char *pam_rhost, *pam_user;
+ const char *pam_rhost, *pam_user, *user = authctxt->user;
if (sshpam_handle != NULL) {
/* We already have a PAM context; check if the user matches */
@@ -464,6 +469,8 @@
debug("PAM: initializing for \"%s\"", user);
sshpam_err =
pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle);
+ the_authctxt = authctxt;
+
if (sshpam_err != PAM_SUCCESS) {
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
@@ -506,7 +513,7 @@
return NULL;
/* Initialize PAM */
- if (sshpam_init(authctxt->user) == -1) {
+ if (sshpam_init(authctxt) == -1) {
error("PAM: initialization failed");
return (NULL);
}
@@ -514,8 +521,6 @@
ctxt = xmalloc(sizeof *ctxt);
memset(ctxt, 0, sizeof(*ctxt));
- force_pwchange = &(authctxt->force_pwchange);
-
/* Start the authentication thread */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
error("PAM: failed create sockets: %s", strerror(errno));
@@ -674,12 +679,12 @@
* This replaces auth-pam.c
*/
void
-start_pam(const char *user)
+start_pam(Authctxt *authctxt)
{
if (!options.use_pam)
fatal("PAM: initialisation requested when UsePAM=no");
- if (sshpam_init(user) == -1)
+ if (sshpam_init(authctxt) == -1)
fatal("PAM: initialisation failed");
}
diff --git a/auth-pam.h b/auth-pam.h
index 4bc8d69..1b3706e 100644
--- a/auth-pam.h
+++ b/auth-pam.h
@@ -1,4 +1,4 @@
-/* $Id: auth-pam.h,v 1.24 2004/02/10 02:23:29 dtucker Exp $ */
+/* $Id: auth-pam.h,v 1.25 2004/03/08 12:04:07 dtucker Exp $ */
/*
* Copyright (c) 2000 Damien Miller. All rights reserved.
@@ -31,7 +31,7 @@
# define SSHD_PAM_SERVICE __progname
#endif
-void start_pam(const char *);
+void start_pam(Authctxt *);
void finish_pam(void);
u_int do_pam_account(void);
void do_pam_session(void);
diff --git a/auth1.c b/auth1.c
index 82fe5fb..f145cf0 100644
--- a/auth1.c
+++ b/auth1.c
@@ -307,7 +307,7 @@
#ifdef USE_PAM
if (options.use_pam)
- PRIVSEP(start_pam(user));
+ PRIVSEP(start_pam(authctxt));
#endif
/*
diff --git a/auth2.c b/auth2.c
index a9490cc..1177efa 100644
--- a/auth2.c
+++ b/auth2.c
@@ -150,24 +150,24 @@
if (authctxt->attempt++ == 0) {
/* setup auth context */
authctxt->pw = PRIVSEP(getpwnamallow(user));
+ authctxt->user = xstrdup(user);
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
authctxt->valid = 1;
debug2("input_userauth_request: setting up authctxt for %s", user);
#ifdef USE_PAM
if (options.use_pam)
- PRIVSEP(start_pam(authctxt->pw->pw_name));
+ PRIVSEP(start_pam(authctxt));
#endif
} else {
logit("input_userauth_request: illegal user %s", user);
authctxt->pw = fakepw();
#ifdef USE_PAM
if (options.use_pam)
- PRIVSEP(start_pam(user));
+ PRIVSEP(start_pam(authctxt));
#endif
}
setproctitle("%s%s", authctxt->pw ? user : "unknown",
use_privsep ? " [net]" : "");
- authctxt->user = xstrdup(user);
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
if (use_privsep)
diff --git a/monitor.c b/monitor.c
index 009dcf1..30f7258 100644
--- a/monitor.c
+++ b/monitor.c
@@ -782,16 +782,10 @@
int
mm_answer_pam_start(int socket, Buffer *m)
{
- char *user;
-
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
- user = buffer_get_string(m, NULL);
-
- start_pam(user);
-
- xfree(user);
+ start_pam(authctxt);
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_ACCOUNT, 1);
diff --git a/monitor_wrap.c b/monitor_wrap.c
index e7c15ce..b1b1c3a 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -686,7 +686,7 @@
#ifdef USE_PAM
void
-mm_start_pam(char *user)
+mm_start_pam(Authctxt *authctxt)
{
Buffer m;
@@ -695,8 +695,6 @@
fatal("UsePAM=no, but ended up in %s anyway", __func__);
buffer_init(&m);
- buffer_put_cstring(&m, user);
-
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
buffer_free(&m);
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 55be10b..2170b13 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -66,7 +66,7 @@
#endif
#ifdef USE_PAM
-void mm_start_pam(char *);
+void mm_start_pam(struct Authctxt *);
u_int mm_do_pam_account(void);
void *mm_sshpam_init_ctx(struct Authctxt *);
int mm_sshpam_query(void *, char **, char **, u_int *, char ***, u_int **);