2000-01-13 23:22:17 +00:00
|
|
|
--- sshd.c.orig Fri Jan 7 01:32:03 2000
|
|
|
|
+++ sshd.c Fri Jan 7 01:40:05 2000
|
|
|
|
@@ -26,6 +26,8 @@
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
#include "servconf.h"
|
|
|
|
#include "uidswap.h"
|
|
|
|
#include "compat.h"
|
1999-12-08 04:06:38 +00:00
|
|
|
+#include <poll.h>
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
+#include <time.h>
|
|
|
|
|
|
|
|
#ifdef LIBWRAP
|
|
|
|
#include <tcpd.h>
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -34,6 +36,16 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
int deny_severity = LOG_WARNING;
|
|
|
|
#endif /* LIBWRAP */
|
|
|
|
|
|
|
|
+#ifdef __FreeBSD__
|
|
|
|
+#include <libutil.h>
|
|
|
|
+#include <syslog.h>
|
|
|
|
+#define LOGIN_CAP
|
|
|
|
+#endif /* __FreeBSD__ */
|
|
|
|
+
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+#include <login_cap.h>
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
+
|
|
|
|
#ifndef O_NOCTTY
|
|
|
|
#define O_NOCTTY 0
|
|
|
|
#endif
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -128,6 +140,32 @@
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
the private key. */
|
|
|
|
RSA *public_key;
|
|
|
|
|
|
|
|
+/* These are used to implement connections_per_period. */
|
|
|
|
+struct magic_connection {
|
|
|
|
+ struct timeval connections_begin;
|
|
|
|
+ unsigned int connections_this_period;
|
|
|
|
+} *magic_connections;
|
|
|
|
+/* Magic number, too! TODO: this doesn't have to be static. */
|
|
|
|
+const size_t MAGIC_CONNECTIONS_SIZE = 1;
|
|
|
|
+
|
|
|
|
+static __inline int
|
2000-02-25 05:35:33 +00:00
|
|
|
+magic_hash(struct sockaddr_storage *sa) {
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static __inline struct timeval
|
|
|
|
+timevaldiff(struct timeval *tv1, struct timeval *tv2) {
|
|
|
|
+ struct timeval diff;
|
|
|
|
+ int carry;
|
|
|
|
+
|
|
|
|
+ carry = tv1->tv_usec > tv2->tv_usec;
|
|
|
|
+ diff.tv_sec = tv2->tv_sec - tv1->tv_sec - (carry ? 0 : 1);
|
|
|
|
+ diff.tv_usec = tv2->tv_usec - tv1->tv_usec + (carry ? 1000000 : 0);
|
|
|
|
+
|
|
|
|
+ return diff;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
/* Prototypes for various functions defined later in this file. */
|
|
|
|
void do_connection();
|
|
|
|
void do_authentication(char *user);
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -301,6 +339,7 @@
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
extern int optind;
|
2000-01-13 23:22:17 +00:00
|
|
|
int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, pid, on = 1;
|
|
|
|
socklen_t fromlen;
|
|
|
|
+ int connections_per_period_exceeded = 0;
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
int remote_major, remote_minor;
|
|
|
|
int silentrsa = 0;
|
2000-01-13 23:22:17 +00:00
|
|
|
fd_set *fdset;
|
|
|
|
@@ -620,6 +659,12 @@
|
|
|
|
fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
|
|
|
|
fdset = (fd_set *)xmalloc(fdsetsz);
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
|
|
|
|
+ /* Initialize the magic_connections table. It's magical! */
|
|
|
|
+ magic_connections = calloc(MAGIC_CONNECTIONS_SIZE,
|
|
|
|
+ sizeof(struct magic_connection));
|
|
|
|
+ if (magic_connections == NULL)
|
|
|
|
+ fatal("calloc: %s", strerror(errno));
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
* Stay listening for connections until the system crashes or
|
|
|
|
* the daemon is killed with a signal.
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -651,9 +696,31 @@
|
|
|
|
error("newsock del O_NONBLOCK: %s", strerror(errno));
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
+ if (options.connections_per_period != 0) {
|
|
|
|
+ struct timeval diff, connections_end;
|
|
|
|
+ struct magic_connection *mc;
|
|
|
|
+
|
|
|
|
+ (void)gettimeofday(&connections_end, NULL);
|
2000-02-25 05:35:33 +00:00
|
|
|
+ mc = &magic_connections[magic_hash(&from)];
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
+ diff = timevaldiff(&mc->connections_begin, &connections_end);
|
|
|
|
+ if (diff.tv_sec >= options.connections_period) {
|
|
|
|
+ /*
|
|
|
|
+ * Slide the window forward only after completely
|
|
|
|
+ * leaving it.
|
|
|
|
+ */
|
|
|
|
+ mc->connections_begin = connections_end;
|
|
|
|
+ mc->connections_this_period = 1;
|
|
|
|
+ } else {
|
|
|
|
+ if (++mc->connections_this_period >
|
|
|
|
+ options.connections_per_period)
|
|
|
|
+ connections_per_period_exceeded = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
/*
|
|
|
|
- * Got connection. Fork a child to handle it, unless
|
|
|
|
- * we are in debugging mode.
|
|
|
|
+ * Got connection. Fork a child to handle it unless
|
|
|
|
+ * we are in debugging mode or the maximum number of
|
|
|
|
+ * connections per period has been exceeded.
|
|
|
|
*/
|
|
|
|
if (debug_flag) {
|
|
|
|
/*
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -667,6 +734,12 @@
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
sock_out = newsock;
|
|
|
|
pid = getpid();
|
|
|
|
break;
|
|
|
|
+ } else if (connections_per_period_exceeded) {
|
|
|
|
+ log("Connection rate limit of %u/%us has been exceeded; "
|
|
|
|
+ "dropping connection from %s.",
|
|
|
|
+ options.connections_per_period, options.connections_period,
|
2000-01-13 23:22:17 +00:00
|
|
|
+ ntop);
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
+ connections_per_period_exceeded = 0;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Normal production daemon. Fork, and have
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -1152,6 +1225,14 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
+ /* Fail if the account's expiration time has passed. */
|
|
|
|
+ if (pw->pw_expire != 0) {
|
|
|
|
+ struct timeval tv;
|
|
|
|
+
|
1999-11-28 22:40:28 +00:00
|
|
|
+ (void)gettimeofday(&tv, NULL);
|
|
|
|
+ if (tv.tv_sec >= pw->pw_expire)
|
|
|
|
+ return 0;
|
1999-11-24 03:36:23 +00:00
|
|
|
+ }
|
|
|
|
/* We found no reason not to let this user try to log on... */
|
|
|
|
return 1;
|
|
|
|
}
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -1187,6 +1268,9 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
pwcopy.pw_gid = pw->pw_gid;
|
|
|
|
pwcopy.pw_dir = xstrdup(pw->pw_dir);
|
|
|
|
pwcopy.pw_shell = xstrdup(pw->pw_shell);
|
|
|
|
+ pwcopy.pw_class = xstrdup(pw->pw_class);
|
|
|
|
+ pwcopy.pw_expire = pw->pw_expire;
|
|
|
|
+ pwcopy.pw_change = pw->pw_change;
|
|
|
|
pw = &pwcopy;
|
|
|
|
|
1999-11-28 22:40:28 +00:00
|
|
|
/*
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -1983,6 +2067,10 @@
|
|
|
|
struct sockaddr_storage from;
|
|
|
|
socklen_t fromlen;
|
1999-11-24 03:36:23 +00:00
|
|
|
struct pty_cleanup_context cleanup_context;
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ login_cap_t *lc;
|
|
|
|
+ char *fname;
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
|
|
|
|
/* Get remote host name. */
|
|
|
|
hostname = get_canonical_hostname();
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2047,6 +2135,12 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
/* Check if .hushlogin exists. */
|
|
|
|
snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
|
|
|
|
quiet_login = stat(line, &st) >= 0;
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ lc = login_getpwclass(pw);
|
|
|
|
+ if (lc == NULL)
|
|
|
|
+ lc = login_getclassbyname(NULL, pw);
|
|
|
|
+ quiet_login = login_getcapbool(lc, "hushlogin", quiet_login);
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
|
1999-11-28 22:40:28 +00:00
|
|
|
/*
|
|
|
|
* If the user has logged in before, display the time of last
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2070,6 +2164,20 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
else
|
|
|
|
printf("Last login: %s from %s\r\n", time_string, buf);
|
|
|
|
}
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ if (command == NULL && !quiet_login && !options.use_login) {
|
|
|
|
+ fname = login_getcapstr(lc, "copyright", NULL, NULL);
|
|
|
|
+ if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
|
1999-11-28 22:40:28 +00:00
|
|
|
+ while (fgets(line, sizeof(line), f) != NULL)
|
1999-11-24 03:36:23 +00:00
|
|
|
+ fputs(line, stdout);
|
|
|
|
+ fclose(f);
|
|
|
|
+ } else
|
|
|
|
+ (void)printf("%s\n\t%s %s\n",
|
|
|
|
+ "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
|
|
|
|
+ "The Regents of the University of California. ",
|
|
|
|
+ "All rights reserved.");
|
|
|
|
+ }
|
|
|
|
+#endif /* LOGIN_CAP */
|
1999-11-28 22:40:28 +00:00
|
|
|
/*
|
|
|
|
* Print /etc/motd unless a command was specified or printing
|
|
|
|
* it was disabled in server options or login(1) will be
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2078,14 +2186,22 @@
|
1999-11-28 22:40:28 +00:00
|
|
|
*/
|
1999-11-24 03:36:23 +00:00
|
|
|
if (command == NULL && options.print_motd && !quiet_login &&
|
|
|
|
!options.use_login) {
|
1999-11-28 22:40:28 +00:00
|
|
|
- /* Print /etc/motd if it exists. */
|
1999-11-24 03:36:23 +00:00
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ fname = login_getcapstr(lc, "welcome", NULL, NULL);
|
|
|
|
+ login_close(lc);
|
|
|
|
+ if (fname == NULL || (f = fopen(fname, "r")) == NULL)
|
1999-11-28 22:40:28 +00:00
|
|
|
+ f = fopen("/etc/motd", "r");
|
|
|
|
+#else /* LOGIN_CAP */
|
1999-11-24 03:36:23 +00:00
|
|
|
f = fopen("/etc/motd", "r");
|
1999-11-28 22:40:28 +00:00
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
+ /* Print /etc/motd if it exists. */
|
1999-11-24 03:36:23 +00:00
|
|
|
if (f) {
|
1999-11-28 22:40:28 +00:00
|
|
|
while (fgets(line, sizeof(line), f))
|
|
|
|
fputs(line, stdout);
|
1999-11-24 03:36:23 +00:00
|
|
|
fclose(f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
+
|
|
|
|
/* Do common processing for the child, such as execing the command. */
|
|
|
|
do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
|
|
|
|
/* NOTREACHED */
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2221,7 +2337,8 @@
|
In the meantime (while things are being worked and decided on on the
OpenBSD OpenSSH front), add ConnectionsPerPeriod to prevent DoS via
running the system out of resources. In reality, this wouldn't
be a full DoS, but would make a system slower, but this is a better
thing to do than let the system get loaded down.
So here we are, rate-limiting. The default settings are now:
Five connections are allowed to authenticate (and not be rejected) in
a period of ten seconds.
One minute is given for login grace time.
More work in this area is being done by alfred@FreeBSD.org and
markus@OpenBSD.org, at the very least. This is, essentially, a
stopgap solution; however, it is a properly implemented and documented
one, and has an easily modifiable framework.
1999-12-06 06:32:22 +00:00
|
|
|
const char *display, const char *auth_proto,
|
|
|
|
const char *auth_data, const char *ttyname)
|
|
|
|
{
|
|
|
|
- const char *shell, *cp = NULL;
|
|
|
|
+ char *shell;
|
|
|
|
+ const char *cp = NULL;
|
|
|
|
char buf[256];
|
|
|
|
FILE *f;
|
|
|
|
unsigned int envsize, i;
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2229,15 +2346,34 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
extern char **environ;
|
|
|
|
struct stat st;
|
|
|
|
char *argv[10];
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ login_cap_t *lc;
|
|
|
|
+
|
|
|
|
+ lc = login_getpwclass(pw);
|
|
|
|
+ if (lc == NULL)
|
|
|
|
+ lc = login_getclassbyname(NULL, pw);
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
|
|
|
|
f = fopen("/etc/nologin", "r");
|
|
|
|
+#ifdef __FreeBSD__
|
|
|
|
+ if (f == NULL)
|
|
|
|
+ f = fopen("/var/run/nologin", "r");
|
|
|
|
+#endif /* __FreeBSD__ */
|
|
|
|
if (f) {
|
1999-11-28 22:40:28 +00:00
|
|
|
/* /etc/nologin exists. Print its contents and exit. */
|
1999-11-24 03:36:23 +00:00
|
|
|
- while (fgets(buf, sizeof(buf), f))
|
|
|
|
- fputs(buf, stderr);
|
|
|
|
- fclose(f);
|
|
|
|
- if (pw->pw_uid != 0)
|
|
|
|
- exit(254);
|
|
|
|
+#ifdef LOGIN_CAP
|
1999-11-28 22:40:28 +00:00
|
|
|
+ /* On FreeBSD, etc., allow overriding nologin via login.conf. */
|
1999-11-24 03:36:23 +00:00
|
|
|
+ if (!login_getcapbool(lc, "ignorenologin", 0)) {
|
1999-11-28 22:40:28 +00:00
|
|
|
+#else /* LOGIN_CAP */
|
|
|
|
+ if (1) {
|
1999-11-24 03:36:23 +00:00
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
+ while (fgets(buf, sizeof(buf), f))
|
|
|
|
+ fputs(buf, stderr);
|
|
|
|
+ fclose(f);
|
|
|
|
+ if (pw->pw_uid != 0)
|
|
|
|
+ exit(254);
|
|
|
|
+ }
|
1999-11-28 22:40:28 +00:00
|
|
|
+
|
|
|
|
}
|
1999-11-24 03:36:23 +00:00
|
|
|
/* Set login name in the kernel. */
|
|
|
|
if (setlogin(pw->pw_name) < 0)
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2247,6 +2383,13 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
/* Login(1) does this as well, and it needs uid 0 for the "-h"
|
|
|
|
switch, so we let login(1) to this for us. */
|
|
|
|
if (!options.use_login) {
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ if (setclasscontext(pw->pw_class, LOGIN_SETPRIORITY |
|
|
|
|
+ LOGIN_SETRESOURCES | LOGIN_SETUMASK) == -1) {
|
|
|
|
+ perror("setclasscontext");
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
if (getuid() == 0 || geteuid() == 0) {
|
|
|
|
if (setgid(pw->pw_gid) < 0) {
|
|
|
|
perror("setgid");
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2269,7 +2412,14 @@
|
1999-11-28 22:40:28 +00:00
|
|
|
* Get the shell from the password data. An empty shell field is
|
|
|
|
* legal, and means /bin/sh.
|
|
|
|
*/
|
1999-11-24 03:36:23 +00:00
|
|
|
+#ifdef LOGIN_CAP
|
1999-11-28 22:40:28 +00:00
|
|
|
+ shell = pw->pw_shell;
|
|
|
|
+ shell = login_getcapstr(lc, "shell", shell, shell);
|
1999-11-24 03:36:23 +00:00
|
|
|
+ if (shell[0] == '\0')
|
|
|
|
+ shell = _PATH_BSHELL;
|
|
|
|
+#else /* LOGIN_CAP */
|
|
|
|
shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
|
|
|
|
#ifdef AFS
|
|
|
|
/* Try to get AFS tokens for the local cell. */
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2293,7 +2443,12 @@
|
1999-11-24 03:36:23 +00:00
|
|
|
child_set_env(&env, &envsize, "USER", pw->pw_name);
|
|
|
|
child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
|
|
|
|
child_set_env(&env, &envsize, "HOME", pw->pw_dir);
|
|
|
|
+#ifdef LOGIN_CAP
|
|
|
|
+ child_set_env(&env, &envsize, "PATH",
|
|
|
|
+ login_getpath(lc, "path", _PATH_STDPATH));
|
|
|
|
+#else /* LOGIN_CAP */
|
|
|
|
child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
|
|
|
|
+#endif /* LOGIN_CAP */
|
|
|
|
|
|
|
|
snprintf(buf, sizeof buf, "%.200s/%.50s",
|
|
|
|
_PATH_MAILDIR, pw->pw_name);
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2383,13 +2538,17 @@
|
1999-11-28 22:40:28 +00:00
|
|
|
*/
|
1999-11-24 03:36:23 +00:00
|
|
|
endpwent();
|
2000-01-13 23:22:17 +00:00
|
|
|
|
1999-11-24 03:36:23 +00:00
|
|
|
+#ifdef LOGIN_CAP
|
2000-01-13 23:22:17 +00:00
|
|
|
+ login_close(lc);
|
1999-11-24 03:36:23 +00:00
|
|
|
+#endif /* LOGIN_CAP */
|
2000-01-13 23:22:17 +00:00
|
|
|
+
|
1999-11-28 22:40:28 +00:00
|
|
|
/*
|
|
|
|
* Close any extra open file descriptors so that we don\'t have them
|
2000-01-13 23:22:17 +00:00
|
|
|
* hanging around in clients. Note that we want to do this after
|
1999-11-28 22:40:28 +00:00
|
|
|
* initgroups, because at least on Solaris 2.3 it leaves file
|
|
|
|
* descriptors open.
|
|
|
|
*/
|
1999-11-24 03:36:23 +00:00
|
|
|
- for (i = 3; i < 64; i++)
|
|
|
|
+ for (i = 3; i < getdtablesize(); i++)
|
|
|
|
close(i);
|
1999-11-28 22:40:28 +00:00
|
|
|
|
|
|
|
/* Change current directory to the user\'s home directory. */
|
2000-01-13 23:22:17 +00:00
|
|
|
@@ -2408,6 +2567,26 @@
|
1999-11-28 22:40:28 +00:00
|
|
|
* in this order).
|
|
|
|
*/
|
|
|
|
if (!options.use_login) {
|
1999-11-24 03:36:23 +00:00
|
|
|
+#ifdef __FreeBSD__
|
1999-11-28 22:40:28 +00:00
|
|
|
+ /*
|
|
|
|
+ * If the password change time is set and has passed, give the
|
|
|
|
+ * user a password expiry notice and chance to change it.
|
|
|
|
+ */
|
|
|
|
+ if (pw->pw_change != 0) {
|
|
|
|
+ struct timeval tv;
|
1999-11-24 03:36:23 +00:00
|
|
|
+
|
1999-11-28 22:40:28 +00:00
|
|
|
+ (void)gettimeofday(&tv, NULL);
|
|
|
|
+ if (tv.tv_sec >= pw->pw_change) {
|
|
|
|
+ (void)printf(
|
|
|
|
+ "Sorry -- your password has expired.\n");
|
|
|
|
+ syslog(LOG_INFO,
|
|
|
|
+ "%s Password expired - forcing change",
|
|
|
|
+ pw->pw_name);
|
|
|
|
+ if (system("/usr/bin/passwd") != 0)
|
|
|
|
+ perror("/usr/bin/passwd");
|
|
|
|
+ }
|
1999-11-24 03:36:23 +00:00
|
|
|
+ }
|
|
|
|
+#endif /* __FreeBSD__ */
|
1999-11-28 22:40:28 +00:00
|
|
|
if (stat(SSH_USER_RC, &st) >= 0) {
|
|
|
|
if (debug_flag)
|
|
|
|
fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
|