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