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 --- |