diff --git a/ChangeLog b/ChangeLog
index c80b816f0..1ce633d7b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -49,6 +49,9 @@
      fix leak
  - (djm) Don't initialise pam_conv structures inline. Avoids HP/UX compiler
    error. Part of Bug #423, patch from  michael_steffens AT hp.com
+ - (djm) Bug #423: reorder setting of PAM_TTY and calling of PAM session 
+   management (now done in do_setusercontext). Largely from 
+   michael_steffens AT hp.com
 
 20030829
  - (bal) openbsd-compat/ clean up.  Considate headers, add in Id on our
@@ -964,4 +967,4 @@
  - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
    Report from murple@murple.net, diagnosis from dtucker@zip.com.au
 
-$Id: ChangeLog,v 1.2935 2003/09/02 13:12:06 djm Exp $
+$Id: ChangeLog,v 1.2936 2003/09/02 13:18:52 djm Exp $
diff --git a/auth-pam.c b/auth-pam.c
index 3f3fbf28c..bc378a32b 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.69 2003/09/02 13:12:06 djm Exp $");
+RCSID("$Id: auth-pam.c,v 1.70 2003/09/02 13:18:53 djm Exp $");
 
 #ifdef USE_PAM
 #include <security/pam_appl.h>
@@ -534,13 +534,23 @@ do_pam_account(void)
 }
 
 void
-do_pam_session(const char *user, const char *tty)
+do_pam_session(void)
 {
 	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, 
 	    (const void *)&null_conv);
 	if (sshpam_err != PAM_SUCCESS)
 		fatal("PAM: failed to set PAM_CONV: %s",
 		    pam_strerror(sshpam_handle, sshpam_err));
+	sshpam_err = pam_open_session(sshpam_handle, 0);
+	if (sshpam_err != PAM_SUCCESS)
+		fatal("PAM: pam_open_session(): %s",
+		    pam_strerror(sshpam_handle, sshpam_err));
+	sshpam_session_open = 1;
+}
+
+void
+do_pam_set_tty(const char *tty)
+{
 	if (tty != NULL) {
 		debug("PAM: setting PAM_TTY to \"%s\"", tty);
 		sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty);
@@ -548,11 +558,6 @@ do_pam_session(const char *user, const char *tty)
 			fatal("PAM: failed to set PAM_TTY: %s",
 			    pam_strerror(sshpam_handle, sshpam_err));
 	}
-	sshpam_err = pam_open_session(sshpam_handle, 0);
-	if (sshpam_err != PAM_SUCCESS)
-		fatal("PAM: pam_open_session(): %s",
-		    pam_strerror(sshpam_handle, sshpam_err));
-	sshpam_session_open = 1;
 }
 
 void
diff --git a/auth-pam.h b/auth-pam.h
index 03868312c..5c952f305 100644
--- a/auth-pam.h
+++ b/auth-pam.h
@@ -1,4 +1,4 @@
-/* $Id: auth-pam.h,v 1.20 2003/08/26 01:58:16 dtucker Exp $ */
+/* $Id: auth-pam.h,v 1.21 2003/09/02 13:18:53 djm Exp $ */
 
 /*
  * Copyright (c) 2000 Damien Miller.  All rights reserved.
@@ -34,7 +34,8 @@
 void start_pam(const char *);
 void finish_pam(void);
 u_int do_pam_account(void);
-void do_pam_session(const char *, const char *);
+void do_pam_session(void);
+void do_pam_set_tty(const char *);
 void do_pam_setcred(int );
 int is_pam_password_change_required(void);
 void do_pam_chauthtok(void);
diff --git a/session.c b/session.c
index 5463eebec..35328ecbb 100644
--- a/session.c
+++ b/session.c
@@ -396,7 +396,6 @@ do_exec_no_pty(Session *s, const char *command)
 
 #if defined(USE_PAM)
 	if (options.use_pam) {
-		do_pam_session(s->pw->pw_name, NULL);
 		do_pam_setcred(1);
 		if (is_pam_password_change_required())
 			packet_disconnect("Password change required but no "
@@ -525,7 +524,7 @@ do_exec_pty(Session *s, const char *command)
 
 #if defined(USE_PAM)
 	if (options.use_pam) {
-		do_pam_session(s->pw->pw_name, s->tty);
+		do_pam_set_tty(s->tty);
 		do_pam_setcred(1);
 	}
 #endif
@@ -1205,8 +1204,10 @@ do_setusercontext(struct passwd *pw)
 		 * These will have been wiped by the above initgroups() call.
 		 * Reestablish them here.
 		 */
-		if (options.use_pam)
+		if (options.use_pam) {
+			do_pam_session();
 			do_pam_setcred(0);
+		}
 # endif /* USE_PAM */
 # if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
 		irix_setusercontext(pw);