Deleted Added
full compact
sshd.c (57430) sshd.c (57432)
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Created: Fri Mar 17 17:09:28 1995 ylo
6 * This program is the ssh daemon. It listens for connections from clients, and
7 * performs authentication, executes use commands or shell, and forwards
8 * information to/from the application to the user client over an encrypted
9 * connection. This can also handle forwarding of X11, TCP/IP, and authentication
10 * agent connections.
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 * Created: Fri Mar 17 17:09:28 1995 ylo
6 * This program is the ssh daemon. It listens for connections from clients, and
7 * performs authentication, executes use commands or shell, and forwards
8 * information to/from the application to the user client over an encrypted
9 * connection. This can also handle forwarding of X11, TCP/IP, and authentication
10 * agent connections.
11 *
12 * $FreeBSD: head/crypto/openssh/sshd.c 57432 2000-02-24 15:29:42Z markm $
11 */
12
13#include "includes.h"
14RCSID("$OpenBSD: sshd.c,v 1.88 2000/02/15 16:52:57 markus Exp $");
15
16#include "xmalloc.h"
17#include "rsa.h"
18#include "ssh.h"
19#include "pty.h"
20#include "packet.h"
21#include "buffer.h"
22#include "cipher.h"
23#include "mpaux.h"
24#include "servconf.h"
25#include "uidswap.h"
26#include "compat.h"
13 */
14
15#include "includes.h"
16RCSID("$OpenBSD: sshd.c,v 1.88 2000/02/15 16:52:57 markus Exp $");
17
18#include "xmalloc.h"
19#include "rsa.h"
20#include "ssh.h"
21#include "pty.h"
22#include "packet.h"
23#include "buffer.h"
24#include "cipher.h"
25#include "mpaux.h"
26#include "servconf.h"
27#include "uidswap.h"
28#include "compat.h"
29#include <poll.h>
30#include <time.h>
27
28#ifdef LIBWRAP
29#include <tcpd.h>
30#include <syslog.h>
31int allow_severity = LOG_INFO;
32int deny_severity = LOG_WARNING;
33#endif /* LIBWRAP */
34
31
32#ifdef LIBWRAP
33#include <tcpd.h>
34#include <syslog.h>
35int allow_severity = LOG_INFO;
36int deny_severity = LOG_WARNING;
37#endif /* LIBWRAP */
38
39#ifdef __FreeBSD__
40#include <libutil.h>
41#include <syslog.h>
42#define LOGIN_CAP
43#endif /* __FreeBSD__ */
44
45#ifdef LOGIN_CAP
46#include <login_cap.h>
47#endif /* LOGIN_CAP */
48
35#ifndef O_NOCTTY
36#define O_NOCTTY 0
37#endif
38
39/* Local Xauthority file. */
40static char *xauthfile = NULL;
41
42/* Server configuration options. */

--- 78 unchanged lines hidden (view full) ---

121
122/* This is set to true when SIGHUP is received. */
123int received_sighup = 0;
124
125/* Public side of the server key. This value is regenerated regularly with
126 the private key. */
127RSA *public_key;
128
49#ifndef O_NOCTTY
50#define O_NOCTTY 0
51#endif
52
53/* Local Xauthority file. */
54static char *xauthfile = NULL;
55
56/* Server configuration options. */

--- 78 unchanged lines hidden (view full) ---

135
136/* This is set to true when SIGHUP is received. */
137int received_sighup = 0;
138
139/* Public side of the server key. This value is regenerated regularly with
140 the private key. */
141RSA *public_key;
142
143/* These are used to implement connections_per_period. */
144struct magic_connection {
145 struct timeval connections_begin;
146 unsigned int connections_this_period;
147} *magic_connections;
148/* Magic number, too! TODO: this doesn't have to be static. */
149const size_t MAGIC_CONNECTIONS_SIZE = 1;
150
151static __inline int
152magic_hash(struct sockaddr *sa) {
153
154 return 0;
155}
156
157static __inline struct timeval
158timevaldiff(struct timeval *tv1, struct timeval *tv2) {
159 struct timeval diff;
160 int carry;
161
162 carry = tv1->tv_usec > tv2->tv_usec;
163 diff.tv_sec = tv2->tv_sec - tv1->tv_sec - (carry ? 0 : 1);
164 diff.tv_usec = tv2->tv_usec - tv1->tv_usec + (carry ? 1000000 : 0);
165
166 return diff;
167}
168
129/* Prototypes for various functions defined later in this file. */
130void do_ssh_kex();
131void do_authentication();
132void do_authloop(struct passwd * pw);
133void do_fake_authloop(char *user);
134void do_authenticated(struct passwd * pw);
135void do_exec_pty(const char *command, int ptyfd, int ttyfd,
136 const char *ttyname, struct passwd * pw, const char *term,

--- 179 unchanged lines hidden (view full) ---

316 */
317int
318main(int ac, char **av)
319{
320 extern char *optarg;
321 extern int optind;
322 int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, pid, on = 1;
323 socklen_t fromlen;
169/* Prototypes for various functions defined later in this file. */
170void do_ssh_kex();
171void do_authentication();
172void do_authloop(struct passwd * pw);
173void do_fake_authloop(char *user);
174void do_authenticated(struct passwd * pw);
175void do_exec_pty(const char *command, int ptyfd, int ttyfd,
176 const char *ttyname, struct passwd * pw, const char *term,

--- 179 unchanged lines hidden (view full) ---

356 */
357int
358main(int ac, char **av)
359{
360 extern char *optarg;
361 extern int optind;
362 int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, pid, on = 1;
363 socklen_t fromlen;
364 int connections_per_period_exceeded = 0;
324 int remote_major, remote_minor;
325 int silentrsa = 0;
326 fd_set *fdset;
327 struct sockaddr_storage from;
328 char buf[100]; /* Must not be larger than remote_version. */
329 char remote_version[100]; /* Must be at least as big as buf. */
330 const char *remote_ip;
331 int remote_port;

--- 303 unchanged lines hidden (view full) ---

635 /* setup fd set for listen */
636 maxfd = 0;
637 for (i = 0; i < num_listen_socks; i++)
638 if (listen_socks[i] > maxfd)
639 maxfd = listen_socks[i];
640 fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
641 fdset = (fd_set *)xmalloc(fdsetsz);
642
365 int remote_major, remote_minor;
366 int silentrsa = 0;
367 fd_set *fdset;
368 struct sockaddr_storage from;
369 char buf[100]; /* Must not be larger than remote_version. */
370 char remote_version[100]; /* Must be at least as big as buf. */
371 const char *remote_ip;
372 int remote_port;

--- 303 unchanged lines hidden (view full) ---

676 /* setup fd set for listen */
677 maxfd = 0;
678 for (i = 0; i < num_listen_socks; i++)
679 if (listen_socks[i] > maxfd)
680 maxfd = listen_socks[i];
681 fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
682 fdset = (fd_set *)xmalloc(fdsetsz);
683
684 /* Initialize the magic_connections table. It's magical! */
685 magic_connections = calloc(MAGIC_CONNECTIONS_SIZE,
686 sizeof(struct magic_connection));
687 if (magic_connections == NULL)
688 fatal("calloc: %s", strerror(errno));
689
643 /*
644 * Stay listening for connections until the system crashes or
645 * the daemon is killed with a signal.
646 */
647 for (;;) {
648 if (received_sighup)
649 sighup_restart();
650 /* Wait in select until there is a connection. */

--- 15 unchanged lines hidden (view full) ---

666 if (errno != EINTR && errno != EWOULDBLOCK)
667 error("accept: %.100s", strerror(errno));
668 continue;
669 }
670 if (fcntl(newsock, F_SETFL, 0) < 0) {
671 error("newsock del O_NONBLOCK: %s", strerror(errno));
672 continue;
673 }
690 /*
691 * Stay listening for connections until the system crashes or
692 * the daemon is killed with a signal.
693 */
694 for (;;) {
695 if (received_sighup)
696 sighup_restart();
697 /* Wait in select until there is a connection. */

--- 15 unchanged lines hidden (view full) ---

713 if (errno != EINTR && errno != EWOULDBLOCK)
714 error("accept: %.100s", strerror(errno));
715 continue;
716 }
717 if (fcntl(newsock, F_SETFL, 0) < 0) {
718 error("newsock del O_NONBLOCK: %s", strerror(errno));
719 continue;
720 }
721 if (options.connections_per_period != 0) {
722 struct timeval diff, connections_end;
723 struct magic_connection *mc;
724
725 (void)gettimeofday(&connections_end, NULL);
726 mc = &magic_connections[magic_hash(ai->ai_addr)];
727 diff = timevaldiff(&mc->connections_begin, &connections_end);
728 if (diff.tv_sec >= options.connections_period) {
729 /*
730 * Slide the window forward only after completely
731 * leaving it.
732 */
733 mc->connections_begin = connections_end;
734 mc->connections_this_period = 1;
735 } else {
736 if (++mc->connections_this_period >
737 options.connections_per_period)
738 connections_per_period_exceeded = 1;
739 }
740 }
741
674 /*
742 /*
675 * Got connection. Fork a child to handle it, unless
676 * we are in debugging mode.
743 * Got connection. Fork a child to handle it unless
744 * we are in debugging mode or the maximum number of
745 * connections per period has been exceeded.
677 */
678 if (debug_flag) {
679 /*
680 * In debugging mode. Close the listening
681 * socket, and start processing the
682 * connection without forking.
683 */
684 debug("Server will not fork when running in debugging mode.");
685 close_listen_socks();
686 sock_in = newsock;
687 sock_out = newsock;
688 pid = getpid();
689 break;
746 */
747 if (debug_flag) {
748 /*
749 * In debugging mode. Close the listening
750 * socket, and start processing the
751 * connection without forking.
752 */
753 debug("Server will not fork when running in debugging mode.");
754 close_listen_socks();
755 sock_in = newsock;
756 sock_out = newsock;
757 pid = getpid();
758 break;
759 } else if (connections_per_period_exceeded) {
760 log("Connection rate limit of %u/%us has been exceeded; "
761 "dropping connection from %s.",
762 options.connections_per_period, options.connections_period,
763 ntop);
764 connections_per_period_exceeded = 0;
690 } else {
691 /*
692 * Normal production daemon. Fork, and have
693 * the child process the connection. The
694 * parent continues listening.
695 */
696 if ((pid = fork()) == 0) {
697 /*

--- 468 unchanged lines hidden (view full) ---

1166 if (match_pattern(grp->gr_name, options.allow_groups[i]))
1167 break;
1168 /* i < options.num_allow_groups iff we break for
1169 loop */
1170 if (i >= options.num_allow_groups)
1171 return 0;
1172 }
1173 }
765 } else {
766 /*
767 * Normal production daemon. Fork, and have
768 * the child process the connection. The
769 * parent continues listening.
770 */
771 if ((pid = fork()) == 0) {
772 /*

--- 468 unchanged lines hidden (view full) ---

1241 if (match_pattern(grp->gr_name, options.allow_groups[i]))
1242 break;
1243 /* i < options.num_allow_groups iff we break for
1244 loop */
1245 if (i >= options.num_allow_groups)
1246 return 0;
1247 }
1248 }
1249 /* Fail if the account's expiration time has passed. */
1250 if (pw->pw_expire != 0) {
1251 struct timeval tv;
1252
1253 (void)gettimeofday(&tv, NULL);
1254 if (tv.tv_sec >= pw->pw_expire)
1255 return 0;
1256 }
1174 /* We found no reason not to let this user try to log on... */
1175 return 1;
1176}
1177
1178/*
1179 * Performs authentication of an incoming connection. Session key has already
1180 * been exchanged and encryption is enabled.
1181 */

--- 30 unchanged lines hidden (view full) ---

1212 /* Take a copy of the returned structure. */
1213 memset(&pwcopy, 0, sizeof(pwcopy));
1214 pwcopy.pw_name = xstrdup(pw->pw_name);
1215 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
1216 pwcopy.pw_uid = pw->pw_uid;
1217 pwcopy.pw_gid = pw->pw_gid;
1218 pwcopy.pw_dir = xstrdup(pw->pw_dir);
1219 pwcopy.pw_shell = xstrdup(pw->pw_shell);
1257 /* We found no reason not to let this user try to log on... */
1258 return 1;
1259}
1260
1261/*
1262 * Performs authentication of an incoming connection. Session key has already
1263 * been exchanged and encryption is enabled.
1264 */

--- 30 unchanged lines hidden (view full) ---

1295 /* Take a copy of the returned structure. */
1296 memset(&pwcopy, 0, sizeof(pwcopy));
1297 pwcopy.pw_name = xstrdup(pw->pw_name);
1298 pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
1299 pwcopy.pw_uid = pw->pw_uid;
1300 pwcopy.pw_gid = pw->pw_gid;
1301 pwcopy.pw_dir = xstrdup(pw->pw_dir);
1302 pwcopy.pw_shell = xstrdup(pw->pw_shell);
1303 pwcopy.pw_class = xstrdup(pw->pw_class);
1304 pwcopy.pw_expire = pw->pw_expire;
1305 pwcopy.pw_change = pw->pw_change;
1220 pw = &pwcopy;
1221
1222 /*
1223 * If we are not running as root, the user must have the same uid as
1224 * the server.
1225 */
1226 if (getuid() != 0 && pw->pw_uid != getuid())
1227 packet_disconnect("Cannot change user when server not running as root.");

--- 763 unchanged lines hidden (view full) ---

1991 char buf[100], *time_string;
1992 FILE *f;
1993 char line[256];
1994 struct stat st;
1995 int quiet_login;
1996 struct sockaddr_storage from;
1997 socklen_t fromlen;
1998 struct pty_cleanup_context cleanup_context;
1306 pw = &pwcopy;
1307
1308 /*
1309 * If we are not running as root, the user must have the same uid as
1310 * the server.
1311 */
1312 if (getuid() != 0 && pw->pw_uid != getuid())
1313 packet_disconnect("Cannot change user when server not running as root.");

--- 763 unchanged lines hidden (view full) ---

2077 char buf[100], *time_string;
2078 FILE *f;
2079 char line[256];
2080 struct stat st;
2081 int quiet_login;
2082 struct sockaddr_storage from;
2083 socklen_t fromlen;
2084 struct pty_cleanup_context cleanup_context;
2085#ifdef LOGIN_CAP
2086 login_cap_t *lc;
2087 char *fname;
2088#endif /* LOGIN_CAP */
1999
2000 /* Get remote host name. */
2001 hostname = get_canonical_hostname();
2002
2003 /*
2004 * Get the time when the user last logged in. Buf will be set to
2005 * contain the hostname the last login was from.
2006 */

--- 48 unchanged lines hidden (view full) ---

2055 }
2056 /* Record that there was a login on that terminal. */
2057 record_login(pid, ttyname, pw->pw_name, pw->pw_uid, hostname,
2058 (struct sockaddr *)&from);
2059
2060 /* Check if .hushlogin exists. */
2061 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
2062 quiet_login = stat(line, &st) >= 0;
2089
2090 /* Get remote host name. */
2091 hostname = get_canonical_hostname();
2092
2093 /*
2094 * Get the time when the user last logged in. Buf will be set to
2095 * contain the hostname the last login was from.
2096 */

--- 48 unchanged lines hidden (view full) ---

2145 }
2146 /* Record that there was a login on that terminal. */
2147 record_login(pid, ttyname, pw->pw_name, pw->pw_uid, hostname,
2148 (struct sockaddr *)&from);
2149
2150 /* Check if .hushlogin exists. */
2151 snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir);
2152 quiet_login = stat(line, &st) >= 0;
2153#ifdef LOGIN_CAP
2154 lc = login_getpwclass(pw);
2155 if (lc == NULL)
2156 lc = login_getclassbyname(NULL, pw);
2157 quiet_login = login_getcapbool(lc, "hushlogin", quiet_login);
2158#endif /* LOGIN_CAP */
2063
2064 /*
2065 * If the user has logged in before, display the time of last
2066 * login. However, don't display anything extra if a command
2067 * has been specified (so that ssh can be used to execute
2068 * commands on a remote machine without users knowing they
2069 * are going to another machine). Login(1) will do this for
2070 * us as well, so check if login(1) is used

--- 7 unchanged lines hidden (view full) ---

2078 *strchr(time_string, '\n') = 0;
2079 /* Display the last login time. Host if displayed
2080 if known. */
2081 if (strcmp(buf, "") == 0)
2082 printf("Last login: %s\r\n", time_string);
2083 else
2084 printf("Last login: %s from %s\r\n", time_string, buf);
2085 }
2159
2160 /*
2161 * If the user has logged in before, display the time of last
2162 * login. However, don't display anything extra if a command
2163 * has been specified (so that ssh can be used to execute
2164 * commands on a remote machine without users knowing they
2165 * are going to another machine). Login(1) will do this for
2166 * us as well, so check if login(1) is used

--- 7 unchanged lines hidden (view full) ---

2174 *strchr(time_string, '\n') = 0;
2175 /* Display the last login time. Host if displayed
2176 if known. */
2177 if (strcmp(buf, "") == 0)
2178 printf("Last login: %s\r\n", time_string);
2179 else
2180 printf("Last login: %s from %s\r\n", time_string, buf);
2181 }
2182#ifdef LOGIN_CAP
2183 if (command == NULL && !quiet_login && !options.use_login) {
2184 fname = login_getcapstr(lc, "copyright", NULL, NULL);
2185 if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
2186 while (fgets(line, sizeof(line), f) != NULL)
2187 fputs(line, stdout);
2188 fclose(f);
2189 } else
2190 (void)printf("%s\n\t%s %s\n",
2191 "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
2192 "The Regents of the University of California. ",
2193 "All rights reserved.");
2194 }
2195#endif /* LOGIN_CAP */
2086 /*
2087 * Print /etc/motd unless a command was specified or printing
2088 * it was disabled in server options or login(1) will be
2089 * used. Note that some machines appear to print it in
2090 * /etc/profile or similar.
2091 */
2092 if (command == NULL && options.print_motd && !quiet_login &&
2093 !options.use_login) {
2196 /*
2197 * Print /etc/motd unless a command was specified or printing
2198 * it was disabled in server options or login(1) will be
2199 * used. Note that some machines appear to print it in
2200 * /etc/profile or similar.
2201 */
2202 if (command == NULL && options.print_motd && !quiet_login &&
2203 !options.use_login) {
2094 /* Print /etc/motd if it exists. */
2204#ifdef LOGIN_CAP
2205 fname = login_getcapstr(lc, "welcome", NULL, NULL);
2206 login_close(lc);
2207 if (fname == NULL || (f = fopen(fname, "r")) == NULL)
2208 f = fopen("/etc/motd", "r");
2209#else /* LOGIN_CAP */
2095 f = fopen("/etc/motd", "r");
2210 f = fopen("/etc/motd", "r");
2211#endif /* LOGIN_CAP */
2212 /* Print /etc/motd if it exists. */
2096 if (f) {
2097 while (fgets(line, sizeof(line), f))
2098 fputs(line, stdout);
2099 fclose(f);
2100 }
2101 }
2213 if (f) {
2214 while (fgets(line, sizeof(line), f))
2215 fputs(line, stdout);
2216 fclose(f);
2217 }
2218 }
2219
2102 /* Do common processing for the child, such as execing the command. */
2103 do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
2104 /* NOTREACHED */
2105 }
2106 if (pid < 0)
2107 packet_disconnect("fork failed: %.100s", strerror(errno));
2108 /* Parent. Close the slave side of the pseudo tty. */
2109 close(ttyfd);

--- 125 unchanged lines hidden (view full) ---

2235 * environment, closing extra file descriptors, setting the user and group
2236 * ids, and executing the command or shell.
2237 */
2238void
2239do_child(const char *command, struct passwd * pw, const char *term,
2240 const char *display, const char *auth_proto,
2241 const char *auth_data, const char *ttyname)
2242{
2220 /* Do common processing for the child, such as execing the command. */
2221 do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
2222 /* NOTREACHED */
2223 }
2224 if (pid < 0)
2225 packet_disconnect("fork failed: %.100s", strerror(errno));
2226 /* Parent. Close the slave side of the pseudo tty. */
2227 close(ttyfd);

--- 125 unchanged lines hidden (view full) ---

2353 * environment, closing extra file descriptors, setting the user and group
2354 * ids, and executing the command or shell.
2355 */
2356void
2357do_child(const char *command, struct passwd * pw, const char *term,
2358 const char *display, const char *auth_proto,
2359 const char *auth_data, const char *ttyname)
2360{
2243 const char *shell, *cp = NULL;
2361 char *shell;
2362 const char *cp = NULL;
2244 char buf[256];
2245 FILE *f;
2246 unsigned int envsize, i;
2247 char **env;
2248 extern char **environ;
2249 struct stat st;
2250 char *argv[10];
2363 char buf[256];
2364 FILE *f;
2365 unsigned int envsize, i;
2366 char **env;
2367 extern char **environ;
2368 struct stat st;
2369 char *argv[10];
2370#ifdef LOGIN_CAP
2371 login_cap_t *lc;
2251
2372
2373 lc = login_getpwclass(pw);
2374 if (lc == NULL)
2375 lc = login_getclassbyname(NULL, pw);
2376#endif /* LOGIN_CAP */
2377
2252 f = fopen("/etc/nologin", "r");
2378 f = fopen("/etc/nologin", "r");
2379#ifdef __FreeBSD__
2380 if (f == NULL)
2381 f = fopen("/var/run/nologin", "r");
2382#endif /* __FreeBSD__ */
2253 if (f) {
2254 /* /etc/nologin exists. Print its contents and exit. */
2383 if (f) {
2384 /* /etc/nologin exists. Print its contents and exit. */
2255 while (fgets(buf, sizeof(buf), f))
2256 fputs(buf, stderr);
2257 fclose(f);
2258 if (pw->pw_uid != 0)
2259 exit(254);
2385#ifdef LOGIN_CAP
2386 /* On FreeBSD, etc., allow overriding nologin via login.conf. */
2387 if (!login_getcapbool(lc, "ignorenologin", 0)) {
2388#else /* LOGIN_CAP */
2389 if (1) {
2390#endif /* LOGIN_CAP */
2391 while (fgets(buf, sizeof(buf), f))
2392 fputs(buf, stderr);
2393 fclose(f);
2394 if (pw->pw_uid != 0)
2395 exit(254);
2396 }
2397
2260 }
2261 /* Set login name in the kernel. */
2262 if (setlogin(pw->pw_name) < 0)
2263 error("setlogin failed: %s", strerror(errno));
2264
2265 /* Set uid, gid, and groups. */
2266 /* Login(1) does this as well, and it needs uid 0 for the "-h"
2267 switch, so we let login(1) to this for us. */
2268 if (!options.use_login) {
2398 }
2399 /* Set login name in the kernel. */
2400 if (setlogin(pw->pw_name) < 0)
2401 error("setlogin failed: %s", strerror(errno));
2402
2403 /* Set uid, gid, and groups. */
2404 /* Login(1) does this as well, and it needs uid 0 for the "-h"
2405 switch, so we let login(1) to this for us. */
2406 if (!options.use_login) {
2407#ifdef LOGIN_CAP
2408 if (setclasscontext(pw->pw_class, LOGIN_SETPRIORITY |
2409 LOGIN_SETRESOURCES | LOGIN_SETUMASK) == -1) {
2410 perror("setclasscontext");
2411 exit(1);
2412 }
2413#endif /* LOGIN_CAP */
2269 if (getuid() == 0 || geteuid() == 0) {
2270 if (setgid(pw->pw_gid) < 0) {
2271 perror("setgid");
2272 exit(1);
2273 }
2274 /* Initialize the group list. */
2275 if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
2276 perror("initgroups");

--- 6 unchanged lines hidden (view full) ---

2283 }
2284 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
2285 fatal("Failed to set uids to %d.", (int) pw->pw_uid);
2286 }
2287 /*
2288 * Get the shell from the password data. An empty shell field is
2289 * legal, and means /bin/sh.
2290 */
2414 if (getuid() == 0 || geteuid() == 0) {
2415 if (setgid(pw->pw_gid) < 0) {
2416 perror("setgid");
2417 exit(1);
2418 }
2419 /* Initialize the group list. */
2420 if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
2421 perror("initgroups");

--- 6 unchanged lines hidden (view full) ---

2428 }
2429 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
2430 fatal("Failed to set uids to %d.", (int) pw->pw_uid);
2431 }
2432 /*
2433 * Get the shell from the password data. An empty shell field is
2434 * legal, and means /bin/sh.
2435 */
2436#ifdef LOGIN_CAP
2437 shell = pw->pw_shell;
2438 shell = login_getcapstr(lc, "shell", shell, shell);
2439 if (shell[0] == '\0')
2440 shell = _PATH_BSHELL;
2441#else /* LOGIN_CAP */
2291 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
2442 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
2443#endif /* LOGIN_CAP */
2292
2293#ifdef AFS
2294 /* Try to get AFS tokens for the local cell. */
2295 if (k_hasafs()) {
2296 char cell[64];
2297
2298 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
2299 krb_afslog(cell, 0);

--- 7 unchanged lines hidden (view full) ---

2307 env = xmalloc(envsize * sizeof(char *));
2308 env[0] = NULL;
2309
2310 if (!options.use_login) {
2311 /* Set basic environment. */
2312 child_set_env(&env, &envsize, "USER", pw->pw_name);
2313 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
2314 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
2444
2445#ifdef AFS
2446 /* Try to get AFS tokens for the local cell. */
2447 if (k_hasafs()) {
2448 char cell[64];
2449
2450 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
2451 krb_afslog(cell, 0);

--- 7 unchanged lines hidden (view full) ---

2459 env = xmalloc(envsize * sizeof(char *));
2460 env[0] = NULL;
2461
2462 if (!options.use_login) {
2463 /* Set basic environment. */
2464 child_set_env(&env, &envsize, "USER", pw->pw_name);
2465 child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
2466 child_set_env(&env, &envsize, "HOME", pw->pw_dir);
2467#ifdef LOGIN_CAP
2468 child_set_env(&env, &envsize, "PATH",
2469 login_getpath(lc, "path", _PATH_STDPATH));
2470#else /* LOGIN_CAP */
2315 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
2471 child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
2472#endif /* LOGIN_CAP */
2316
2317 snprintf(buf, sizeof buf, "%.200s/%.50s",
2318 _PATH_MAILDIR, pw->pw_name);
2319 child_set_env(&env, &envsize, "MAIL", buf);
2320
2321 /* Normal systems set SHELL by default. */
2322 child_set_env(&env, &envsize, "SHELL", shell);
2323 }

--- 73 unchanged lines hidden (view full) ---

2397 channel_close_all();
2398
2399 /*
2400 * Close any extra file descriptors. Note that there may still be
2401 * descriptors left by system functions. They will be closed later.
2402 */
2403 endpwent();
2404
2473
2474 snprintf(buf, sizeof buf, "%.200s/%.50s",
2475 _PATH_MAILDIR, pw->pw_name);
2476 child_set_env(&env, &envsize, "MAIL", buf);
2477
2478 /* Normal systems set SHELL by default. */
2479 child_set_env(&env, &envsize, "SHELL", shell);
2480 }

--- 73 unchanged lines hidden (view full) ---

2554 channel_close_all();
2555
2556 /*
2557 * Close any extra file descriptors. Note that there may still be
2558 * descriptors left by system functions. They will be closed later.
2559 */
2560 endpwent();
2561
2562#ifdef LOGIN_CAP
2563 login_close(lc);
2564#endif /* LOGIN_CAP */
2565
2405 /*
2406 * Close any extra open file descriptors so that we don\'t have them
2407 * hanging around in clients. Note that we want to do this after
2408 * initgroups, because at least on Solaris 2.3 it leaves file
2409 * descriptors open.
2410 */
2566 /*
2567 * Close any extra open file descriptors so that we don\'t have them
2568 * hanging around in clients. Note that we want to do this after
2569 * initgroups, because at least on Solaris 2.3 it leaves file
2570 * descriptors open.
2571 */
2411 for (i = 3; i < 64; i++)
2572 for (i = 3; i < getdtablesize(); i++)
2412 close(i);
2413
2414 /* Change current directory to the user\'s home directory. */
2415 if (chdir(pw->pw_dir) < 0)
2416 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
2417 pw->pw_dir, strerror(errno));
2418
2419 /*
2420 * Must take new environment into use so that .ssh/rc, /etc/sshrc and
2421 * xauth are run in the proper environment.
2422 */
2423 environ = env;
2424
2425 /*
2426 * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
2427 * in this order).
2428 */
2429 if (!options.use_login) {
2573 close(i);
2574
2575 /* Change current directory to the user\'s home directory. */
2576 if (chdir(pw->pw_dir) < 0)
2577 fprintf(stderr, "Could not chdir to home directory %s: %s\n",
2578 pw->pw_dir, strerror(errno));
2579
2580 /*
2581 * Must take new environment into use so that .ssh/rc, /etc/sshrc and
2582 * xauth are run in the proper environment.
2583 */
2584 environ = env;
2585
2586 /*
2587 * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
2588 * in this order).
2589 */
2590 if (!options.use_login) {
2591#ifdef __FreeBSD__
2592 /*
2593 * If the password change time is set and has passed, give the
2594 * user a password expiry notice and chance to change it.
2595 */
2596 if (pw->pw_change != 0) {
2597 struct timeval tv;
2598
2599 (void)gettimeofday(&tv, NULL);
2600 if (tv.tv_sec >= pw->pw_change) {
2601 (void)printf(
2602 "Sorry -- your password has expired.\n");
2603 syslog(LOG_INFO,
2604 "%s Password expired - forcing change",
2605 pw->pw_name);
2606 if (system("/usr/bin/passwd") != 0)
2607 perror("/usr/bin/passwd");
2608 }
2609 }
2610#endif /* __FreeBSD__ */
2430 if (stat(SSH_USER_RC, &st) >= 0) {
2431 if (debug_flag)
2432 fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
2433
2434 f = popen("/bin/sh " SSH_USER_RC, "w");
2435 if (f) {
2436 if (auth_proto != NULL && auth_data != NULL)
2437 fprintf(f, "%s %s\n", auth_proto, auth_data);

--- 104 unchanged lines hidden ---
2611 if (stat(SSH_USER_RC, &st) >= 0) {
2612 if (debug_flag)
2613 fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
2614
2615 f = popen("/bin/sh " SSH_USER_RC, "w");
2616 if (f) {
2617 if (auth_proto != NULL && auth_data != NULL)
2618 fprintf(f, "%s %s\n", auth_proto, auth_data);

--- 104 unchanged lines hidden ---