summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2004-01-30 09:48:58 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2004-01-30 09:48:58 +0000
commit6b8cd81185d109e8cb3c1c4ee5aad053e8cf8838 (patch)
tree77a3cad5aa3d754c78031ced9f98d53deeaf8a05 /usr.bin
parent37c661a56e70ec46912339948f738f902333cee0 (diff)
support for password change; ok dtucker@
(set password-dead=1w in login.conf to use this).
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/ssh/auth-passwd.c70
-rw-r--r--usr.bin/ssh/auth.h3
-rw-r--r--usr.bin/ssh/pathnames.h5
-rw-r--r--usr.bin/ssh/session.c89
4 files changed, 116 insertions, 51 deletions
diff --git a/usr.bin/ssh/auth-passwd.c b/usr.bin/ssh/auth-passwd.c
index 1ef70dee5e6..ac2f1d5b25c 100644
--- a/usr.bin/ssh/auth-passwd.c
+++ b/usr.bin/ssh/auth-passwd.c
@@ -36,15 +36,24 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-passwd.c,v 1.30 2003/11/04 08:54:09 djm Exp $");
+RCSID("$OpenBSD: auth-passwd.c,v 1.31 2004/01/30 09:48:57 markus Exp $");
#include "packet.h"
#include "log.h"
#include "servconf.h"
#include "auth.h"
-
+#include "auth-options.h"
extern ServerOptions options;
+int sys_auth_passwd(Authctxt *, const char *);
+
+static void
+disable_forwarding(void)
+{
+ no_port_forwarding_flag = 1;
+ no_agent_forwarding_flag = 1;
+ no_x11_forwarding_flag = 1;
+}
/*
* Tries to authenticate the user using password. Returns true if
@@ -68,26 +77,47 @@ auth_password(Authctxt *authctxt, const char *password)
/* Fall back to ordinary passwd authentication. */
}
#endif
+ return (sys_auth_passwd(authctxt, password) && ok);
+}
+
#ifdef BSD_AUTH
- if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
- (char *)password) == 0)
- return 0;
- else
- return ok;
+int
+sys_auth_passwd(Authctxt *authctxt, const char *password)
+{
+ struct passwd *pw = authctxt->pw;
+ auth_session_t *as;
+
+ as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
+ (char *)password);
+ if (auth_getstate(as) & AUTH_PWEXPIRED) {
+ auth_close(as);
+ disable_forwarding();
+ authctxt->force_pwchange = 1;
+ return (1);
+ } else {
+ return (auth_close(as));
+ }
+}
#else
+int
+sys_auth_passwd(Authctxt *authctxt, const char *password)
+{
+ struct passwd *pw = authctxt->pw;
+ char *encrypted_password;
+
/* Check for users with no password. */
if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
- return ok;
- else {
- /* Encrypt the candidate password using the proper salt. */
- char *encrypted_password = crypt(password,
- (pw->pw_passwd[0] && pw->pw_passwd[1]) ?
- pw->pw_passwd : "xx");
- /*
- * Authentication is accepted if the encrypted passwords
- * are identical.
- */
- return (strcmp(encrypted_password, pw->pw_passwd) == 0) && ok;
- }
-#endif
+ return (1);
+
+ /* Encrypt the candidate password using the proper salt. */
+ encrypted_password = crypt(password,
+ (pw->pw_passwd[0] && pw->pw_passwd[1]) ?
+ pw->pw_passwd : "xx");
+
+ /*
+ * Authentication is accepted if the encrypted passwords
+ * are identical.
+ */
+ return (strcmp(encrypted_password, pw->pw_passwd) == 0);
}
+#endif
diff --git a/usr.bin/ssh/auth.h b/usr.bin/ssh/auth.h
index 360e9c3c5d7..e45137bdce8 100644
--- a/usr.bin/ssh/auth.h
+++ b/usr.bin/ssh/auth.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.h,v 1.48 2003/11/04 08:54:09 djm Exp $ */
+/* $OpenBSD: auth.h,v 1.49 2004/01/30 09:48:57 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -52,6 +52,7 @@ struct Authctxt {
int valid; /* user exists and is allowed to login */
int attempt;
int failures;
+ int force_pwchange;
char *user; /* username sent by the client */
char *service;
struct passwd *pw; /* set if 'valid' */
diff --git a/usr.bin/ssh/pathnames.h b/usr.bin/ssh/pathnames.h
index 3bc6b50e12b..2037054a76d 100644
--- a/usr.bin/ssh/pathnames.h
+++ b/usr.bin/ssh/pathnames.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pathnames.h,v 1.13 2002/05/23 19:24:30 markus Exp $ */
+/* $OpenBSD: pathnames.h,v 1.14 2004/01/30 09:48:57 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -128,3 +128,6 @@
/* chroot directory for unprivileged user when UsePrivilegeSeparation=yes */
#define _PATH_PRIVSEP_CHROOT_DIR "/var/empty"
+
+/* for passwd change */
+#define _PATH_PASSWD_PROG "/usr/bin/passwd"
diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c
index fd3cc58a5b4..ab425aed95f 100644
--- a/usr.bin/ssh/session.c
+++ b/usr.bin/ssh/session.c
@@ -33,7 +33,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.171 2004/01/13 19:23:15 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -1007,6 +1007,22 @@ do_setusercontext(struct passwd *pw)
}
static void
+do_pwchange(Session *s)
+{
+ fprintf(stderr, "WARNING: Your password has expired.\n");
+ if (s->ttyfd != -1) {
+ fprintf(stderr,
+ "You must change your password now and login again!\n");
+ execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
+ perror("passwd");
+ } else {
+ fprintf(stderr,
+ "Password change required but no TTY available.\n");
+ }
+ exit(1);
+}
+
+static void
launch_login(struct passwd *pw, const char *hostname)
{
/* Launch login(1). */
@@ -1020,6 +1036,40 @@ launch_login(struct passwd *pw, const char *hostname)
exit(1);
}
+static void
+child_close_fds(void)
+{
+ int i;
+
+ if (packet_get_connection_in() == packet_get_connection_out())
+ close(packet_get_connection_in());
+ else {
+ close(packet_get_connection_in());
+ close(packet_get_connection_out());
+ }
+ /*
+ * Close all descriptors related to channels. They will still remain
+ * open in the parent.
+ */
+ /* XXX better use close-on-exec? -markus */
+ channel_close_all();
+
+ /*
+ * Close any extra file descriptors. Note that there may still be
+ * descriptors left by system functions. They will be closed later.
+ */
+ endpwent();
+
+ /*
+ * Close any extra open file descriptors so that we don\'t have them
+ * hanging around in clients. Note that we want to do this after
+ * initgroups, because at least on Solaris 2.3 it leaves file
+ * descriptors open.
+ */
+ for (i = 3; i < 64; i++)
+ close(i);
+}
+
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@@ -1033,11 +1083,18 @@ do_child(Session *s, const char *command)
char *argv[10];
const char *shell, *shell0, *hostname = NULL;
struct passwd *pw = s->pw;
- u_int i;
/* remove hostkey from the child's memory */
destroy_sensitive_data();
+ /* Force a password change */
+ if (s->authctxt->force_pwchange) {
+ do_setusercontext(pw);
+ child_close_fds();
+ do_pwchange(s);
+ exit(1);
+ }
+
/* login(1) is only called if we execute the login shell */
if (options.use_login && command != NULL)
options.use_login = 0;
@@ -1078,33 +1135,7 @@ do_child(Session *s, const char *command)
* closed before building the environment, as we call
* get_remote_ipaddr there.
*/
- if (packet_get_connection_in() == packet_get_connection_out())
- close(packet_get_connection_in());
- else {
- close(packet_get_connection_in());
- close(packet_get_connection_out());
- }
- /*
- * Close all descriptors related to channels. They will still remain
- * open in the parent.
- */
- /* XXX better use close-on-exec? -markus */
- channel_close_all();
-
- /*
- * Close any extra file descriptors. Note that there may still be
- * descriptors left by system functions. They will be closed later.
- */
- endpwent();
-
- /*
- * Close any extra open file descriptors so that we don\'t have them
- * hanging around in clients. Note that we want to do this after
- * initgroups, because at least on Solaris 2.3 it leaves file
- * descriptors open.
- */
- for (i = 3; i < 64; i++)
- close(i);
+ child_close_fds();
/*
* Must take new environment into use so that .ssh/rc,