session.c revision 147005
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"
36RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $");
37RCSID("$FreeBSD: head/crypto/openssh/session.c 147005 2005-06-05 15:46:09Z des $");
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 "match.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#if defined(KRB5) && defined(USE_AFS)
63#include <kafs.h>
64#endif
65
66#ifdef GSSAPI
67#include "ssh-gss.h"
68#endif
69
70/* func */
71
72Session *session_new(void);
73void	session_set_fds(Session *, int, int, int);
74void	session_pty_cleanup(Session *);
75void	session_proctitle(Session *);
76int	session_setup_x11fwd(Session *);
77void	do_exec_pty(Session *, const char *);
78void	do_exec_no_pty(Session *, const char *);
79void	do_exec(Session *, const char *);
80void	do_login(Session *, const char *);
81#ifdef LOGIN_NEEDS_UTMPX
82static void	do_pre_login(Session *s);
83#endif
84void	do_child(Session *, const char *);
85void	do_motd(void);
86int	check_quietlogin(Session *, const char *);
87
88static void do_authenticated1(Authctxt *);
89static void do_authenticated2(Authctxt *);
90
91static int session_pty_req(Session *);
92
93/* import */
94extern ServerOptions options;
95extern char *__progname;
96extern int log_stderr;
97extern int debug_flag;
98extern u_int utmp_len;
99extern int startup_pipe;
100extern void destroy_sensitive_data(void);
101extern Buffer loginmsg;
102
103/* original command from peer. */
104const char *original_command = NULL;
105
106/* data */
107#define MAX_SESSIONS 10
108Session	sessions[MAX_SESSIONS];
109
110#ifdef HAVE_LOGIN_CAP
111login_cap_t *lc;
112#endif
113
114static int is_child = 0;
115
116/* Name and directory of socket for authentication agent forwarding. */
117static char *auth_sock_name = NULL;
118static char *auth_sock_dir = NULL;
119
120/* removes the agent forwarding socket */
121
122static void
123auth_sock_cleanup_proc(struct passwd *pw)
124{
125	if (auth_sock_name != NULL) {
126		temporarily_use_uid(pw);
127		unlink(auth_sock_name);
128		rmdir(auth_sock_dir);
129		auth_sock_name = NULL;
130		restore_uid();
131	}
132}
133
134static int
135auth_input_request_forwarding(struct passwd * pw)
136{
137	Channel *nc;
138	int sock;
139	struct sockaddr_un sunaddr;
140
141	if (auth_sock_name != NULL) {
142		error("authentication forwarding requested twice.");
143		return 0;
144	}
145
146	/* Temporarily drop privileged uid for mkdir/bind. */
147	temporarily_use_uid(pw);
148
149	/* Allocate a buffer for the socket name, and format the name. */
150	auth_sock_name = xmalloc(MAXPATHLEN);
151	auth_sock_dir = xmalloc(MAXPATHLEN);
152	strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
153
154	/* Create private directory for socket */
155	if (mkdtemp(auth_sock_dir) == NULL) {
156		packet_send_debug("Agent forwarding disabled: "
157		    "mkdtemp() failed: %.100s", strerror(errno));
158		restore_uid();
159		xfree(auth_sock_name);
160		xfree(auth_sock_dir);
161		auth_sock_name = NULL;
162		auth_sock_dir = NULL;
163		return 0;
164	}
165	snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
166		 auth_sock_dir, (long) getpid());
167
168	/* Create the socket. */
169	sock = socket(AF_UNIX, SOCK_STREAM, 0);
170	if (sock < 0)
171		packet_disconnect("socket: %.100s", strerror(errno));
172
173	/* Bind it to the name. */
174	memset(&sunaddr, 0, sizeof(sunaddr));
175	sunaddr.sun_family = AF_UNIX;
176	strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
177
178	if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
179		packet_disconnect("bind: %.100s", strerror(errno));
180
181	/* Restore the privileged uid. */
182	restore_uid();
183
184	/* Start listening on the socket. */
185	if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
186		packet_disconnect("listen: %.100s", strerror(errno));
187
188	/* Allocate a channel for the authentication agent socket. */
189	nc = channel_new("auth socket",
190	    SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
191	    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
192	    0, "auth socket", 1);
193	strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
194	return 1;
195}
196
197static void
198display_loginmsg(void)
199{
200        if (buffer_len(&loginmsg) > 0) {
201                buffer_append(&loginmsg, "\0", 1);
202                printf("%s", (char *)buffer_ptr(&loginmsg));
203                buffer_clear(&loginmsg);
204        }
205}
206
207void
208do_authenticated(Authctxt *authctxt)
209{
210	setproctitle("%s", authctxt->pw->pw_name);
211
212	/*
213	 * Cancel the alarm we set to limit the time taken for
214	 * authentication.
215	 */
216	alarm(0);
217	if (startup_pipe != -1) {
218		close(startup_pipe);
219		startup_pipe = -1;
220	}
221	/* setup the channel layer */
222	if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
223		channel_permit_all_opens();
224
225	if (compat20)
226		do_authenticated2(authctxt);
227	else
228		do_authenticated1(authctxt);
229
230	do_cleanup(authctxt);
231}
232
233/*
234 * Prepares for an interactive session.  This is called after the user has
235 * been successfully authenticated.  During this message exchange, pseudo
236 * terminals are allocated, X11, TCP/IP, and authentication agent forwardings
237 * are requested, etc.
238 */
239static void
240do_authenticated1(Authctxt *authctxt)
241{
242	Session *s;
243	char *command;
244	int success, type, screen_flag;
245	int enable_compression_after_reply = 0;
246	u_int proto_len, data_len, dlen, compression_level = 0;
247
248	s = session_new();
249	if (s == NULL) {
250		error("no more sessions");
251		return;
252	}
253	s->authctxt = authctxt;
254	s->pw = authctxt->pw;
255
256	/*
257	 * We stay in this loop until the client requests to execute a shell
258	 * or a command.
259	 */
260	for (;;) {
261		success = 0;
262
263		/* Get a packet from the client. */
264		type = packet_read();
265
266		/* Process the packet. */
267		switch (type) {
268		case SSH_CMSG_REQUEST_COMPRESSION:
269			compression_level = packet_get_int();
270			packet_check_eom();
271			if (compression_level < 1 || compression_level > 9) {
272				packet_send_debug("Received invalid compression level %d.",
273				    compression_level);
274				break;
275			}
276			if (!options.compression) {
277				debug2("compression disabled");
278				break;
279			}
280			/* Enable compression after we have responded with SUCCESS. */
281			enable_compression_after_reply = 1;
282			success = 1;
283			break;
284
285		case SSH_CMSG_REQUEST_PTY:
286			success = session_pty_req(s);
287			break;
288
289		case SSH_CMSG_X11_REQUEST_FORWARDING:
290			s->auth_proto = packet_get_string(&proto_len);
291			s->auth_data = packet_get_string(&data_len);
292
293			screen_flag = packet_get_protocol_flags() &
294			    SSH_PROTOFLAG_SCREEN_NUMBER;
295			debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag);
296
297			if (packet_remaining() == 4) {
298				if (!screen_flag)
299					debug2("Buggy client: "
300					    "X11 screen flag missing");
301				s->screen = packet_get_int();
302			} else {
303				s->screen = 0;
304			}
305			packet_check_eom();
306			success = session_setup_x11fwd(s);
307			if (!success) {
308				xfree(s->auth_proto);
309				xfree(s->auth_data);
310				s->auth_proto = NULL;
311				s->auth_data = NULL;
312			}
313			break;
314
315		case SSH_CMSG_AGENT_REQUEST_FORWARDING:
316			if (no_agent_forwarding_flag || compat13) {
317				debug("Authentication agent forwarding not permitted for this authentication.");
318				break;
319			}
320			debug("Received authentication agent forwarding request.");
321			success = auth_input_request_forwarding(s->pw);
322			break;
323
324		case SSH_CMSG_PORT_FORWARD_REQUEST:
325			if (no_port_forwarding_flag) {
326				debug("Port forwarding not permitted for this authentication.");
327				break;
328			}
329			if (!options.allow_tcp_forwarding) {
330				debug("Port forwarding not permitted.");
331				break;
332			}
333			debug("Received TCP/IP port forwarding request.");
334			channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
335			success = 1;
336			break;
337
338		case SSH_CMSG_MAX_PACKET_SIZE:
339			if (packet_set_maxsize(packet_get_int()) > 0)
340				success = 1;
341			break;
342
343		case SSH_CMSG_EXEC_SHELL:
344		case SSH_CMSG_EXEC_CMD:
345			if (type == SSH_CMSG_EXEC_CMD) {
346				command = packet_get_string(&dlen);
347				debug("Exec command '%.500s'", command);
348				do_exec(s, command);
349				xfree(command);
350			} else {
351				do_exec(s, NULL);
352			}
353			packet_check_eom();
354			session_close(s);
355			return;
356
357		default:
358			/*
359			 * Any unknown messages in this phase are ignored,
360			 * and a failure message is returned.
361			 */
362			logit("Unknown packet type received after authentication: %d", type);
363		}
364		packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
365		packet_send();
366		packet_write_wait();
367
368		/* Enable compression now that we have replied if appropriate. */
369		if (enable_compression_after_reply) {
370			enable_compression_after_reply = 0;
371			packet_start_compression(compression_level);
372		}
373	}
374}
375
376/*
377 * This is called to fork and execute a command when we have no tty.  This
378 * will call do_child from the child, and server_loop from the parent after
379 * setting up file descriptors and such.
380 */
381void
382do_exec_no_pty(Session *s, const char *command)
383{
384	pid_t pid;
385
386#ifdef USE_PIPES
387	int pin[2], pout[2], perr[2];
388	/* Allocate pipes for communicating with the program. */
389	if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
390		packet_disconnect("Could not create pipes: %.100s",
391				  strerror(errno));
392#else /* USE_PIPES */
393	int inout[2], err[2];
394	/* Uses socket pairs to communicate with the program. */
395	if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
396	    socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
397		packet_disconnect("Could not create socket pairs: %.100s",
398				  strerror(errno));
399#endif /* USE_PIPES */
400	if (s == NULL)
401		fatal("do_exec_no_pty: no session");
402
403	session_proctitle(s);
404
405#if defined(USE_PAM)
406	if (options.use_pam && !use_privsep)
407		do_pam_setcred(1);
408#endif /* USE_PAM */
409
410	/* Fork the child. */
411	if ((pid = fork()) == 0) {
412		is_child = 1;
413
414		/* Child.  Reinitialize the log since the pid has changed. */
415		log_init(__progname, options.log_level, options.log_facility, log_stderr);
416
417		/*
418		 * Create a new session and process group since the 4.4BSD
419		 * setlogin() affects the entire process group.
420		 */
421		if (setsid() < 0)
422			error("setsid failed: %.100s", strerror(errno));
423
424#ifdef USE_PIPES
425		/*
426		 * Redirect stdin.  We close the parent side of the socket
427		 * pair, and make the child side the standard input.
428		 */
429		close(pin[1]);
430		if (dup2(pin[0], 0) < 0)
431			perror("dup2 stdin");
432		close(pin[0]);
433
434		/* Redirect stdout. */
435		close(pout[0]);
436		if (dup2(pout[1], 1) < 0)
437			perror("dup2 stdout");
438		close(pout[1]);
439
440		/* Redirect stderr. */
441		close(perr[0]);
442		if (dup2(perr[1], 2) < 0)
443			perror("dup2 stderr");
444		close(perr[1]);
445#else /* USE_PIPES */
446		/*
447		 * Redirect stdin, stdout, and stderr.  Stdin and stdout will
448		 * use the same socket, as some programs (particularly rdist)
449		 * seem to depend on it.
450		 */
451		close(inout[1]);
452		close(err[1]);
453		if (dup2(inout[0], 0) < 0)	/* stdin */
454			perror("dup2 stdin");
455		if (dup2(inout[0], 1) < 0)	/* stdout.  Note: same socket as stdin. */
456			perror("dup2 stdout");
457		if (dup2(err[0], 2) < 0)	/* stderr */
458			perror("dup2 stderr");
459#endif /* USE_PIPES */
460
461#ifdef _UNICOS
462		cray_init_job(s->pw); /* set up cray jid and tmpdir */
463#endif
464
465		/* Do processing for the child (exec command etc). */
466		do_child(s, command);
467		/* NOTREACHED */
468	}
469#ifdef _UNICOS
470	signal(WJSIGNAL, cray_job_termination_handler);
471#endif /* _UNICOS */
472#ifdef HAVE_CYGWIN
473	if (is_winnt)
474		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
475#endif
476	if (pid < 0)
477		packet_disconnect("fork failed: %.100s", strerror(errno));
478	s->pid = pid;
479	/* Set interactive/non-interactive mode. */
480	packet_set_interactive(s->display != NULL);
481#ifdef USE_PIPES
482	/* We are the parent.  Close the child sides of the pipes. */
483	close(pin[0]);
484	close(pout[1]);
485	close(perr[1]);
486
487	if (compat20) {
488		if (s->is_subsystem) {
489			close(perr[0]);
490			perr[0] = -1;
491		}
492		session_set_fds(s, pin[1], pout[0], perr[0]);
493	} else {
494		/* Enter the interactive session. */
495		server_loop(pid, pin[1], pout[0], perr[0]);
496		/* server_loop has closed pin[1], pout[0], and perr[0]. */
497	}
498#else /* USE_PIPES */
499	/* We are the parent.  Close the child sides of the socket pairs. */
500	close(inout[0]);
501	close(err[0]);
502
503	/*
504	 * Clear loginmsg, since it's the child's responsibility to display
505	 * it to the user, otherwise multiple sessions may accumulate
506	 * multiple copies of the login messages.
507	 */
508	buffer_clear(&loginmsg);
509
510	/*
511	 * Enter the interactive session.  Note: server_loop must be able to
512	 * handle the case that fdin and fdout are the same.
513	 */
514	if (compat20) {
515		session_set_fds(s, inout[1], inout[1], s->is_subsystem ? -1 : err[1]);
516	} else {
517		server_loop(pid, inout[1], inout[1], err[1]);
518		/* server_loop has closed inout[1] and err[1]. */
519	}
520#endif /* USE_PIPES */
521}
522
523/*
524 * This is called to fork and execute a command when we have a tty.  This
525 * will call do_child from the child, and server_loop from the parent after
526 * setting up file descriptors, controlling tty, updating wtmp, utmp,
527 * lastlog, and other such operations.
528 */
529void
530do_exec_pty(Session *s, const char *command)
531{
532	int fdout, ptyfd, ttyfd, ptymaster;
533	pid_t pid;
534
535	if (s == NULL)
536		fatal("do_exec_pty: no session");
537	ptyfd = s->ptyfd;
538	ttyfd = s->ttyfd;
539
540#if defined(USE_PAM)
541	if (options.use_pam) {
542		do_pam_set_tty(s->tty);
543		if (!use_privsep)
544			do_pam_setcred(1);
545	}
546#endif
547
548	/* Fork the child. */
549	if ((pid = fork()) == 0) {
550		is_child = 1;
551
552		/* Child.  Reinitialize the log because the pid has changed. */
553		log_init(__progname, options.log_level, options.log_facility, log_stderr);
554		/* Close the master side of the pseudo tty. */
555		close(ptyfd);
556
557		/* Make the pseudo tty our controlling tty. */
558		pty_make_controlling_tty(&ttyfd, s->tty);
559
560		/* Redirect stdin/stdout/stderr from the pseudo tty. */
561		if (dup2(ttyfd, 0) < 0)
562			error("dup2 stdin: %s", strerror(errno));
563		if (dup2(ttyfd, 1) < 0)
564			error("dup2 stdout: %s", strerror(errno));
565		if (dup2(ttyfd, 2) < 0)
566			error("dup2 stderr: %s", strerror(errno));
567
568		/* Close the extra descriptor for the pseudo tty. */
569		close(ttyfd);
570
571		/* record login, etc. similar to login(1) */
572#ifndef HAVE_OSF_SIA
573		if (!(options.use_login && command == NULL)) {
574#ifdef _UNICOS
575			cray_init_job(s->pw); /* set up cray jid and tmpdir */
576#endif /* _UNICOS */
577			do_login(s, command);
578		}
579# ifdef LOGIN_NEEDS_UTMPX
580		else
581			do_pre_login(s);
582# endif
583#endif
584
585		/* Do common processing for the child, such as execing the command. */
586		do_child(s, command);
587		/* NOTREACHED */
588	}
589#ifdef _UNICOS
590	signal(WJSIGNAL, cray_job_termination_handler);
591#endif /* _UNICOS */
592#ifdef HAVE_CYGWIN
593	if (is_winnt)
594		cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
595#endif
596	if (pid < 0)
597		packet_disconnect("fork failed: %.100s", strerror(errno));
598	s->pid = pid;
599
600	/* Parent.  Close the slave side of the pseudo tty. */
601	close(ttyfd);
602
603	/*
604	 * Create another descriptor of the pty master side for use as the
605	 * standard input.  We could use the original descriptor, but this
606	 * simplifies code in server_loop.  The descriptor is bidirectional.
607	 */
608	fdout = dup(ptyfd);
609	if (fdout < 0)
610		packet_disconnect("dup #1 failed: %.100s", strerror(errno));
611
612	/* we keep a reference to the pty master */
613	ptymaster = dup(ptyfd);
614	if (ptymaster < 0)
615		packet_disconnect("dup #2 failed: %.100s", strerror(errno));
616	s->ptymaster = ptymaster;
617
618	/* Enter interactive session. */
619	packet_set_interactive(1);
620	if (compat20) {
621		session_set_fds(s, ptyfd, fdout, -1);
622	} else {
623		server_loop(pid, ptyfd, fdout, -1);
624		/* server_loop _has_ closed ptyfd and fdout. */
625	}
626}
627
628#ifdef LOGIN_NEEDS_UTMPX
629static void
630do_pre_login(Session *s)
631{
632	socklen_t fromlen;
633	struct sockaddr_storage from;
634	pid_t pid = getpid();
635
636	/*
637	 * Get IP address of client. If the connection is not a socket, let
638	 * the address be 0.0.0.0.
639	 */
640	memset(&from, 0, sizeof(from));
641	fromlen = sizeof(from);
642	if (packet_connection_is_on_socket()) {
643		if (getpeername(packet_get_connection_in(),
644		    (struct sockaddr *) & from, &fromlen) < 0) {
645			debug("getpeername: %.100s", strerror(errno));
646			cleanup_exit(255);
647		}
648	}
649
650	record_utmp_only(pid, s->tty, s->pw->pw_name,
651	    get_remote_name_or_ip(utmp_len, options.use_dns),
652	    (struct sockaddr *)&from, fromlen);
653}
654#endif
655
656/*
657 * This is called to fork and execute a command.  If another command is
658 * to be forced, execute that instead.
659 */
660void
661do_exec(Session *s, const char *command)
662{
663	if (forced_command) {
664		original_command = command;
665		command = forced_command;
666		debug("Forced command '%.900s'", command);
667	}
668
669#ifdef SSH_AUDIT_EVENTS
670	if (command != NULL)
671		PRIVSEP(audit_run_command(command));
672	else if (s->ttyfd == -1) {
673		char *shell = s->pw->pw_shell;
674
675		if (shell[0] == '\0')	/* empty shell means /bin/sh */
676			shell =_PATH_BSHELL;
677		PRIVSEP(audit_run_command(shell));
678	}
679#endif
680
681	if (s->ttyfd != -1)
682		do_exec_pty(s, command);
683	else
684		do_exec_no_pty(s, command);
685
686	original_command = NULL;
687
688	/*
689	 * Clear loginmsg: it's the child's responsibility to display
690	 * it to the user, otherwise multiple sessions may accumulate
691	 * multiple copies of the login messages.
692	 */
693	buffer_clear(&loginmsg);
694}
695
696/* administrative, login(1)-like work */
697void
698do_login(Session *s, const char *command)
699{
700	socklen_t fromlen;
701	struct sockaddr_storage from;
702	struct passwd * pw = s->pw;
703	pid_t pid = getpid();
704
705	/*
706	 * Get IP address of client. If the connection is not a socket, let
707	 * the address be 0.0.0.0.
708	 */
709	memset(&from, 0, sizeof(from));
710	fromlen = sizeof(from);
711	if (packet_connection_is_on_socket()) {
712		if (getpeername(packet_get_connection_in(),
713		    (struct sockaddr *) & from, &fromlen) < 0) {
714			debug("getpeername: %.100s", strerror(errno));
715			cleanup_exit(255);
716		}
717	}
718
719	/* Record that there was a login on that tty from the remote host. */
720	if (!use_privsep)
721		record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
722		    get_remote_name_or_ip(utmp_len,
723		    options.use_dns),
724		    (struct sockaddr *)&from, fromlen);
725
726#ifdef USE_PAM
727	/*
728	 * If password change is needed, do it now.
729	 * This needs to occur before the ~/.hushlogin check.
730	 */
731	if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
732		display_loginmsg();
733		do_pam_chauthtok();
734		s->authctxt->force_pwchange = 0;
735		/* XXX - signal [net] parent to enable forwardings */
736	}
737#endif
738
739	if (check_quietlogin(s, command))
740		return;
741
742	display_loginmsg();
743
744	do_motd();
745}
746
747/*
748 * Display the message of the day.
749 */
750void
751do_motd(void)
752{
753	FILE *f;
754	char buf[256];
755#ifdef HAVE_LOGIN_CAP
756	const char *fname;
757#endif
758
759#ifdef HAVE_LOGIN_CAP
760	fname = login_getcapstr(lc, "copyright", NULL, NULL);
761	if (fname != NULL && (f = fopen(fname, "r")) != NULL) {
762		while (fgets(buf, sizeof(buf), f) != NULL)
763			fputs(buf, stdout);
764			fclose(f);
765	} else
766#endif /* HAVE_LOGIN_CAP */
767		(void)printf("%s\n\t%s %s\n",
768	"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
769	"The Regents of the University of California. ",
770	"All rights reserved.");
771
772	(void)printf("\n");
773
774	if (options.print_motd) {
775#ifdef HAVE_LOGIN_CAP
776		f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
777		    "/etc/motd"), "r");
778#else
779		f = fopen("/etc/motd", "r");
780#endif
781		if (f) {
782			while (fgets(buf, sizeof(buf), f))
783				fputs(buf, stdout);
784			fclose(f);
785		}
786	}
787}
788
789
790/*
791 * Check for quiet login, either .hushlogin or command given.
792 */
793int
794check_quietlogin(Session *s, const char *command)
795{
796	char buf[256];
797	struct passwd *pw = s->pw;
798	struct stat st;
799
800	/* Return 1 if .hushlogin exists or a command given. */
801	if (command != NULL)
802		return 1;
803	snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
804#ifdef HAVE_LOGIN_CAP
805	if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
806		return 1;
807#else
808	if (stat(buf, &st) >= 0)
809		return 1;
810#endif
811	return 0;
812}
813
814/*
815 * Sets the value of the given variable in the environment.  If the variable
816 * already exists, its value is overriden.
817 */
818void
819child_set_env(char ***envp, u_int *envsizep, const char *name,
820	const char *value)
821{
822	char **env;
823	u_int envsize;
824	u_int i, namelen;
825
826	/*
827	 * If we're passed an uninitialized list, allocate a single null
828	 * entry before continuing.
829	 */
830	if (*envp == NULL && *envsizep == 0) {
831		*envp = xmalloc(sizeof(char *));
832		*envp[0] = NULL;
833		*envsizep = 1;
834	}
835
836	/*
837	 * Find the slot where the value should be stored.  If the variable
838	 * already exists, we reuse the slot; otherwise we append a new slot
839	 * at the end of the array, expanding if necessary.
840	 */
841	env = *envp;
842	namelen = strlen(name);
843	for (i = 0; env[i]; i++)
844		if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
845			break;
846	if (env[i]) {
847		/* Reuse the slot. */
848		xfree(env[i]);
849	} else {
850		/* New variable.  Expand if necessary. */
851		envsize = *envsizep;
852		if (i >= envsize - 1) {
853			if (envsize >= 1000)
854				fatal("child_set_env: too many env vars");
855			envsize += 50;
856			env = (*envp) = xrealloc(env, envsize * sizeof(char *));
857			*envsizep = envsize;
858		}
859		/* Need to set the NULL pointer at end of array beyond the new slot. */
860		env[i + 1] = NULL;
861	}
862
863	/* Allocate space and format the variable in the appropriate slot. */
864	env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
865	snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
866}
867
868/*
869 * Reads environment variables from the given file and adds/overrides them
870 * into the environment.  If the file does not exist, this does nothing.
871 * Otherwise, it must consist of empty lines, comments (line starts with '#')
872 * and assignments of the form name=value.  No other forms are allowed.
873 */
874static void
875read_environment_file(char ***env, u_int *envsize,
876	const char *filename)
877{
878	FILE *f;
879	char buf[4096];
880	char *cp, *value;
881	u_int lineno = 0;
882
883	f = fopen(filename, "r");
884	if (!f)
885		return;
886
887	while (fgets(buf, sizeof(buf), f)) {
888		if (++lineno > 1000)
889			fatal("Too many lines in environment file %s", filename);
890		for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
891			;
892		if (!*cp || *cp == '#' || *cp == '\n')
893			continue;
894		if (strchr(cp, '\n'))
895			*strchr(cp, '\n') = '\0';
896		value = strchr(cp, '=');
897		if (value == NULL) {
898			fprintf(stderr, "Bad line %u in %.100s\n", lineno,
899			    filename);
900			continue;
901		}
902		/*
903		 * Replace the equals sign by nul, and advance value to
904		 * the value string.
905		 */
906		*value = '\0';
907		value++;
908		child_set_env(env, envsize, cp, value);
909	}
910	fclose(f);
911}
912
913#ifdef HAVE_ETC_DEFAULT_LOGIN
914/*
915 * Return named variable from specified environment, or NULL if not present.
916 */
917static char *
918child_get_env(char **env, const char *name)
919{
920	int i;
921	size_t len;
922
923	len = strlen(name);
924	for (i=0; env[i] != NULL; i++)
925		if (strncmp(name, env[i], len) == 0 && env[i][len] == '=')
926			return(env[i] + len + 1);
927	return NULL;
928}
929
930/*
931 * Read /etc/default/login.
932 * We pick up the PATH (or SUPATH for root) and UMASK.
933 */
934static void
935read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
936{
937	char **tmpenv = NULL, *var;
938	u_int i, tmpenvsize = 0;
939	u_long mask;
940
941	/*
942	 * We don't want to copy the whole file to the child's environment,
943	 * so we use a temporary environment and copy the variables we're
944	 * interested in.
945	 */
946	read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login");
947
948	if (tmpenv == NULL)
949		return;
950
951	if (uid == 0)
952		var = child_get_env(tmpenv, "SUPATH");
953	else
954		var = child_get_env(tmpenv, "PATH");
955	if (var != NULL)
956		child_set_env(env, envsize, "PATH", var);
957
958	if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
959		if (sscanf(var, "%5lo", &mask) == 1)
960			umask((mode_t)mask);
961
962	for (i = 0; tmpenv[i] != NULL; i++)
963		xfree(tmpenv[i]);
964	xfree(tmpenv);
965}
966#endif /* HAVE_ETC_DEFAULT_LOGIN */
967
968void copy_environment(char **source, char ***env, u_int *envsize)
969{
970	char *var_name, *var_val;
971	int i;
972
973	if (source == NULL)
974		return;
975
976	for(i = 0; source[i] != NULL; i++) {
977		var_name = xstrdup(source[i]);
978		if ((var_val = strstr(var_name, "=")) == NULL) {
979			xfree(var_name);
980			continue;
981		}
982		*var_val++ = '\0';
983
984		debug3("Copy environment: %s=%s", var_name, var_val);
985		child_set_env(env, envsize, var_name, var_val);
986
987		xfree(var_name);
988	}
989}
990
991static char **
992do_setup_env(Session *s, const char *shell)
993{
994	char buf[256];
995	u_int i, envsize;
996	char **env, *laddr, *path = NULL;
997#ifdef HAVE_LOGIN_CAP
998	extern char **environ;
999	char **senv, **var;
1000#endif
1001	struct passwd *pw = s->pw;
1002
1003	/* Initialize the environment. */
1004	envsize = 100;
1005	env = xmalloc(envsize * sizeof(char *));
1006	env[0] = NULL;
1007
1008#ifdef HAVE_CYGWIN
1009	/*
1010	 * The Windows environment contains some setting which are
1011	 * important for a running system. They must not be dropped.
1012	 */
1013	{
1014		char **p;
1015
1016		p = fetch_windows_environment();
1017		copy_environment(p, &env, &envsize);
1018		free_windows_environment(p);
1019	}
1020#endif
1021
1022	if (getenv("TZ"))
1023		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
1024
1025#ifdef GSSAPI
1026	/* Allow any GSSAPI methods that we've used to alter
1027	 * the childs environment as they see fit
1028	 */
1029	ssh_gssapi_do_child(&env, &envsize);
1030#endif
1031
1032	if (!options.use_login) {
1033		/* Set basic environment. */
1034		for (i = 0; i < s->num_env; i++)
1035			child_set_env(&env, &envsize, s->env[i].name,
1036			    s->env[i].val);
1037
1038		child_set_env(&env, &envsize, "USER", pw->pw_name);
1039		child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
1040#ifdef _AIX
1041		child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
1042#endif
1043		child_set_env(&env, &envsize, "HOME", pw->pw_dir);
1044		snprintf(buf, sizeof buf, "%.200s/%.50s",
1045			 _PATH_MAILDIR, pw->pw_name);
1046		child_set_env(&env, &envsize, "MAIL", buf);
1047#ifdef HAVE_LOGIN_CAP
1048		child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
1049		child_set_env(&env, &envsize, "TERM", "su");
1050		senv = environ;
1051		environ = xmalloc(sizeof(char *));
1052		*environ = NULL;
1053		(void) setusercontext(lc, pw, pw->pw_uid,
1054		    LOGIN_SETENV|LOGIN_SETPATH);
1055		copy_environment(environ, &env, &envsize);
1056		for (var = environ; *var != NULL; ++var)
1057			xfree(*var);
1058		xfree(environ);
1059		environ = senv;
1060#else /* HAVE_LOGIN_CAP */
1061# ifndef HAVE_CYGWIN
1062		/*
1063		 * There's no standard path on Windows. The path contains
1064		 * important components pointing to the system directories,
1065		 * needed for loading shared libraries. So the path better
1066		 * remains intact here.
1067		 */
1068#  ifdef HAVE_ETC_DEFAULT_LOGIN
1069		read_etc_default_login(&env, &envsize, pw->pw_uid);
1070		path = child_get_env(env, "PATH");
1071#  endif /* HAVE_ETC_DEFAULT_LOGIN */
1072		if (path == NULL || *path == '\0') {
1073			child_set_env(&env, &envsize, "PATH",
1074			    s->pw->pw_uid == 0 ?
1075				SUPERUSER_PATH : _PATH_STDPATH);
1076		}
1077# endif /* HAVE_CYGWIN */
1078#endif /* HAVE_LOGIN_CAP */
1079
1080		/* Normal systems set SHELL by default. */
1081		child_set_env(&env, &envsize, "SHELL", shell);
1082	}
1083
1084	/* Set custom environment options from RSA authentication. */
1085	if (!options.use_login) {
1086		while (custom_environment) {
1087			struct envstring *ce = custom_environment;
1088			char *str = ce->s;
1089
1090			for (i = 0; str[i] != '=' && str[i]; i++)
1091				;
1092			if (str[i] == '=') {
1093				str[i] = 0;
1094				child_set_env(&env, &envsize, str, str + i + 1);
1095			}
1096			custom_environment = ce->next;
1097			xfree(ce->s);
1098			xfree(ce);
1099		}
1100	}
1101
1102	/* SSH_CLIENT deprecated */
1103	snprintf(buf, sizeof buf, "%.50s %d %d",
1104	    get_remote_ipaddr(), get_remote_port(), get_local_port());
1105	child_set_env(&env, &envsize, "SSH_CLIENT", buf);
1106
1107	laddr = get_local_ipaddr(packet_get_connection_in());
1108	snprintf(buf, sizeof buf, "%.50s %d %.50s %d",
1109	    get_remote_ipaddr(), get_remote_port(), laddr, get_local_port());
1110	xfree(laddr);
1111	child_set_env(&env, &envsize, "SSH_CONNECTION", buf);
1112
1113	if (s->ttyfd != -1)
1114		child_set_env(&env, &envsize, "SSH_TTY", s->tty);
1115	if (s->term)
1116		child_set_env(&env, &envsize, "TERM", s->term);
1117	if (s->display)
1118		child_set_env(&env, &envsize, "DISPLAY", s->display);
1119	if (original_command)
1120		child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
1121		    original_command);
1122
1123#ifdef _UNICOS
1124	if (cray_tmpdir[0] != '\0')
1125		child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
1126#endif /* _UNICOS */
1127
1128	/*
1129	 * Since we clear KRB5CCNAME at startup, if it's set now then it
1130	 * must have been set by a native authentication method (eg AIX or
1131	 * SIA), so copy it to the child.
1132	 */
1133	{
1134		char *cp;
1135
1136		if ((cp = getenv("KRB5CCNAME")) != NULL)
1137			child_set_env(&env, &envsize, "KRB5CCNAME", cp);
1138	}
1139
1140#ifdef _AIX
1141	{
1142		char *cp;
1143
1144		if ((cp = getenv("AUTHSTATE")) != NULL)
1145			child_set_env(&env, &envsize, "AUTHSTATE", cp);
1146		read_environment_file(&env, &envsize, "/etc/environment");
1147	}
1148#endif
1149#ifdef KRB5
1150	if (s->authctxt->krb5_ccname)
1151		child_set_env(&env, &envsize, "KRB5CCNAME",
1152		    s->authctxt->krb5_ccname);
1153#endif
1154#ifdef USE_PAM
1155	/*
1156	 * Pull in any environment variables that may have
1157	 * been set by PAM.
1158	 */
1159	if (options.use_pam) {
1160		char **p;
1161
1162		p = fetch_pam_child_environment();
1163		copy_environment(p, &env, &envsize);
1164		free_pam_environment(p);
1165
1166		p = fetch_pam_environment();
1167		copy_environment(p, &env, &envsize);
1168		free_pam_environment(p);
1169	}
1170#endif /* USE_PAM */
1171
1172	if (auth_sock_name != NULL)
1173		child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
1174		    auth_sock_name);
1175
1176	/* read $HOME/.ssh/environment. */
1177	if (options.permit_user_env && !options.use_login) {
1178		snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
1179		    strcmp(pw->pw_dir, "/") ? pw->pw_dir : "");
1180		read_environment_file(&env, &envsize, buf);
1181	}
1182	if (debug_flag) {
1183		/* dump the environment */
1184		fprintf(stderr, "Environment:\n");
1185		for (i = 0; env[i]; i++)
1186			fprintf(stderr, "  %.200s\n", env[i]);
1187	}
1188	return env;
1189}
1190
1191/*
1192 * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found
1193 * first in this order).
1194 */
1195static void
1196do_rc_files(Session *s, const char *shell)
1197{
1198	FILE *f = NULL;
1199	char cmd[1024];
1200	int do_xauth;
1201	struct stat st;
1202
1203	do_xauth =
1204	    s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL;
1205
1206	/* ignore _PATH_SSH_USER_RC for subsystems */
1207	if (!s->is_subsystem && (stat(_PATH_SSH_USER_RC, &st) >= 0)) {
1208		snprintf(cmd, sizeof cmd, "%s -c '%s %s'",
1209		    shell, _PATH_BSHELL, _PATH_SSH_USER_RC);
1210		if (debug_flag)
1211			fprintf(stderr, "Running %s\n", cmd);
1212		f = popen(cmd, "w");
1213		if (f) {
1214			if (do_xauth)
1215				fprintf(f, "%s %s\n", s->auth_proto,
1216				    s->auth_data);
1217			pclose(f);
1218		} else
1219			fprintf(stderr, "Could not run %s\n",
1220			    _PATH_SSH_USER_RC);
1221	} else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) {
1222		if (debug_flag)
1223			fprintf(stderr, "Running %s %s\n", _PATH_BSHELL,
1224			    _PATH_SSH_SYSTEM_RC);
1225		f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w");
1226		if (f) {
1227			if (do_xauth)
1228				fprintf(f, "%s %s\n", s->auth_proto,
1229				    s->auth_data);
1230			pclose(f);
1231		} else
1232			fprintf(stderr, "Could not run %s\n",
1233			    _PATH_SSH_SYSTEM_RC);
1234	} else if (do_xauth && options.xauth_location != NULL) {
1235		/* Add authority data to .Xauthority if appropriate. */
1236		if (debug_flag) {
1237			fprintf(stderr,
1238			    "Running %.500s remove %.100s\n",
1239			    options.xauth_location, s->auth_display);
1240			fprintf(stderr,
1241			    "%.500s add %.100s %.100s %.100s\n",
1242			    options.xauth_location, s->auth_display,
1243			    s->auth_proto, s->auth_data);
1244		}
1245		snprintf(cmd, sizeof cmd, "%s -q -",
1246		    options.xauth_location);
1247		f = popen(cmd, "w");
1248		if (f) {
1249			fprintf(f, "remove %s\n",
1250			    s->auth_display);
1251			fprintf(f, "add %s %s %s\n",
1252			    s->auth_display, s->auth_proto,
1253			    s->auth_data);
1254			pclose(f);
1255		} else {
1256			fprintf(stderr, "Could not run %s\n",
1257			    cmd);
1258		}
1259	}
1260}
1261
1262static void
1263do_nologin(struct passwd *pw)
1264{
1265	FILE *f = NULL;
1266	char buf[1024];
1267
1268#ifdef HAVE_LOGIN_CAP
1269	if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
1270		f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
1271		    _PATH_NOLOGIN), "r");
1272#else
1273	if (pw->pw_uid)
1274		f = fopen(_PATH_NOLOGIN, "r");
1275#endif
1276	if (f) {
1277		/* /etc/nologin exists.  Print its contents and exit. */
1278		logit("User %.100s not allowed because %s exists",
1279		    pw->pw_name, _PATH_NOLOGIN);
1280		while (fgets(buf, sizeof(buf), f))
1281			fputs(buf, stderr);
1282		fclose(f);
1283		fflush(NULL);
1284		exit(254);
1285	}
1286}
1287
1288/* Set login name, uid, gid, and groups. */
1289void
1290do_setusercontext(struct passwd *pw)
1291{
1292#ifndef HAVE_CYGWIN
1293	if (getuid() == 0 || geteuid() == 0)
1294#endif /* HAVE_CYGWIN */
1295	{
1296
1297#ifdef HAVE_SETPCRED
1298		if (setpcred(pw->pw_name, (char **)NULL) == -1)
1299			fatal("Failed to set process credentials");
1300#endif /* HAVE_SETPCRED */
1301#ifdef HAVE_LOGIN_CAP
1302# ifdef __bsdi__
1303		setpgid(0, 0);
1304# endif
1305#ifdef GSSAPI
1306		if (options.gss_authentication) {
1307			temporarily_use_uid(pw);
1308			ssh_gssapi_storecreds();
1309			restore_uid();
1310		}
1311#endif
1312# ifdef USE_PAM
1313		if (options.use_pam) {
1314			do_pam_session();
1315			do_pam_setcred(0);
1316		}
1317# endif /* USE_PAM */
1318		if (setusercontext(lc, pw, pw->pw_uid,
1319		    (LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH))) < 0) {
1320			perror("unable to set user context");
1321			exit(1);
1322		}
1323#else
1324# if defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
1325		/* Sets login uid for accounting */
1326		if (getluid() == -1 && setluid(pw->pw_uid) == -1)
1327			error("setluid: %s", strerror(errno));
1328# endif /* defined(HAVE_GETLUID) && defined(HAVE_SETLUID) */
1329
1330		if (setlogin(pw->pw_name) < 0)
1331			error("setlogin failed: %s", strerror(errno));
1332		if (setgid(pw->pw_gid) < 0) {
1333			perror("setgid");
1334			exit(1);
1335		}
1336		/* Initialize the group list. */
1337		if (initgroups(pw->pw_name, pw->pw_gid) < 0) {
1338			perror("initgroups");
1339			exit(1);
1340		}
1341		endgrent();
1342#ifdef GSSAPI
1343		if (options.gss_authentication) {
1344			temporarily_use_uid(pw);
1345			ssh_gssapi_storecreds();
1346			restore_uid();
1347		}
1348#endif
1349# ifdef USE_PAM
1350		/*
1351		 * PAM credentials may take the form of supplementary groups.
1352		 * These will have been wiped by the above initgroups() call.
1353		 * Reestablish them here.
1354		 */
1355		if (options.use_pam) {
1356			do_pam_session();
1357			do_pam_setcred(0);
1358		}
1359# endif /* USE_PAM */
1360# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1361		irix_setusercontext(pw);
1362#  endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1363# ifdef _AIX
1364		aix_usrinfo(pw);
1365# endif /* _AIX */
1366		/* Permanently switch to the desired uid. */
1367		permanently_set_uid(pw);
1368#endif
1369	}
1370
1371#ifdef HAVE_CYGWIN
1372	if (is_winnt)
1373#endif
1374	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
1375		fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
1376}
1377
1378static void
1379do_pwchange(Session *s)
1380{
1381	fflush(NULL);
1382	fprintf(stderr, "WARNING: Your password has expired.\n");
1383	if (s->ttyfd != -1) {
1384		fprintf(stderr,
1385		    "You must change your password now and login again!\n");
1386#ifdef PASSWD_NEEDS_USERNAME
1387		execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
1388		    (char *)NULL);
1389#else
1390		execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
1391#endif
1392		perror("passwd");
1393	} else {
1394		fprintf(stderr,
1395		    "Password change required but no TTY available.\n");
1396	}
1397	exit(1);
1398}
1399
1400static void
1401launch_login(struct passwd *pw, const char *hostname)
1402{
1403	/* Launch login(1). */
1404
1405	execl(LOGIN_PROGRAM, "login", "-h", hostname,
1406#ifdef xxxLOGIN_NEEDS_TERM
1407		    (s->term ? s->term : "unknown"),
1408#endif /* LOGIN_NEEDS_TERM */
1409#ifdef LOGIN_NO_ENDOPT
1410	    "-p", "-f", pw->pw_name, (char *)NULL);
1411#else
1412	    "-p", "-f", "--", pw->pw_name, (char *)NULL);
1413#endif
1414
1415	/* Login couldn't be executed, die. */
1416
1417	perror("login");
1418	exit(1);
1419}
1420
1421static void
1422child_close_fds(void)
1423{
1424	int i;
1425
1426	if (packet_get_connection_in() == packet_get_connection_out())
1427		close(packet_get_connection_in());
1428	else {
1429		close(packet_get_connection_in());
1430		close(packet_get_connection_out());
1431	}
1432	/*
1433	 * Close all descriptors related to channels.  They will still remain
1434	 * open in the parent.
1435	 */
1436	/* XXX better use close-on-exec? -markus */
1437	channel_close_all();
1438
1439	/*
1440	 * Close any extra file descriptors.  Note that there may still be
1441	 * descriptors left by system functions.  They will be closed later.
1442	 */
1443	endpwent();
1444
1445	/*
1446	 * Close any extra open file descriptors so that we don\'t have them
1447	 * hanging around in clients.  Note that we want to do this after
1448	 * initgroups, because at least on Solaris 2.3 it leaves file
1449	 * descriptors open.
1450	 */
1451	for (i = 3; i < 64; i++)
1452		close(i);
1453}
1454
1455/*
1456 * Performs common processing for the child, such as setting up the
1457 * environment, closing extra file descriptors, setting the user and group
1458 * ids, and executing the command or shell.
1459 */
1460void
1461do_child(Session *s, const char *command)
1462{
1463	extern char **environ;
1464	char **env;
1465	char *argv[10];
1466	const char *shell, *shell0, *hostname = NULL;
1467	struct passwd *pw = s->pw;
1468#ifdef HAVE_LOGIN_CAP
1469	int lc_requirehome;
1470#endif
1471
1472	/* remove hostkey from the child's memory */
1473	destroy_sensitive_data();
1474
1475	/* Force a password change */
1476	if (s->authctxt->force_pwchange) {
1477		do_setusercontext(pw);
1478		child_close_fds();
1479		do_pwchange(s);
1480		exit(1);
1481	}
1482
1483	/* login(1) is only called if we execute the login shell */
1484	if (options.use_login && command != NULL)
1485		options.use_login = 0;
1486
1487#ifdef _UNICOS
1488	cray_setup(pw->pw_uid, pw->pw_name, command);
1489#endif /* _UNICOS */
1490
1491	/*
1492	 * Login(1) does this as well, and it needs uid 0 for the "-h"
1493	 * switch, so we let login(1) to this for us.
1494	 */
1495	if (!options.use_login) {
1496#ifdef HAVE_OSF_SIA
1497		session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty);
1498		if (!check_quietlogin(s, command))
1499			do_motd();
1500#else /* HAVE_OSF_SIA */
1501		do_nologin(pw);
1502		do_setusercontext(pw);
1503		/*
1504		 * PAM session modules in do_setusercontext may have
1505		 * generated messages, so if this in an interactive
1506		 * login then display them too.
1507		 */
1508		if (!check_quietlogin(s, command))
1509			display_loginmsg();
1510#endif /* HAVE_OSF_SIA */
1511	}
1512
1513#ifdef USE_PAM
1514	if (options.use_pam && !options.use_login && !is_pam_session_open()) {
1515		debug3("PAM session not opened, exiting");
1516		display_loginmsg();
1517		exit(254);
1518	}
1519#endif
1520
1521	/*
1522	 * Get the shell from the password data.  An empty shell field is
1523	 * legal, and means /bin/sh.
1524	 */
1525	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
1526
1527	/*
1528	 * Make sure $SHELL points to the shell from the password file,
1529	 * even if shell is overridden from login.conf
1530	 */
1531	env = do_setup_env(s, shell);
1532
1533#ifdef HAVE_LOGIN_CAP
1534	shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
1535#endif
1536
1537	/* we have to stash the hostname before we close our socket. */
1538	if (options.use_login)
1539		hostname = get_remote_name_or_ip(utmp_len,
1540		    options.use_dns);
1541	/*
1542	 * Close the connection descriptors; note that this is the child, and
1543	 * the server will still have the socket open, and it is important
1544	 * that we do not shutdown it.  Note that the descriptors cannot be
1545	 * closed before building the environment, as we call
1546	 * get_remote_ipaddr there.
1547	 */
1548	child_close_fds();
1549
1550	/*
1551	 * Must take new environment into use so that .ssh/rc,
1552	 * /etc/ssh/sshrc and xauth are run in the proper environment.
1553	 */
1554	environ = env;
1555
1556#ifdef HAVE_LOGIN_CAP
1557	lc_requirehome = login_getcapbool(lc, "requirehome", 0);
1558	login_close(lc);
1559#endif
1560#if defined(KRB5) && defined(USE_AFS)
1561	/*
1562	 * At this point, we check to see if AFS is active and if we have
1563	 * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
1564	 * if we can (and need to) extend the ticket into an AFS token. If
1565	 * we don't do this, we run into potential problems if the user's
1566	 * home directory is in AFS and it's not world-readable.
1567	 */
1568
1569	if (options.kerberos_get_afs_token && k_hasafs() &&
1570	     (s->authctxt->krb5_ctx != NULL)) {
1571		char cell[64];
1572
1573		debug("Getting AFS token");
1574
1575		k_setpag();
1576
1577		if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
1578			krb5_afslog(s->authctxt->krb5_ctx,
1579			    s->authctxt->krb5_fwd_ccache, cell, NULL);
1580
1581		krb5_afslog_home(s->authctxt->krb5_ctx,
1582		    s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
1583	}
1584#endif
1585
1586	/* Change current directory to the user\'s home directory. */
1587	if (chdir(pw->pw_dir) < 0) {
1588		fprintf(stderr, "Could not chdir to home directory %s: %s\n",
1589		    pw->pw_dir, strerror(errno));
1590#ifdef HAVE_LOGIN_CAP
1591		if (lc_requirehome)
1592			exit(1);
1593#endif
1594	}
1595
1596	if (!options.use_login)
1597		do_rc_files(s, shell);
1598
1599	/* restore SIGPIPE for child */
1600	signal(SIGPIPE,  SIG_DFL);
1601
1602	if (options.use_login) {
1603		launch_login(pw, hostname);
1604		/* NEVERREACHED */
1605	}
1606
1607	/* Get the last component of the shell name. */
1608	if ((shell0 = strrchr(shell, '/')) != NULL)
1609		shell0++;
1610	else
1611		shell0 = shell;
1612
1613	/*
1614	 * If we have no command, execute the shell.  In this case, the shell
1615	 * name to be passed in argv[0] is preceded by '-' to indicate that
1616	 * this is a login shell.
1617	 */
1618	if (!command) {
1619		char argv0[256];
1620
1621		/* Start the shell.  Set initial character to '-'. */
1622		argv0[0] = '-';
1623
1624		if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1)
1625		    >= sizeof(argv0) - 1) {
1626			errno = EINVAL;
1627			perror(shell);
1628			exit(1);
1629		}
1630
1631		/* Execute the shell. */
1632		argv[0] = argv0;
1633		argv[1] = NULL;
1634		execve(shell, argv, env);
1635
1636		/* Executing the shell failed. */
1637		perror(shell);
1638		exit(1);
1639	}
1640	/*
1641	 * Execute the command using the user's shell.  This uses the -c
1642	 * option to execute the command.
1643	 */
1644	argv[0] = (char *) shell0;
1645	argv[1] = "-c";
1646	argv[2] = (char *) command;
1647	argv[3] = NULL;
1648	execve(shell, argv, env);
1649	perror(shell);
1650	exit(1);
1651}
1652
1653Session *
1654session_new(void)
1655{
1656	int i;
1657	static int did_init = 0;
1658	if (!did_init) {
1659		debug("session_new: init");
1660		for (i = 0; i < MAX_SESSIONS; i++) {
1661			sessions[i].used = 0;
1662		}
1663		did_init = 1;
1664	}
1665	for (i = 0; i < MAX_SESSIONS; i++) {
1666		Session *s = &sessions[i];
1667		if (! s->used) {
1668			memset(s, 0, sizeof(*s));
1669			s->chanid = -1;
1670			s->ptyfd = -1;
1671			s->ttyfd = -1;
1672			s->used = 1;
1673			s->self = i;
1674			debug("session_new: session %d", i);
1675			return s;
1676		}
1677	}
1678	return NULL;
1679}
1680
1681static void
1682session_dump(void)
1683{
1684	int i;
1685	for (i = 0; i < MAX_SESSIONS; i++) {
1686		Session *s = &sessions[i];
1687		debug("dump: used %d session %d %p channel %d pid %ld",
1688		    s->used,
1689		    s->self,
1690		    s,
1691		    s->chanid,
1692		    (long)s->pid);
1693	}
1694}
1695
1696int
1697session_open(Authctxt *authctxt, int chanid)
1698{
1699	Session *s = session_new();
1700	debug("session_open: channel %d", chanid);
1701	if (s == NULL) {
1702		error("no more sessions");
1703		return 0;
1704	}
1705	s->authctxt = authctxt;
1706	s->pw = authctxt->pw;
1707	if (s->pw == NULL || !authctxt->valid)
1708		fatal("no user for session %d", s->self);
1709	debug("session_open: session %d: link with channel %d", s->self, chanid);
1710	s->chanid = chanid;
1711	return 1;
1712}
1713
1714Session *
1715session_by_tty(char *tty)
1716{
1717	int i;
1718	for (i = 0; i < MAX_SESSIONS; i++) {
1719		Session *s = &sessions[i];
1720		if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
1721			debug("session_by_tty: session %d tty %s", i, tty);
1722			return s;
1723		}
1724	}
1725	debug("session_by_tty: unknown tty %.100s", tty);
1726	session_dump();
1727	return NULL;
1728}
1729
1730static Session *
1731session_by_channel(int id)
1732{
1733	int i;
1734	for (i = 0; i < MAX_SESSIONS; i++) {
1735		Session *s = &sessions[i];
1736		if (s->used && s->chanid == id) {
1737			debug("session_by_channel: session %d channel %d", i, id);
1738			return s;
1739		}
1740	}
1741	debug("session_by_channel: unknown channel %d", id);
1742	session_dump();
1743	return NULL;
1744}
1745
1746static Session *
1747session_by_pid(pid_t pid)
1748{
1749	int i;
1750	debug("session_by_pid: pid %ld", (long)pid);
1751	for (i = 0; i < MAX_SESSIONS; i++) {
1752		Session *s = &sessions[i];
1753		if (s->used && s->pid == pid)
1754			return s;
1755	}
1756	error("session_by_pid: unknown pid %ld", (long)pid);
1757	session_dump();
1758	return NULL;
1759}
1760
1761static int
1762session_window_change_req(Session *s)
1763{
1764	s->col = packet_get_int();
1765	s->row = packet_get_int();
1766	s->xpixel = packet_get_int();
1767	s->ypixel = packet_get_int();
1768	packet_check_eom();
1769	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1770	return 1;
1771}
1772
1773static int
1774session_pty_req(Session *s)
1775{
1776	u_int len;
1777	int n_bytes;
1778
1779	if (no_pty_flag) {
1780		debug("Allocating a pty not permitted for this authentication.");
1781		return 0;
1782	}
1783	if (s->ttyfd != -1) {
1784		packet_disconnect("Protocol error: you already have a pty.");
1785		return 0;
1786	}
1787
1788	s->term = packet_get_string(&len);
1789
1790	if (compat20) {
1791		s->col = packet_get_int();
1792		s->row = packet_get_int();
1793	} else {
1794		s->row = packet_get_int();
1795		s->col = packet_get_int();
1796	}
1797	s->xpixel = packet_get_int();
1798	s->ypixel = packet_get_int();
1799
1800	if (strcmp(s->term, "") == 0) {
1801		xfree(s->term);
1802		s->term = NULL;
1803	}
1804
1805	/* Allocate a pty and open it. */
1806	debug("Allocating pty.");
1807	if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
1808		if (s->term)
1809			xfree(s->term);
1810		s->term = NULL;
1811		s->ptyfd = -1;
1812		s->ttyfd = -1;
1813		error("session_pty_req: session %d alloc failed", s->self);
1814		return 0;
1815	}
1816	debug("session_pty_req: session %d alloc %s", s->self, s->tty);
1817
1818	/* for SSH1 the tty modes length is not given */
1819	if (!compat20)
1820		n_bytes = packet_remaining();
1821	tty_parse_modes(s->ttyfd, &n_bytes);
1822
1823	if (!use_privsep)
1824		pty_setowner(s->pw, s->tty);
1825
1826	/* Set window size from the packet. */
1827	pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
1828
1829	packet_check_eom();
1830	session_proctitle(s);
1831	return 1;
1832}
1833
1834static int
1835session_subsystem_req(Session *s)
1836{
1837	struct stat st;
1838	u_int len;
1839	int success = 0;
1840	char *cmd, *subsys = packet_get_string(&len);
1841	int i;
1842
1843	packet_check_eom();
1844	logit("subsystem request for %.100s", subsys);
1845
1846	for (i = 0; i < options.num_subsystems; i++) {
1847		if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1848			cmd = options.subsystem_command[i];
1849			if (stat(cmd, &st) < 0) {
1850				error("subsystem: cannot stat %s: %s", cmd,
1851				    strerror(errno));
1852				break;
1853			}
1854			debug("subsystem: exec() %s", cmd);
1855			s->is_subsystem = 1;
1856			do_exec(s, cmd);
1857			success = 1;
1858			break;
1859		}
1860	}
1861
1862	if (!success)
1863		logit("subsystem request for %.100s failed, subsystem not found",
1864		    subsys);
1865
1866	xfree(subsys);
1867	return success;
1868}
1869
1870static int
1871session_x11_req(Session *s)
1872{
1873	int success;
1874
1875	s->single_connection = packet_get_char();
1876	s->auth_proto = packet_get_string(NULL);
1877	s->auth_data = packet_get_string(NULL);
1878	s->screen = packet_get_int();
1879	packet_check_eom();
1880
1881	success = session_setup_x11fwd(s);
1882	if (!success) {
1883		xfree(s->auth_proto);
1884		xfree(s->auth_data);
1885		s->auth_proto = NULL;
1886		s->auth_data = NULL;
1887	}
1888	return success;
1889}
1890
1891static int
1892session_shell_req(Session *s)
1893{
1894	packet_check_eom();
1895	do_exec(s, NULL);
1896	return 1;
1897}
1898
1899static int
1900session_exec_req(Session *s)
1901{
1902	u_int len;
1903	char *command = packet_get_string(&len);
1904	packet_check_eom();
1905	do_exec(s, command);
1906	xfree(command);
1907	return 1;
1908}
1909
1910static int
1911session_break_req(Session *s)
1912{
1913
1914	packet_get_int();	/* ignored */
1915	packet_check_eom();
1916
1917	if (s->ttyfd == -1 ||
1918	    tcsendbreak(s->ttyfd, 0) < 0)
1919		return 0;
1920	return 1;
1921}
1922
1923static int
1924session_env_req(Session *s)
1925{
1926	char *name, *val;
1927	u_int name_len, val_len, i;
1928
1929	name = packet_get_string(&name_len);
1930	val = packet_get_string(&val_len);
1931	packet_check_eom();
1932
1933	/* Don't set too many environment variables */
1934	if (s->num_env > 128) {
1935		debug2("Ignoring env request %s: too many env vars", name);
1936		goto fail;
1937	}
1938
1939	for (i = 0; i < options.num_accept_env; i++) {
1940		if (match_pattern(name, options.accept_env[i])) {
1941			debug2("Setting env %d: %s=%s", s->num_env, name, val);
1942			s->env = xrealloc(s->env, sizeof(*s->env) *
1943			    (s->num_env + 1));
1944			s->env[s->num_env].name = name;
1945			s->env[s->num_env].val = val;
1946			s->num_env++;
1947			return (1);
1948		}
1949	}
1950	debug2("Ignoring env request %s: disallowed name", name);
1951
1952 fail:
1953	xfree(name);
1954	xfree(val);
1955	return (0);
1956}
1957
1958static int
1959session_auth_agent_req(Session *s)
1960{
1961	static int called = 0;
1962	packet_check_eom();
1963	if (no_agent_forwarding_flag) {
1964		debug("session_auth_agent_req: no_agent_forwarding_flag");
1965		return 0;
1966	}
1967	if (called) {
1968		return 0;
1969	} else {
1970		called = 1;
1971		return auth_input_request_forwarding(s->pw);
1972	}
1973}
1974
1975int
1976session_input_channel_req(Channel *c, const char *rtype)
1977{
1978	int success = 0;
1979	Session *s;
1980
1981	if ((s = session_by_channel(c->self)) == NULL) {
1982		logit("session_input_channel_req: no session %d req %.100s",
1983		    c->self, rtype);
1984		return 0;
1985	}
1986	debug("session_input_channel_req: session %d req %s", s->self, rtype);
1987
1988	/*
1989	 * a session is in LARVAL state until a shell, a command
1990	 * or a subsystem is executed
1991	 */
1992	if (c->type == SSH_CHANNEL_LARVAL) {
1993		if (strcmp(rtype, "shell") == 0) {
1994			success = session_shell_req(s);
1995		} else if (strcmp(rtype, "exec") == 0) {
1996			success = session_exec_req(s);
1997		} else if (strcmp(rtype, "pty-req") == 0) {
1998			success =  session_pty_req(s);
1999		} else if (strcmp(rtype, "x11-req") == 0) {
2000			success = session_x11_req(s);
2001		} else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) {
2002			success = session_auth_agent_req(s);
2003		} else if (strcmp(rtype, "subsystem") == 0) {
2004			success = session_subsystem_req(s);
2005		} else if (strcmp(rtype, "env") == 0) {
2006			success = session_env_req(s);
2007		}
2008	}
2009	if (strcmp(rtype, "window-change") == 0) {
2010		success = session_window_change_req(s);
2011	} else if (strcmp(rtype, "break") == 0) {
2012		success = session_break_req(s);
2013	}
2014
2015	return success;
2016}
2017
2018void
2019session_set_fds(Session *s, int fdin, int fdout, int fderr)
2020{
2021	if (!compat20)
2022		fatal("session_set_fds: called for proto != 2.0");
2023	/*
2024	 * now that have a child and a pipe to the child,
2025	 * we can activate our channel and register the fd's
2026	 */
2027	if (s->chanid == -1)
2028		fatal("no channel for session %d", s->self);
2029	channel_set_fds(s->chanid,
2030	    fdout, fdin, fderr,
2031	    fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
2032	    1,
2033	    CHAN_SES_WINDOW_DEFAULT);
2034}
2035
2036/*
2037 * Function to perform pty cleanup. Also called if we get aborted abnormally
2038 * (e.g., due to a dropped connection).
2039 */
2040void
2041session_pty_cleanup2(Session *s)
2042{
2043	if (s == NULL) {
2044		error("session_pty_cleanup: no session");
2045		return;
2046	}
2047	if (s->ttyfd == -1)
2048		return;
2049
2050	debug("session_pty_cleanup: session %d release %s", s->self, s->tty);
2051
2052	/* Record that the user has logged out. */
2053	if (s->pid != 0)
2054		record_logout(s->pid, s->tty, s->pw->pw_name);
2055
2056	/* Release the pseudo-tty. */
2057	if (getuid() == 0)
2058		pty_release(s->tty);
2059
2060	/*
2061	 * Close the server side of the socket pairs.  We must do this after
2062	 * the pty cleanup, so that another process doesn't get this pty
2063	 * while we're still cleaning up.
2064	 */
2065	if (close(s->ptymaster) < 0)
2066		error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno));
2067
2068	/* unlink pty from session */
2069	s->ttyfd = -1;
2070}
2071
2072void
2073session_pty_cleanup(Session *s)
2074{
2075	PRIVSEP(session_pty_cleanup2(s));
2076}
2077
2078static char *
2079sig2name(int sig)
2080{
2081#define SSH_SIG(x) if (sig == SIG ## x) return #x
2082	SSH_SIG(ABRT);
2083	SSH_SIG(ALRM);
2084	SSH_SIG(FPE);
2085	SSH_SIG(HUP);
2086	SSH_SIG(ILL);
2087	SSH_SIG(INT);
2088	SSH_SIG(KILL);
2089	SSH_SIG(PIPE);
2090	SSH_SIG(QUIT);
2091	SSH_SIG(SEGV);
2092	SSH_SIG(TERM);
2093	SSH_SIG(USR1);
2094	SSH_SIG(USR2);
2095#undef	SSH_SIG
2096	return "SIG@openssh.com";
2097}
2098
2099static void
2100session_exit_message(Session *s, int status)
2101{
2102	Channel *c;
2103
2104	if ((c = channel_lookup(s->chanid)) == NULL)
2105		fatal("session_exit_message: session %d: no channel %d",
2106		    s->self, s->chanid);
2107	debug("session_exit_message: session %d channel %d pid %ld",
2108	    s->self, s->chanid, (long)s->pid);
2109
2110	if (WIFEXITED(status)) {
2111		channel_request_start(s->chanid, "exit-status", 0);
2112		packet_put_int(WEXITSTATUS(status));
2113		packet_send();
2114	} else if (WIFSIGNALED(status)) {
2115		channel_request_start(s->chanid, "exit-signal", 0);
2116		packet_put_cstring(sig2name(WTERMSIG(status)));
2117#ifdef WCOREDUMP
2118		packet_put_char(WCOREDUMP(status));
2119#else /* WCOREDUMP */
2120		packet_put_char(0);
2121#endif /* WCOREDUMP */
2122		packet_put_cstring("");
2123		packet_put_cstring("");
2124		packet_send();
2125	} else {
2126		/* Some weird exit cause.  Just exit. */
2127		packet_disconnect("wait returned status %04x.", status);
2128	}
2129
2130	/* disconnect channel */
2131	debug("session_exit_message: release channel %d", s->chanid);
2132	channel_cancel_cleanup(s->chanid);
2133	/*
2134	 * emulate a write failure with 'chan_write_failed', nobody will be
2135	 * interested in data we write.
2136	 * Note that we must not call 'chan_read_failed', since there could
2137	 * be some more data waiting in the pipe.
2138	 */
2139	if (c->ostate != CHAN_OUTPUT_CLOSED)
2140		chan_write_failed(c);
2141	s->chanid = -1;
2142}
2143
2144void
2145session_close(Session *s)
2146{
2147	int i;
2148
2149	debug("session_close: session %d pid %ld", s->self, (long)s->pid);
2150	if (s->ttyfd != -1)
2151		session_pty_cleanup(s);
2152	if (s->term)
2153		xfree(s->term);
2154	if (s->display)
2155		xfree(s->display);
2156	if (s->auth_display)
2157		xfree(s->auth_display);
2158	if (s->auth_data)
2159		xfree(s->auth_data);
2160	if (s->auth_proto)
2161		xfree(s->auth_proto);
2162	s->used = 0;
2163	for (i = 0; i < s->num_env; i++) {
2164		xfree(s->env[i].name);
2165		xfree(s->env[i].val);
2166	}
2167	if (s->env != NULL)
2168		xfree(s->env);
2169	session_proctitle(s);
2170}
2171
2172void
2173session_close_by_pid(pid_t pid, int status)
2174{
2175	Session *s = session_by_pid(pid);
2176	if (s == NULL) {
2177		debug("session_close_by_pid: no session for pid %ld",
2178		    (long)pid);
2179		return;
2180	}
2181	if (s->chanid != -1)
2182		session_exit_message(s, status);
2183	session_close(s);
2184}
2185
2186/*
2187 * this is called when a channel dies before
2188 * the session 'child' itself dies
2189 */
2190void
2191session_close_by_channel(int id, void *arg)
2192{
2193	Session *s = session_by_channel(id);
2194	if (s == NULL) {
2195		debug("session_close_by_channel: no session for id %d", id);
2196		return;
2197	}
2198	debug("session_close_by_channel: channel %d child %ld",
2199	    id, (long)s->pid);
2200	if (s->pid != 0) {
2201		debug("session_close_by_channel: channel %d: has child", id);
2202		/*
2203		 * delay detach of session, but release pty, since
2204		 * the fd's to the child are already closed
2205		 */
2206		if (s->ttyfd != -1)
2207			session_pty_cleanup(s);
2208		return;
2209	}
2210	/* detach by removing callback */
2211	channel_cancel_cleanup(s->chanid);
2212	s->chanid = -1;
2213	session_close(s);
2214}
2215
2216void
2217session_destroy_all(void (*closefunc)(Session *))
2218{
2219	int i;
2220	for (i = 0; i < MAX_SESSIONS; i++) {
2221		Session *s = &sessions[i];
2222		if (s->used) {
2223			if (closefunc != NULL)
2224				closefunc(s);
2225			else
2226				session_close(s);
2227		}
2228	}
2229}
2230
2231static char *
2232session_tty_list(void)
2233{
2234	static char buf[1024];
2235	int i;
2236	char *cp;
2237
2238	buf[0] = '\0';
2239	for (i = 0; i < MAX_SESSIONS; i++) {
2240		Session *s = &sessions[i];
2241		if (s->used && s->ttyfd != -1) {
2242
2243			if (strncmp(s->tty, "/dev/", 5) != 0) {
2244				cp = strrchr(s->tty, '/');
2245				cp = (cp == NULL) ? s->tty : cp + 1;
2246			} else
2247				cp = s->tty + 5;
2248
2249			if (buf[0] != '\0')
2250				strlcat(buf, ",", sizeof buf);
2251			strlcat(buf, cp, sizeof buf);
2252		}
2253	}
2254	if (buf[0] == '\0')
2255		strlcpy(buf, "notty", sizeof buf);
2256	return buf;
2257}
2258
2259void
2260session_proctitle(Session *s)
2261{
2262	if (s->pw == NULL)
2263		error("no user for session %d", s->self);
2264	else
2265		setproctitle("%s@%s", s->pw->pw_name, session_tty_list());
2266}
2267
2268int
2269session_setup_x11fwd(Session *s)
2270{
2271	struct stat st;
2272	char display[512], auth_display[512];
2273	char hostname[MAXHOSTNAMELEN];
2274
2275	if (no_x11_forwarding_flag) {
2276		packet_send_debug("X11 forwarding disabled in user configuration file.");
2277		return 0;
2278	}
2279	if (!options.x11_forwarding) {
2280		debug("X11 forwarding disabled in server configuration file.");
2281		return 0;
2282	}
2283	if (!options.xauth_location ||
2284	    (stat(options.xauth_location, &st) == -1)) {
2285		packet_send_debug("No xauth program; cannot forward with spoofing.");
2286		return 0;
2287	}
2288	if (options.use_login) {
2289		packet_send_debug("X11 forwarding disabled; "
2290		    "not compatible with UseLogin=yes.");
2291		return 0;
2292	}
2293	if (s->display != NULL) {
2294		debug("X11 display already set.");
2295		return 0;
2296	}
2297	if (x11_create_display_inet(options.x11_display_offset,
2298	    options.x11_use_localhost, s->single_connection,
2299	    &s->display_number) == -1) {
2300		debug("x11_create_display_inet failed.");
2301		return 0;
2302	}
2303
2304	/* Set up a suitable value for the DISPLAY variable. */
2305	if (gethostname(hostname, sizeof(hostname)) < 0)
2306		fatal("gethostname: %.100s", strerror(errno));
2307	/*
2308	 * auth_display must be used as the displayname when the
2309	 * authorization entry is added with xauth(1).  This will be
2310	 * different than the DISPLAY string for localhost displays.
2311	 */
2312	if (options.x11_use_localhost) {
2313		snprintf(display, sizeof display, "localhost:%u.%u",
2314		    s->display_number, s->screen);
2315		snprintf(auth_display, sizeof auth_display, "unix:%u.%u",
2316		    s->display_number, s->screen);
2317		s->display = xstrdup(display);
2318		s->auth_display = xstrdup(auth_display);
2319	} else {
2320#ifdef IPADDR_IN_DISPLAY
2321		struct hostent *he;
2322		struct in_addr my_addr;
2323
2324		he = gethostbyname(hostname);
2325		if (he == NULL) {
2326			error("Can't get IP address for X11 DISPLAY.");
2327			packet_send_debug("Can't get IP address for X11 DISPLAY.");
2328			return 0;
2329		}
2330		memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr));
2331		snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr),
2332		    s->display_number, s->screen);
2333#else
2334		snprintf(display, sizeof display, "%.400s:%u.%u", hostname,
2335		    s->display_number, s->screen);
2336#endif
2337		s->display = xstrdup(display);
2338		s->auth_display = xstrdup(display);
2339	}
2340
2341	return 1;
2342}
2343
2344static void
2345do_authenticated2(Authctxt *authctxt)
2346{
2347	server_loop2(authctxt);
2348}
2349
2350void
2351do_cleanup(Authctxt *authctxt)
2352{
2353	static int called = 0;
2354
2355	debug("do_cleanup");
2356
2357	/* no cleanup if we're in the child for login shell */
2358	if (is_child)
2359		return;
2360
2361	/* avoid double cleanup */
2362	if (called)
2363		return;
2364	called = 1;
2365
2366	if (authctxt == NULL)
2367		return;
2368#ifdef KRB5
2369	if (options.kerberos_ticket_cleanup &&
2370	    authctxt->krb5_ctx)
2371		krb5_cleanup_proc(authctxt);
2372#endif
2373
2374#ifdef GSSAPI
2375	if (compat20 && options.gss_cleanup_creds)
2376		ssh_gssapi_cleanup_creds();
2377#endif
2378
2379#ifdef USE_PAM
2380	if (options.use_pam) {
2381		sshpam_cleanup();
2382		sshpam_thread_cleanup();
2383	}
2384#endif
2385
2386	/* remove agent socket */
2387	auth_sock_cleanup_proc(authctxt->pw);
2388
2389	/*
2390	 * Cleanup ptys/utmp only if privsep is disabled,
2391	 * or if running in monitor.
2392	 */
2393	if (!use_privsep || mm_is_monitor())
2394		session_destroy_all(session_pty_cleanup2);
2395}
2396