- (djm) Workaround PAM inconsistencies between Solaris derived PAM code
   and Linux-PAM. Based on report and fix from Andrew Morgan
   <morgan@transmeta.com>
diff --git a/CREDITS b/CREDITS
index b8c5482..797b189 100644
--- a/CREDITS
+++ b/CREDITS
@@ -8,6 +8,7 @@
 Andre Lucas <andre.lucas@dial.pipex.com> - new login code, many fixes
 Andreas Steinmetz <ast@domdv.de> - Shadow password expiry support
 Andrew McGill <andrewm@datrix.co.za> - SCO fixes
+Andrew Morgan <morgan@transmeta.com> - PAM bugfixes
 Andrew Stribblehill <a.d.stribblehill@durham.ac.uk> - Bugfixes
 Andy Sloane <andy@guildsoftware.com> - bugfixes
 Aran Cox <acox@cv.telegroup.com> - SCO bugfixes
diff --git a/ChangeLog b/ChangeLog
index 38bd2b3..a99195e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+20001220
+ - (djm) Workaround PAM inconsistencies between Solaris derived PAM code 
+   and Linux-PAM. Based on report and fix from Andrew Morgan
+   <morgan@transmeta.com>
+
 20001218
  - (stevesk) rsa.c: entropy.h not needed.
  - (bal) split CFLAGS into CFLAGS and CPPFLAGS in configure.in and Makefile.
diff --git a/acconfig.h b/acconfig.h
index bfbacba..21832fe 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -218,6 +218,10 @@
 /* to pam_strerror */
 #undef HAVE_OLD_PAM
 
+/* Define if you are using Solaris-derived PAM which passes pam_messages  */
+/* to the conversation function with an extra level of indirection */
+#undef PAM_SUN_CODEBASE
+ 
 /* Set this to your mail directory if you don't have maillock.h */
 #undef MAIL_DIRECTORY
 
diff --git a/auth-pam.c b/auth-pam.c
index 1e07760..07847cb 100644
--- a/auth-pam.c
+++ b/auth-pam.c
@@ -29,7 +29,7 @@
 #include "xmalloc.h"
 #include "servconf.h"
 
-RCSID("$Id: auth-pam.c,v 1.19 2000/12/03 00:51:51 djm Exp $");
+RCSID("$Id: auth-pam.c,v 1.20 2000/12/20 02:34:49 djm Exp $");
 
 #define NEW_AUTHTOK_MSG \
 	"Warning: Your password has expired, please change it now"
@@ -97,13 +97,13 @@
 		return PAM_CONV_ERR; 
 
 	for (count = 0; count < num_msg; count++) {
-		switch ((*msg)[count].msg_style) {
+		switch(PAM_MSG_MEMBER(msg, count, msg_style)) {
 			case PAM_PROMPT_ECHO_ON:
 				if (pamstate == INITIAL_LOGIN) {
 					free(reply);
 					return PAM_CONV_ERR;
 				} else {
-					fputs((*msg)[count].msg, stderr);
+					fputs(PAM_MSG_MEMBER(msg, count, msg), stderr);
 					fgets(buf, sizeof(buf), stdin);
 					reply[count].resp = xstrdup(buf);
 					reply[count].resp_retcode = PAM_SUCCESS;
@@ -118,7 +118,7 @@
 					reply[count].resp = xstrdup(pampasswd);
 				} else {
 					reply[count].resp = 
-						xstrdup(read_passphrase((*msg)[count].msg, 1));
+						xstrdup(read_passphrase(PAM_MSG_MEMBER(msg, count, msg), 1));
 				}
 				reply[count].resp_retcode = PAM_SUCCESS;
 				break;
@@ -126,9 +126,9 @@
 			case PAM_TEXT_INFO:
 				if ((*msg)[count].msg != NULL) {
 					if (pamstate == INITIAL_LOGIN)
-						pam_msg_cat((*msg)[count].msg);
+						pam_msg_cat(PAM_MSG_MEMBER(msg, count, msg));
 					else {
-						fputs((*msg)[count].msg, stderr);
+						fputs(PAM_MSG_MEMBER(msg, count, msg), stderr);
 						fputs("\n", stderr);
 					}
 				}
diff --git a/auth2-pam.c b/auth2-pam.c
index 8ffbc24..30e0210 100644
--- a/auth2-pam.c
+++ b/auth2-pam.c
@@ -1,5 +1,5 @@
 #include "includes.h"
-RCSID("$Id: auth2-pam.c,v 1.1 2000/12/03 00:51:51 djm Exp $");
+RCSID("$Id: auth2-pam.c,v 1.2 2000/12/20 02:34:49 djm Exp $");
 
 #ifdef USE_PAM
 #include "ssh.h"
@@ -70,8 +70,8 @@
 	packet_put_cstring("");				/* Instructions */
 	packet_put_cstring("");				/* Language */
 	for (i = 0, j = 0; i < num_msg; i++) {
-		if(((*msg)[i].msg_style == PAM_PROMPT_ECHO_ON) ||
-		   ((*msg)[i].msg_style == PAM_PROMPT_ECHO_OFF) ||
+		if((PAM_MSG_MEMBER(msg, i, msg_style) == PAM_PROMPT_ECHO_ON) ||
+		   (PAM_MSG_MEMBER(msg, i, msg_style) == PAM_PROMPT_ECHO_OFF) ||
 		   (i == num_msg - 1)) {
 			j++;
 		}
@@ -79,7 +79,7 @@
 	packet_put_int(j);				/* Number of prompts. */
 	context_pam2.num_expected = j;
 	for (i = 0, j = 0; i < num_msg; i++) {
-		switch((*msg)[i].msg_style) {
+		switch(PAM_MSG_MEMBER(msg, i, msg_style)) {
 			case PAM_PROMPT_ECHO_ON:
 				echo = 1;
 				break;
@@ -91,18 +91,18 @@
 				break;
 		}
 		if(text) {
-			tmp = xmalloc(strlen(text) + strlen((*msg)[i].msg) + 2);
+			tmp = xmalloc(strlen(text) + strlen(PAM_MSG_MEMBER(msg, i, msg)) + 2);
 			strcpy(tmp, text);
 			strcat(tmp, "\n");
-			strcat(tmp, (*msg)[i].msg);
+			strcat(tmp, PAM_MSG_MEMBER(msg, i, msg));
 			xfree(text);
 			text = tmp;
 			tmp = NULL;
 		} else {
-			text = xstrdup((*msg)[i].msg);
+			text = xstrdup(PAM_MSG_MEMBER(msg, i, msg));
 		}
-		if(((*msg)[i].msg_style == PAM_PROMPT_ECHO_ON) ||
-		   ((*msg)[i].msg_style == PAM_PROMPT_ECHO_OFF) ||
+		if((PAM_MSG_MEMBER(msg, i, msg_style) == PAM_PROMPT_ECHO_ON) ||
+		   (PAM_MSG_MEMBER(msg, i, msg_style) == PAM_PROMPT_ECHO_OFF) ||
 		   (i == num_msg - 1)) {
 			debug("sending prompt ssh-%d(pam-%d) = \"%s\"",
 			      j, i, text);
diff --git a/configure.in b/configure.in
index 9f3b10c..4601cd3 100644
--- a/configure.in
+++ b/configure.in
@@ -88,6 +88,7 @@
 *-*-hpux11*)
 	CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE"
 	IPADDR_IN_DISPLAY=yes
+	AC_DEFINE(PAM_SUN_CODEBASE)
 	AC_DEFINE(USE_PIPES)
 	AC_DEFINE(DISABLE_SHADOW)
 	AC_DEFINE(DISABLE_UTMP)
@@ -149,6 +150,7 @@
 	CPPFLAGS="$CPPFLAGS -I/usr/local/include"
 	LDFLAGS="$LDFLAGS -L/usr/local/lib -R/usr/local/lib -L/usr/ucblib -R/usr/ucblib"
 	need_dash_r=1
+	AC_DEFINE(PAM_SUN_CODEBASE)
 	# hardwire lastlog location (can't detect it on some versions)
 	conf_lastlog_location="/var/adm/lastlog"
 	AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x)
@@ -164,6 +166,7 @@
 *-*-sunos4*)
 	CPPFLAGS="$CPPFLAGS -DSUNOS4"
 	AC_CHECK_FUNCS(getpwanam)
+	AC_DEFINE(PAM_SUN_CODEBASE)
 	conf_utmp_location=/etc/utmp
 	conf_wtmp_location=/var/adm/wtmp
 	conf_lastlog_location=/var/adm/lastlog
@@ -1614,6 +1617,13 @@
 
 echo ""
 
+if test "x$PAM_MSG" = "xyes" ; then
+	echo "PAM is enabled. You may need to install a PAM control file for sshd,"
+	echo "otherwise password authentication may fail. Example PAM control files"
+	echo "can be found in the contrib/ subdirectory"
+	echo ""
+fi
+
 if test ! -z "$BUILTIN_RNG" ; then
 	echo "WARNING: you are using the builtin random number collection service."
 	echo "Please read WARNING.RNG and request that your OS vendor includes"
diff --git a/defines.h b/defines.h
index 642b007..4c3941c 100644
--- a/defines.h
+++ b/defines.h
@@ -340,6 +340,12 @@
 # define PAM_STRERROR(a,b) pam_strerror((a),(b))
 #endif
 
+#ifdef PAM_SUN_CODEBASE
+# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member)
+#else
+# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member)
+#endif
+
 #if defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO)
 # undef HAVE_GETADDRINFO
 #endif /* defined(BROKEN_GETADDRINFO) && defined(HAVE_GETADDRINFO) */