Patch for changing expired passwords

Dave Dykstra dwd at bell-labs.com
Fri Aug 24 03:22:40 EST 2001


Ben & Damien,

On Thu, Jun 21, 2001 at 01:08:07PM -0500, Dave Dykstra wrote:
> Markus has now installed a variation on my changes to session.c into
> openbsd openssh CVS, and Ben has pulled in the session.c changes into the
> portable openssh CVS, so here is an update of my patch based on the current
> portable openssh CVS.  Markus decided to defer the additional logging I
> suggested in auth.c, so I left that out.

Will this patch be able to be incorporated in the next portable release?
I've seen several people asking about this functionality, and Markus did
the preparation work in the base code.


> Note: I pointed out to Markus in private email that the line 
> "forced_command = NULL" should not be there in do_exec(), and it is
> unfortunately in the context of the following diff so if that change
> gets applied first this might not apply cleanly anymore.

That has since happened, but the patch still applied to the current
CVS with some small fuzz factors.  Here's an updated version anyhow.

- Dave


--- auth.c.O	Thu Aug 23 12:12:37 2001
+++ auth.c	Thu Aug 23 12:12:58 2001
@@ -49,6 +49,9 @@
 #include "uidswap.h"
 #include "tildexpand.h"
 
+/* set when password has expired */
+int forced_passwd_change = 0;
+
 /* import */
 extern ServerOptions options;
 
@@ -89,8 +92,12 @@
 
 		/* Check password expiry */
 		if ((spw->sp_lstchg >= 0) && (spw->sp_max >= 0) &&
-		    (days > (spw->sp_lstchg + spw->sp_max)))
-			return 0;
+		    (days > (spw->sp_lstchg + spw->sp_max))) {
+			if ((pw->pw_uid == 0))
+				return 0;
+
+			forced_passwd_change = 1;
+		}
 	}
 #else
 	/* Shouldn't be called if pw is NULL, but better safe than sorry... */
--- auth.h.O	Thu Aug 23 12:12:37 2001
+++ auth.h	Thu Aug 23 12:12:58 2001
@@ -40,6 +40,9 @@
 #include <krb5.h>
 #endif
 
+/* set when password has expired */
+extern int forced_passwd_change;
+
 typedef struct Authctxt Authctxt;
 typedef struct KbdintDevice KbdintDevice;
 
--- session.c.O	Thu Aug 23 12:12:37 2001
+++ session.c	Thu Aug 23 12:12:58 2001
@@ -657,7 +657,31 @@
 void
 do_exec(Session *s, const char *command)
 {
-	if (forced_command) {
+	if (forced_passwd_change) {
+		char *user = s->pw->pw_name;
+		char *msg;
+
+		if (s->ttyfd != -1) {
+			msg = "Password for %.100s has expired, running 'passwd' to reset it";
+			/*
+			 * Can't pass "user" to 'passwd' because Linux doesn't
+			 * allow it.
+			 * Also, the prompt is friendlier without "user".
+			 */
+			command = PASSWD_PATH;
+		} else {
+			msg = "Password for %.100s has expired and cannot be changed without a pty";
+			/*
+			 * Without a pty, Solaris 'passwd' prints "Permission
+			 * denied", but Linux attempts to change the password
+			 * and fails miserably, so echo an error message instead
+			 */
+			command = "/bin/sh -c 'echo Permission denied >&2; exit 1'";
+		}
+		log(msg, user);
+		packet_send_debug(msg, user);
+
+	} else if (forced_command) {
 		original_command = command;
 		command = forced_command;
 		debug("Forced command '%.900s'", command);
--- configure.in.O	Thu Aug 23 12:12:37 2001
+++ configure.in	Thu Aug 23 12:12:58 2001
@@ -1418,6 +1418,10 @@
 	AC_DEFINE_UNQUOTED(RSH_PATH, "$rsh_path")
 fi
 
+AC_PATH_PROG(PASSWD_PATH, passwd)
+AC_DEFINE_UNQUOTED(PASSWD_PATH, "$PASSWD_PATH")
+
+
 # Check for mail directory (last resort if we cannot get it from headers)
 if test ! -z "$MAIL" ; then
 	maildir=`dirname $MAIL`
--- acconfig.h.O	Thu Aug 23 12:12:37 2001
+++ acconfig.h	Thu Aug 23 12:12:58 2001
@@ -217,6 +217,9 @@
 /* Define if rsh is found in your path */
 #undef RSH_PATH
 
+/* Define if passwd is found in your path */
+#undef PASSWD_PATH
+
 /* Define if you want to allow MD5 passwords */
 #undef HAVE_MD5_PASSWORDS
 



More information about the openssh-unix-dev mailing list