xref: /freebsd/crypto/openssh/session.c (revision 54ab3ed82b639b593fb0fe6db845e38a9d18970e)
1 /*
2  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
3  *                    All rights reserved
4  *
5  * As far as I am concerned, the code I have written for this software
6  * can be used freely for any purpose.  Any derived versions of this
7  * software must be clearly marked as such, and if the derived work is
8  * incompatible with the protocol description in the RFC file, it must be
9  * called by a name other than "ssh" or "Secure Shell".
10  *
11  * SSH2 support by Markus Friedl.
12  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "includes.h"
36 RCSID("$OpenBSD: session.c,v 1.80 2001/06/04 21:59:43 markus Exp $");
37 RCSID("$FreeBSD$");
38 
39 #include "ssh.h"
40 #include "ssh1.h"
41 #include "ssh2.h"
42 #include "xmalloc.h"
43 #include "sshpty.h"
44 #include "packet.h"
45 #include "buffer.h"
46 #include "mpaux.h"
47 #include "uidswap.h"
48 #include "compat.h"
49 #include "channels.h"
50 #include "nchan.h"
51 #include "bufaux.h"
52 #include "auth.h"
53 #include "auth-options.h"
54 #include "pathnames.h"
55 #include "log.h"
56 #include "servconf.h"
57 #include "sshlogin.h"
58 #include "serverloop.h"
59 #include "canohost.h"
60 #include "session.h"
61 
62 #ifdef __FreeBSD__
63 #define _PATH_CHPASS "/usr/bin/passwd"
64 #endif /* __FreeBSD__ */
65 
66 #ifdef HAVE_LOGIN_CAP
67 #include <login_cap.h>
68 #endif
69 
70 #ifdef KRB5
71 extern krb5_context ssh_context;
72 #endif
73 
74 /* types */
75 
76 #define TTYSZ 64
77 typedef struct Session Session;
78 struct Session {
79 	int	used;
80 	int	self;
81 	struct	passwd *pw;
82 	pid_t	pid;
83 	/* tty */
84 	char	*term;
85 	int	ptyfd, ttyfd, ptymaster;
86 	int	row, col, xpixel, ypixel;
87 	char	tty[TTYSZ];
88 	/* X11 */
89 	char	*display;
90 	int	screen;
91 	char	*auth_proto;
92 	char	*auth_data;
93 	int	single_connection;
94 	/* proto 2 */
95 	int	chanid;
96 	int	is_subsystem;
97 };
98 
99 /* func */
100 
101 Session *session_new(void);
102 void	session_set_fds(Session *s, int fdin, int fdout, int fderr);
103 void	session_pty_cleanup(Session *s);
104 void	session_proctitle(Session *s);
105 void	do_exec_pty(Session *s, const char *command);
106 void	do_exec_no_pty(Session *s, const char *command);
107 void	do_login(Session *s, const char *command);
108 void	do_child(Session *s, const char *command);
109 void	do_motd(void);
110 int	check_quietlogin(Session *s, const char *command);
111 void	xauthfile_cleanup_proc(void *pw);
112 
113 void	do_authenticated1(Authctxt *authctxt);
114 void	do_authenticated2(Authctxt *authctxt);
115 
116 /* import */
117 extern ServerOptions options;
118 extern char *__progname;
119 extern int log_stderr;
120 extern int debug_flag;
121 extern u_int utmp_len;
122 extern int startup_pipe;
123 extern void destroy_sensitive_data(void);
124 
125 /* Local Xauthority file. */
126 static char *xauthfile;
127 
128 /* original command from peer. */
129 char *original_command = NULL;
130 
131 /* data */
132 #define MAX_SESSIONS 10
133 Session	sessions[MAX_SESSIONS];
134 
135 #ifdef HAVE_LOGIN_CAP
136 static login_cap_t *lc;
137 #endif
138 
139 void
140 do_authenticated(Authctxt *authctxt)
141 {
142 	/*
143 	 * Cancel the alarm we set to limit the time taken for
144 	 * authentication.
145 	 */
146 	alarm(0);
147 	if (startup_pipe != -1) {
148 		close(startup_pipe);
149 		startup_pipe = -1;
150 	}
151 #ifdef HAVE_LOGIN_CAP
152 	if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) {
153 		error("unable to get login class");
154 		return;
155 	}
156 #ifdef BSD_AUTH
157 	if (auth_approval(NULL, lc, authctxt->pw->pw_name, "ssh") <= 0) {
158 		packet_disconnect("Approval failure for %s",
159 		    authctxt->pw->pw_name);
160 	}
161 #endif
162 #endif
163 	/* setup the channel layer */
164 	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
165 		channel_permit_all_opens();
166 
167 	if (compat20)
168 		do_authenticated2(authctxt);
169 	else
170 		do_authenticated1(authctxt);
171 
172 	/* remote user's local Xauthority file and agent socket */
173 	if (xauthfile)
174 		xauthfile_cleanup_proc(authctxt->pw);
175 	if (auth_get_socket_name())
176 		auth_sock_cleanup_proc(authctxt->pw);
177 }
178 
179 /*
180  * Remove local Xauthority file.
181  */
182 void
183 xauthfile_cleanup_proc(void *_pw)
184 {
185 	struct passwd *pw = _pw;
186 	char *p;
187 
188 	debug("xauthfile_cleanup_proc called");
189 	if (xauthfile != NULL) {
190 		temporarily_use_uid(pw);
191 		unlink(xauthfile);
192 		p = strrchr(xauthfile, '/');
193 		if (p != NULL) {
194 			*p = '\0';
195 			rmdir(xauthfile);
196 		}
197 		xfree(xauthfile);
198 		xauthfile = NULL;
199 		restore_uid();
200 	}
201 }
202 
203 /*
204  * Function to perform cleanup if we get aborted abnormally (e.g., due to a
205  * dropped connection).
206  */
207 void
208 pty_cleanup_proc(void *session)
209 {
210 	Session *s=session;
211 	if (s == NULL)
212 		fatal("pty_cleanup_proc: no session");
213 	debug("pty_cleanup_proc: %s", s->tty);
214 
215 	if (s->pid != 0) {
216 		/* Record that the user has logged out. */
217 		record_logout(s->pid, s->tty);
218 	}
219 
220 	/* Release the pseudo-tty. */
221 	pty_release(s->tty);
222 }
223 
224 /*
225  * Prepares for an interactive session.  This is called after the user has
226  * been successfully authenticated.  During this message exchange, pseudo
227  * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
228  * are requested, etc.
229  */
230 void
231 do_authenticated1(Authctxt *authctxt)
232 {
233 	Session *s;
234 	char *command;
235 	int success, type, fd, n_bytes, plen, screen_flag, have_pty = 0;
236 	int compression_level = 0, enable_compression_after_reply = 0;
237 	u_int proto_len, data_len, dlen;
238 	struct stat st;
239 
240 	s = session_new();
241 	s->pw = authctxt->pw;
242 
243 	/*
244 	 * We stay in this loop until the client requests to execute a shell
245 	 * or a command.
246 	 */
247 	for (;;) {
248 		success = 0;
249 
250 		/* Get a packet from the client. */
251 		type = packet_read(&plen);
252 
253 		/* Process the packet. */
254 		switch (type) {
255 		case SSH_CMSG_REQUEST_COMPRESSION:
256 			packet_integrity_check(plen, 4, type);
257 			compression_level = packet_get_int();
258 			if (compression_level < 1 || compression_level > 9) {
259 				packet_send_debug("Received illegal compression level %d.",
260 				     compression_level);
261 				break;
262 			}
263 			/* Enable compression after we have responded with SUCCESS. */
264 			enable_compression_after_reply = 1;
265 			success = 1;
266 			break;
267 
268 		case SSH_CMSG_REQUEST_PTY:
269 			if (no_pty_flag) {
270 				debug("Allocating a pty not permitted for this authentication.");
271 				break;
272 			}
273 			if (have_pty)
274 				packet_disconnect("Protocol error: you already have a pty.");
275 
276 			debug("Allocating pty.");
277 
278 			/* Allocate a pty and open it. */
279 			if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
280 			    sizeof(s->tty))) {
281 				error("Failed to allocate pty.");
282 				break;
283 			}
284 			fatal_add_cleanup(pty_cleanup_proc, (void *)s);
285 			pty_setowner(s->pw, s->tty);
286 
287 			/* Get TERM from the packet.  Note that the value may be of arbitrary length. */
288 			s->term = packet_get_string(&dlen);
289 			packet_integrity_check(dlen, strlen(s->term), type);
290 			/* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */
291 			/* Remaining bytes */
292 			n_bytes = plen - (4 + dlen + 4 * 4);
293 
294 			if (strcmp(s->term, "") == 0) {
295 				xfree(s->term);
296 				s->term = NULL;
297 			}
298 			/* Get window size from the packet. */
299 			s->row = packet_get_int();
300 			s->col = packet_get_int();
301 			s->xpixel = packet_get_int();
302 			s->ypixel = packet_get_int();
303 			pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
304 
305 			/* Get tty modes from the packet. */
306 			tty_parse_modes(s->ttyfd, &n_bytes);
307 			packet_integrity_check(plen, 4 + dlen + 4 * 4 + n_bytes, type);
308 
309 			session_proctitle(s);
310 
311 			/* Indicate that we now have a pty. */
312 			success = 1;
313 			have_pty = 1;
314 			break;
315 
316 		case SSH_CMSG_X11_REQUEST_FORWARDING:
317 			if (!options.x11_forwarding) {
318 				packet_send_debug("X11 forwarding disabled in server configuration file.");
319 				break;
320 			}
321 			if (!options.xauth_location ||
322 			    (stat(options.xauth_location, &st) == -1)) {
323 				packet_send_debug("No xauth program; cannot forward with spoofing.");
324 				break;
325 			}
326 			if (no_x11_forwarding_flag) {
327 				packet_send_debug("X11 forwarding not permitted for this authentication.");
328 				break;
329 			}
330 			debug("Received request for X11 forwarding with auth spoofing.");
331 			if (s->display != NULL)
332 				packet_disconnect("Protocol error: X11 display already set.");
333 
334 			s->auth_proto = packet_get_string(&proto_len);
335 			s->auth_data = packet_get_string(&data_len);
336 
337 			screen_flag = packet_get_protocol_flags() &
338 			    SSH_PROTOFLAG_SCREEN_NUMBER;
339 			debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
340 
341 			if (packet_remaining() == 4) {
342 				if (!screen_flag)
343 					debug2("Buggy client: "
344 					    "X11 screen flag missing");
345 				packet_integrity_check(plen,
346 				    4 + proto_len + 4 + data_len + 4, type);
347 				s->screen = packet_get_int();
348 			} else {
349 				packet_integrity_check(plen,
350 				    4 + proto_len + 4 + data_len, type);
351 				s->screen = 0;
352 			}
353 			s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
354 
355 			if (s->display == NULL)
356 				break;
357 
358 			/* Setup to always have a local .Xauthority. */
359 			xauthfile = xmalloc(MAXPATHLEN);
360 			strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
361 			temporarily_use_uid(s->pw);
362 			if (mkdtemp(xauthfile) == NULL) {
363 				restore_uid();
364 				error("private X11 dir: mkdtemp %s failed: %s",
365 				    xauthfile, strerror(errno));
366 				xfree(xauthfile);
367 				xauthfile = NULL;
368 				/* XXXX remove listening channels */
369 				break;
370 			}
371 			strlcat(xauthfile, "/cookies", MAXPATHLEN);
372 			fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
373 			if (fd >= 0)
374 				close(fd);
375 			restore_uid();
376 			fatal_add_cleanup(xauthfile_cleanup_proc, s->pw);
377 			success = 1;
378 			break;
379 
380 		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
381 			if (no_agent_forwarding_flag || compat13) {
382 				debug("Authentication agent forwarding not permitted for this authentication.");
383 				break;
384 			}
385 			debug("Received authentication agent forwarding request.");
386 			success = auth_input_request_forwarding(s->pw);
387 			break;
388 
389 		case SSH_CMSG_PORT_FORWARD_REQUEST:
390 			if (no_port_forwarding_flag) {
391 				debug("Port forwarding not permitted for this authentication.");
392 				break;
393 			}
394 			if (!options.allow_tcp_forwarding) {
395 				debug("Port forwarding not permitted.");
396 				break;
397 			}
398 			debug("Received TCP/IP port forwarding request.");
399 			channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
400 			success = 1;
401 			break;
402 
403 		case SSH_CMSG_MAX_PACKET_SIZE:
404 			if (packet_set_maxsize(packet_get_int()) > 0)
405 				success = 1;
406 			break;
407 
408 		case SSH_CMSG_EXEC_SHELL:
409 		case SSH_CMSG_EXEC_CMD:
410 			if (type == SSH_CMSG_EXEC_CMD) {
411 				command = packet_get_string(&dlen);
412 				debug("Exec command '%.500s'", command);
413 				packet_integrity_check(plen, 4 + dlen, type);
414 			} else {
415 				command = NULL;
416 				packet_integrity_check(plen, 0, type);
417 			}
418 			if (forced_command != NULL) {
419 				original_command = command;
420 				command = forced_command;
421 				debug("Forced command '%.500s'", forced_command);
422 			}
423 			if (have_pty)
424 				do_exec_pty(s, command);
425 			else
426 				do_exec_no_pty(s, command);
427 
428 			if (command != NULL)
429 				xfree(command);
430 			return;
431 
432 		default:
433 			/*
434 			 * Any unknown messages in this phase are ignored,
435 			 * and a failure message is returned.
436 			 */
437 			log("Unknown packet type received after authentication: %d", type);
438 		}
439 		packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
440 		packet_send();
441 		packet_write_wait();
442 
443 		/* Enable compression now that we have replied if appropriate. */
444 		if (enable_compression_after_reply) {
445 			enable_compression_after_reply = 0;
446 			packet_start_compression(compression_level);
447 		}
448 	}
449 }
450 
451 /*
452  * This is called to fork and execute a command when we have no tty.  This
453  * will call do_child from the child, and server_loop from the parent after
454  * setting up file descriptors and such.
455  */
456 void
457 do_exec_no_pty(Session *s, const char *command)
458 {
459 	int pid;
460 
461 #ifdef USE_PIPES
462 	int pin[2], pout[2], perr[2];
463 	/* Allocate pipes for communicating with the program. */
464 	if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
465 		packet_disconnect("Could not create pipes: %.100s",
466 				  strerror(errno));
467 #else /* USE_PIPES */
468 	int inout[2], err[2];
469 	/* Uses socket pairs to communicate with the program. */
470 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
471 	    socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
472 		packet_disconnect("Could not create socket pairs: %.100s",
473 				  strerror(errno));
474 #endif /* USE_PIPES */
475 	if (s == NULL)
476 		fatal("do_exec_no_pty: no session");
477 
478 	session_proctitle(s);
479 
480 #ifdef USE_PAM
481 	do_pam_setcred();
482 #endif /* USE_PAM */
483 
484 	/* Fork the child. */
485 	if ((pid = fork()) == 0) {
486 		/* Child.  Reinitialize the log since the pid has changed. */
487 		log_init(__progname, options.log_level, options.log_facility, log_stderr);
488 
489 		/*
490 		 * Create a new session and process group since the 4.4BSD
491 		 * setlogin() affects the entire process group.
492 		 */
493 		if (setsid() < 0)
494 			error("setsid failed: %.100s", strerror(errno));
495 
496 #ifdef USE_PIPES
497 		/*
498 		 * Redirect stdin.  We close the parent side of the socket
499 		 * pair, and make the child side the standard input.
500 		 */
501 		close(pin[1]);
502 		if (dup2(pin[0], 0) < 0)
503 			perror("dup2 stdin");
504 		close(pin[0]);
505 
506 		/* Redirect stdout. */
507 		close(pout[0]);
508 		if (dup2(pout[1], 1) < 0)
509 			perror("dup2 stdout");
510 		close(pout[1]);
511 
512 		/* Redirect stderr. */
513 		close(perr[0]);
514 		if (dup2(perr[1], 2) < 0)
515 			perror("dup2 stderr");
516 		close(perr[1]);
517 #else /* USE_PIPES */
518 		/*
519 		 * Redirect stdin, stdout, and stderr.  Stdin and stdout will
520 		 * use the same socket, as some programs (particularly rdist)
521 		 * seem to depend on it.
522 		 */
523 		close(inout[1]);
524 		close(err[1]);
525 		if (dup2(inout[0], 0) < 0)	/* stdin */
526 			perror("dup2 stdin");
527 		if (dup2(inout[0], 1) < 0)	/* stdout.  Note: same socket as stdin. */
528 			perror("dup2 stdout");
529 		if (dup2(err[0], 2) < 0)	/* stderr */
530 			perror("dup2 stderr");
531 #endif /* USE_PIPES */
532 
533 		/* Do processing for the child (exec command etc). */
534 		do_child(s, command);
535 		/* NOTREACHED */
536 	}
537 	if (pid < 0)
538 		packet_disconnect("fork failed: %.100s", strerror(errno));
539 	s->pid = pid;
540 	/* Set interactive/non-interactive mode. */
541 	packet_set_interactive(s->display != NULL);
542 #ifdef USE_PIPES
543 	/* We are the parent.  Close the child sides of the pipes. */
544 	close(pin[0]);
545 	close(pout[1]);
546 	close(perr[1]);
547 
548 	if (compat20) {
549 		session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]);
550 	} else {
551 		/* Enter the interactive session. */
552 		server_loop(pid, pin[1], pout[0], perr[0]);
553 		/* server_loop has closed pin[1], pout[0], and perr[0]. */
554 	}
555 #else /* USE_PIPES */
556 	/* We are the parent.  Close the child sides of the socket pairs. */
557 	close(inout[0]);
558 	close(err[0]);
559 
560 	/*
561 	 * Enter the interactive session.  Note: server_loop must be able to
562 	 * handle the case that fdin and fdout are the same.
563 	 */
564 	if (compat20) {
565 		session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
566 	} else {
567 		server_loop(pid, inout[1], inout[1], err[1]);
568 		/* server_loop has closed inout[1] and err[1]. */
569 	}
570 #endif /* USE_PIPES */
571 }
572 
573 /*
574  * This is called to fork and execute a command when we have a tty.  This
575  * will call do_child from the child, and server_loop from the parent after
576  * setting up file descriptors, controlling tty, updating wtmp, utmp,
577  * lastlog, and other such operations.
578  */
579 void
580 do_exec_pty(Session *s, const char *command)
581 {
582 	int fdout, ptyfd, ttyfd, ptymaster;
583 	pid_t pid;
584 
585 	if (s == NULL)
586 		fatal("do_exec_pty: no session");
587 	ptyfd = s->ptyfd;
588 	ttyfd = s->ttyfd;
589 
590 #ifdef USE_PAM
591 	do_pam_session(s->pw->pw_name, s->tty);
592 	do_pam_setcred();
593 #endif /* USE_PAM */
594 
595 	/* Fork the child. */
596 	if ((pid = fork()) == 0) {
597 		/* Child.  Reinitialize the log because the pid has changed. */
598 		log_init(__progname, options.log_level, options.log_facility, log_stderr);
599 
600 		/* Close the master side of the pseudo tty. */
601 		close(ptyfd);
602 
603 		/* Make the pseudo tty our controlling tty. */
604 		pty_make_controlling_tty(&ttyfd, s->tty);
605 
606 		/* Redirect stdin from the pseudo tty. */
607 		if (dup2(ttyfd, fileno(stdin)) < 0)
608 			error("dup2 stdin failed: %.100s", strerror(errno));
609 
610 		/* Redirect stdout to the pseudo tty. */
611 		if (dup2(ttyfd, fileno(stdout)) < 0)
612 			error("dup2 stdin failed: %.100s", strerror(errno));
613 
614 		/* Redirect stderr to the pseudo tty. */
615 		if (dup2(ttyfd, fileno(stderr)) < 0)
616 			error("dup2 stdin failed: %.100s", strerror(errno));
617 
618 		/* Close the extra descriptor for the pseudo tty. */
619 		close(ttyfd);
620 
621 		/* record login, etc. similar to login(1) */
622 		if (!(options.use_login && command == NULL))
623 			do_login(s, command);
624 
625 		/* Do common processing for the child, such as execing the command. */
626 		do_child(s, command);
627 		/* NOTREACHED */
628 	}
629 	if (pid < 0)
630 		packet_disconnect("fork failed: %.100s", strerror(errno));
631 	s->pid = pid;
632 
633 	/* Parent.  Close the slave side of the pseudo tty. */
634 	close(ttyfd);
635 
636 	/*
637 	 * Create another descriptor of the pty master side for use as the
638 	 * standard input.  We could use the original descriptor, but this
639 	 * simplifies code in server_loop.  The descriptor is bidirectional.
640 	 */
641 	fdout = dup(ptyfd);
642 	if (fdout < 0)
643 		packet_disconnect("dup #1 failed: %.100s", strerror(errno));
644 
645 	/* we keep a reference to the pty master */
646 	ptymaster = dup(ptyfd);
647 	if (ptymaster < 0)
648 		packet_disconnect("dup #2 failed: %.100s", strerror(errno));
649 	s->ptymaster = ptymaster;
650 
651 	/* Enter interactive session. */
652 	packet_set_interactive(1);
653 	if (compat20) {
654 		session_set_fds(s, ptyfd, fdout, -1);
655 	} else {
656 		server_loop(pid, ptyfd, fdout, -1);
657 		/* server_loop _has_ closed ptyfd and fdout. */
658 		session_pty_cleanup(s);
659 	}
660 }
661 
662 /* administrative, login(1)-like work */
663 void
664 do_login(Session *s, const char *command)
665 {
666 	FILE *f;
667 	char *time_string, *newcommand;
668 	char buf[256];
669 	char hostname[MAXHOSTNAMELEN];
670 	socklen_t fromlen;
671 	struct sockaddr_storage from;
672 	time_t last_login_time;
673 	struct passwd * pw = s->pw;
674 	pid_t pid = getpid();
675 #ifdef HAVE_LOGIN_CAP
676 	char *fname;
677 #endif /* HAVE_LOGIN_CAP */
678 #ifdef __FreeBSD__
679 #define DEFAULT_WARN  (2L * 7L * 86400L)  /* Two weeks */
680 	struct timeval tv;
681 	time_t warntime = DEFAULT_WARN;
682 #endif /* __FreeBSD__ */
683 
684 	/*
685 	 * Get IP address of client. If the connection is not a socket, let
686 	 * the address be 0.0.0.0.
687 	 */
688 	memset(&from, 0, sizeof(from));
689 	if (packet_connection_is_on_socket()) {
690 		fromlen = sizeof(from);
691 		if (getpeername(packet_get_connection_in(),
692 		     (struct sockaddr *) & from, &fromlen) < 0) {
693 			debug("getpeername: %.100s", strerror(errno));
694 			fatal_cleanup();
695 		}
696 	}
697 
698 	/* Get the time and hostname when the user last logged in. */
699 	if (options.print_lastlog) {
700 		hostname[0] = '\0';
701 		last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
702 		    hostname, sizeof(hostname));
703 	}
704 
705 	/* Record that there was a login on that tty from the remote host. */
706 	record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
707 	    get_remote_name_or_ip(utmp_len, options.reverse_mapping_check),
708 	    (struct sockaddr *)&from);
709 
710 #ifdef USE_PAM
711 	/*
712 	 * If password change is needed, do it now.
713 	 * This needs to occur before the ~/.hushlogin check.
714 	 */
715 	if (pam_password_change_required()) {
716 		print_pam_messages();
717 		do_pam_chauthtok();
718 	}
719 #endif
720 
721 #ifdef USE_PAM
722 	if (!check_quietlogin(s, command) && !pam_password_change_required())
723 		print_pam_messages();
724 #endif /* USE_PAM */
725 
726 #ifdef __FreeBSD__
727 	if (pw->pw_change || pw->pw_expire)
728 		(void)gettimeofday(&tv, NULL);
729 #ifdef HAVE_LOGIN_CAP
730 	warntime = login_getcaptime(lc, "warnpassword",
731 				    DEFAULT_WARN, DEFAULT_WARN);
732 #endif /* HAVE_LOGIN_CAP */
733 	/*
734 	 * If the password change time is set and has passed, give the
735 	 * user a password expiry notice and chance to change it.
736 	 */
737 	if (pw->pw_change != 0) {
738 		if (tv.tv_sec >= pw->pw_change) {
739 			(void)printf(
740 			    "Sorry -- your password has expired.\n");
741 			log("%s Password expired - forcing change",
742 			    pw->pw_name);
743 			if (newcommand != NULL)
744 				xfree(newcommand);
745 			newcommand = xstrdup(_PATH_CHPASS);
746 		} else if (pw->pw_change - tv.tv_sec < warntime &&
747 			   !check_quietlogin(s, command))
748 			(void)printf(
749 			    "Warning: your password expires on %s",
750 			     ctime(&pw->pw_change));
751 	}
752 #ifdef HAVE_LOGIN_CAP
753 	warntime = login_getcaptime(lc, "warnexpire",
754 				    DEFAULT_WARN, DEFAULT_WARN);
755 #endif /* HAVE_LOGIN_CAP */
756 #ifndef USE_PAM
757 	if (pw->pw_expire) {
758 		if (tv.tv_sec >= pw->pw_expire) {
759 			(void)printf(
760 			    "Sorry -- your account has expired.\n");
761 			log(
762 	   "LOGIN %.200s REFUSED (EXPIRED) FROM %.200s ON TTY %.200s",
763 				pw->pw_name, get_remote_name_or_ip(utmp_len,
764 				options.reverse_mapping_check), s->tty);
765 			exit(254);
766 		} else if (pw->pw_expire - tv.tv_sec < warntime &&
767 			   !check_quietlogin(s, command))
768 			(void)printf(
769 			    "Warning: your account expires on %s",
770 			     ctime(&pw->pw_expire));
771 	}
772 #endif /* !USE_PAM */
773 #endif /* __FreeBSD__ */
774 
775 #ifdef HAVE_LOGIN_CAP
776 	if (!auth_ttyok(lc, s->tty)) {
777 		(void)printf("Permission denied.\n");
778 		log(
779 	       "LOGIN %.200s REFUSED (TTY) FROM %.200s ON TTY %.200s",
780 		    pw->pw_name, get_remote_name_or_ip(utmp_len,
781 			options.reverse_mapping_check), s->tty);
782 		exit(254);
783 	}
784 #endif /* HAVE_LOGIN_CAP */
785 
786 	/*
787 	 * If the user has logged in before, display the time of last
788 	 * login. However, don't display anything extra if a command
789 	 * has been specified (so that ssh can be used to execute
790 	 * commands on a remote machine without users knowing they
791 	 * are going to another machine). Login(1) will do this for
792 	 * us as well, so check if login(1) is used
793 	 */
794 	if (command == NULL && options.print_lastlog &&
795 	    last_login_time != 0 && !check_quietlogin(s, command) &&
796 	    !options.use_login) {
797 		time_string = ctime(&last_login_time);
798 		/* Remove the trailing newline. */
799 		if (strchr(time_string, '\n'))
800 			*strchr(time_string, '\n') = 0;
801 		if (strcmp(hostname, "") == 0)
802 			printf("Last login: %s\r\n", time_string);
803 		else
804 			printf("Last login: %s from %s\r\n", time_string, hostname);
805 	}
806 
807 #ifdef HAVE_LOGIN_CAP
808 	if (command == NULL && !check_quietlogin(s, command) &&
809 	    !options.use_login) {
810 		fname = login_getcapstr(lc, "copyright", NULL, NULL);
811 		if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
812 			while (fgets(buf, sizeof(buf), f) != NULL)
813 				fputs(buf, stdout);
814 				fclose(f);
815 		} else
816 			(void)printf("%s\n\t%s %s\n",
817 		"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
818 		"The Regents of the University of California. ",
819 		"All rights reserved.");
820 	}
821 #endif /* HAVE_LOGIN_CAP */
822 
823 	/*
824 	 * Print /etc/motd unless a command was specified or printing
825 	 * it was disabled in server options or login(1) will be
826 	 * used.  Note that some machines appear to print it in
827 	 * /etc/profile or similar.
828 	 */
829 	if (command == NULL && !check_quietlogin(s, command) && !options.use_login)
830 		do_motd();
831 }
832 
833 /*
834  * Display the message of the day.
835  */
836 void
837 do_motd(void)
838 {
839 	FILE *f;
840 	char buf[256];
841 
842 	if (options.print_motd) {
843 #ifdef HAVE_LOGIN_CAP
844 		f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
845 		    "/etc/motd"), "r");
846 #else /* !HAVE_LOGIN_CAP */
847 		f = fopen("/etc/motd", "r");
848 #endif /* HAVE_LOGIN_CAP */
849 		if (f) {
850 			while (fgets(buf, sizeof(buf), f))
851 				fputs(buf, stdout);
852 			fclose(f);
853 		}
854 	}
855 }
856 
857 /*
858  * Check for quiet login, either .hushlogin or command given.
859  */
860 int
861 check_quietlogin(Session *s, const char *command)
862 {
863 	char buf[256];
864 	struct passwd * pw = s->pw;
865 	struct stat st;
866 
867 	/* Return 1 if .hushlogin exists or a command given. */
868 	if (command != NULL)
869 		return 1;
870 	snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
871 #ifdef HAVE_LOGIN_CAP
872 	if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
873 		return 1;
874 #else
875 	if (stat(buf, &st) >= 0)
876 		return 1;
877 #endif
878 	return 0;
879 }
880 
881 /*
882  * Sets the value of the given variable in the environment.  If the variable
883  * already exists, its value is overriden.
884  */
885 void
886 child_set_env(char ***envp, u_int *envsizep, const char *name,
887 	      const char *value)
888 {
889 	u_int i, namelen;
890 	char **env;
891 
892 	/*
893 	 * Find the slot where the value should be stored.  If the variable
894 	 * already exists, we reuse the slot; otherwise we append a new slot
895 	 * at the end of the array, expanding if necessary.
896 	 */
897 	env = *envp;
898 	namelen = strlen(name);
899 	for (i = 0; env[i]; i++)
900 		if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
901 			break;
902 	if (env[i]) {
903 		/* Reuse the slot. */
904 		xfree(env[i]);
905 	} else {
906 		/* New variable.  Expand if necessary. */
907 		if (i >= (*envsizep) - 1) {
908 			(*envsizep) += 50;
909 			env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
910 		}
911 		/* Need to set the NULL pointer at end of array beyond the new slot. */
912 		env[i + 1] = NULL;
913 	}
914 
915 	/* Allocate space and format the variable in the appropriate slot. */
916 	env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
917 	snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
918 }
919 
920 /*
921  * Reads environment variables from the given file and adds/overrides them
922  * into the environment.  If the file does not exist, this does nothing.
923  * Otherwise, it must consist of empty lines, comments (line starts with '#')
924  * and assignments of the form name=value.  No other forms are allowed.
925  */
926 void
927 read_environment_file(char ***env, u_int *envsize,
928 		      const char *filename)
929 {
930 	FILE *f;
931 	char buf[4096];
932 	char *cp, *value;
933 
934 	f = fopen(filename, "r");
935 	if (!f)
936 		return;
937 
938 	while (fgets(buf, sizeof(buf), f)) {
939 		for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
940 			;
941 		if (!*cp || *cp == '#' || *cp == '\n')
942 			continue;
943 		if (strchr(cp, '\n'))
944 			*strchr(cp, '\n') = '\0';
945 		value = strchr(cp, '=');
946 		if (value == NULL) {
947 			fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
948 			continue;
949 		}
950 		/*
951 		 * Replace the equals sign by nul, and advance value to
952 		 * the value string.
953 		 */
954 		*value = '\0';
955 		value++;
956 		child_set_env(env, envsize, cp, value);
957 	}
958 	fclose(f);
959 }
960 
961 #ifdef USE_PAM
962 /*
963  * Sets any environment variables which have been specified by PAM
964  */
965 void do_pam_environment(char ***env, int *envsize)
966 {
967 	char *equals, var_name[512], var_val[512];
968 	char **pam_env;
969 	int i;
970 
971 	if ((pam_env = fetch_pam_environment()) == NULL)
972 		return;
973 
974 	for(i = 0; pam_env[i] != NULL; i++) {
975 		if ((equals = strstr(pam_env[i], "=")) == NULL)
976 			continue;
977 
978 		if (strlen(pam_env[i]) < (sizeof(var_name) - 1)) {
979 			memset(var_name, '\0', sizeof(var_name));
980 			memset(var_val, '\0', sizeof(var_val));
981 
982 			strncpy(var_name, pam_env[i], equals - pam_env[i]);
983 			strcpy(var_val, equals + 1);
984 
985 			child_set_env(env, envsize, var_name, var_val);
986 		}
987 	}
988 }
989 #endif /* USE_PAM */
990 
991 
992 /*
993  * Performs common processing for the child, such as setting up the
994  * environment, closing extra file descriptors, setting the user and group
995  * ids, and executing the command or shell.
996  */
997 void
998 do_child(Session *s, const char *command)
999 {
1000 	const char *shell, *hostname = NULL, *cp = NULL;
1001 	struct passwd * pw = s->pw;
1002 	char buf[256];
1003 	char cmd[1024];
1004 	FILE *f = NULL;
1005 	u_int envsize, i;
1006 	char **env = NULL;
1007 	extern char **environ;
1008 	struct stat st;
1009 	char *argv[10];
1010 	int do_xauth = s->auth_proto != NULL && s->auth_data != NULL;
1011 
1012 	/* remove hostkey from the child's memory */
1013 	destroy_sensitive_data();
1014 
1015 	/* login(1) is only called if we execute the login shell */
1016 	if (options.use_login && command != NULL)
1017 		options.use_login = 0;
1018 
1019 #ifndef USE_PAM
1020 	if (!options.use_login) {
1021 #ifdef HAVE_LOGIN_CAP
1022 	if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1023 		f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
1024 		    _PATH_NOLOGIN), "r");
1025 #else
1026 		if (pw->pw_uid)
1027 			f = fopen(_PATH_NOLOGIN, "r");
1028 #endif
1029 		if (f) {
1030 			/* /etc/nologin exists.  Print its contents and exit. */
1031 			while (fgets(buf, sizeof(buf), f))
1032 				fputs(buf, stderr);
1033 			fclose(f);
1034 			exit(254);
1035 		}
1036 	}
1037 #endif /* !USE_PAM */
1038 	/* Set login name, uid, gid, and groups. */
1039 	/* Login(1) does this as well, and it needs uid 0 for the "-h"
1040 	   switch, so we let login(1) to this for us. */
1041 	if (!options.use_login) {
1042 #ifdef HAVE_LOGIN_CAP
1043 		char **tmpenv;
1044 
1045 		/* Initialize temp environment */
1046 		envsize = 64;
1047 		env = xmalloc(envsize * sizeof(char *));
1048 		env[0] = NULL;
1049 
1050 		child_set_env(&env, &envsize, "PATH",
1051 			      (pw->pw_uid == 0) ?
1052 			      _PATH_STDPATH : _PATH_DEFPATH);
1053 
1054 		snprintf(buf, sizeof buf, "%.200s/%.50s",
1055 			 _PATH_MAILDIR, pw->pw_name);
1056 		child_set_env(&env, &envsize, "MAIL", buf);
1057 
1058 		if (getenv("TZ"))
1059 			child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1060 
1061 		/* Save parent environment */
1062 		tmpenv = environ;
1063 		environ = env;
1064 
1065 		if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) < 0)
1066 			fatal("setusercontext failed: %s", strerror(errno));
1067 
1068 		/* Restore parent environment */
1069 		env = environ;
1070 		environ = tmpenv;
1071 
1072 		for (envsize = 0; env[envsize] != NULL; ++envsize)
1073 			;
1074 		envsize = (envsize < 100) ? 100 : envsize + 16;
1075 		env = xrealloc(env, envsize * sizeof(char *));
1076 
1077 #endif /* !HAVE_LOGIN_CAP */
1078 		if (getuid() == 0 || geteuid() == 0) {
1079 #ifdef HAVE_LOGIN_CAP
1080 			if (setusercontext(lc, pw, pw->pw_uid,
1081 			    (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
1082 				perror("unable to set user context");
1083 				exit(1);
1084 			}
1085 #else
1086 			if (setlogin(pw->pw_name) < 0)
1087 				error("setlogin failed: %s", strerror(errno));
1088 			if (setgid(pw->pw_gid) < 0) {
1089 				perror("setgid");
1090 				exit(1);
1091 			}
1092 			/* Initialize the group list. */
1093 			if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1094 				perror("initgroups");
1095 				exit(1);
1096 			}
1097 			endgrent();
1098 
1099 			/* Permanently switch to the desired uid. */
1100 			permanently_set_uid(pw);
1101 #endif /* HAVE_LOGIN_CAP */
1102 		}
1103 		if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1104 			fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1105 	}
1106 	/*
1107 	 * Get the shell from the password data.  An empty shell field is
1108 	 * legal, and means /bin/sh.
1109 	 */
1110 	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1111 #ifdef HAVE_LOGIN_CAP
1112 	shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1113 #endif
1114 
1115 #ifdef AFS
1116 	/* Try to get AFS tokens for the local cell. */
1117 	if (k_hasafs()) {
1118 		char cell[64];
1119 
1120 		if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1121 			krb_afslog(cell, 0);
1122 
1123 		krb_afslog(0, 0);
1124 	}
1125 #endif /* AFS */
1126 
1127 	/* Initialize the environment. */
1128 	if (env == NULL) {
1129 		envsize = 100;
1130 		env = xmalloc(envsize * sizeof(char *));
1131 		env[0] = NULL;
1132 	}
1133 
1134 	if (!options.use_login) {
1135 		/* Set basic environment. */
1136 		child_set_env(&env, &envsize, "USER", pw->pw_name);
1137 		child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
1138 		child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1139 #ifdef HAVE_LOGIN_CAP
1140 		(void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
1141 		child_set_env(&env, &envsize, "PATH", getenv("PATH"));
1142 #else
1143 		child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1144 #endif
1145 
1146 		snprintf(buf, sizeof buf, "%.200s/%.50s",
1147 			 _PATH_MAILDIR, pw->pw_name);
1148 		child_set_env(&env, &envsize, "MAIL", buf);
1149 
1150 		/* Normal systems set SHELL by default. */
1151 		child_set_env(&env, &envsize, "SHELL", shell);
1152 	}
1153 	if (getenv("TZ"))
1154 		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1155 
1156 	/* Set custom environment options from RSA authentication. */
1157 	if (!options.use_login) {
1158 	while (custom_environment) {
1159 		struct envstring *ce = custom_environment;
1160 		char *s = ce->s;
1161 		int i;
1162 		for (i = 0; s[i] != '=' && s[i]; i++);
1163 		if (s[i] == '=') {
1164 			s[i] = 0;
1165 			child_set_env(&env, &envsize, s, s + i + 1);
1166 		}
1167 		custom_environment = ce->next;
1168 		xfree(ce->s);
1169 		xfree(ce);
1170 	}
1171 	}
1172 
1173 	snprintf(buf, sizeof buf, "%.50s %d %d",
1174 		 get_remote_ipaddr(), get_remote_port(), get_local_port());
1175 	child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1176 
1177 	if (s->ttyfd != -1)
1178 		child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1179 	if (s->term)
1180 		child_set_env(&env, &envsize, "TERM", s->term);
1181 	if (s->display)
1182 		child_set_env(&env, &envsize, "DISPLAY", s->display);
1183 	if (original_command)
1184 		child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1185 		    original_command);
1186 
1187 #ifdef KRB4
1188 	{
1189 		extern char *ticket;
1190 
1191 		if (ticket)
1192 			child_set_env(&env, &envsize, "KRBTKFILE", ticket);
1193 	}
1194 #endif /* KRB4 */
1195 #ifdef KRB5
1196 {
1197 	  extern krb5_ccache mem_ccache;
1198 
1199 	   if (mem_ccache) {
1200 	     krb5_error_code problem;
1201 	      krb5_ccache ccache;
1202 #ifdef AFS
1203 	      if (k_hasafs())
1204 		krb5_afslog(ssh_context, mem_ccache, NULL, NULL);
1205 #endif /* AFS */
1206 
1207 	      problem = krb5_cc_default(ssh_context, &ccache);
1208 	      if (problem) {}
1209 	      else {
1210 		problem = krb5_cc_copy_cache(ssh_context, mem_ccache, ccache);
1211 		 if (problem) {}
1212 	      }
1213 
1214 	      krb5_cc_close(ssh_context, ccache);
1215 	   }
1216 
1217 	   krb5_cleanup_proc(NULL);
1218 	}
1219 #endif /* KRB5 */
1220 
1221 #ifdef USE_PAM
1222 	/* Pull in any environment variables that may have been set by PAM. */
1223 	do_pam_environment(&env, &envsize);
1224 #endif /* USE_PAM */
1225 
1226 	if (xauthfile)
1227 		child_set_env(&env, &envsize, "XAUTHORITY", xauthfile);
1228 	if (auth_get_socket_name() != NULL)
1229 		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1230 			      auth_get_socket_name());
1231 
1232 	/* read $HOME/.ssh/environment. */
1233 	if (!options.use_login) {
1234 		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1235 		    pw->pw_dir);
1236 		read_environment_file(&env, &envsize, buf);
1237 	}
1238 	if (debug_flag) {
1239 		/* dump the environment */
1240 		fprintf(stderr, "Environment:\n");
1241 		for (i = 0; env[i]; i++)
1242 			fprintf(stderr, "  %.200s\n", env[i]);
1243 	}
1244 	/* we have to stash the hostname before we close our socket. */
1245 	if (options.use_login)
1246 		hostname = get_remote_name_or_ip(utmp_len,
1247 		    options.reverse_mapping_check);
1248 	/*
1249 	 * Close the connection descriptors; note that this is the child, and
1250 	 * the server will still have the socket open, and it is important
1251 	 * that we do not shutdown it.  Note that the descriptors cannot be
1252 	 * closed before building the environment, as we call
1253 	 * get_remote_ipaddr there.
1254 	 */
1255 	if (packet_get_connection_in() == packet_get_connection_out())
1256 		close(packet_get_connection_in());
1257 	else {
1258 		close(packet_get_connection_in());
1259 		close(packet_get_connection_out());
1260 	}
1261 	/*
1262 	 * Close all descriptors related to channels.  They will still remain
1263 	 * open in the parent.
1264 	 */
1265 	/* XXX better use close-on-exec? -markus */
1266 	channel_close_all();
1267 
1268 	/*
1269 	 * Close any extra file descriptors.  Note that there may still be
1270 	 * descriptors left by system functions.  They will be closed later.
1271 	 */
1272 	endpwent();
1273 
1274 	/*
1275 	 * Restore any signal handlers set by sshd previously that should
1276 	 * be restored to their initial state.
1277 	 */
1278 	signal(SIGPIPE, SIG_DFL);
1279 
1280 	/* Change current directory to the user\'s home directory. */
1281 	if (
1282 #ifdef __FreeBSD__
1283 		!*pw->pw_dir ||
1284 #endif /* __FreeBSD__ */
1285 		chdir(pw->pw_dir) < 0
1286 	   ) {
1287 #ifdef HAVE_LOGIN_CAP
1288 		if (login_getcapbool(lc, "requirehome", 0)) {
1289 			(void)printf("Home directory not available\n");
1290 			log("LOGIN %.200s REFUSED (HOMEDIR) ON TTY %.200s",
1291 				pw->pw_name, ttyname);
1292 			exit(254);
1293 		}
1294 #endif /* HAVE_LOGIN_CAP */
1295 #ifdef __FreeBSD__
1296 		if (chdir("/") < 0) {
1297 			(void)printf("Cannot find root directory\n");
1298 			log("LOGIN %.200s REFUSED (ROOTDIR) ON TTY %.200s",
1299 				pw->pw_name, ttyname);
1300 			exit(254);
1301 		}
1302 		if (!check_quietlogin(s, command) || *pw->pw_dir)
1303 			(void)printf(
1304 		       "No home directory.\nLogging in with home = \"/\".\n");
1305 
1306 #else /* !__FreeBSD__ */
1307 
1308 		fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1309 			pw->pw_dir, strerror(errno));
1310 #endif /* __FreeBSD__ */
1311 	}
1312 
1313 	/*
1314 	 * Close any extra open file descriptors so that we don\'t have them
1315 	 * hanging around in clients.  Note that we want to do this after
1316 	 * initgroups, because at least on Solaris 2.3 it leaves file
1317 	 * descriptors open.
1318 	 */
1319 	for (i = 3; i < getdtablesize(); i++)
1320 		close(i);
1321 
1322 	/*
1323 	 * Must take new environment into use so that .ssh/rc, /etc/sshrc and
1324 	 * xauth are run in the proper environment.
1325 	 */
1326 	environ = env;
1327 
1328 	/*
1329 	 * Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
1330 	 * in this order).
1331 	 */
1332 	if (!options.use_login) {
1333 		/* ignore _PATH_SSH_USER_RC for subsystems */
1334 		if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
1335 			snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1336 			    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1337 			if (debug_flag)
1338 				fprintf(stderr, "Running %s\n", cmd);
1339 			f = popen(cmd, "w");
1340 			if (f) {
1341 				if (do_xauth)
1342 					fprintf(f, "%s %s\n", s->auth_proto,
1343 					    s->auth_data);
1344 				pclose(f);
1345 			} else
1346 				fprintf(stderr, "Could not run %s\n",
1347 				    _PATH_SSH_USER_RC);
1348 		} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1349 			if (debug_flag)
1350 				fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1351 				    _PATH_SSH_SYSTEM_RC);
1352 			f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1353 			if (f) {
1354 				if (do_xauth)
1355 					fprintf(f, "%s %s\n", s->auth_proto,
1356 					    s->auth_data);
1357 				pclose(f);
1358 			} else
1359 				fprintf(stderr, "Could not run %s\n",
1360 				    _PATH_SSH_SYSTEM_RC);
1361 		} else if (do_xauth && options.xauth_location != NULL) {
1362 			/* Add authority data to .Xauthority if appropriate. */
1363 			char *screen = strchr(s->display, ':');
1364 
1365 			if (debug_flag) {
1366 				fprintf(stderr,
1367 				    "Running %.100s add "
1368 				    "%.100s %.100s %.100s\n",
1369 				    options.xauth_location, s->display,
1370 				    s->auth_proto, s->auth_data);
1371 				if (screen != NULL)
1372 					fprintf(stderr,
1373 					    "Adding %.*s/unix%s %s %s\n",
1374 					    (int)(screen - s->display),
1375 					    s->display, screen,
1376 					    s->auth_proto, s->auth_data);
1377 			}
1378 			snprintf(cmd, sizeof cmd, "%s -q -",
1379 			    options.xauth_location);
1380 			f = popen(cmd, "w");
1381 			if (f) {
1382 				fprintf(f, "add %s %s %s\n", s->display,
1383 				    s->auth_proto, s->auth_data);
1384 				if (screen != NULL)
1385 					fprintf(f, "add %.*s/unix%s %s %s\n",
1386 					    (int)(screen - s->display),
1387 					    s->display, screen,
1388 					    s->auth_proto,
1389 					    s->auth_data);
1390 				pclose(f);
1391 			} else {
1392 				fprintf(stderr, "Could not run %s\n",
1393 				    cmd);
1394 			}
1395 		}
1396 		/* Get the last component of the shell name. */
1397 		cp = strrchr(shell, '/');
1398 		if (cp)
1399 			cp++;
1400 		else
1401 			cp = shell;
1402 	}
1403 
1404 	/* restore SIGPIPE for child */
1405 	signal(SIGPIPE,  SIG_DFL);
1406 
1407 	/*
1408 	 * If we have no command, execute the shell.  In this case, the shell
1409 	 * name to be passed in argv[0] is preceded by '-' to indicate that
1410 	 * this is a login shell.
1411 	 */
1412 	if (!command) {
1413 		if (!options.use_login) {
1414 			char buf[256];
1415 
1416 			/*
1417 			 * Check for mail if we have a tty and it was enabled
1418 			 * in server options.
1419 			 */
1420 			if (s->ttyfd != -1 && options.check_mail) {
1421 				char *mailbox;
1422 				struct stat mailstat;
1423 
1424 				mailbox = getenv("MAIL");
1425 				if (mailbox != NULL) {
1426 					if (stat(mailbox, &mailstat) != 0 ||
1427 					    mailstat.st_size == 0)
1428 #ifdef __FreeBSD__
1429 						;
1430 #else /* !__FreeBSD__ */
1431 						printf("No mail.\n");
1432 #endif /* __FreeBSD__ */
1433 					else if (mailstat.st_mtime < mailstat.st_atime)
1434 						printf("You have mail.\n");
1435 					else
1436 						printf("You have new mail.\n");
1437 				}
1438 			}
1439 			/* Start the shell.  Set initial character to '-'. */
1440 			buf[0] = '-';
1441 			strncpy(buf + 1, cp, sizeof(buf) - 1);
1442 			buf[sizeof(buf) - 1] = 0;
1443 
1444 			/* Execute the shell. */
1445 			argv[0] = buf;
1446 			argv[1] = NULL;
1447 			execve(shell, argv, env);
1448 
1449 			/* Executing the shell failed. */
1450 			perror(shell);
1451 			exit(1);
1452 
1453 		} else {
1454 			/* Launch login(1). */
1455 
1456 			execl("/usr/bin/login", "login", "-h", hostname,
1457 			     "-p", "-f", "--", pw->pw_name, NULL);
1458 
1459 			/* Login couldn't be executed, die. */
1460 
1461 			perror("login");
1462 			exit(1);
1463 		}
1464 	}
1465 	/*
1466 	 * Execute the command using the user's shell.  This uses the -c
1467 	 * option to execute the command.
1468 	 */
1469 	argv[0] = (char *) cp;
1470 	argv[1] = "-c";
1471 	argv[2] = (char *) command;
1472 	argv[3] = NULL;
1473 	execve(shell, argv, env);
1474 	perror(shell);
1475 	exit(1);
1476 }
1477 
1478 Session *
1479 session_new(void)
1480 {
1481 	int i;
1482 	static int did_init = 0;
1483 	if (!did_init) {
1484 		debug("session_new: init");
1485 		for(i = 0; i < MAX_SESSIONS; i++) {
1486 			sessions[i].used = 0;
1487 			sessions[i].self = i;
1488 		}
1489 		did_init = 1;
1490 	}
1491 	for(i = 0; i < MAX_SESSIONS; i++) {
1492 		Session *s = &sessions[i];
1493 		if (! s->used) {
1494 			memset(s, 0, sizeof(*s));
1495 			s->chanid = -1;
1496 			s->ptyfd = -1;
1497 			s->ttyfd = -1;
1498 			s->used = 1;
1499 			debug("session_new: session %d", i);
1500 			return s;
1501 		}
1502 	}
1503 	return NULL;
1504 }
1505 
1506 void
1507 session_dump(void)
1508 {
1509 	int i;
1510 	for(i = 0; i < MAX_SESSIONS; i++) {
1511 		Session *s = &sessions[i];
1512 		debug("dump: used %d session %d %p channel %d pid %d",
1513 		    s->used,
1514 		    s->self,
1515 		    s,
1516 		    s->chanid,
1517 		    s->pid);
1518 	}
1519 }
1520 
1521 int
1522 session_open(int chanid)
1523 {
1524 	Session *s = session_new();
1525 	debug("session_open: channel %d", chanid);
1526 	if (s == NULL) {
1527 		error("no more sessions");
1528 		return 0;
1529 	}
1530 	s->pw = auth_get_user();
1531 	if (s->pw == NULL)
1532 		fatal("no user for session %d", s->self);
1533 	debug("session_open: session %d: link with channel %d", s->self, chanid);
1534 	s->chanid = chanid;
1535 	return 1;
1536 }
1537 
1538 Session *
1539 session_by_channel(int id)
1540 {
1541 	int i;
1542 	for(i = 0; i < MAX_SESSIONS; i++) {
1543 		Session *s = &sessions[i];
1544 		if (s->used && s->chanid == id) {
1545 			debug("session_by_channel: session %d channel %d", i, id);
1546 			return s;
1547 		}
1548 	}
1549 	debug("session_by_channel: unknown channel %d", id);
1550 	session_dump();
1551 	return NULL;
1552 }
1553 
1554 Session *
1555 session_by_pid(pid_t pid)
1556 {
1557 	int i;
1558 	debug("session_by_pid: pid %d", pid);
1559 	for(i = 0; i < MAX_SESSIONS; i++) {
1560 		Session *s = &sessions[i];
1561 		if (s->used && s->pid == pid)
1562 			return s;
1563 	}
1564 	error("session_by_pid: unknown pid %d", pid);
1565 	session_dump();
1566 	return NULL;
1567 }
1568 
1569 int
1570 session_window_change_req(Session *s)
1571 {
1572 	s->col = packet_get_int();
1573 	s->row = packet_get_int();
1574 	s->xpixel = packet_get_int();
1575 	s->ypixel = packet_get_int();
1576 	packet_done();
1577 	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1578 	return 1;
1579 }
1580 
1581 int
1582 session_pty_req(Session *s)
1583 {
1584 	u_int len;
1585 	int n_bytes;
1586 
1587 	if (no_pty_flag)
1588 		return 0;
1589 	if (s->ttyfd != -1)
1590 		return 0;
1591 	s->term = packet_get_string(&len);
1592 	s->col = packet_get_int();
1593 	s->row = packet_get_int();
1594 	s->xpixel = packet_get_int();
1595 	s->ypixel = packet_get_int();
1596 
1597 	if (strcmp(s->term, "") == 0) {
1598 		xfree(s->term);
1599 		s->term = NULL;
1600 	}
1601 	/* Allocate a pty and open it. */
1602 	if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) {
1603 		xfree(s->term);
1604 		s->term = NULL;
1605 		s->ptyfd = -1;
1606 		s->ttyfd = -1;
1607 		error("session_pty_req: session %d alloc failed", s->self);
1608 		return 0;
1609 	}
1610 	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1611 	/*
1612 	 * Add a cleanup function to clear the utmp entry and record logout
1613 	 * time in case we call fatal() (e.g., the connection gets closed).
1614 	 */
1615 	fatal_add_cleanup(pty_cleanup_proc, (void *)s);
1616 	pty_setowner(s->pw, s->tty);
1617 	/* Get window size from the packet. */
1618 	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1619 
1620 	/* Get tty modes from the packet. */
1621 	tty_parse_modes(s->ttyfd, &n_bytes);
1622 	packet_done();
1623 
1624 	session_proctitle(s);
1625 
1626 	return 1;
1627 }
1628 
1629 int
1630 session_subsystem_req(Session *s)
1631 {
1632 	u_int len;
1633 	int success = 0;
1634 	char *subsys = packet_get_string(&len);
1635 	int i;
1636 
1637 	packet_done();
1638 	log("subsystem request for %s", subsys);
1639 
1640 	for (i = 0; i < options.num_subsystems; i++) {
1641 		if(strcmp(subsys, options.subsystem_name[i]) == 0) {
1642 			debug("subsystem: exec() %s", options.subsystem_command[i]);
1643 			s->is_subsystem = 1;
1644 			do_exec_no_pty(s, options.subsystem_command[i]);
1645 			success = 1;
1646 		}
1647 	}
1648 
1649 	if (!success)
1650 		log("subsystem request for %s failed, subsystem not found", subsys);
1651 
1652 	xfree(subsys);
1653 	return success;
1654 }
1655 
1656 int
1657 session_x11_req(Session *s)
1658 {
1659 	int fd;
1660 	struct stat st;
1661 	if (no_x11_forwarding_flag) {
1662 		debug("X11 forwarding disabled in user configuration file.");
1663 		return 0;
1664 	}
1665 	if (!options.x11_forwarding) {
1666 		debug("X11 forwarding disabled in server configuration file.");
1667 		return 0;
1668 	}
1669 	if (!options.xauth_location ||
1670 	    (stat(options.xauth_location, &st) == -1)) {
1671 		packet_send_debug("No xauth program; cannot forward with spoofing.");
1672 		return 0;
1673 	}
1674 	if (xauthfile != NULL) {
1675 		debug("X11 fwd already started.");
1676 		return 0;
1677 	}
1678 
1679 	debug("Received request for X11 forwarding with auth spoofing.");
1680 	if (s->display != NULL)
1681 		packet_disconnect("Protocol error: X11 display already set.");
1682 
1683 	s->single_connection = packet_get_char();
1684 	s->auth_proto = packet_get_string(NULL);
1685 	s->auth_data = packet_get_string(NULL);
1686 	s->screen = packet_get_int();
1687 	packet_done();
1688 
1689 	s->display = x11_create_display_inet(s->screen, options.x11_display_offset);
1690 	if (s->display == NULL) {
1691 		xfree(s->auth_proto);
1692 		xfree(s->auth_data);
1693 		return 0;
1694 	}
1695 	xauthfile = xmalloc(MAXPATHLEN);
1696 	strlcpy(xauthfile, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
1697 	temporarily_use_uid(s->pw);
1698 	if (mkdtemp(xauthfile) == NULL) {
1699 		restore_uid();
1700 		error("private X11 dir: mkdtemp %s failed: %s",
1701 		    xauthfile, strerror(errno));
1702 		xfree(xauthfile);
1703 		xauthfile = NULL;
1704 		xfree(s->auth_proto);
1705 		xfree(s->auth_data);
1706 		/* XXXX remove listening channels */
1707 		return 0;
1708 	}
1709 	strlcat(xauthfile, "/cookies", MAXPATHLEN);
1710 	fd = open(xauthfile, O_RDWR|O_CREAT|O_EXCL, 0600);
1711 	if (fd >= 0)
1712 		close(fd);
1713 	restore_uid();
1714 	fatal_add_cleanup(xauthfile_cleanup_proc, s->pw);
1715 	return 1;
1716 }
1717 
1718 int
1719 session_shell_req(Session *s)
1720 {
1721 	/* if forced_command == NULL, the shell is execed */
1722 	char *shell = forced_command;
1723 	packet_done();
1724 	if (s->ttyfd == -1)
1725 		do_exec_no_pty(s, shell);
1726 	else
1727 		do_exec_pty(s, shell);
1728 	return 1;
1729 }
1730 
1731 int
1732 session_exec_req(Session *s)
1733 {
1734 	u_int len;
1735 	char *command = packet_get_string(&len);
1736 	packet_done();
1737 	if (forced_command) {
1738 		original_command = command;
1739 		command = forced_command;
1740 		debug("Forced command '%.500s'", forced_command);
1741 	}
1742 	if (s->ttyfd == -1)
1743 		do_exec_no_pty(s, command);
1744 	else
1745 		do_exec_pty(s, command);
1746 	if (forced_command == NULL)
1747 		xfree(command);
1748 	return 1;
1749 }
1750 
1751 int
1752 session_auth_agent_req(Session *s)
1753 {
1754 	static int called = 0;
1755 	packet_done();
1756 	if (no_agent_forwarding_flag) {
1757 		debug("session_auth_agent_req: no_agent_forwarding_flag");
1758 		return 0;
1759 	}
1760 	if (called) {
1761 		return 0;
1762 	} else {
1763 		called = 1;
1764 		return auth_input_request_forwarding(s->pw);
1765 	}
1766 }
1767 
1768 void
1769 session_input_channel_req(int id, void *arg)
1770 {
1771 	u_int len;
1772 	int reply;
1773 	int success = 0;
1774 	char *rtype;
1775 	Session *s;
1776 	Channel *c;
1777 
1778 	rtype = packet_get_string(&len);
1779 	reply = packet_get_char();
1780 
1781 	s = session_by_channel(id);
1782 	if (s == NULL)
1783 		fatal("session_input_channel_req: channel %d: no session", id);
1784 	c = channel_lookup(id);
1785 	if (c == NULL)
1786 		fatal("session_input_channel_req: channel %d: bad channel", id);
1787 
1788 	debug("session_input_channel_req: session %d channel %d request %s reply %d",
1789 	    s->self, id, rtype, reply);
1790 
1791 	/*
1792 	 * a session is in LARVAL state until a shell, a command
1793 	 * or a subsystem is executed
1794 	 */
1795 	if (c->type == SSH_CHANNEL_LARVAL) {
1796 		if (strcmp(rtype, "shell") == 0) {
1797 			success = session_shell_req(s);
1798 		} else if (strcmp(rtype, "exec") == 0) {
1799 			success = session_exec_req(s);
1800 		} else if (strcmp(rtype, "pty-req") == 0) {
1801 			success =  session_pty_req(s);
1802 		} else if (strcmp(rtype, "x11-req") == 0) {
1803 			success = session_x11_req(s);
1804 		} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
1805 			success = session_auth_agent_req(s);
1806 		} else if (strcmp(rtype, "subsystem") == 0) {
1807 			success = session_subsystem_req(s);
1808 		}
1809 	}
1810 	if (strcmp(rtype, "window-change") == 0) {
1811 		success = session_window_change_req(s);
1812 	}
1813 
1814 	if (reply) {
1815 		packet_start(success ?
1816 		    SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE);
1817 		packet_put_int(c->remote_id);
1818 		packet_send();
1819 	}
1820 	xfree(rtype);
1821 }
1822 
1823 void
1824 session_set_fds(Session *s, int fdin, int fdout, int fderr)
1825 {
1826 	if (!compat20)
1827 		fatal("session_set_fds: called for proto != 2.0");
1828 	/*
1829 	 * now that have a child and a pipe to the child,
1830 	 * we can activate our channel and register the fd's
1831 	 */
1832 	if (s->chanid == -1)
1833 		fatal("no channel for session %d", s->self);
1834 	channel_set_fds(s->chanid,
1835 	    fdout, fdin, fderr,
1836 	    fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
1837 	    1);
1838 }
1839 
1840 void
1841 session_pty_cleanup(Session *s)
1842 {
1843 	if (s == NULL || s->ttyfd == -1)
1844 		return;
1845 
1846 	debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
1847 
1848 	/* Cancel the cleanup function. */
1849 	fatal_remove_cleanup(pty_cleanup_proc, (void *)s);
1850 
1851 	/* Record that the user has logged out. */
1852 	record_logout(s->pid, s->tty);
1853 
1854 	/* Release the pseudo-tty. */
1855 	pty_release(s->tty);
1856 
1857 	/*
1858 	 * Close the server side of the socket pairs.  We must do this after
1859 	 * the pty cleanup, so that another process doesn't get this pty
1860 	 * while we're still cleaning up.
1861 	 */
1862 	if (close(s->ptymaster) < 0)
1863 		error("close(s->ptymaster): %s", strerror(errno));
1864 }
1865 
1866 void
1867 session_exit_message(Session *s, int status)
1868 {
1869 	Channel *c;
1870 	if (s == NULL)
1871 		fatal("session_close: no session");
1872 	c = channel_lookup(s->chanid);
1873 	if (c == NULL)
1874 		fatal("session_close: session %d: no channel %d",
1875 		    s->self, s->chanid);
1876 	debug("session_exit_message: session %d channel %d pid %d",
1877 	    s->self, s->chanid, s->pid);
1878 
1879 	if (WIFEXITED(status)) {
1880 		channel_request_start(s->chanid,
1881 		    "exit-status", 0);
1882 		packet_put_int(WEXITSTATUS(status));
1883 		packet_send();
1884 	} else if (WIFSIGNALED(status)) {
1885 		channel_request_start(s->chanid,
1886 		    "exit-signal", 0);
1887 		packet_put_int(WTERMSIG(status));
1888 		packet_put_char(WCOREDUMP(status));
1889 		packet_put_cstring("");
1890 		packet_put_cstring("");
1891 		packet_send();
1892 	} else {
1893 		/* Some weird exit cause.  Just exit. */
1894 		packet_disconnect("wait returned status %04x.", status);
1895 	}
1896 
1897 	/* disconnect channel */
1898 	debug("session_exit_message: release channel %d", s->chanid);
1899 	channel_cancel_cleanup(s->chanid);
1900 	/*
1901 	 * emulate a write failure with 'chan_write_failed', nobody will be
1902 	 * interested in data we write.
1903 	 * Note that we must not call 'chan_read_failed', since there could
1904 	 * be some more data waiting in the pipe.
1905 	 */
1906 	if (c->ostate != CHAN_OUTPUT_CLOSED)
1907 		chan_write_failed(c);
1908 	s->chanid = -1;
1909 }
1910 
1911 void
1912 session_free(Session *s)
1913 {
1914 	debug("session_free: session %d pid %d", s->self, s->pid);
1915 	if (s->term)
1916 		xfree(s->term);
1917 	if (s->display)
1918 		xfree(s->display);
1919 	if (s->auth_data)
1920 		xfree(s->auth_data);
1921 	if (s->auth_proto)
1922 		xfree(s->auth_proto);
1923 	s->used = 0;
1924 }
1925 
1926 void
1927 session_close(Session *s)
1928 {
1929 	session_pty_cleanup(s);
1930 	session_free(s);
1931 	session_proctitle(s);
1932 }
1933 
1934 void
1935 session_close_by_pid(pid_t pid, int status)
1936 {
1937 	Session *s = session_by_pid(pid);
1938 	if (s == NULL) {
1939 		debug("session_close_by_pid: no session for pid %d", s->pid);
1940 		return;
1941 	}
1942 	if (s->chanid != -1)
1943 		session_exit_message(s, status);
1944 	session_close(s);
1945 }
1946 
1947 /*
1948  * this is called when a channel dies before
1949  * the session 'child' itself dies
1950  */
1951 void
1952 session_close_by_channel(int id, void *arg)
1953 {
1954 	Session *s = session_by_channel(id);
1955 	if (s == NULL) {
1956 		debug("session_close_by_channel: no session for channel %d", id);
1957 		return;
1958 	}
1959 	/* disconnect channel */
1960 	channel_cancel_cleanup(s->chanid);
1961 	s->chanid = -1;
1962 
1963 	debug("session_close_by_channel: channel %d kill %d", id, s->pid);
1964 	if (s->pid == 0) {
1965 		/* close session immediately */
1966 		session_close(s);
1967 	} else {
1968 		/* notify child, delay session cleanup */
1969 		if (s->pid <= 1)
1970 			fatal("session_close_by_channel: Unsafe s->pid = %d", s->pid);
1971 		if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0)
1972 			error("session_close_by_channel: kill %d: %s",
1973 			    s->pid, strerror(errno));
1974 	}
1975 }
1976 
1977 char *
1978 session_tty_list(void)
1979 {
1980 	static char buf[1024];
1981 	int i;
1982 	buf[0] = '\0';
1983 	for(i = 0; i < MAX_SESSIONS; i++) {
1984 		Session *s = &sessions[i];
1985 		if (s->used && s->ttyfd != -1) {
1986 			if (buf[0] != '\0')
1987 				strlcat(buf, ",", sizeof buf);
1988 			strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
1989 		}
1990 	}
1991 	if (buf[0] == '\0')
1992 		strlcpy(buf, "notty", sizeof buf);
1993 	return buf;
1994 }
1995 
1996 void
1997 session_proctitle(Session *s)
1998 {
1999 	if (s->pw == NULL)
2000 		error("no user for session %d", s->self);
2001 	else
2002 		setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
2003 }
2004 
2005 void
2006 do_authenticated2(Authctxt *authctxt)
2007 {
2008 
2009 	server_loop2();
2010 }
2011