freebsd-ports/security/openssh/files/patch-an
Brian Feldman f0ca59b2b5 Update the CVS_DATE. This brings in support for TIS authentication,
obsoleting a couple patches (it's the same code, though, except for
additions).

This also brings in KNFization of everything (please hold the cheering
down :) and made me reroll all my patches.

My patches have been almost entirely rewritten.  The places are the
same, but the code's rewritten.  It fits with the style (KNF) now,
and looks better.

I've also added strlcat.c to the build, which, just like strlcpy.c, is
necessary for compatibility with older libcs.  After strlcat() snuck
into the OpenSSH code recently, this would prevent OpenSSH from
building on (e.g.) FreeBSD 3.2.  Adding it to ssh/lib/ makes it work
yet again :)
1999-11-24 03:36:23 +00:00

232 lines
6.6 KiB
Text

--- /usr/ports/distfiles/OpenSSH-1.2/src/usr.bin/ssh/sshd.c Tue Nov 23 18:59:05 1999
+++ ./sshd.c Tue Nov 23 20:33:18 1999
@@ -39,6 +39,16 @@
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
@@ -1008,6 +1018,14 @@
return 0;
}
}
+ /* Fail if the account's expiration time has passed. */
+ if (pw->pw_expire != 0) {
+ struct timeval tv;
+
+ (void)gettimeofday(&tv, NULL);
+ if (tv.tv_sec >= pw->pw_expire)
+ return 0;
+ }
/* We found no reason not to let this user try to log on... */
return 1;
}
@@ -1042,6 +1060,9 @@
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;
/* If we are not running as root, the user must have the same uid
@@ -1790,6 +1811,10 @@
struct sockaddr_in from;
int fromlen;
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();
@@ -1850,6 +1875,12 @@
/* 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 */
/* If the user has logged in before, display the time of
last login. However, don't display anything extra if a
@@ -1871,12 +1902,31 @@
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) {
+ while (fgets(line, sizeof(line), f))
+ 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 */
/* Print /etc/motd unless a command was specified or
printing it was disabled in server options or login(1)
will be used. Note that some machines appear to print
it in /etc/profile or similar. */
if (command == NULL && options.print_motd && !quiet_login &&
!options.use_login) {
+#ifdef LOGIN_CAP
+ fname = login_getcapstr(lc, "welcome", NULL, NULL);
+ login_close(lc);
+ if (fname == NULL || (f = fopen(fname, "r")) == NULL)
+#endif /* LOGIN_CAP */
/* Print /etc/motd if it exists. */
f = fopen("/etc/motd", "r");
if (f) {
@@ -1885,6 +1935,7 @@
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 */
@@ -2030,17 +2081,38 @@
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 */
/* Check /etc/nologin. */
f = fopen("/etc/nologin", "r");
+#ifdef __FreeBSD__
+ if (f == NULL)
+ f = fopen("/var/run/nologin", "r");
+#endif /* __FreeBSD__ */
if (f) {
- /* /etc/nologin exists. Print its contents and exit. */
- while (fgets(buf, sizeof(buf), f))
- fputs(buf, stderr);
- fclose(f);
- if (pw->pw_uid != 0)
- exit(254);
- }
+ /* /etc/nologin exists. */
+#ifdef LOGIN_CAP
+ /*
+ * If the user doesn't have "ignorenologin" set, print
+ * its contents and exit.
+ */
+ if (!login_getcapbool(lc, "ignorenologin", 0)) {
+#endif /* LOGIN_CAP */
+ while (fgets(buf, sizeof(buf), f))
+ fputs(buf, stderr);
+ fclose(f);
+ if (pw->pw_uid != 0)
+ exit(254);
+#ifdef LOGIN_CAP
+ }
+#endif /* LOGIN_CAP */
+ }
/* Set login name in the kernel. */
if (setlogin(pw->pw_name) < 0)
error("setlogin failed: %s", strerror(errno));
@@ -2049,6 +2121,13 @@
/* 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");
@@ -2069,7 +2148,13 @@
}
/* Get the shell from the password data. An empty shell field is
legal, and means /bin/sh. */
+#ifdef LOGIN_CAP
+ shell = login_getcapstr(lc, "shell", pw->pw_shell, pw->pw_shell);
+ 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. */
@@ -2094,7 +2179,12 @@
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);
@@ -2189,13 +2279,35 @@
later. */
endpwent();
endhostent();
+#ifdef LOGIN_CAP
+ login_close(lc);
+#endif /* LOGIN_CAP */
/* 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++)
+ for (i = 3; i < getdtablesize(); i++)
close(i);
+
+#ifdef __FreeBSD__
+ /*
+ * 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;
+
+ (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");
+ }
+ }
+#endif /* __FreeBSD__ */
/* Change current directory to the user\'s home directory. */
if (chdir(pw->pw_dir) < 0)