Patch for changing expired passwords
Dave Dykstra
dwd at bell-labs.com
Tue Oct 16 04:00:54 EST 2001
On Fri, Oct 12, 2001 at 02:42:28PM -0700, Iain Morgan wrote:
> A fix for this issue is definitely needed. We have had to back off of
> implementing OpenSSH on our SGI's and Crays due to the issue of password
> expiration.
>
> At a glance, one item that I would take execption with is the special handling
> for root. Perhaps the behaviour for root should be configurable.
I certainly wouldn't want an extra configuration option, but looking back I
can't think of any reason why I would have put that check in there. I took
it out; the updated patch is below. I tested expiring a root login, and
there's not even any adverse interactions with the PermitRootLogin option,
because that is checked separately before it gets to allowed_user() in
auth.c.
- Dave Dykstra
--- auth.c.O Fri Oct 12 14:42:38 2001
+++ auth.c Mon Oct 15 13:57:05 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;
@@ -90,7 +93,7 @@
/* Check password expiry */
if ((spw->sp_lstchg >= 0) && (spw->sp_max >= 0) &&
(days > (spw->sp_lstchg + spw->sp_max)))
- 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 13:18:52 2001
+++ auth.h Fri Oct 12 15:00:10 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 Fri Oct 12 14:42:41 2001
+++ session.c Fri Oct 12 15:04:29 2001
@@ -656,7 +656,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 Fri Oct 12 14:42:39 2001
+++ configure.in Fri Oct 12 15:00:57 2001
@@ -1449,6 +1449,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 Fri Oct 12 14:42:37 2001
+++ acconfig.h Mon Oct 15 13:59:02 2001
@@ -214,6 +214,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