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