grace logins on solaris

Damien Miller djm at mindrot.org
Wed May 31 09:56:06 EST 2000


On Tue, 30 May 2000, Chip Christian wrote:

> That's a step in the right direction, sure.  I'll test, but I assume when 
> grace logins are exhausted, pam_acct_mgmt returns something else.
> 
> Can this string (found from a -d invocation) also be displayed in this case?
> 
> 	debug: Adding PAM message: \
> 	Your password has expired and you have 4 grace login(s).
> 
> At some point I might find the free time to craft up the code for the 
> other case...

Hmmm, that message should have been displayed.

Can you try this patch:

Index: auth-pam.c
===================================================================
RCS file: /var/cvs/openssh/auth-pam.c,v
retrieving revision 1.4
diff -u -r1.4 auth-pam.c
--- auth-pam.c	2000/04/29 14:47:29	1.4
+++ auth-pam.c	2000/05/30 23:52:46
@@ -15,10 +15,14 @@
 
 RCSID("$Id: auth-pam.c,v 1.4 2000/04/29 14:47:29 damien Exp $");
 
+#define NEW_AUTHTOK_MSG \
+	"Warning: You password has expired, please change it now"
+
 /* Callbacks */
 static int pamconv(int num_msg, const struct pam_message **msg,
 	  struct pam_response **resp, void *appdata_ptr);
 void pam_cleanup_proc(void *context);
+void pam_msg_cat(const char *msg);
 
 /* module-local variables */
 static struct pam_conv conv = {
@@ -27,7 +31,7 @@
 };
 static struct pam_handle_t *pamh = NULL;
 static const char *pampasswd = NULL;
-static char *pamconv_msg = NULL;
+static char *pam_msg = NULL;
 
 /* PAM conversation function. This is really a kludge to get the password */
 /* into PAM and to pick up any messages generated by PAM into pamconv_msg */
@@ -36,8 +40,6 @@
 {
 	struct pam_response *reply;
 	int count;
-	size_t msg_len;
-	char *p;
 
 	/* PAM will free this later */
 	reply = malloc(num_msg * sizeof(*reply));
@@ -54,31 +56,14 @@
 				reply[count].resp_retcode = PAM_SUCCESS;
 				reply[count].resp = xstrdup(pampasswd);
 				break;
-
 			case PAM_TEXT_INFO:
 				reply[count].resp_retcode = PAM_SUCCESS;
 				reply[count].resp = xstrdup("");
 
-				if (msg[count]->msg == NULL)
-					break;
+				if (msg[count]->msg != NULL)
+					pam_msg_cat(msg[count]->msg);
 
-				debug("Adding PAM message: %s", msg[count]->msg);
-
-				msg_len = strlen(msg[count]->msg);
-				if (pamconv_msg) {
-					size_t n = strlen(pamconv_msg);
-					pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2);
-					p = pamconv_msg + n;
-				} else {
-					pamconv_msg = p = xmalloc(msg_len + 2);
-				}
-				memcpy(p, msg[count]->msg, msg_len);
-				p[msg_len] = '\n';
-				p[msg_len + 1] = '\0';
 				break;
-
-			case PAM_PROMPT_ECHO_ON:
-			case PAM_ERROR_MSG:
 			default:
 				free(reply);
 				return PAM_CONV_ERR;
@@ -100,19 +85,19 @@
 		pam_retval = pam_close_session((pam_handle_t *)pamh, 0);
 		if (pam_retval != PAM_SUCCESS) {
 			log("Cannot close PAM session: %.200s", 
-			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+				PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
 		}
 
 		pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED);
 		if (pam_retval != PAM_SUCCESS) {
 			log("Cannot delete credentials: %.200s", 
-			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+				PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
 		}
 
 		pam_retval = pam_end((pam_handle_t *)pamh, pam_retval);
 		if (pam_retval != PAM_SUCCESS) {
 			log("Cannot release PAM authentication: %.200s", 
-			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+				PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
 		}
 	}
 }
@@ -135,7 +120,8 @@
 	
 	pam_retval = pam_authenticate((pam_handle_t *)pamh, 0);
 	if (pam_retval == PAM_SUCCESS) {
-		debug("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name);
+		debug("PAM Password authentication accepted for user \"%.100s\"", 
+			pw->pw_name);
 		return 1;
 	} else {
 		debug("PAM Password authentication for \"%.100s\" failed: %s", 
@@ -148,26 +134,36 @@
 int do_pam_account(char *username, char *remote_user)
 {
 	int pam_retval;
-
+	
 	debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname());
 	pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, 
 		get_canonical_hostname());
 	if (pam_retval != PAM_SUCCESS) {
-		fatal("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+		fatal("PAM set rhost failed: %.200s", 
+			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
 	}
 
 	if (remote_user != NULL) {
 		debug("PAM setting ruser to \"%.200s\"", remote_user);
 		pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user);
 		if (pam_retval != PAM_SUCCESS) {
-			fatal("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+			fatal("PAM set ruser failed: %.200s", 
+				PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
 		}
 	}
 
 	pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0);
-	if (pam_retval != PAM_SUCCESS) {
-		log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
-		return(0);
+	switch (pam_retval) {
+		case PAM_SUCCESS:
+			/* This is what we want */
+			break;
+		case PAM_NEW_AUTHTOK_REQD:
+			pam_msg_cat(NEW_AUTHTOK_MSG);
+			break;
+		default:
+			log("PAM rejected by account configuration: %.200s", 
+				PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+			return(0);
 	}
 	
 	return(1);
@@ -181,13 +177,17 @@
 	if (ttyname != NULL) {
 		debug("PAM setting tty to \"%.200s\"", ttyname);
 		pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname);
-		if (pam_retval != PAM_SUCCESS)
-			fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+		if (pam_retval != PAM_SUCCESS) {
+			fatal("PAM set tty failed: %.200s", 
+				PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+		}
 	}
 
 	pam_retval = pam_open_session((pam_handle_t *)pamh, 0);
-	if (pam_retval != PAM_SUCCESS)
-		fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+	if (pam_retval != PAM_SUCCESS) {
+		fatal("PAM session setup failed: %.200s", 
+			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+	}
 }
 
 /* Set PAM credentials */ 
@@ -197,8 +197,10 @@
  
 	debug("PAM establishing creds");
 	pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED);
-	if (pam_retval != PAM_SUCCESS)
-		fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+	if (pam_retval != PAM_SUCCESS) {
+		fatal("PAM setcred failed: %.200s", 
+			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+	}
 }
 
 /* Cleanly shutdown PAM */
@@ -217,9 +219,12 @@
 
 	pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, 
 		(pam_handle_t**)&pamh);
-	if (pam_retval != PAM_SUCCESS)
-		fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
 
+	if (pam_retval != PAM_SUCCESS) {
+		fatal("PAM initialisation failed: %.200s", 
+			PAM_STRERROR((pam_handle_t *)pamh, pam_retval));
+	}
+	
 	fatal_add_cleanup(&pam_cleanup_proc, NULL);
 }
 
@@ -237,8 +242,30 @@
 /* or account checking to stderr */
 void print_pam_messages(void)
 {
-	if (pamconv_msg != NULL)
-		fprintf(stderr, pamconv_msg);
+	if (pam_msg != NULL)
+		fprintf(stderr, pam_msg);
+}
+
+/* Append a message to the PAM message buffer */
+void pam_msg_cat(const char *msg)
+{
+	char *p;
+	size_t new_msg_len;
+	size_t pam_msg_len;
+	
+	new_msg_len = strlen(msg);
+	
+	if (pam_msg) {
+		pam_msg_len = strlen(pam_msg);
+		pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2);
+		p = pam_msg + pam_msg_len;
+	} else {
+		pam_msg = p = xmalloc(new_msg_len + 2);
+	}
+
+	memcpy(p, msg, new_msg_len);
+	p[new_msg_len] = '\n';
+	p[new_msg_len + 1] = '\0';
 }
 
 #endif /* USE_PAM */

-- 
| "Bombay is 250ms from New York in the new world order" - Alan Cox
| Damien Miller - http://www.mindrot.org/
| Email: djm at mindrot.org (home) -or- djm at ibs.com.au (work)








More information about the openssh-unix-dev mailing list