source: trunk/third/ssh/sshd.c @ 12779

Revision 12779, 137.3 KB checked in by ghudson, 26 years ago (diff)
Nuke broken SGI project management code.
Line 
1/*
2
3sshd.c
4
5Author: Tatu Ylonen <ylo@cs.hut.fi>
6
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8                   All rights reserved
9
10Created: Fri Mar 17 17:09:28 1995 ylo
11
12This program is the ssh daemon.  It listens for connections from clients, and
13performs authentication, executes use commands or shell, and forwards
14information to/from the application to the user client over an encrypted
15connection.  This can also handle forwarding of X11, TCP/IP, and authentication
16agent connections.
17
18*/
19
20/*
21 * $Id: sshd.c,v 1.18 1999-03-27 01:59:28 ghudson Exp $
22 * $Log: not supported by cvs2svn $
23 * Revision 1.17  1999/03/16 19:03:38  danw
24 * log a debugging error if al_acct_create fails
25 *
26 * Revision 1.16  1999/03/08 18:20:11  danw
27 * merge changes
28 *
29 * Revision 1.15  1999/02/27 17:08:21  ghudson
30 * Teach sshd how to switch on SIGUSR1/SIGUSR2.
31 * Note: the current implementation only works with LIBWRAP defined,
32 *  since that's how we build it.
33 *
34 * Revision 1.14  1998/06/30 21:10:02  danw
35 * put xauthority data in /tmp, not afs
36 *
37 * Revision 1.13  1998/05/13 20:18:55  danw
38 * merge in changes from 1.2.23
39 *
40 * Revision 1.12  1998/04/25 23:15:56  ghudson
41 * Take advantage of relaxed al_acct_create() contract.
42 *
43 * Revision 1.11  1998/04/09 22:51:48  ghudson
44 * Support local accounts as determined by libal.
45 *
46 * Revision 1.10  1998/03/12 20:37:12  danw
47 * recheck pw->pw_dir after al_acct_create in case we got a temp homedir
48 *
49 * Revision 1.9  1998/03/01 16:12:59  danw
50 * Use xmalloc, not malloc. (pointed out by mhpower)
51 *
52 * Revision 1.8  1998/02/28 17:58:31  danw
53 * Don't use packet_disconnect for `you are not allowed to log in here'
54 *
55 * Revision 1.7  1998/02/02 23:20:15  danw
56 * use our DEFAULT_PATH, not the OS's unless the builder overrides it on
57 * the command line.
58 *
59 * Revision 1.6  1998/01/24 01:47:26  danw
60 * merge in changes for 1.2.22
61 *
62 * Revision 1.5  1998/01/01 18:18:21  danw
63 * Don't set KRB5CCNAME if the user didn't get tickets
64 *
65 * Revision 1.4  1997/11/19 20:44:45  danw
66 * do chown later
67 *
68 * Revision 1.3  1997/11/15 00:04:20  danw
69 * Use atexit() functions to destroy tickets and call al_acct_revert.
70 * Work around Solaris lossage with libucb and grantpt.
71 *
72 * Revision 1.2  1997/11/12 21:16:18  danw
73 * Athena-login changes (including some krb4 stuff)
74 *
75 * Revision 1.1.1.1  1997/10/17 22:26:00  danw
76 * Import of ssh 1.2.21
77 *
78 * Revision 1.1.1.2  1998/01/24 01:25:18  danw
79 * Import of ssh 1.2.22
80 *
81 * Revision 1.1.1.3  1998/05/13 19:11:09  danw
82 * Import of ssh 1.2.23
83 *
84 * Revision 1.1.1.4  1999/03/08 17:43:02  danw
85 * Import of ssh 1.2.26
86 *
87 * Revision 1.55  1998/07/08 14:55:22  tri
88 *      Fixed version negotiation so, that ssh 2
89 *      compatibility is even remotedly possible.
90 *
91 * Revision 1.54  1998/07/08 00:48:46  kivinen
92 *      Added better HPUX TCB auth support. Added SGI proj support.
93 *      Changed to use match_host in the allow/deny checking. Changed
94 *      to use PASSWD_PATH. Added checking that if allow/deny group is
95 *      set then the group must exists.
96 *
97 * Revision 1.53  1998/06/11 00:11:24  kivinen
98 *      Added ENABLE_SO_LINGER ifdef. Added username to /bin/password
99 *      commands. Added user@host support.
100 *
101 * Revision 1.52  1998/05/23  20:28:12  kivinen
102 *      Changed () -> (void). Added HAVE_OSF1_C2_SECURITY include
103 *      files. Added days_before_{account,password}_expires support.
104 *      Added chalnecho TIS authentication server response code
105 *      support. Added call to osf1c2_check_account_and_terminal
106 *      function. Added SSH_BINDIR to path read from
107 *      /etc/default/login. Fixed BSDI login_getclass code for BSDI
108 *      2.1.
109 *
110 * Revision 1.51  1998/05/11  18:51:07  kivinen
111 *      Fixed AIX authstate code.
112 *
113 * Revision 1.50  1998/04/30 01:58:40  kivinen
114 *      Fixed osflim handling so that now it allows setting resource
115 *      to 0. Added -V option (for ssh version 2 compat mode). Added
116 *      LIBWRAP code to also when in debugging mode. Added BSDI
117 *      setusercontext code.
118 *
119 * Revision 1.49  1998/04/17 00:42:36  kivinen
120 *      Freebsd login capabilities support. Added REMOTEUSER
121 *      environment variable setting. Changed locked account checking
122 *      so that it will not care if the account is locked if
123 *      kerberos_or_local_password is not set. Added nologin-allow
124 *      support. Added setting of AUTHSTATE and KRB5CCNAME enviroment
125 *      variables if AIX authenticate() function is used.
126 *
127 * Revision 1.48  1998/03/27 17:05:01  kivinen
128 *      Added SIGDANGER code. Fixed kerberos initialization code so
129 *      ssh will check the error codes of initialization function.
130 *      added ignore_root_rhosts code. Moved initgroups before closing
131 *      all filedescriptors.
132 *
133 * Revision 1.47  1998/01/03 06:42:43  kivinen
134 *      Added allow/deny groups option support.
135 *
136 * Revision 1.46  1998/01/02 06:39:36  kivinen
137 *      Added new mail checking. Added expiration checkind for bsdi,
138 *      and warning when password is about to expire. Fixed kerberos
139 *      ticket name handling. Added support for XAuthLocation option.
140 *      Added support for login capabilities for bsdi, only support
141 *      ignorelogin option.
142 *      Added osfc2 resource limit setting.
143 *
144 * Revision 1.45  1997/10/01 19:16:32  ylo
145 *      Clarified error message about xauth not being in path.
146 *
147 * Revision 1.44  1997/05/08 03:06:51  kivinen
148 *      Fixed sighup handling (added select before accept, changed
149 *      execv to execvp so sshd is searched from path).
150 *
151 * Revision 1.43  1997/04/27 21:51:11  kivinen
152 *      Added F-SECURE stuff. Added {Allow,Deny}Forwarding{To,Port}
153 *      feature. Added {Allow,Deny}Users feature from Steve Kann
154 *      <stevek@SteveK.COM>.
155 *
156 * Revision 1.42  1997/04/23 00:05:35  kivinen
157 *      Added ifdefs around password expiration and inactivity checks,
158 *      because some systems dont have sp_expire and sp_inact fields.
159 *
160 * Revision 1.41  1997/04/21 01:05:56  kivinen
161 *      Added waitpid loop to main_sigchld_handler if we have it.
162 *      Added check to pty_cleanup_proc so it will not cleanup pty
163 *      twice.
164 *      Changed argument to server_loop from ttyname to
165 *      cleanup_context.
166 *
167 * Revision 1.40  1997/04/17 04:04:58  kivinen
168 *      Removed extra variable err.
169 *
170 * Revision 1.39  1997/04/17 04:04:13  kivinen
171 *      Added fatal: to all errors that cause sshd to exit.
172 *      Added resetting of SIGCHLD before running libwrap code.
173 *      Moved pty/pipe closing to server_loop. Added ttyname argument
174 *      to server_loop.
175 *      Server_loop will also now release the pty if it is allocated.
176 *
177 * Revision 1.38  1997/04/05 22:03:38  kivinen
178 *      Added check that userfile_get_des_1_magic_phrase succeeded,
179 *      before using the passphrase. Moved closing of pty after the
180 *      pty_release.
181 *
182 * Revision 1.37  1997/04/05 17:28:31  ylo
183 *      Added a workaround for the Windows SSH problem with X11
184 *      forwarding.
185 *
186 * Revision 1.36  1997/03/27 05:59:50  kivinen
187 *      Fixed bug in HAVE_USERSEC_H code.
188 *
189 * Revision 1.35  1997/03/27 03:12:22  kivinen
190 *      Added kerberos patches from Glenn Machin.
191 *      Added USELOGIN patches from Brian Cully.
192 *
193 * Revision 1.34  1997/03/26 05:32:42  kivinen
194 *      Added idle_timeout variable.
195 *      If debug_flag is given set rsa to verbose.
196 *      Changed uid 0 to bee UID_ROOT.
197 *
198 * Revision 1.33  1997/03/25 05:48:29  kivinen
199 *      Implemented SilentDeny and umask options. Added HAVE_DAEMON
200 *      support.
201 *      Moved LIBWRAP code to child.
202 *      Moved closing of sockets/pipes out from server_loop.
203 *
204 * Revision 1.32  1997/03/19 23:04:43  kivinen
205 *      Fixed typo.
206 *
207 * Revision 1.31  1997/03/19 21:17:57  kivinen
208 *      Added some errno printing to all fatal calls.
209 *      Added SSH_ORIGINAL_COMMAND environment variable setting. It
210 *      will have the original command from the network when using
211 *      forced command. It can be used to get arguments for forced
212 *      command.
213 *
214 * Revision 1.30  1997/03/19 19:25:57  kivinen
215 *      Added input buffer clearing for error conditions, so packet.c
216 *      can check that buffer must be empty before new packet is read
217 *      in.
218 *
219 * Revision 1.29  1997/03/19 17:53:17  kivinen
220 *      Added more ETC_SHADOW support and SECURE_RPC, SECURE_NFS and
221 *      NIS_PLUS support from Andy Polyakov <appro@fy.chalmers.se>.
222 *      Added TIS authentication code from Andre April
223 *      <Andre.April@cediti.be>.
224 *      Moved authentication fail loop to do_authentication_fail_loop
225 *      function. Added checks that username isn't longer than 255
226 *      characters.
227 *      Changed do_authentication to get cipher_type, so it can
228 *      disable RhostsRsa authentication if using unsecure cipher
229 *      (NONE, or ARCFOUR).
230 *      Changed order of environment variables set to child, because
231 *      digital unixes telnet dumps core if USER is the first
232 *      environment variable set.
233 *      Added code that will set all ip-address to xauth so it should
234 *      work for multihosted machines too. Dont use xauth add
235 *      host/unix:0 on crays, because it complains about it. Patch
236 *      from Arne Henrik Juul <arnej@imf.unit.no>
237 *
238 * Revision 1.28  1996/11/24 08:26:15  kivinen
239 *      Added SSHD_NO_{PORT,X11}_FORWARDING support.
240 *
241 * Revision 1.27  1996/11/04 06:35:01  ylo
242 *      Updated processing of check_emulation output.
243 *
244 * Revision 1.26  1996/10/29 22:46:25  kivinen
245 *      log -> log_msg. Added old agent emulation code (disable agent
246 *      forwarding if the other end is too old).
247 *
248 * Revision 1.25  1996/10/23 15:59:13  ttsalo
249 *       Changed BINDIR's name to SSH_BINDIR to prevent conflicts
250 *
251 * Revision 1.24  1996/10/21 16:35:23  ttsalo
252 *       Removed some fd auth code
253 *
254 * Revision 1.23  1996/10/21 16:18:34  ttsalo
255 *       Had to remove BINDIR from line 2518
256 *
257 * Revision 1.22  1996/10/20 16:19:36  ttsalo
258 *      Added global variable 'original_real_uid' and it's initialization
259 *
260 * Revision 1.20  1996/09/27 17:19:16  ylo
261 *      Merged ultrix patches from Corey Satten.
262 *
263 * Revision 1.19  1996/09/22 22:38:49  ylo
264 *      Added endgrent() before closing all file descriptors.
265 *
266 * Revision 1.18  1996/09/08 17:40:31  ttsalo
267 *      BSD4.4Lite's _PATH_DEFPATH is checked when defining DEFAULT_PATH.
268 *      (Patch from Andrey A. Chernov <ache@lsd.relcom.eu.net>)
269 *
270 * Revision 1.17  1996/08/29 14:51:23  ttsalo
271 *      Agent-socket directory handling implemented
272 *
273 * Revision 1.16  1996/08/22 22:16:24  ylo
274 *      Log remote commands executed by root, and log the fact that a
275 *      remote command was executed by an ordinary user, but not the
276 *      actual command (for privacy reasons).
277 *
278 * Revision 1.15  1996/08/16 02:47:18  ylo
279 *      Log root logins at LOG_NOTICE.
280 *
281 * Revision 1.14  1996/08/13 09:04:23  ttsalo
282 *      Home directory, .ssh and .ssh/authorized_keys are now
283 *      checked for wrong owner and group & world writeability.
284 *
285 * Revision 1.13  1996/08/13 00:23:31  ylo
286 *      When doing X11 forwarding, check the existence of xauth and
287 *      deny forwarding if it doesn't exist.  This makes copying
288 *      binaries compiled on one system to other systems easier.
289 *
290 *      Run /etc/sshrc with /bin/sh instead of the user's shell.
291 *
292 * Revision 1.12  1996/07/29 04:58:54  ylo
293 *      Add xauth data also for `hostname`/unix:$display as some X
294 *      servers actually seem to use this version.  (Kludge to work
295 *      around X11 bug.)
296 *
297 * Revision 1.11  1996/07/15 23:21:55  ylo
298 *      Don't allow more than five password authentication attempts,
299 *      and log attempts after the first one.
300 *
301 * Revision 1.10  1996/07/12 07:28:02  ttsalo
302 *      Small ultrix patch
303 *
304 * Revision 1.9  1996/06/05 17:57:34  ylo
305 *      If /etc/nologin exists, print that fact in plain text before
306 *      printing the actual contents.  I am getting too many
307 *      complaints about it.
308 *
309 * Revision 1.8  1996/06/03 19:25:49  ylo
310 *      Fixed a typo.
311 *
312 * Revision 1.7  1996/05/29 07:41:46  ylo
313 *      Added arguments to userfile_init.
314 *
315 * Revision 1.6  1996/05/29 07:16:38  ylo
316 *      Disallow any user names that start with a '-' or '+' (or '@',
317 *      just to be sure).  There is some indication that getpw* might
318 *      returns such names on some systems with NIS.  Ouuuch!
319 *
320 * Revision 1.5  1996/05/28 16:41:14  ylo
321 *      Merged Cray patches from Wayne Schroeder.
322 *      Use setsid instead of setpgrp on ultrix.
323 *
324 * Revision 1.4  1996/04/26 00:22:51  ylo
325 *      Improved error messages related to reading host key.
326 *      Fixed ip addr in "Closing connection" message.
327 *
328 * Revision 1.3  1996/04/22 23:49:47  huima
329 * Changed protocol version to 1.4, added calls to emulate module.
330 *
331 * Revision 1.2  1996/02/18  21:49:51  ylo
332 *      Moved userfile_uninit to proper place.
333 *      Use setluid if it exists (at least OSF/1).
334 *
335 * Revision 1.1.1.1  1996/02/18 21:38:13  ylo
336 *      Imported ssh-1.2.13.
337 *
338 * Revision 1.31  1995/10/02  01:28:59  ylo
339 *      Include sys/syslog.h if NEED_SYS_SYSLOG_H.
340 *      Print proper ETCDIR in usage().
341 *
342 * Revision 1.30  1995/09/27  02:54:43  ylo
343 *      Fixed a minor error.
344 *
345 * Revision 1.29  1995/09/27  02:49:06  ylo
346 *      Fixed syntax errors.
347 *
348 * Revision 1.28  1995/09/27  02:18:51  ylo
349 *      Added support for SCO unix.
350 *      Added support for .hushlogin.
351 *      Read $HOME/.environment.
352 *      Pass X11 proto and cookie in stdin instead of command line.
353 *      Added support for $HOME/.ssh/rc and /etc/sshrc.
354 *
355 * Revision 1.27  1995/09/25  00:03:53  ylo
356 *      Added screen number.
357 *      Don't display motd and login time if executing a command.
358 *
359 * Revision 1.26  1995/09/22  22:22:34  ylo
360 *      Fixed a bug in the new environment code.
361 *
362 * Revision 1.25  1995/09/21  17:16:49  ylo
363 *      Fixes to libwrap code.
364 *      Fixed problem in wait() in key regeneration.  Now only
365 *      ackquires light noise at regeneration.
366 *      Support for ignore_rhosts.
367 *      Don't use X11 forwarding with spoofing if no xauth.
368 *      Rewrote the code to initialize the environment in the child.
369 *      Added code to read /etc/environment into child environment.
370 *      Fixed setpcred argument type.
371 *
372 * Revision 1.24  1995/09/11  17:35:53  ylo
373 *      Added libwrap support.
374 *      Log daemon name without path.
375 *
376 * Revision 1.23  1995/09/10  23:43:32  ylo
377 *      Added a newline in xauth message.
378 *
379 * Revision 1.22  1995/09/10  23:29:43  ylo
380 *      Renamed sigchld_handler main_sigchld_handler to avoid
381 *      conflict.
382 *
383 * Revision 1.21  1995/09/10  23:26:53  ylo
384 *      Child xauth line printed with fprintf instead of debug().
385 *
386 * Revision 1.20  1995/09/10  22:43:17  ylo
387 *      Added uid-swapping stuff.
388 *      Moved do_session to serverloop.c and renamed it server_loop.
389 *      Changed SIGCHLD handling.
390 *      Merged OSF/1 C2 security stuff.
391 *
392 * Revision 1.19  1995/09/09  21:26:47  ylo
393 * /m/shadows/u2/users/ylo/ssh/README
394 *
395 * Revision 1.18  1995/09/06  19:53:19  ylo
396 *      Fixed spelling of fascist.
397 *
398 * Revision 1.17  1995/09/06  16:02:40  ylo
399 *      Added /usr/bin/X11 to default DEFAULT_PATH.
400 *      Fixed inetd_flag & debug_flag together.
401 *      Fixed -i.
402 *
403 * Revision 1.16  1995/08/31  09:43:14  ylo
404 *      Fixed LOGNAME.
405 *
406 * Revision 1.15  1995/08/31  09:26:22  ylo
407 *      Copy struct pw.
408 *      Use socketpairs for communicating with the shell/command.
409 *      Use same socket for stdin and stdout. (may help rdist)
410 *      Put LOGNAME in environment.
411 *      Run xauth directly, without the shell in between.
412 *      Fixed the HPSUX kludge.
413 *
414 * Revision 1.14  1995/08/29  22:36:12  ylo
415 *      Added SIGHUP handling.  Added SIGTERM and SIGQUIT handling.
416 *      Permit root login if forced command.
417 *      Added DenyHosts, AllowHosts.  Added PrintMotd.
418 *      New file descriptor code.
419 *      Use HPSUX and SIGCHLD kludges only on HPUX.
420 *
421 * Revision 1.13  1995/08/22  14:06:11  ylo
422 *      Added /usr/local/bin in default DEFAULT_PATH.
423 *
424 * Revision 1.12  1995/08/21  23:33:48  ylo
425 *      Added "-f conffile" option.
426 *      Added support for the server configuration file.
427 *      Added allow/deny host code.
428 *      Added code to optionally deny root logins.
429 *      Added code to configure allowed authentication methods.
430 *      Changes to log initialization arguments.
431 *      Eliminated NO_RHOSTS_AUTHENTICATION.
432 *
433 * Revision 1.11  1995/08/18  22:58:06  ylo
434 *      Added support for O_NONBLOCK_BROKEN.
435 *      Added support for TTY_GROUP.
436 *
437 * Revision 1.10  1995/07/27  02:19:09  ylo
438 *      Tell packet_set_encryption_key that we are the server.
439 *
440 *      Temporary kludge to make TCP/IP port forwarding work
441 *      properly.  This kludge will increase idle CPU usage because
442 *      sshd wakes up every 300ms.
443 *
444 * Revision 1.9  1995/07/27  00:41:34  ylo
445 *      If DEFAULT_PATH defined by configure, use that value.
446 *
447 * Revision 1.8  1995/07/26  23:21:06  ylo
448 *      Removed include version.h.  Added include mpaux.h.
449 *
450 *      Print software version with -d.
451 *
452 *      Added support for protocol version 1.1.  Fixes minor security
453 *      problems, and updates the protocol to match the draft RFC.
454 *      Compatibility code makes it possible to use old clients with
455 *      this server.
456 *
457 * Revision 1.7  1995/07/16  01:01:41  ylo
458 *      Removed hostname argument from record_logout.
459 *      Added call to pty_release.
460 *      Set tty mode depending on whether we have tty group.
461 *
462 * Revision 1.6  1995/07/15  22:27:04  ylo
463 *      Added printing of /etc/motd.
464 *
465 * Revision 1.5  1995/07/15  21:41:04  ylo
466 *      Changed the HPSUX kludge (child_has_terminated).  It caused
467 *      sshd to busy-loop if the program exited but there were open
468 *      connections.
469 *
470 * Revision 1.4  1995/07/14  23:37:43  ylo
471 *      Limit outgoing packet size to 512 bytes for interactive
472 *      connections.
473 *
474 * Revision 1.3  1995/07/13  17:33:17  ylo
475 *      Only record the pid in /etc/sshd_pid if running without the
476 *      debugging flag.
477 *
478 * Revision 1.2  1995/07/13  01:40:47  ylo
479 *      Removed "Last modified" header.
480 *      Added cvs log.
481 *
482 * $Endlog$
483 */
484
485#include "includes.h"
486#include <gmp.h>
487#include "xmalloc.h"
488#include "rsa.h"
489#include "ssh.h"
490#include "pty.h"
491#include "packet.h"
492#include "buffer.h"
493#include "cipher.h"
494#include "mpaux.h"
495#include "servconf.h"
496#include "userfile.h"
497#include "emulate.h"
498#ifdef HAVE_USERSEC_H
499#include <usersec.h>
500#endif /* HAVE_USERSEC_H */
501#ifdef HAVE_ULIMIT_H
502#include <ulimit.h>
503#endif /* HAVE_ULIMIT_H */
504#ifdef HAVE_HPUX_TCB_AUTH
505#include <sys/types.h>
506#include <hpsecurity.h>
507#include <prot.h>
508#endif
509#ifdef HAVE_ETC_SHADOW
510#ifdef HAVE_SHADOW_H
511#include <shadow.h>
512#endif /* HAVE_SHADOW_H */
513#ifndef SHADOW
514#define SHADOW "/etc/shadow"
515#endif
516#endif /* HAVE_ETC_SHADOW */
517
518#ifdef HAVE_OSF1_C2_SECURITY
519#include <prot.h>
520#endif /* HAVE_OSF1_C2_SECURITY */
521
522#if defined (__bsdi__) && _BSDI_VERSION >= 199510
523#include <tzfile.h>
524#include <login_cap.h>
525#endif /* __bsdi__  && _BSDI_VERISION >= 199510 */
526
527#ifdef LIBWRAP
528#include <tcpd.h>
529#include <syslog.h>
530#ifdef NEED_SYS_SYSLOG_H
531#include <sys/syslog.h>
532#endif /* NEED_SYS_SYSLOG_H */
533int allow_severity = LOG_INFO;
534int deny_severity = LOG_WARNING;
535#endif /* LIBWRAP */
536
537#ifdef CRAY
538#include <udb.h>
539#include <unistd.h>
540#include <sys/category.h>
541extern char *setlimits();
542#endif
543
544#ifdef HAVE_SGI_PROJ_H
545#include <proj.h>
546#include <unistd.h>
547#include <sys/types.h>
548#endif
549
550#ifdef HAVE_TIS
551/* Support for TIS authentication server
552   Contributed by Andre April <Andre.April@cediti.be>. */
553#include "firewall.h"   /* TIS authsrv authentication */
554#endif
555
556#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
557#include <login_cap.h>
558#endif
559
560#ifdef _PATH_BSHELL
561#define DEFAULT_SHELL           _PATH_BSHELL
562#else
563#define DEFAULT_SHELL           "/bin/sh"
564#endif
565
566#ifndef DEFAULT_PATH
567#define DEFAULT_PATH    "/bin/athena:/usr/athena/bin:/usr/bsd:/bin:/usr/bin:/usr/ucb:/usr/bin/X11:/usr/local/bin"
568#endif /* DEFAULT_PATH */
569
570#ifndef O_NOCTTY
571#define O_NOCTTY        0
572#endif
573
574#ifdef KERBEROS
575#ifdef KRB5
576#include <krb5.h>
577/* Global the contexts */
578krb5_context ssh_context = 0;
579krb5_auth_context auth_context = 0;
580int havecred = 0;
581#endif /* KRB5 */
582char *ticket = "none\0";
583#endif /* KERBEROS */
584
585#include <al.h>
586extern int setpag(), ktc_ForgetAllTokens();
587extern char *tkt_string();
588void try_afscall(int (*func)(void));
589void al_cleanup(void);
590int *al_warnings = NULL;
591char *al_user;
592int al_local_acct;
593
594/* Server configuration options. */
595ServerOptions options;
596
597/* Name of the server configuration file. */
598char *config_file_name = SERVER_CONFIG_FILE;
599
600/* Debug mode flag.  This can be set on the command line.  If debug
601   mode is enabled, extra debugging output will be sent to the system
602   log, the daemon will not go to background, and will exit after processing
603   the first connection. */
604int debug_flag = 0;
605
606/* Flag indicating that the daemon is being started from inetd. */
607int inetd_flag = 0;
608
609/* argv[0] without path. */
610char *av0;
611
612/* Saved arguments to main(). */
613char **saved_argv;
614
615/* This is set to the socket that the server is listening; this is used in
616   the SIGHUP signal handler. */
617int listen_sock;
618
619/* Whether the server should accept connections. */
620static int switched = 0;
621static int enabled = 1;
622
623/* This is not really needed, and could be eliminated if server-specific
624   and client-specific code were removed from newchannels.c */
625uid_t original_real_uid = 0;
626
627/* Flags set in auth-rsa from authorized_keys flags.  These are set in
628  auth-rsa.c. */
629int no_port_forwarding_flag = 0;
630int no_agent_forwarding_flag = 0;
631int no_x11_forwarding_flag = 0;
632int no_pty_flag = 0;
633time_t idle_timeout = 0;
634char *forced_command = NULL;  /* RSA authentication "command=" option. */
635char *original_command = NULL;  /* original command from protocol. */
636struct envstring *custom_environment = NULL;
637                          /* RSA authentication "environment=" options. */
638
639/* Session id for the current session. */
640unsigned char session_id[16];
641
642/* Any really sensitive data in the application is contained in this structure.
643   The idea is that this structure could be locked into memory so that the
644   pages do not get written into swap.  However, there are some problems.
645   The private key contains MP_INTs, and we do not (in principle) have
646   access to the internals of them, and locking just the structure is not
647   very useful.  Currently, memory locking is not implemented. */
648struct
649{
650  /* Random number generator. */
651  RandomState random_state;
652 
653  /* Private part of server key. */
654  RSAPrivateKey private_key;
655
656  /* Private part of host key. */
657  RSAPrivateKey host_key;
658} sensitive_data;
659
660/* Flag indicating whether the current session key has been used.  This flag
661   is set whenever the key is used, and cleared when the key is regenerated. */
662int key_used = 0;
663
664/* This is set to true when SIGHUP is received. */
665int received_sighup = 0;
666
667/* Public side of the server key.  This value is regenerated regularly with
668   the private key. */
669RSAPublicKey public_key;
670
671/* Remote end username (mallocated) or NULL if not available */
672char *remote_user_name;
673
674/* Days before the password / account expires, or -1 if information not
675   available */
676int days_before_account_expires = -1;
677int days_before_password_expires = -1;
678
679/* Prototypes for various functions defined later in this file. */
680void do_connection(int privileged_port);
681void do_authentication(char *user, int privileged_port, int cipher_type);
682void do_authenticated(struct passwd *pw);
683void do_exec_pty(const char *command, int ptyfd, int ttyfd,
684                 const char *ttyname, struct passwd *pw, const char *term,
685                 const char *display, const char *auth_proto,
686                 const char *auth_data);
687void do_exec_no_pty(const char *command, struct passwd *pw,
688                    const char *display, const char *auth_proto,
689                    const char *auth_data);
690void do_child(const char *command, struct passwd *pw, const char *term,
691              const char *display, const char *auth_proto,
692              const char *auth_data, const char *ttyname);
693
694
695/* Signal handler for SIGHUP.  Sshd execs itself when it receives SIGHUP;
696   the effect is to reread the configuration file (and to regenerate
697   the server key). */
698
699RETSIGTYPE sighup_handler(int sig)
700{
701  received_sighup = 1;
702  signal(SIGHUP, sighup_handler);
703}
704
705/* Called from the main program after receiving SIGHUP.  Restarts the
706   server. */
707
708void sighup_restart(void)
709{
710  log_msg("Received SIGHUP; restarting.");
711  close(listen_sock);
712  execvp(saved_argv[0], saved_argv);
713  log_msg("RESTART FAILED: av[0]='%s', error: %s.",
714      saved_argv[0], strerror(errno));
715  exit(1);
716}
717
718/* Generic signal handler for terminating signals in the master daemon.
719   These close the listen socket; not closing it seems to cause "Address
720   already in use" problems on some machines, which is inconvenient. */
721
722RETSIGTYPE sigterm_handler(int sig)
723{
724  log_msg("Received signal %d; terminating.", sig);
725  close(listen_sock);
726  exit(255);
727}
728
729#ifdef SIGDANGER
730/* Signal handler for AIX's SIGDANGER low-memory signal
731   It logs the signal and ignores the message. */
732RETSIGTYPE sigdanger_handler(int sig)
733{
734  log_msg("Received signal %d (SIGDANGER, means memory is low); ignoring.",
735          sig);
736}
737#endif /* SIGDANGER */
738
739/* SIGCHLD handler.  This is called whenever a child dies.  This will then
740   reap any zombies left by exited c. */
741
742RETSIGTYPE main_sigchld_handler(int sig)
743{
744  int status;
745#ifdef HAVE_WAITPID
746  /* Reap all childrens */
747  while (waitpid(-1, &status, WNOHANG) > 0)
748    ;
749#else
750  wait(&status);
751#endif
752  signal(SIGCHLD, main_sigchld_handler);
753}
754
755/* Signal handler for the alarm after the login grace period has expired. */
756
757RETSIGTYPE grace_alarm_handler(int sig)
758{
759  /* Close the connection. */
760  packet_close();
761 
762  /* Log error and exit. */
763  fatal_severity(SYSLOG_SEVERITY_INFO,
764                 "Timeout before authentication.");
765}
766
767/* Signal handler for the key regeneration alarm.  Note that this
768   alarm only occurs in the daemon waiting for connections, and it does not
769   do anything with the private key or random state before forking.  Thus there
770   should be no concurrency control/asynchronous execution problems. */
771
772RETSIGTYPE key_regeneration_alarm(int sig)
773{
774  /* Check if we should generate a new key. */
775  if (key_used)
776    {
777      /* This should really be done in the background. */
778      log_msg("Generating new %d bit RSA key.", options.server_key_bits);
779      random_acquire_light_environmental_noise(&sensitive_data.random_state);
780      rsa_generate_key(&sensitive_data.private_key, &public_key,
781                       &sensitive_data.random_state, options.server_key_bits);
782      random_save(&sensitive_data.random_state, geteuid(),
783                  options.random_seed_file);
784      key_used = 0;
785      log_msg("RSA key generation complete.");
786    }
787
788  /* Reschedule the alarm. */
789  signal(SIGALRM, key_regeneration_alarm);
790  alarm(options.key_regeneration_time);
791}
792
793RETSIGTYPE sigusr1_handler(int sig)
794{
795  enabled = 1;
796  signal(SIGUSR1, sigusr1_handler);
797}
798
799RETSIGTYPE sigusr2_handler(int sig)
800{
801  if (switched)
802    enabled = 0;
803  signal(SIGUSR2, sigusr2_handler);
804}
805
806/* Main program for the daemon. */
807
808int main(int ac, char **av)
809{
810  extern char *optarg;
811  extern int optind;
812  int opt, aux, sock_in, sock_out, newsock, i, pid, on = 1;
813  int remote_major, remote_minor;
814  int perm_denied = 0;
815  int ret;
816  fd_set fdset;
817  struct sockaddr_in sin;
818  char buf[100]; /* Must not be larger than remote_version. */
819  char remote_version[100]; /* Must be at least as big as buf. */
820  char *comment;
821  char *ssh_remote_version_string = NULL;
822  FILE *f;
823#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
824  struct linger linger;
825#endif /* SO_LINGER */
826  int done;
827 
828  /* Save argv[0]. */
829  saved_argv = av;
830  if (strchr(av[0], '/'))
831    av0 = strrchr(av[0], '/') + 1;
832  else
833    av0 = av[0];
834
835  /* Prevent core dumps to avoid revealing sensitive information. */
836  signals_prevent_core();
837
838  /* Set SIGPIPE to be ignored. */
839  signal(SIGPIPE, SIG_IGN);
840
841  /* Initialize configuration options to their default values. */
842  initialize_server_options(&options);
843
844  /* Parse command-line arguments. */
845  while ((opt = getopt(ac, av, "f:p:b:k:h:g:diqV:sS")) != EOF)
846    {
847      switch (opt)
848        {
849        case 'f':
850          config_file_name = optarg;
851          break;
852        case 'd':
853          debug_flag = 1;
854          break;
855        case 'i':
856          inetd_flag = 1;
857          break;
858        case 'q':
859          options.quiet_mode = 1;
860          break;
861        case 'b':
862          options.server_key_bits = atoi(optarg);
863          break;
864        case 'p':
865          options.port = atoi(optarg);
866          break;
867        case 'g':
868          options.login_grace_time = atoi(optarg);
869          break;
870        case 'k':
871          options.key_regeneration_time = atoi(optarg);
872          break;
873        case 'h':
874          options.host_key_file = optarg;
875          break;
876        case 's':
877          switched = 1;
878          break;
879        case 'S':
880          switched = 1;
881          enabled = 0;
882          break;
883        case 'V':
884          ssh_remote_version_string = optarg;
885          break;
886        case '?':
887        default:
888#ifdef F_SECURE_COMMERCIAL
889
890#endif /* F_SECURE_COMMERCIAL */
891          fprintf(stderr, "sshd version %s [%s]\n", SSH_VERSION, HOSTTYPE);
892          fprintf(stderr, "Usage: %s [options]\n", av0);
893          fprintf(stderr, "Options:\n");
894          fprintf(stderr, "  -f file    Configuration file (default %s/sshd_config)\n", ETCDIR);
895          fprintf(stderr, "  -d         Debugging mode\n");
896          fprintf(stderr, "  -i         Started from inetd\n");
897          fprintf(stderr, "  -q         Quiet (no logging)\n");
898          fprintf(stderr, "  -p port    Listen on the specified port (default: 22)\n");
899          fprintf(stderr, "  -k seconds Regenerate server key every this many seconds (default: 3600)\n");
900          fprintf(stderr, "  -g seconds Grace period for authentication (default: 300)\n");
901          fprintf(stderr, "  -b bits    Size of server RSA key (default: 768 bits)\n");
902          fprintf(stderr, "  -h file    File from which to read host key (default: %s)\n",
903                  HOST_KEY_FILE);
904          fprintf(stderr, "  -V str     Remote version string already read from the socket\n");
905          exit(1);
906        }
907    }
908
909  /* Read server configuration options from the configuration file. */
910  read_server_config(&options, config_file_name);
911
912  /* Fill in default values for those options not explicitly set. */
913  fill_default_server_options(&options);
914
915  /* Check certain values for sanity. */
916  if (options.server_key_bits < 512 ||
917      options.server_key_bits > 32768)
918    {
919      fprintf(stderr, "fatal: Bad server key size.\n");
920      exit(1);
921    }
922  if (options.port < 1 || options.port > 65535)
923    {
924      fprintf(stderr, "fatal: Bad port number.\n");
925      exit(1);
926    }
927  if (options.umask != -1)
928    {
929      umask(options.umask);
930    }
931
932  /* Check that there are no remaining arguments. */
933  if (optind < ac)
934    {
935      fprintf(stderr, "fatal: Extra argument %s.\n", av[optind]);
936      exit(1);
937    }
938
939  /* Initialize the log (it is reinitialized below in case we forked). */
940  log_init(av0, debug_flag && !inetd_flag,
941           debug_flag || options.fascist_logging,
942           options.quiet_mode, options.log_facility);
943
944#ifdef F_SECURE_COMMERCIAL
945
946#endif /* F_SECURE_COMMERCIAL */
947  debug("sshd version %.100s [%.100s]", SSH_VERSION, HOSTTYPE);
948
949  /* Load the host key.  It must have empty passphrase. */
950  done = load_private_key(geteuid(), options.host_key_file, "",
951                          &sensitive_data.host_key, &comment);
952
953#ifdef SECURE_RPC
954  if (!done)
955    {
956      char *passphrase;
957
958      passphrase = userfile_get_des_1_magic_phrase(geteuid());
959      if (passphrase != NULL)
960        {
961          done = load_private_key(geteuid(), options.host_key_file,
962                                  passphrase, &sensitive_data.host_key, &comment);
963          if (done)
964            debug ("Using SUN-DES-1 magic phrase to decrypt host key.");
965          memset(passphrase, 0, strlen(passphrase));
966          xfree(passphrase);
967        }
968    }
969#endif
970  if (!done)
971    {
972      if (debug_flag)
973        {
974          fprintf(stderr, "Could not load host key: %.200s\n",
975                  options.host_key_file);
976          fprintf(stderr, "fatal: Please check that you have sufficient permissions and the file exists.\n");
977        }
978      else
979        {
980          log_init(av0, !inetd_flag, 1, 0, options.log_facility);
981          error("fatal: Could not load host key: %.200s.  Check path and permissions.",
982                options.host_key_file);
983        }
984      exit(1);
985    }
986  xfree(comment);
987
988#ifdef SCO
989  (void) set_auth_parameters(ac, av);
990#endif
991
992#ifdef HAVE_OSF1_C2_SECURITY
993  initialize_osf_security(ac, av);
994#endif /* HAVE_OSF1_C2_SECURITY */
995
996  /* If not in debugging mode, and not started from inetd, disconnect from
997     the controlling terminal, and fork.  The original process exits. */
998  if (!debug_flag && !inetd_flag)
999#ifdef HAVE_DAEMON
1000    if (daemon(0, 0) < 0)
1001      error("daemon: %.100s", strerror(errno));
1002#else /* HAVE_DAEMON */
1003    {
1004#ifdef TIOCNOTTY
1005      int fd;
1006#endif /* TIOCNOTTY */
1007
1008      /* Fork, and have the parent exit.  The child becomes the server. */
1009      if (fork())
1010        exit(0);
1011
1012      /* Redirect stdin, stdout, and stderr to /dev/null. */
1013      freopen("/dev/null", "r", stdin);
1014      freopen("/dev/null", "w", stdout);
1015      freopen("/dev/null", "w", stderr);
1016
1017      /* Disconnect from the controlling tty. */
1018#ifdef TIOCNOTTY
1019      fd = open("/dev/tty", O_RDWR|O_NOCTTY);
1020      if (fd >= 0)
1021        {
1022          (void)ioctl(fd, TIOCNOTTY, NULL);
1023          close(fd);
1024        }
1025#endif /* TIOCNOTTY */
1026#ifdef HAVE_SETSID
1027#ifdef ultrix
1028      setpgrp(0, 0);
1029#else /* ultrix */
1030      if (setsid() < 0)
1031        error("setsid: %.100s", strerror(errno));
1032#endif
1033#endif /* HAVE_SETSID */
1034    }
1035#endif /* HAVE_DAEMON */
1036   
1037  /* Reinitialize the log (because of the fork above). */
1038  log_init(av0, debug_flag && !inetd_flag,
1039           debug_flag || options.fascist_logging,
1040           options.quiet_mode, options.log_facility);
1041
1042  /* Check that server and host key lengths differ sufficiently.  This is
1043     necessary to make double encryption work with rsaref.  Oh, I hate
1044     software patents. */
1045  if (options.server_key_bits >
1046      sensitive_data.host_key.bits - SSH_KEY_BITS_RESERVED &&
1047      options.server_key_bits <
1048      sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED)
1049    {
1050      options.server_key_bits =
1051        sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED;
1052      debug("Forcing server key to %d bits to make it differ from host key.",
1053            options.server_key_bits);
1054    }
1055
1056  /* Initialize memory allocation so that any freed MP_INT data will be
1057     zeroed. */
1058  rsa_set_mp_memory_allocation();
1059
1060  /* Do not display messages to stdout in RSA code. */
1061  rsa_set_verbose(debug_flag);
1062
1063  /* Initialize the random number generator. */
1064  debug("Initializing random number generator; seed file %.200s",
1065        options.random_seed_file);
1066  random_initialize(&sensitive_data.random_state, geteuid(),
1067                    options.random_seed_file);
1068 
1069  /* Chdir to the root directory so that the current disk can be unmounted
1070     if desired. */
1071  chdir("/");
1072
1073  idle_timeout = options.idle_timeout;
1074 
1075  /* Start listening for a socket, unless started from inetd. */
1076  if (inetd_flag)
1077    {
1078      int s1, s2;
1079      s1 = dup(0);  /* Make sure descriptors 0, 1, and 2 are in use. */
1080      s2 = dup(s1);
1081      sock_in = dup(0);
1082      sock_out = dup(1);
1083      /* We intentionally do not close the descriptors 0, 1, and 2 as our
1084         code for setting the descriptors won\'t work if ttyfd happens to
1085         be one of those. */
1086      debug("inetd sockets after dupping: %d, %d", sock_in, sock_out);
1087
1088      /* Generate an rsa key. */
1089      log_msg("Generating %d bit RSA key.", options.server_key_bits);
1090      rsa_generate_key(&sensitive_data.private_key, &public_key,
1091                       &sensitive_data.random_state,
1092                   options.server_key_bits);
1093      random_save(&sensitive_data.random_state, geteuid(),
1094                  options.random_seed_file);
1095      log_msg("RSA key generation complete.");
1096    }
1097  else
1098    {
1099      /* Create socket for listening. */
1100      listen_sock = socket(AF_INET, SOCK_STREAM, 0);
1101      if (listen_sock < 0)
1102        fatal("socket: %.100s", strerror(errno));
1103
1104      /* Set socket options.  We try to make the port reusable and have it
1105         close as fast as possible without waiting in unnecessary wait states
1106         on close. */
1107      setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
1108                 sizeof(on));
1109#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
1110      linger.l_onoff = 1;
1111      linger.l_linger = 15;
1112      setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, (void *)&linger,
1113                 sizeof(linger));
1114#endif /* SO_LINGER */
1115
1116      /* Initialize the socket address. */
1117      memset(&sin, 0, sizeof(sin));
1118      sin.sin_family = AF_INET;
1119      sin.sin_addr = options.listen_addr;
1120      sin.sin_port = htons(options.port);
1121
1122      /* Bind the socket to the desired port. */
1123      if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
1124        {
1125          error("bind: %.100s", strerror(errno));
1126          shutdown(listen_sock, 2);
1127          close(listen_sock);
1128          fatal("Bind to port %d failed: %.200s.", options.port,
1129                strerror(errno));
1130        }
1131
1132      if (!debug_flag)
1133        {
1134          /* Record our pid in /etc/sshd_pid to make it easier to kill the
1135             correct sshd.  We don\'t want to do this before the bind above
1136             because the bind will fail if there already is a daemon, and this
1137             will overwrite any old pid in the file. */
1138          f = fopen(options.pid_file, "w");
1139          if (f)
1140            {
1141              fprintf(f, "%u\n", (unsigned int)getpid());
1142              fclose(f);
1143            }
1144        }
1145
1146      /* Start listening on the port. */
1147      log_msg("Server listening on port %d.", options.port);
1148      if (listen(listen_sock, 5) < 0)
1149        fatal("listen: %.100s", strerror(errno));
1150
1151      /* Generate an rsa key. */
1152      log_msg("Generating %d bit RSA key.", options.server_key_bits);
1153      rsa_generate_key(&sensitive_data.private_key, &public_key,
1154                       &sensitive_data.random_state,
1155                       options.server_key_bits);
1156      random_save(&sensitive_data.random_state, geteuid(),
1157                  options.random_seed_file);
1158      log_msg("RSA key generation complete.");
1159
1160      /* Schedule server key regeneration alarm. */
1161      signal(SIGALRM, key_regeneration_alarm);
1162      alarm(options.key_regeneration_time);
1163
1164      /* Arrange to restart on SIGHUP.  The handler needs listen_sock. */
1165      signal(SIGHUP, sighup_handler);
1166      signal(SIGTERM, sigterm_handler);
1167      signal(SIGQUIT, sigterm_handler);
1168
1169      /* Switch on and off on SIGUSR1 and SIGUSR2 (conditional on switched). */
1170      signal(SIGUSR1, sigusr1_handler);
1171      signal(SIGUSR2, sigusr2_handler);
1172     
1173      /* AIX sends SIGDANGER when memory runs low.  The default action is
1174         to terminate the process.  This sometimes makes it difficult to
1175         log in and fix the problem. */
1176     
1177#ifdef SIGDANGER
1178      signal(SIGDANGER, sigdanger_handler);
1179#endif /* SIGDANGER */
1180     
1181      /* Arrange SIGCHLD to be caught. */
1182      signal(SIGCHLD, main_sigchld_handler);
1183
1184#ifdef KERBEROS
1185#ifdef KRB5
1186      /* Initialize contexts and setup replay cache */
1187      if (!ssh_context)
1188        {
1189          krb5_error_code r;
1190         
1191          if ((r = krb5_init_context(&ssh_context)))
1192            fatal("Kerberos V5: %s while initializing krb5.",
1193                  error_message(r));
1194          krb5_init_ets(ssh_context);
1195        }
1196#endif
1197#endif
1198
1199      /* Stay listening for connections until the system crashes or the
1200         daemon is killed with a signal. */
1201      for (;;)
1202        {
1203          if (received_sighup)
1204            sighup_restart();
1205         
1206          /* Wait in select until there is a connection. */
1207          FD_ZERO(&fdset);
1208          FD_SET(listen_sock, &fdset);
1209          ret = select(listen_sock + 1, &fdset, NULL, NULL, NULL);
1210          if (ret < 0 || !FD_ISSET(listen_sock, &fdset))
1211            {
1212              if (errno == EINTR)
1213                continue;
1214              error("select: %.100s", strerror(errno));
1215              continue;
1216            }
1217         
1218          aux = sizeof(sin);
1219          newsock = accept(listen_sock, (struct sockaddr *)&sin, &aux);
1220          if (newsock < 0)
1221            {
1222              if (errno == EINTR)
1223                continue;
1224              error("accept: %.100s", strerror(errno));
1225              continue;
1226            }
1227
1228          /* Got connection.  Fork a child to handle it, unless we are in
1229             debugging mode. */
1230          if (debug_flag)
1231            {
1232              /* In debugging mode.  Close the listening socket, and start
1233                 processing the connection without forking. */
1234              debug("Server will not fork when running in debugging mode.");
1235              close(listen_sock);
1236              sock_in = newsock;
1237              sock_out = newsock;
1238              pid = getpid();
1239#ifdef LIBWRAP
1240              {
1241                struct request_info req;
1242               
1243                signal(SIGCHLD, SIG_DFL);
1244               
1245                request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL);
1246                fromhost(&req);
1247                if (!hosts_access(&req) || !enabled)
1248                  refuse(&req);
1249              }
1250#endif /* LIBWRAP */
1251              break;
1252            }
1253          else
1254            {
1255              /* Normal production daemon.  Fork, and have the child process
1256                 the connection.  The parent continues listening. */
1257              if ((pid = fork()) == 0)
1258                {
1259                  /* Child.  Close the listening socket, and start using
1260                     the accepted socket.  Reinitialize logging (since our
1261                     pid has changed).  We break out of the loop to handle
1262                     the connection. */
1263                  close(listen_sock);
1264                  sock_in = newsock;
1265                  sock_out = newsock;
1266#ifdef LIBWRAP
1267                  {
1268                    struct request_info req;
1269                   
1270                    signal(SIGCHLD, SIG_DFL);
1271                   
1272                    request_init(&req, RQ_DAEMON, av0, RQ_FILE, newsock, NULL);
1273                    fromhost(&req);
1274                    if (!hosts_access(&req) || !enabled)
1275                      refuse(&req);
1276                  }
1277#endif /* LIBWRAP */
1278
1279                  log_init(av0, debug_flag && !inetd_flag,
1280                           options.fascist_logging || debug_flag,
1281                           options.quiet_mode, options.log_facility);
1282                  break;
1283                }
1284            }
1285
1286          /* Parent.  Stay in the loop. */
1287          if (pid < 0)
1288            error("fork: %.100s", strerror(errno));
1289          else
1290            debug("Forked child %d.", pid);
1291
1292          /* Mark that the key has been used (it was "given" to the child). */
1293          key_used = 1;
1294
1295          random_acquire_light_environmental_noise(&sensitive_data.
1296                                                   random_state);
1297         
1298          /* Close the new socket (the child is now taking care of it). */
1299          close(newsock);
1300        }
1301    }
1302 
1303  /* This is the child processing a new connection. */
1304
1305  /* Disable the key regeneration alarm.  We will not regenerate the key
1306     since we are no longer in a position to give it to anyone.  We will
1307     not restart on SIGHUP since it no longer makes sense. */
1308  alarm(0);
1309  signal(SIGALRM, SIG_DFL);
1310  signal(SIGHUP, SIG_DFL);
1311  signal(SIGTERM, SIG_DFL);
1312  signal(SIGQUIT, SIG_DFL);
1313  signal(SIGCHLD, SIG_DFL);
1314
1315  /* Set socket options for the connection.  We want the socket to close
1316     as fast as possible without waiting for anything.  If the connection
1317     is not a socket, these will do nothing. */
1318  /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */
1319#if defined(SO_LINGER) && defined(ENABLE_SO_LINGER)
1320  linger.l_onoff = 1;
1321  linger.l_linger = 15;
1322  setsockopt(sock_in, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger));
1323#endif /* SO_LINGER */
1324
1325  /* Register our connection.  This turns encryption off because we do not
1326     have a key. */
1327  packet_set_connection(sock_in, sock_out, &sensitive_data.random_state);
1328
1329  /* Log the connection. */
1330  log_msg("Connection from %.100s port %d",
1331      get_remote_ipaddr(), get_remote_port());
1332
1333  /* Check whether logins are denied from this host. */
1334  {
1335    const char *hostname = get_canonical_hostname();
1336    const char *ipaddr = get_remote_ipaddr();
1337    int i;
1338    if (options.num_deny_hosts > 0)
1339      {
1340        for (i = 0; i < options.num_deny_hosts; i++)
1341          if (match_host(hostname, ipaddr, options.deny_hosts[i]))
1342            perm_denied = 1;
1343      }
1344    if ((!perm_denied) && options.num_allow_hosts > 0)
1345      {
1346        for (i = 0; i < options.num_allow_hosts; i++)
1347          if (match_host(hostname, ipaddr, options.allow_hosts[i]))
1348            break;
1349        if (i >= options.num_allow_hosts)
1350          perm_denied = 1;
1351      }
1352    if (perm_denied && options.silent_deny)
1353      {
1354        close(sock_in);
1355        close(sock_out);
1356        exit(0);
1357      }
1358  }
1359
1360  /* We don\'t want to listen forever unless the other side successfully
1361     authenticates itself.  So we set up an alarm which is cleared after
1362     successful authentication.  A limit of zero indicates no limit.
1363     Note that we don\'t set the alarm in debugging mode; it is just annoying
1364     to have the server exit just when you are about to discover the bug. */
1365  signal(SIGALRM, grace_alarm_handler);
1366  if (!debug_flag)
1367    alarm(options.login_grace_time);
1368
1369 
1370  if (ssh_remote_version_string == NULL)
1371    {
1372      /* Send our protocol version identification. */
1373      sprintf(buf, "SSH-%d.%d-%.50s",
1374              PROTOCOL_MAJOR, PROTOCOL_MINOR, SSH_VERSION);
1375#ifdef F_SECURE_COMMERCIAL
1376
1377#endif /* F_SECURE_COMMERCIAL */
1378      strcat(buf, "\n");
1379      if (write(sock_out, buf, strlen(buf)) != strlen(buf))
1380        fatal_severity(SYSLOG_SEVERITY_INFO,
1381                       "Could not write ident string.");
1382    }
1383
1384  if (ssh_remote_version_string == NULL)
1385    {
1386      /* Read other side\'s version identification. */
1387      for (i = 0; i < sizeof(buf) - 1; i++)
1388        {
1389          if (read(sock_in, &buf[i], 1) != 1)
1390            fatal_severity(SYSLOG_SEVERITY_INFO,
1391                           "Did not receive ident string.");
1392          if (buf[i] == '\r')
1393            {
1394              buf[i] = '\n';
1395              buf[i + 1] = 0;
1396              break;
1397            }
1398          if (buf[i] == '\n')
1399            {
1400              /* buf[i] == '\n' */
1401              buf[i + 1] = 0;
1402              break;
1403            }
1404        }
1405      buf[sizeof(buf) - 1] = 0;
1406    }
1407  else
1408    {
1409      strncpy(buf, ssh_remote_version_string, sizeof(buf) - 1);
1410      buf[sizeof(buf) - 1] = 0;
1411    }
1412 
1413  /* Check that the versions match.  In future this might accept several
1414     versions and set appropriate flags to handle them. */
1415  if (sscanf(buf, "SSH-%d.%d-%[^\n]\n", &remote_major, &remote_minor,
1416             remote_version) != 3)
1417    {
1418      const char *s = "Protocol mismatch.\n";
1419      (void) write(sock_out, s, strlen(s));
1420      close(sock_in);
1421      close(sock_out);
1422      fatal_severity(SYSLOG_SEVERITY_INFO,
1423                     "Bad protocol version identification: %.100s", buf);
1424    }
1425  debug("Client protocol version %d.%d; client software version %.100s",
1426        remote_major, remote_minor, remote_version);
1427
1428  switch (check_emulation(remote_major, remote_minor,
1429                          NULL, NULL))
1430    {
1431    case EMULATE_MAJOR_VERSION_MISMATCH:
1432      {
1433        const char *s = "Protocol major versions differ.\n";
1434        (void) write(sock_out, s, strlen(s));
1435        close(sock_in);
1436        close(sock_out);
1437        fatal_severity(SYSLOG_SEVERITY_INFO,
1438                       "Protocol major versions differ: %d vs. %d",
1439                       PROTOCOL_MAJOR, remote_major);
1440      }
1441      break;
1442    case EMULATE_VERSION_TOO_OLD:
1443      packet_disconnect("Your ssh version is too old and is no "
1444                        "longer supported.  Please install a newer version.");
1445      break;
1446    case EMULATE_VERSION_NEWER:
1447      packet_disconnect("This server does not support your "
1448                        "new ssh version.");
1449      break;
1450    case EMULATE_VERSION_OK:
1451      break;
1452    default:
1453      fatal("Unexpected return value from check_emulation.");
1454    }
1455
1456  if (perm_denied)
1457    {
1458      const char *hostname = get_canonical_hostname();
1459     
1460      log_msg("Connection from %.200s not allowed.\n", hostname);
1461      packet_disconnect("Sorry, you are not allowed to connect.");
1462      /*NOTREACHED*/
1463    }
1464
1465  packet_set_nonblocking();
1466 
1467  /* Handle the connection.   We pass as argument whether the connection
1468     came from a privileged port. */
1469  do_connection(get_remote_port() < 1024);
1470
1471  /* Try to remove authentication socket and directory */
1472  auth_delete_socket(NULL);
1473 
1474  /* The connection has been terminated. */
1475  log_msg("Closing connection to %.100s", get_remote_ipaddr());
1476  packet_close();
1477  exit(0);
1478}
1479
1480/* Process an incoming connection.  Protocol version identifiers have already
1481   been exchanged.  This sends server key and performs the key exchange.
1482   Server and host keys will no longer be needed after this functions. */
1483
1484void do_connection(int privileged_port)
1485{
1486  int i;
1487  MP_INT session_key_int;
1488  unsigned char session_key[SSH_SESSION_KEY_LENGTH];
1489  unsigned char check_bytes[8];
1490  char *user;
1491  unsigned int cipher_type, auth_mask, protocol_flags;
1492
1493  /* Generate check bytes that the client must send back in the user packet
1494     in order for it to be accepted; this is used to defy ip spoofing
1495     attacks.  Note that this only works against somebody doing IP spoofing
1496     from a remote machine; any machine on the local network can still see
1497     outgoing packets and catch the random cookie.  This only affects
1498     rhosts authentication, and this is one of the reasons why it is
1499     inherently insecure. */
1500  for (i = 0; i < 8; i++)
1501    check_bytes[i] = random_get_byte(&sensitive_data.random_state);
1502 
1503  /* Send our public key.  We include in the packet 64 bits of random
1504     data that must be matched in the reply in order to prevent IP spoofing. */
1505  packet_start(SSH_SMSG_PUBLIC_KEY);
1506  for (i = 0; i < 8; i++)
1507    packet_put_char(check_bytes[i]);
1508
1509  /* Store our public server RSA key. */
1510  packet_put_int(public_key.bits);
1511  packet_put_mp_int(&public_key.e);
1512  packet_put_mp_int(&public_key.n);
1513
1514  /* Store our public host RSA key. */
1515  packet_put_int(sensitive_data.host_key.bits);
1516  packet_put_mp_int(&sensitive_data.host_key.e);
1517  packet_put_mp_int(&sensitive_data.host_key.n);
1518
1519  /* Put protocol flags. */
1520  packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);
1521
1522  /* Declare which ciphers we support. */
1523  packet_put_int(cipher_mask());
1524
1525  /* Declare supported authentication types. */
1526  auth_mask = 0;
1527  if (options.rhosts_authentication)
1528    auth_mask |= 1 << SSH_AUTH_RHOSTS;
1529  if (options.rhosts_rsa_authentication)
1530    auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
1531  if (options.rsa_authentication)
1532    auth_mask |= 1 << SSH_AUTH_RSA;
1533#ifdef HAVE_TIS
1534  if (options.tis_authentication)
1535    auth_mask |= 1 << SSH_AUTH_TIS;
1536#endif
1537#ifdef KERBEROS
1538#ifdef KRB5
1539  if (options.kerberos_authentication)
1540    auth_mask |= 1 << SSH_AUTH_KERBEROS;
1541#endif
1542#endif
1543#ifdef KERBEROS_TGT_PASSING
1544#ifdef KRB5
1545  if (options.kerberos_tgt_passing)
1546    auth_mask |= 1 << SSH_PASS_KERBEROS_TGT;
1547#endif
1548#endif
1549  if (options.password_authentication)
1550    auth_mask |= 1 << SSH_AUTH_PASSWORD;
1551  packet_put_int(auth_mask);
1552
1553  /* Send the packet and wait for it to be sent. */
1554  packet_send();
1555  packet_write_wait();
1556
1557  debug("Sent %d bit public key and %d bit host key.",
1558        public_key.bits, sensitive_data.host_key.bits);
1559
1560  /* Read clients reply (cipher type and session key). */
1561  packet_read_expect(SSH_CMSG_SESSION_KEY);
1562
1563  /* Get cipher type. */
1564  cipher_type = packet_get_char();
1565
1566  /* Get check bytes from the packet.  These must match those we sent earlier
1567     with the public key packet. */
1568  for (i = 0; i < 8; i++)
1569    if (check_bytes[i] != packet_get_char())
1570      packet_disconnect("IP Spoofing check bytes do not match.");
1571
1572  debug("Encryption type: %.200s", cipher_name(cipher_type));
1573
1574  /* Get the encrypted integer. */
1575  mpz_init(&session_key_int);
1576  packet_get_mp_int(&session_key_int);
1577
1578  /* Get protocol flags. */
1579  protocol_flags = packet_get_int();
1580  packet_set_protocol_flags(protocol_flags);
1581
1582  /* Decrypt it using our private server key and private host key (key with
1583     larger modulus first). */
1584  if (mpz_cmp(&sensitive_data.private_key.n, &sensitive_data.host_key.n) > 0)
1585    {
1586      /* Private key has bigger modulus. */
1587      assert(sensitive_data.private_key.bits >=
1588             sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED);
1589      rsa_private_decrypt(&session_key_int, &session_key_int,
1590                          &sensitive_data.private_key);
1591      rsa_private_decrypt(&session_key_int, &session_key_int,
1592                          &sensitive_data.host_key);
1593    }
1594  else
1595    {
1596      /* Host key has bigger modulus (or they are equal). */
1597      assert(sensitive_data.host_key.bits >=
1598             sensitive_data.private_key.bits + SSH_KEY_BITS_RESERVED);
1599      rsa_private_decrypt(&session_key_int, &session_key_int,
1600                          &sensitive_data.host_key);
1601      rsa_private_decrypt(&session_key_int, &session_key_int,
1602                          &sensitive_data.private_key);
1603    }
1604
1605  /* Compute session id for this session. */
1606  compute_session_id(session_id, check_bytes, sensitive_data.host_key.bits,
1607                     &sensitive_data.host_key.n,
1608                     sensitive_data.private_key.bits,
1609                     &sensitive_data.private_key.n);
1610
1611  /* Extract session key from the decrypted integer.  The key is in the
1612     least significant 256 bits of the integer; the first byte of the
1613     key is in the highest bits. */
1614  mp_linearize_msb_first(session_key, sizeof(session_key),
1615                         &session_key_int);
1616 
1617  /* Xor the first 16 bytes of the session key with the session id. */
1618  for (i = 0; i < 16; i++)
1619    session_key[i] ^= session_id[i];
1620
1621  /* Destroy the decrypted integer.  It is no longer needed. */
1622  mpz_clear(&session_key_int);
1623 
1624  /* Set the session key.  From this on all communications will be
1625     encrypted. */
1626  packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH,
1627                            cipher_type, 0);
1628 
1629  /* Destroy our copy of the session key.  It is no longer needed. */
1630  memset(session_key, 0, sizeof(session_key));
1631
1632  debug("Received session key; encryption turned on.");
1633
1634  /* Send an acknowledgement packet.  Note that this packet is sent
1635     encrypted. */
1636  packet_start(SSH_SMSG_SUCCESS);
1637  packet_send();
1638  packet_write_wait();
1639
1640  /* Get the name of the user that we wish to log in as. */
1641  packet_read_expect(SSH_CMSG_USER);
1642
1643  /* Get the user name. */
1644  user = packet_get_string(NULL);
1645
1646  /* Destroy the private and public keys.  They will no longer be needed. */
1647  rsa_clear_public_key(&public_key);
1648  rsa_clear_private_key(&sensitive_data.private_key);
1649  rsa_clear_private_key(&sensitive_data.host_key);
1650
1651  /* Do the authentication. */
1652  do_authentication(user, privileged_port, cipher_type);
1653}
1654
1655/* Returns true if logging in as the specified user is permitted.  Returns
1656   false if login is not permitted (e.g., the account is expired). */
1657
1658int login_permitted(char *user, struct passwd *pwd)
1659{
1660  char passwd[6];               /* Only for account lock check */
1661  struct group *grp;
1662  char *group;
1663 
1664  strncpy(passwd, pwd->pw_passwd, sizeof(passwd));
1665  passwd[sizeof(passwd) - 1] = '\0';
1666#ifdef HAVE_USERSEC_H
1667  {
1668    char *expiration, current_time[100], normalized[100];
1669    int rlogin_permitted;
1670    time_t t;
1671    struct tm *tm;
1672    if (setuserdb(S_READ) < 0)
1673      {
1674        debug("setuserdb S_READ failed: %.200s.", strerror(errno));
1675        return 0;
1676      }
1677    if (getuserattr(user, S_RLOGINCHK, &rlogin_permitted, SEC_BOOL) < 0)
1678      {
1679        debug("getuserattr S_RLOGINCHK failed: %.200s", strerror(errno));
1680        enduserdb();
1681        return 0;
1682      }
1683    if (getuserattr(user, S_EXPIRATION, &expiration, SEC_CHAR) < 0)
1684      {
1685        debug("getuserattr S_EXPIRATION failed: %.200s.", strerror(errno));
1686        enduserdb();
1687        return 0;
1688      }
1689    if (!rlogin_permitted)
1690      {
1691        debug("Remote logins to account %.100s not permitted by user profile.",
1692              user);
1693        enduserdb();
1694        return 0;
1695      }
1696    if (strcmp(expiration, "0") == 0)
1697      {
1698        /* The account does not expire - return success immediately. */
1699        enduserdb();
1700        return 1;
1701      }
1702    if (strlen(expiration) != 10)
1703      {
1704        debug("Account %.100s expiration date is in wrong format.", user);
1705        enduserdb();
1706        return 0;
1707      }
1708    t = time(NULL);
1709    tm = localtime(&t);
1710    sprintf(current_time, "%04d%02d%02d%02d%02d",
1711            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
1712            tm->tm_hour, tm->tm_min);
1713    if (expiration[8] < '7') /* Assume year < 70 is 20YY. */
1714      strcpy(normalized, "20");
1715    else
1716      strcpy(normalized, "19");
1717    strcat(normalized, expiration + 8);
1718    strcat(normalized, expiration);
1719    normalized[12] = '\0';
1720    if (strcmp(normalized, current_time) < 0)
1721      {
1722        debug("Account %.100s has expired - access denied.", user);
1723        enduserdb();
1724        return 0;
1725      }
1726    enduserdb();
1727    /* XXX No days_before_password_expires calculation here */
1728  }
1729#endif /* HAVE_USERSEC_H */
1730#ifdef HAVE_ETC_SHADOW
1731  {
1732    struct spwd *sp;
1733   
1734    sp = getspnam(user);
1735#if defined(SECURE_RPC) && defined(NIS_PLUS)
1736    if (geteuid() == UID_ROOT && pwd->pw_uid != UID_ROOT /* do we have guts? */
1737        && (!sp || !sp->sp_pwdp || !strcmp(sp->sp_pwdp,"*NP*")))
1738      {
1739        if (seteuid(pwd->pw_uid) == UID_ROOT)
1740          {
1741            sp = getspnam(user); /* retry as user */
1742            seteuid(UID_ROOT);
1743          }
1744      }
1745#endif /* SECURE_RPC && NIS_PLUS */
1746    if (!sp)
1747      {
1748        /*
1749         * Some systems, e.g.: IRIX, may or may not have /etc/shadow.
1750         * Just check if there is one. If such system is also an YP
1751         * client, then valid password might already be present in passwd
1752         * structure. Just check if it's other than "x". Assume that
1753         * YP server is always right if this is the case.
1754         *                                      appro@fy.chalmers.se
1755         */
1756        struct stat sbf;
1757       
1758        if ((stat(SHADOW, &sbf) == 0) && !strcmp(pwd->pw_passwd,"x"))
1759          {
1760            debug("Can't find %.100s's shadow - access denied.", user);
1761            endspent();
1762            return 0;
1763          }
1764      }
1765    else
1766      {
1767        time_t today = time((time_t *)NULL)/24/60/60; /* what a day! */
1768
1769#ifdef HAVE_STRUCT_SPWD_EXPIRE
1770        /* Check for expiration date */
1771        if (sp->sp_expire > 0 && today > sp->sp_expire)
1772          {
1773            debug("Account %.100s has expired - access denied.", user);
1774            endspent();
1775            return 0;
1776          }
1777        if (sp->sp_expire > 0)
1778          {
1779            days_before_account_expires = sp->sp_expire - today;
1780          }
1781#endif
1782       
1783#ifdef HAVE_STRUCT_SPWD_INACT
1784        /* Check for last login */
1785        if (sp->sp_inact > 0)
1786          {
1787            char buf[64];
1788            unsigned long llt;
1789           
1790            llt = get_last_login_time(pwd->pw_uid, user, buf, sizeof(buf));
1791            if (llt && (today - llt/24/60/60) > sp->sp_inact)
1792              {
1793                debug("Account %.100s was inactive for more than %d days.",
1794                      user, sp->sp_inact);
1795                endspent();
1796                return 0;
1797              }
1798          }
1799#endif
1800       
1801        /* Check if password is valid */
1802        if (sp->sp_lstchg == 0 ||
1803            (sp->sp_max > 0 && today > sp->sp_lstchg + sp->sp_max))
1804          {
1805            debug("Account %.100s's password is too old - forced to change.",
1806                  user);
1807            if (options.forced_passwd_change)
1808              {
1809                forced_command = xmalloc(sizeof(PASSWD_PATH) +
1810                                         strlen(user) + 1);
1811                sprintf(forced_command, "%s %s", PASSWD_PATH, user);
1812              }
1813            else
1814              {
1815                endspent();
1816                return 0;
1817              }
1818          }
1819        else
1820          {
1821            if (sp->sp_max > 0)
1822              {
1823                days_before_password_expires =
1824                  sp->sp_lstchg + sp->sp_max - today;
1825              }
1826          }
1827        strncpy(passwd, sp->sp_pwdp, sizeof(passwd));
1828        passwd[sizeof(passwd) - 1] = '\0';
1829      }
1830    endspent();
1831  }
1832#endif /* HAVE_ETC_SHADOW */
1833#ifdef __FreeBSD__
1834  {
1835    time_t currtime;
1836   
1837    if (pwd->pw_change || pwd->pw_expire)
1838      currtime = time(NULL);
1839   
1840    /*
1841     * Check for an expired password
1842     */
1843    if (pwd->pw_change && pwd->pw_change <= currtime)
1844      {
1845        debug("Account %.100s's password is too old - forced to change.",
1846              user);
1847        if (options.forced_passwd_change)
1848          {
1849            forced_command = xmalloc(sizeof(PASSWD_PATH) + strlen(user) + 1);
1850            sprintf(forced_command, "%s %s", PASSWD_PATH, user);
1851          }
1852        else
1853          {
1854            return 0;
1855          }
1856      }
1857    else
1858      {
1859        if (pwd->pw_change)
1860          {
1861            days_before_password_expires = (pwd->pw_change - currtime) / 86400;
1862          }
1863      }
1864   
1865    /*
1866     * Check for expired account
1867     */
1868    if (pwd->pw_expire && pwd->pw_expire <= currtime)
1869      {
1870        debug("Account %.100s has expired - access denied.", user);
1871        return 0;
1872      }
1873    else
1874      {
1875        if (pwd->pw_expire)
1876          {
1877            days_before_account_expires = (pwd->pw_expire - currtime) / 86400;
1878          }
1879      }
1880  }
1881#endif  /* !FreeBSD */
1882
1883#ifdef HAVE_HPUX_TCB_AUTH
1884  {
1885    struct pr_passwd *pr;
1886    time_t expire, warntime;
1887    short  tries;
1888   
1889    pr = getprpwnam(user);
1890    if (pr)
1891      {
1892        /*
1893         * Check whether lock field exists & is set, if so
1894         * deny the user access
1895         */
1896        if ( pr->uflg.fg_lock && pr->ufld.fd_lock )
1897          {
1898            debug("Account %.100s is locked.",user);
1899            packet_send_debug("\n\tAdministrative lock on account");
1900            endprpwent();
1901            return 0;
1902          }
1903        /*
1904         * Check whether account lifetime exceeded, if so
1905         * deny the user access
1906         */
1907        if ( pr->uflg.fg_acct_expire && time(NULL) > pr->ufld.fd_acct_expire )
1908          {
1909            debug("Account %.100s lifetime exceeded.", user);
1910            packet_send_debug("\n\tAccount lifetime exceeded");
1911            endprpwent();
1912            return 0;
1913          }
1914        /*
1915         * Check whether pw_admin_num is set, if so
1916         * force passwd change.
1917         */
1918        if ( pr->uflg.fg_pw_admin_num && pr->ufld.fd_pw_admin_num )
1919          {
1920            debug("Account %.100s requires passwd change",user);
1921            if (options.forced_passwd_change)
1922              {
1923                forced_command = xmalloc(sizeof(PASSWD_PATH) +
1924                                         strlen(user) + 1);
1925                sprintf(forced_command, "%s %s", PASSWD_PATH, user);
1926                options.permit_empty_passwd = 1;
1927              }
1928            else
1929              {
1930                endprpwent();
1931                return 0;
1932              }
1933          }
1934        /*
1935        * Check whether passwd aging is enabled for this user
1936        * (either explicitly, i.e., flag set and value != 0, or
1937        * system wide, sys flag set and sys value != 0).  A user
1938        * flag set and value == 0 means passwd aging explicitly
1939        * disabled for this user.  If passwd expired, force
1940        * passwd change.
1941        */
1942        if ( pr->uflg.fg_expire )
1943          expire = pr->ufld.fd_expire;
1944        else if ( pr->sflg.fg_expire )
1945          expire = pr->sfld.fd_expire;
1946        else
1947          expire = 0;
1948        if ( expire )
1949          {
1950            days_before_password_expires = expire / 86400;
1951            if ( pr->uflg.fg_pw_expire_warning )
1952              warntime = pr->ufld.fd_pw_expire_warning;
1953            else if ( pr->sflg.fg_pw_expire_warning )
1954              warntime = pr->sfld.fd_pw_expire_warning;
1955            else
1956              warntime = 7*24*60*60; /* default to 7 days warning */
1957            if ( time(NULL) > pr->ufld.fd_schange + expire )
1958              {
1959                debug("Account %.100s passwd expired, requires change", user);
1960                if (options.forced_passwd_change)
1961                  {
1962                    forced_command = xmalloc(sizeof(PASSWD_PATH) +
1963                                             strlen(user) + 1);
1964                    sprintf(forced_command, "%s %s", PASSWD_PATH, user);
1965                  }
1966                else
1967                  {
1968                    endprpwent();
1969                    return 0;
1970                  }
1971              }
1972          }
1973        /*
1974         * Check for inactivity.  If set to disable inactive accounts,
1975         * then we must deny access if inactive for said period of time.
1976         */
1977        if ( pr->uflg.fg_max_llogin )
1978          expire = pr->ufld.fd_max_llogin;
1979        else if ( pr->sflg.fg_max_llogin )
1980          expire = pr->sfld.fd_max_llogin;
1981        else
1982          expire = 0;
1983        if ( expire && pr->ufld.fd_slogin
1984             && time(NULL) > pr->ufld.fd_slogin + expire )
1985          {
1986            debug("Account %.100s locked due to inactivity.", user);
1987            packet_send_debug("\n\tAccount locked due to inactivity");
1988            endprpwent();
1989            return 0;
1990          }
1991        /*
1992         * If configured to lock on too many unsuccessful login attempts,
1993         * then check and deny access
1994         */
1995        if ( pr->uflg.fg_max_tries )
1996          tries = pr->ufld.fd_max_tries;
1997        else if ( pr->sflg.fg_max_tries )
1998          tries = pr->sfld.fd_max_tries;
1999        else
2000          tries = 0;
2001        if ( tries &&  pr->ufld.fd_nlogins > tries )
2002          {
2003            debug("Account %.100s locked, too many unsuccessful login attempts",
2004                  user);
2005            packet_send_debug("\n\tToo many unsuccessful attempts");
2006            endprpwent();
2007            return 0;
2008          }
2009      }
2010    endprpwent();
2011  }
2012#endif /* HAVE_HPUX_TCB_AUTH */ 
2013
2014  /*
2015   * Check if account is locked. Check if encrypted password starts
2016   * with "*LK*".
2017   */
2018  {
2019    if ((strncmp(passwd,"*LK*", 4) == 0)
2020#if defined(KERBEROS) && defined(KRB5)
2021        && (options.kerberos_or_local_passwd != 0)
2022#endif /* defined(KERBEROS) && defined(KRB5) */
2023        )
2024      {
2025        debug("Account %.100s is locked.", user);
2026        return 0;
2027      }
2028  }
2029#ifdef CHECK_ETC_SHELLS
2030  {
2031    int  invalid = 1;
2032    char *shell = pwd->pw_shell, *etc_shell, *getusershell();
2033   
2034    if (!shell || !*shell)
2035      shell = DEFAULT_SHELL;
2036   
2037    while (invalid && (etc_shell = getusershell()))
2038      invalid = strcmp(etc_shell,shell);
2039    endusershell();
2040   
2041    if (invalid)
2042      {
2043        debug("Account %.100s doesn't have valid shell", user);
2044        return 0;
2045      }
2046  }
2047#endif /* CHECK_ETC_SHELLS */
2048 
2049  /* here we check the AllowUser and DenyUser config options - SteveK */
2050  /* Check whether logins are permitted for this user. */
2051  if (options.num_allow_users > 0)
2052    {
2053      int i;
2054      const char *hostname = get_canonical_hostname();
2055      const char *ipaddr = get_remote_ipaddr();
2056     
2057      for (i = 0; i < options.num_allow_users; i++)
2058        if (match_user(user, hostname, ipaddr, options.allow_users[i]))
2059          break;
2060      if (i >= options.num_allow_users)
2061        {
2062          log_msg("Connection for %.200s not allowed from %s\n",
2063                  user, get_canonical_hostname());
2064          return 0;
2065        }
2066    }
2067 
2068  /* Check whether logins are denied for this user. */
2069  if (options.num_deny_users > 0)
2070    {
2071      int i;
2072      const char *hostname = get_canonical_hostname();
2073      const char *ipaddr = get_remote_ipaddr();
2074     
2075      for (i = 0; i < options.num_deny_users; i++)
2076        if (match_user(user, hostname, ipaddr, options.deny_users[i]))
2077          {
2078            log_msg("Connection for %.200s denied from %s\n",
2079                    user, get_canonical_hostname());
2080            return 0;
2081          }
2082    }
2083 
2084  /* Check whether logins are deneid for this group. */
2085  grp = getgrgid(pwd->pw_gid);
2086  if (grp)
2087    group = grp->gr_name;
2088  else
2089    {
2090      log_msg("Unknown group id %d\n", pwd->pw_gid);
2091      group = "none";
2092    }
2093 
2094  if (options.num_allow_groups > 0)
2095    {
2096      int i;
2097      for (i = 0; i < options.num_allow_groups; i++)
2098        if (match_pattern(group, options.allow_groups[i]))
2099          break;
2100      if (grp == NULL || i >= options.num_allow_groups)
2101        {
2102          log_msg("Connection for %.200s not allowed from %s\n",
2103                  group, get_canonical_hostname());
2104          return 0;
2105        }
2106    }
2107 
2108  /* Check whether logins are denied for this group. */
2109  if (options.num_deny_groups > 0)
2110    {
2111      int i;
2112      for (i = 0; i < options.num_deny_groups; i++)
2113        if (grp && match_pattern(group, options.deny_groups[i]))
2114          {
2115            log_msg("Connection for %.200s denied from %s\n",
2116                    group, get_canonical_hostname());
2117            return 0;
2118          }
2119    }
2120 
2121  return 1;
2122}
2123
2124/* This function is called by userfile_init after fork() to clean up sensitive
2125   data.  RSA keys have already been destroyed before we get here.  However,
2126   normal encryption keys and socket connections (access rights) need to
2127   be destroyed. */
2128
2129static void sshd_userfile_cleanup(void *context)
2130{
2131  endpwent();
2132
2133  /* Close the connection descriptors; note that this is the child, and the
2134     server will still have the socket open, and it is important that we
2135     do not shutdown it.  Note that the descriptors cannot be closed before
2136     building the environment, as we call get_remote_ipaddr there. */
2137  if (packet_get_connection_in() == packet_get_connection_out())
2138    close(packet_get_connection_in());
2139  else
2140    {
2141      close(packet_get_connection_in());
2142      close(packet_get_connection_out());
2143    }
2144  /* Close all descriptors related to channels.  They will still remain
2145     open in the parent. */
2146  channel_close_all();
2147
2148  /* Set dummy encryption key to clear key data from memory.  This key will
2149     never be used. */
2150  packet_set_encryption_key((void *)"0123456789ABCDEF0123456789ABCDEF",
2151                            16, SSH_CIPHER_3DES, 0);
2152}
2153
2154/* Fails all authentication requests */
2155void do_authentication_fail_loop(void)
2156{
2157  /* The user does not exist. */
2158  packet_start(SSH_SMSG_FAILURE);
2159  packet_send();
2160  packet_write_wait();
2161 
2162  /* Keep reading packets, and always respond with a failure.  This is to
2163     avoid disclosing whether such a user really exists. */
2164  for (;;)
2165    {
2166      /* Read a packet.  This will not return if the client disconnects. */
2167      (void) packet_read();
2168      packet_get_all();
2169     
2170      /* Send failure.  This should be indistinguishable from a failed
2171         authentication. */
2172      packet_start(SSH_SMSG_FAILURE);
2173      packet_send();
2174      packet_write_wait();
2175    }
2176  /*NOTREACHED*/
2177  abort();
2178}
2179
2180/* Performs authentication of an incoming connection.  Session key has already
2181   been exchanged and encryption is enabled.  User is the user name to log
2182   in as (received from the clinet).  Privileged_port is true if the
2183   connection comes from a privileged port (used for .rhosts authentication).*/
2184
2185void do_authentication(char *user, int privileged_port, int cipher_type)
2186{
2187  int type;
2188  int authenticated = 0;
2189  int authentication_type = 0;
2190  char *password;
2191  struct passwd *pw, *pw2, pwcopy;
2192  char *client_user;
2193  unsigned int client_host_key_bits;
2194  MP_INT client_host_key_e, client_host_key_n;
2195  int password_attempts = 0;
2196#if defined(KERBEROS) && defined(KRB5)
2197  char kuser[128];
2198  krb5_principal client = 0, tkt_client = 0;
2199  krb5_data krb5data;
2200#endif /* defined(KERBEROS) && defined(KRB5) */
2201#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
2202  login_cap_t *lc;
2203  const char *hostname;
2204  const char *ipaddr;
2205  char *cap_hlist, *hp;
2206  int perm_denied = 0;
2207 
2208  hostname = get_canonical_hostname();
2209  ipaddr = get_remote_ipaddr();
2210#endif /* HAVE_LOGIN_CAP_H */
2211  int status, i;
2212  char *filetext, *errmem;
2213  const char *err;
2214
2215  if (strlen(user) > 255)
2216    do_authentication_fail_loop();
2217
2218#if defined(KERBEROS) && defined(KRB5)
2219  /* For KRB5 allow the user to input fully qualified name i.e.
2220     "username@realm" as the local user name. Then use this name to call
2221     out to krb5_aname_to_localname to find if there is a localname
2222     for this user. By doing this local names do not have to match
2223     kerberos network names. This comes in handy when doing cross realm
2224     authentication, or when you want auth_password to authenticate
2225     to the users local realm.  Pass client down to auth_password(),
2226     auth_kerberos() and auth_kerberos_tgt() */
2227 
2228  if (!ssh_context)
2229    {
2230      krb5_error_code r;
2231     
2232      if ((r = krb5_init_context(&ssh_context)))
2233        fatal("Kerberos V5: %s while initializing krb5.",
2234              error_message(r));
2235      krb5_init_ets(ssh_context);
2236    }
2237  debug("Connection attempt for %.100s from %s.", user,
2238        get_canonical_hostname());
2239 
2240  if (strchr(user,'@') || strchr(user,'%'))
2241    {
2242      if (strchr(user,'%'))
2243        *strchr(user,'%') = '@';
2244      krb5_parse_name(ssh_context, user, &client);
2245      if (!(krb5_aname_to_localname(ssh_context, client,
2246                                    sizeof(kuser), kuser)))
2247        user = kuser;
2248    }
2249  else
2250    krb5_parse_name(ssh_context, user, &client);
2251#endif /* defined(KERBEROS) && defined(KRB5) */
2252                         
2253  /* Verify that the user is a valid user.  We disallow usernames starting
2254     with any characters that are commonly used to start NIS entries. */
2255  status = al_login_allowed(user, 1, &al_local_acct, &filetext);
2256  if (status != AL_SUCCESS)
2257    {
2258      /* We don't want to use `packet_disconnect', because it will syslog
2259         at LOG_ERR. Ssh doesn't provide a primitive way to give an
2260         informative message and disconnect without any bad feelings... */
2261
2262      char *buf;
2263
2264      err = al_strerror(status, &errmem);
2265      if (filetext && *filetext)
2266        {
2267          buf = xmalloc(40 + strlen(err) + strlen(filetext));
2268          sprintf(buf, "You are not allowed to log in here: %s\n%s",
2269                  err, filetext);
2270        }
2271      else
2272        {
2273          buf = xmalloc(40 + strlen(err));
2274          sprintf(buf, "You are not allowed to log in here: %s\n", err);
2275        }
2276      packet_start(SSH_MSG_DISCONNECT);
2277      packet_put_string(buf, strlen(buf));
2278      packet_send();
2279      packet_write_wait();
2280
2281      fatal_severity(SYSLOG_SEVERITY_INFO, "Login denied: %s", err);
2282      /* not reached */
2283    }
2284  if (!al_local_acct)
2285    {
2286      status = al_acct_create(user, NULL, getpid(), 0, 0, NULL);
2287      if (status != AL_SUCCESS && debug_flag)
2288        {
2289          err = al_strerror(status, &errmem);
2290          debug("al_acct_create failed for user %s: %s", user, err);
2291          al_free_errmem(errmem);
2292        }
2293      al_user = xstrdup(user);
2294      atexit(al_cleanup);
2295    }
2296  pw = getpwnam(user);
2297
2298  if (!pw || user[0] == '-' || user[0] == '+' || user[0] == '@' ||
2299      !login_permitted(user, pw))
2300    do_authentication_fail_loop();
2301 
2302  /* Take a copy of the returned structure. */
2303  memset(&pwcopy, 0, sizeof(pwcopy));
2304  pwcopy.pw_name = xstrdup(pw->pw_name);
2305  pwcopy.pw_passwd = xstrdup(pw->pw_passwd);
2306  pwcopy.pw_uid = pw->pw_uid;
2307  pwcopy.pw_gid = pw->pw_gid;
2308#if (defined (__bsdi__) && _BSDI_VERSION >= 199510) || (defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H))
2309  pwcopy.pw_class = xstrdup(pw->pw_class);
2310  pwcopy.pw_change = pw->pw_change;
2311  pwcopy.pw_expire = pw->pw_expire;
2312#endif /*  __bsdi__  && _BSDI_VERSION >= 199510 */
2313  pwcopy.pw_dir = xstrdup(pw->pw_dir);
2314  pwcopy.pw_shell = xstrdup(pw->pw_shell);
2315  pw = &pwcopy;
2316
2317  /* Start a child process running on the user's uid.  It will be used to
2318     read files in the user's directory.  Note that the private host
2319     key has already been cleared when this is called.  We still want to
2320     clean up at least the encryption keys. */
2321  userfile_init(pw->pw_name, pw->pw_uid, pw->pw_gid,
2322                sshd_userfile_cleanup, NULL);
2323
2324  /* If we are not running as root, the user must have the same uid as the
2325     server. */
2326  if (getuid() != UID_ROOT && pw->pw_uid != getuid())
2327    packet_disconnect("Cannot change user when server not running as root.");
2328
2329  debug("Attempting authentication for %.100s.", user);
2330
2331#if defined (KERBEROS) && defined (KRB5)
2332  if (!options.kerberos_authentication && options.password_authentication &&
2333      auth_password(user, "", 0))
2334#else /* defined(KERBEROS) && defined(KRB5) */
2335  /* If the user has no password, accept authentication immediately. */
2336  if (options.password_authentication && auth_password(user, ""))
2337#endif /* defined(KERBEROS) && defined(KRB5) */
2338    {
2339      /* Authentication with empty password succeeded. */
2340      debug("Login for user %.100s accepted without authentication.", user);
2341      authentication_type = SSH_AUTH_PASSWORD;
2342      authenticated = 1;
2343      /* Success packet will be sent after loop below. */
2344    }
2345  else
2346    {
2347      /* Indicate that authentication is needed. */
2348      packet_start(SSH_SMSG_FAILURE);
2349      packet_send();
2350      packet_write_wait();
2351    }
2352
2353  /* Loop until the user has been authenticated or the connection is closed. */
2354  while (!authenticated)
2355    {
2356      /* Get a packet from the client. */
2357      type = packet_read();
2358     
2359      /* Process the packet. */
2360      switch (type)
2361        {
2362#ifdef KERBEROS_TGT_PASSING
2363#ifdef KRB5
2364        case SSH_CMSG_HAVE_KERBEROS_TGT:
2365          if (!options.kerberos_tgt_passing ||
2366              (!(options.kerberos_authentication ||
2367                 options.password_authentication ||
2368                 options.rsa_authentication)))
2369            {
2370              packet_get_all();
2371              log_msg("Kerberos tgt passing disabled.");
2372              break;
2373            }
2374         
2375          /* Accept Kerberos tgt. */
2376          krb5data.data = packet_get_string((unsigned int *) &krb5data.length);
2377         
2378          if (!auth_kerberos_tgt(user, &krb5data, client) ||
2379              !krb5_kuserok(ssh_context, client, user)){
2380            log_msg("Kerberos tgt REFUSED for %s", user);
2381            debug("Kerberos tgt REFUSED for %s", user);
2382          }
2383          free(krb5data.data);
2384#endif
2385          continue;
2386#endif /* KERBEROS_TGT_PASSING */
2387         
2388#ifdef KERBEROS
2389#ifdef KRB5
2390        case SSH_CMSG_AUTH_KERBEROS:
2391          if (!options.kerberos_authentication)
2392            {
2393              packet_get_all();
2394              log_msg("Kerberos authentication disabled.");
2395              break;
2396            }
2397          /* Try Kerberos authentication. */
2398          krb5data.data = packet_get_string((unsigned int *) &krb5data.length);
2399          if (auth_kerberos(user, &krb5data, &tkt_client))
2400            {
2401              char *tkt_user;
2402             
2403              free(krb5data.data);
2404              krb5_unparse_name(ssh_context, tkt_client, &tkt_user);
2405             
2406              /* Check ~/.klogin authorization now. */
2407              if (krb5_kuserok(ssh_context, tkt_client, user))
2408                {
2409                  if (client)
2410                    krb5_free_principal(ssh_context, client);
2411                  client = tkt_client;
2412                  /* Client has successfully authenticated to us. */
2413                  log_msg("Kerberos authentication accepted %.100s for login to account %.100s from %.200s",
2414                          tkt_user, user, get_canonical_hostname());
2415                  authentication_type = SSH_AUTH_KERBEROS;
2416                  authenticated = 1;
2417                  break;
2418                }
2419              else
2420                {
2421                  krb5_free_principal(ssh_context, tkt_client);
2422                  packet_send_debug("Kerberos authorization failed.");
2423                  log_msg( "Kerberos authorization failed for %.100s for login to account %.100s from %.200s.",
2424                           tkt_user, user, get_canonical_hostname());
2425                }
2426              free(tkt_user);
2427            }
2428#endif /* KRB5 */
2429          debug("Kerberos authentication failed for %.100s from %.200s",
2430                user, get_canonical_hostname());
2431          break;
2432#endif /* KERBEROS */
2433         
2434        case SSH_CMSG_AUTH_RHOSTS:
2435          if (!options.rhosts_authentication)
2436            {
2437              packet_get_all();
2438              log_msg("Rhosts authentication disabled.");
2439              break;
2440            }
2441
2442          /* Rhosts authentication (also uses /etc/hosts.equiv). */
2443          if (!privileged_port)
2444            {
2445              packet_get_all();
2446              log_msg("Rhosts authentication not available for connections from unprivileged port.");
2447              break;
2448            }
2449
2450          /* Get client user name.  Note that we just have to trust the client;
2451             this is one reason why rhosts authentication is insecure.
2452             (Another is IP-spoofing on a local network.) */
2453          client_user = packet_get_string(NULL);
2454
2455          /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
2456          if (auth_rhosts(pw, client_user, options.ignore_rhosts,
2457                          options.ignore_root_rhosts,
2458                          options.strict_modes))
2459            {
2460              /* Authentication accepted. */
2461              log_msg("Rhosts authentication accepted for %.100s, remote %.100s on %.700s.",
2462                  user, client_user, get_canonical_hostname());
2463              authentication_type = SSH_AUTH_RHOSTS;
2464              authenticated = 1;
2465              remote_user_name = client_user;
2466              break;
2467            }
2468          debug("Rhosts authentication failed for '%.100s', remote '%.100s', host '%.200s'.",
2469                user, client_user, get_canonical_hostname());
2470          xfree(client_user);
2471          break;
2472
2473        case SSH_CMSG_AUTH_RHOSTS_RSA:
2474          if (!options.rhosts_rsa_authentication)
2475            {
2476              packet_get_all();
2477              log_msg("Rhosts with RSA authentication disabled.");
2478              break;
2479            }
2480
2481          /* Rhosts authentication (also uses /etc/hosts.equiv) with RSA
2482             host authentication. */
2483          if (!privileged_port)
2484            {
2485              packet_get_all();
2486              log_msg("RhostsRsa authentication not available for connections from unprivileged port.");
2487              break;
2488            }
2489          if (cipher_type == SSH_CIPHER_NONE)
2490            {
2491              packet_get_all();
2492              log_msg("RhostsRsa authentication not available for unencrypted session.");
2493              break;
2494            }
2495          if (cipher_type == SSH_CIPHER_ARCFOUR)
2496            {
2497              packet_get_all();
2498              log_msg("RhostsRsa authentication not available for session encrypted with arcfour.");
2499              break;
2500            }
2501
2502          /* Get client user name.  Note that we just have to trust the client;
2503             root on the client machine can claim to be any user. */
2504          client_user = packet_get_string(NULL);
2505
2506          /* Get the client host key. */
2507          mpz_init(&client_host_key_e);
2508          mpz_init(&client_host_key_n);
2509          client_host_key_bits = packet_get_int();
2510          packet_get_mp_int(&client_host_key_e);
2511          packet_get_mp_int(&client_host_key_n);
2512
2513          /* Try to authenticate using /etc/hosts.equiv and .rhosts. */
2514          if (auth_rhosts_rsa(&sensitive_data.random_state,
2515                              pw, client_user,
2516                              client_host_key_bits, &client_host_key_e,
2517                              &client_host_key_n, options.ignore_rhosts,
2518                              options.ignore_root_rhosts,
2519                              options.strict_modes))
2520            {
2521              /* Authentication accepted. */
2522              authentication_type = SSH_AUTH_RHOSTS_RSA;
2523              authenticated = 1;
2524              remote_user_name = client_user;
2525              mpz_clear(&client_host_key_e);
2526              mpz_clear(&client_host_key_n);
2527              break;
2528            }
2529          debug("RhostsRSA authentication failed for '%.100s', remote '%.100s', host '%.200s'.",
2530                user, client_user, get_canonical_hostname());
2531          xfree(client_user);
2532          mpz_clear(&client_host_key_e);
2533          mpz_clear(&client_host_key_n);
2534          break;
2535         
2536        case SSH_CMSG_AUTH_RSA:
2537          if (!options.rsa_authentication)
2538            {
2539              packet_get_all();
2540              log_msg("RSA authentication disabled.");
2541              break;
2542            }
2543
2544          /* RSA authentication requested. */
2545          {
2546            MP_INT n;
2547            mpz_init(&n);
2548            packet_get_mp_int(&n);
2549            if (auth_rsa(pw, &n, &sensitive_data.random_state,
2550                         options.strict_modes))
2551              {
2552                /* Successful authentication. */
2553                mpz_clear(&n);
2554                log_msg("RSA authentication for %.100s accepted.", user);
2555                authentication_type = SSH_AUTH_RSA;
2556                authenticated = 1;
2557                break;
2558              }
2559            mpz_clear(&n);
2560            debug("RSA authentication for %.100s failed.", user);
2561          }
2562          break;
2563
2564#ifdef HAVE_TIS
2565        case SSH_CMSG_AUTH_TIS:
2566          /* Support for TIS authentication server
2567             Contributed by Andre April <Andre.April@cediti.be>. */
2568          debug("TIS Authentication...");
2569          if (!options.tis_authentication) {
2570            packet_get_all();
2571            log_msg("Tis authsrv authentication disabled.");
2572            break;
2573          } else {
2574            char buf[128];
2575            char prompt[128];
2576            char mapping[128];
2577            FILE *f;
2578            int found = 0;
2579            char *key, *value, *resp;
2580            Cfg* cfg;
2581           
2582            /* Tis authsrvr authentication requested */
2583            /* Asks Tis server for challenge */
2584            cfg = cfg_read("sshd");
2585            auth_open(cfg);
2586            if (auth_recv(buf, sizeof(buf))) {
2587              log_msg("Cannot connect to authentication server");
2588              packet_start(SSH_SMSG_FAILURE);
2589              packet_send();
2590              packet_write_wait();
2591              break;
2592            }
2593            if (strncmp(buf, "Authsrv ready", 13)) {
2594              auth_close();
2595              log_msg("Bad response from authentication server");
2596              packet_start(SSH_SMSG_FAILURE);
2597              packet_send();
2598              packet_write_wait();
2599              break;
2600            }
2601           
2602            /* If /etc/sshd_tis.map exists, try to find in that file
2603               the name in the Tis database corresponding to "user".
2604               It the file does not exist or "user" is not found in the
2605               file, both names are supposed to be the same. */
2606            f = fopen(TIS_MAP_FILE, "r");
2607            if (f != 0) {
2608              debug("searching for %s in /etc/sshd_tis.map", user);
2609              while (fgets(mapping, 128, f)) {
2610                mapping[strlen(mapping)-1] = '\0';      /* suppress '\n' */
2611                key = strtok(mapping, ":");
2612                value = strtok(0, ":");
2613                if (!strcmp(key, user)) {
2614                  found = 1;
2615                  debug("user %s is mapped to %s", user, value);
2616                  break;
2617                }
2618              }
2619            } else {
2620              debug("cannot open /etc/sshd_tis.map");
2621            }
2622            if (found && (value != 0)) {
2623              /* Limit user name to 100 characters to prevent buffer
2624                 overflow. Who is going to use a longer name, anyway? */
2625              if (strlen(value) > 100) {
2626                log_msg("User name longer than 100 characters!!!");
2627                break;  /* Authentication fails */
2628              }
2629              debug("asking authorization for %s", value);
2630              sprintf(buf, "authorize %s sshd", value);
2631              debug("string sent to server: '%s'", buf);
2632            } else {
2633              if (strlen(user) > 100) {
2634                /* Should not happen since do_authentication already
2635                   checked that "user" is a valid user and Unix
2636                   usernames are limited to 8 chars */
2637                log_msg("User name longer than 100 characters!!!");
2638                break;  /* Authentication fails */
2639              }
2640              debug("asking authorization for %s", user);
2641              sprintf(buf, "authorize %s sshd", user);
2642            }
2643            auth_send(buf);
2644            auth_recv(buf, 100); /* More than enough for the challenge */
2645           
2646            if (!strncmp(buf, "challenge ", 10) ||
2647                !strncmp(buf, "chalnecho ", 10)) {
2648              sprintf(prompt,"Challenge \"%.100s\": ",&buf[10]);
2649              debug("TIS challenge %s", buf);
2650              packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
2651              packet_put_string(prompt, strlen(prompt));
2652              packet_send();
2653              packet_write_wait();
2654            } else {
2655              if (!strncmp(buf, "password", 8)) {
2656                debug("TIS password");
2657                packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
2658                packet_put_string("Password: ", 10);
2659                packet_send();
2660                packet_write_wait();
2661              } else {
2662                /* Unknown user */
2663                auth_close();
2664                debug("Unknown user from authentication server");
2665                break;
2666              }
2667            }
2668            type = packet_read();
2669            if (type != SSH_CMSG_AUTH_TIS_RESPONSE) {
2670              packet_get_all();
2671              auth_close();
2672              log_msg("Protocol error: got %d in respsonse to TIS challenge",
2673                      type);
2674              break;
2675            }
2676            password = packet_get_string(NULL);
2677            resp = xmalloc(strlen(password) + 12);
2678            sprintf(resp,"response '%s'",password);
2679            auth_send(resp);
2680            xfree(resp);
2681            auth_recv(buf, sizeof(buf));
2682            debug("response from authsrvr = %s",buf);
2683            if (!strncmp(buf, "ok", 2)) {
2684              auth_close();
2685              memset(password, 0, strlen(password));
2686              xfree(password);
2687              authentication_type = SSH_AUTH_TIS;
2688              authenticated = 1;
2689              break;
2690            } else {
2691              debug("TIS authentication for %s failed",user);
2692              memset(password, 0, strlen(password));
2693              xfree(password);
2694              break;
2695            }
2696          }
2697          break;        /* TIS authsrv authentication not supported */
2698#endif
2699        case SSH_CMSG_AUTH_PASSWORD:
2700          if (!options.password_authentication)
2701            {
2702              packet_get_all();
2703              log_msg("Password authentication disabled.");
2704              break;
2705            }
2706          if (cipher_type == SSH_CIPHER_NONE)
2707            {
2708              packet_get_all();
2709              log_msg("Password authentication not available for unencrypted session.");
2710              break;
2711            }
2712
2713          /* Password authentication requested. */
2714          /* Read user password.  It is in plain text, but was transmitted
2715             over the encrypted channel so it is not visible to an outside
2716             observer. */
2717          password = packet_get_string(NULL);
2718
2719          if (password_attempts >= 5)
2720            { /* Too many password authentication attempts. */
2721              packet_disconnect("Too many password authentication attempts from %.100s for user %.100s.",
2722                                get_canonical_hostname(), user);
2723              /*NOTREACHED*/
2724            }
2725         
2726          /* Count password authentication attempts, and log if appropriate. */
2727          if (password_attempts > 0)
2728            {
2729              /* Log failures if attempted more than once. */
2730              debug("Password authentication failed for user %.100s from %.100s.",
2731                    user, get_canonical_hostname());
2732            }
2733          password_attempts++;
2734
2735          /* Try authentication with the password. */
2736#if defined(KERBEROS) && defined(KRB5)
2737          if (auth_password(user, password, client))
2738#else  /* defined(KERBEROS) && defined(KRB5) */
2739          if (auth_password(user, password))
2740#endif /* defined(KERBEROS) && defined(KRB5) */
2741            {
2742              /* Successful authentication. */
2743              /* Clear the password from memory. */
2744              memset(password, 0, strlen(password));
2745              xfree(password);
2746              log_msg("Password authentication for %.100s accepted.", user);
2747              authentication_type = SSH_AUTH_PASSWORD;
2748              authenticated = 1;
2749              break;
2750            }
2751          debug("Password authentication for %.100s failed.", user);
2752          memset(password, 0, strlen(password));
2753          xfree(password);
2754          break;
2755
2756        default:
2757          /* Any unknown messages will be ignored (and failure returned)
2758             during authentication. */
2759          packet_get_all();
2760          log_msg("Unknown message during authentication: type %d", type);
2761          break; /* Respond with a failure message. */
2762        }
2763      /* If successfully authenticated, break out of loop. */
2764      if (authenticated)
2765        break;
2766
2767#ifdef KERBEROS
2768      /* If you forwarded a ticket you get one shot for proper
2769         authentication. */
2770      /* If tgt was passed, destroy it */
2771      if (ticket){
2772          if (strcmp(ticket,"none"))
2773            {
2774              krb5_ccache ccache;
2775              if (!krb5_cc_resolve(ssh_context, ticket, &ccache))
2776                krb5_cc_destroy(ssh_context, ccache);
2777              dest_tkt();
2778            }
2779          else
2780            ticket = NULL;
2781      }
2782#endif /* KERBEROS */
2783     
2784      /* Send a message indicating that the authentication attempt failed. */
2785      packet_start(SSH_SMSG_FAILURE);
2786      packet_send();
2787      packet_write_wait();
2788    }
2789
2790  /* Check if the user is logging in as root and root logins are disallowed. */
2791  if (pw->pw_uid == UID_ROOT && options.permit_root_login == 1)
2792    {
2793      if (authentication_type == SSH_AUTH_PASSWORD)
2794        packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
2795                          get_canonical_hostname());
2796    }
2797  else
2798    if (pw->pw_uid == UID_ROOT && options.permit_root_login == 0)
2799      {
2800        if (forced_command)
2801          log_msg("Root login accepted for forced command.", forced_command);
2802        else
2803          packet_disconnect("ROOT LOGIN REFUSED FROM %.200s",
2804                            get_canonical_hostname());
2805      }
2806
2807#if defined (__FreeBSD__) && defined (HAVE_LOGIN_CAP_H)
2808 
2809  lc = login_getclass(pw->pw_class);
2810 
2811  /* Check if the user's login class allows them to log in
2812   * from the remote host.
2813   */
2814  if((cap_hlist = login_getcapstr(lc, "host.deny", NULL, NULL)) != NULL)
2815    {
2816      hp = strtok(cap_hlist, ",");
2817      while(hp != NULL)
2818        {
2819          if (match_host(hostname, ipaddr, hp))
2820            perm_denied = 1;
2821          hp = strtok(NULL, ",");
2822        }
2823    }
2824  if((!perm_denied) &&
2825     ((cap_hlist = login_getcapstr(lc, "host.allow", NULL, NULL)) != NULL))
2826    {
2827      perm_denied = 1; /* Set default assuming the worst. */
2828      hp = strtok(cap_hlist, ",");
2829      while(hp != NULL)
2830        {
2831          if(match_host(hostname, ipaddr, hp))
2832            perm_denied = 0;
2833          hp = strtok(NULL,",");
2834        }
2835    }
2836  login_close(lc);
2837  if(perm_denied)
2838    {
2839      const char *hostname;
2840     
2841      hostname = get_canonical_hostname();
2842      log_severity(SYSLOG_SEVERITY_NOTICE,
2843                   "Denied connection for %.200s from %.200s [%.200s].\n",
2844                   pw->pw_name, hostname, ipaddr);
2845      packet_disconnect("Sorry, you are not allowed to connect.");
2846    }
2847#endif
2848 
2849  /* Log root logins with severity NOTICE. */
2850  if (pw->pw_uid == UID_ROOT)
2851    log_severity(SYSLOG_SEVERITY_NOTICE, "ROOT LOGIN as '%.100s' from %.100s",
2852                 pw->pw_name, get_canonical_hostname());
2853 
2854  if (havecred)
2855    try_afscall(setpag);
2856  if (!al_local_acct)
2857    {
2858      status = al_acct_create(pw->pw_name, NULL, getpid(), havecred, 1,
2859                              &al_warnings);
2860      if (status != AL_SUCCESS && status != AL_WARNINGS)
2861        packet_disconnect("%s\n", al_strerror(status, &errmem));
2862    }
2863
2864  /* al_acct_create may have given us a temp homedir */
2865  pw2 = getpwnam(pw->pw_name);
2866  free(pw->pw_dir);
2867  pw->pw_dir = xstrdup(pw2->pw_dir);
2868
2869  /* The user has been authenticated and accepted. */
2870  packet_start(SSH_SMSG_SUCCESS);
2871  packet_send();
2872  packet_write_wait();
2873
2874  /* Perform session preparation. */
2875  do_authenticated(pw);
2876}
2877
2878/* Prepares for an interactive session.  This is called after the user has
2879   been successfully authenticated.  During this message exchange, pseudo
2880   terminals are allocated, X11, TCP/IP, and authentication agent forwardings
2881   are requested, etc. */
2882
2883void do_authenticated(struct passwd *pw)
2884{
2885  int type;
2886  int compression_level = 0, enable_compression_after_reply = 0;
2887  int have_pty = 0, ptyfd = -1, ttyfd = -1;
2888  int row, col, xpixel, ypixel, screen;
2889  unsigned long max_size;
2890  char ttyname[64];
2891  char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL;
2892  struct group *grp;
2893  gid_t tty_gid;
2894  mode_t tty_mode;
2895  struct stat st;
2896  int i;
2897 
2898  /* Cancel the alarm we set to limit the time taken for authentication. */
2899  alarm(0);
2900
2901  /* Inform the channel mechanism that we are the server side and that
2902     the client may request to connect to any port at all.  (The user could
2903     do it anyway, and we wouldn\'t know what is permitted except by the
2904     client telling us, so we can equally well trust the client not to request
2905     anything bogus.) */
2906  channel_permit_all_opens();
2907
2908#ifdef F_SECURE_COMMERCIAL
2909
2910
2911
2912
2913
2914
2915
2916
2917#endif /* F_SECURE_COMMERCIAL */
2918     
2919
2920  /* We stay in this loop until the client requests to execute a shell or a
2921     command. */
2922  while (1)
2923    {
2924      /* Get a packet from the client. */
2925      type = packet_read();
2926     
2927      /* Process the packet. */
2928      switch (type)
2929        {
2930        case SSH_CMSG_REQUEST_COMPRESSION:
2931          compression_level = packet_get_int();
2932          if (compression_level < 1 || compression_level > 9)
2933            {
2934              packet_send_debug("Received illegal compression level %d.",
2935                                compression_level);
2936              goto fail;
2937            }
2938          /* Enable compression after we have responded with SUCCESS. */
2939          enable_compression_after_reply = 1;
2940          break;
2941
2942        case SSH_CMSG_MAX_PACKET_SIZE:
2943          /* Get maximum size from paket. */
2944          max_size = packet_get_int();
2945
2946          /* Make sure that it is acceptable. */
2947          if (max_size < 4096 || max_size > 256 * 1024)
2948            {
2949              packet_send_debug("Received illegal max packet size %lu.",
2950                                max_size);
2951              goto fail;
2952            }
2953
2954          /* Set the size and return success. */
2955          packet_set_max_size(max_size);
2956          break;
2957
2958        case SSH_CMSG_REQUEST_PTY:
2959          if (no_pty_flag)
2960            {
2961              packet_get_all();
2962              debug("Allocating a pty not permitted for this authentication.");
2963              goto fail;
2964            }
2965          if (have_pty)
2966            packet_disconnect("Protocol error: you already have a pty.");
2967
2968          debug("Allocating pty.");
2969
2970          /* Allocate a pty and open it. */
2971          if (!pty_allocate(&ptyfd, &ttyfd, ttyname))
2972            {
2973              packet_get_all();
2974              error("Failed to allocate pty.");
2975              goto fail;
2976            }
2977
2978          /* Determine the group to make the owner of the tty. */
2979#ifdef TTY_GROUP
2980          grp = getgrnam(TTY_GROUP);
2981#else /* TTY_GROUP */
2982          grp = getgrnam("tty");
2983#endif /* TTY_GROUP */
2984          if (grp)
2985            {
2986              tty_gid = grp->gr_gid;
2987              tty_mode = S_IRUSR|S_IWUSR|S_IWGRP;
2988            }
2989          else
2990            {
2991              tty_gid = pw->pw_gid;
2992              tty_mode = S_IRUSR|S_IWUSR|S_IWGRP|S_IWOTH;
2993            }
2994
2995          /* Change ownership of the tty. */
2996          (void)chown(ttyname, pw->pw_uid, tty_gid);
2997          (void)chmod(ttyname, tty_mode);
2998
2999          /* Get TERM from the packet.  Note that the value may be of arbitrary
3000             length. */
3001          term = packet_get_string(NULL);
3002          if (strcmp(term, "") == 0)
3003            term = NULL;
3004
3005          /* Get window size from the packet. */
3006          row = packet_get_int();
3007          col = packet_get_int();
3008          xpixel = packet_get_int();
3009          ypixel = packet_get_int();
3010          pty_change_window_size(ptyfd, row, col, xpixel, ypixel);
3011
3012          /* Get tty modes from the packet. */
3013          tty_parse_modes(ttyfd);
3014
3015          /* Indicate that we now have a pty. */
3016          have_pty = 1;
3017          break;
3018
3019        case SSH_CMSG_X11_REQUEST_FORWARDING:
3020#ifdef SSHD_NO_X11_FORWARDING
3021          packet_get_all();
3022          debug("X11 forwarding disabled in this site.");
3023          packet_send_debug("X11 forwarding disabled in this site.");
3024          goto fail;
3025#else
3026          if (!options.x11_forwarding)
3027            {
3028              packet_get_all();
3029              packet_send_debug("X11 forwarding disabled in server configuration file.");
3030              goto fail;
3031            }
3032#ifdef XAUTH_PATH
3033          if (no_x11_forwarding_flag)
3034            {
3035              packet_get_all();
3036              packet_send_debug("X11 forwarding not permitted for this authentication.");
3037              goto fail;
3038            }
3039          debug("Received request for X11 forwarding with auth spoofing.");
3040          if (display)
3041            packet_disconnect("Protocol error: X11 display already set.");
3042
3043          /* Check whether we have xauth installed on this machine (in case
3044             the binary was moved from elsewhere). */
3045          if (stat(options.xauth_path, &st) < 0)
3046            {
3047              packet_get_all();
3048              packet_send_debug("Remote host has no X11 installed.");
3049              goto fail;
3050            }
3051
3052          /* Process the request. */
3053          proto = packet_get_string(NULL);
3054          data = packet_get_string(NULL);
3055          if (packet_get_protocol_flags() & SSH_PROTOFLAG_SCREEN_NUMBER ||
3056              packet_get_len() > 0)
3057            screen = packet_get_int();
3058          else
3059            screen = 0;
3060          display = x11_create_display_inet(screen);
3061          if (!display)
3062            goto fail;
3063          break;
3064#else /* XAUTH_PATH */
3065          /* No xauth program; we won't accept forwarding with spoofing. */
3066          packet_get_all();
3067          packet_send_debug("Client requested X11 forwarding, but the server has no xauth program.");
3068          packet_send_debug("This is usually caused by \"xauth\" not being in PATH during compile.");
3069          goto fail;
3070#endif /* XAUTH_PATH */
3071#endif /* SSHD_NO_X11_FORWARDING */
3072
3073        case SSH_CMSG_AGENT_REQUEST_FORWARDING:
3074          if (no_agent_forwarding_flag)
3075            {
3076              packet_get_all();
3077              debug("Authentication agent forwarding not permitted for this authentication.");
3078              goto fail;
3079            }
3080          if (emulation_information & EMULATE_OLD_AGENT_BUG)
3081            {
3082              debug("Authentication agent forwarding denied because the other end uses too old version.");
3083              goto fail;
3084            }
3085          debug("Received authentication agent forwarding request.");
3086          if (!auth_input_request_forwarding(pw))
3087            {
3088              goto fail;
3089            }
3090          break;
3091
3092        case SSH_CMSG_PORT_FORWARD_REQUEST:
3093#ifdef SSHD_NO_PORT_FORWARDING
3094          packet_get_all();
3095          debug("All port forwardings disabled in this site.");
3096          packet_send_debug("All port forwardings disabled in this site.");
3097          goto fail;
3098#else
3099          if (no_port_forwarding_flag || !options.allow_tcp_forwarding)
3100            {
3101              packet_get_all();
3102              debug("Port forwarding not permitted for this authentication.");
3103              goto fail;
3104            }
3105          debug("Received TCP/IP port forwarding request.");
3106          channel_input_port_forward_request(pw->pw_uid == UID_ROOT);
3107          break;
3108#endif
3109
3110        case SSH_CMSG_EXEC_SHELL:
3111          /* Set interactive/non-interactive mode. */
3112          packet_set_interactive(have_pty || display != NULL,
3113                                 options.keepalives);
3114           
3115          if (forced_command != NULL)
3116            goto do_forced_command;
3117          debug("Forking shell.");
3118          if (have_pty)
3119            do_exec_pty(NULL, ptyfd, ttyfd, ttyname, pw, term, display, proto,
3120                        data);
3121          else
3122            do_exec_no_pty(NULL, pw, display, proto, data);
3123          return;
3124
3125        case SSH_CMSG_EXEC_CMD:
3126          /* Set interactive/non-interactive mode. */
3127          packet_set_interactive(have_pty || display != NULL,
3128                                 options.keepalives);
3129
3130          /* Get command from the packet. */
3131          command = packet_get_string(NULL);
3132         
3133          if (forced_command != NULL)
3134            {
3135              original_command = command;
3136              goto do_forced_command;
3137            }
3138          debug("Executing command '%.500s'", command);
3139          if (have_pty)
3140            do_exec_pty(command, ptyfd, ttyfd, ttyname, pw, term, display,
3141                        proto, data);
3142          else
3143            do_exec_no_pty(command, pw, display, proto, data);
3144          xfree(command);
3145          return;
3146
3147        default:
3148          /* Any unknown messages in this phase are ignored, and a failure
3149             message is returned. */
3150          packet_get_all();
3151          log_msg("Unknown packet type received after authentication: %d", type);
3152          goto fail;
3153        }
3154
3155      /* The request was successfully processed. */
3156      packet_start(SSH_SMSG_SUCCESS);
3157      packet_send();
3158      packet_write_wait();
3159
3160      /* Enable compression now that we have replied if appropriate. */
3161      if (enable_compression_after_reply)
3162        {
3163          enable_compression_after_reply = 0;
3164          packet_start_compression(compression_level);
3165        }
3166
3167      continue;
3168
3169    fail:
3170      /* The request failed. */
3171      packet_get_all();
3172      packet_start(SSH_SMSG_FAILURE);
3173      packet_send();
3174      packet_write_wait();
3175      continue;
3176     
3177    do_forced_command:
3178      /* There is a forced command specified for this login.  Execute it. */
3179      debug("Executing forced command: %.900s", forced_command);
3180      if (have_pty)
3181        do_exec_pty(forced_command, ptyfd, ttyfd, ttyname, pw, term, display,
3182                    proto, data);
3183      else
3184        do_exec_no_pty(forced_command, pw, display, proto, data);
3185      return;
3186    }
3187}
3188
3189/* This is called to fork and execute a command when we have no tty.  This
3190   will call do_child from the child, and server_loop from the parent after
3191   setting up file descriptors and such. */
3192
3193void do_exec_no_pty(const char *command, struct passwd *pw,
3194                    const char *display, const char *auth_proto,
3195                    const char *auth_data)
3196
3197  int pid;
3198#ifdef USE_PIPES
3199  int pin[2], pout[2], perr[2];
3200#else /* USE_PIPES */
3201  int inout[2], err[2];
3202#endif /* USE_PIPES */
3203
3204#ifdef HAVE_OSF1_C2_SECURITY
3205  {
3206    const char *str;
3207    if (str = osf1c2_check_account_and_terminal(pw->pw_name, NULL))
3208      {
3209        packet_disconnect(str);
3210      }
3211  }
3212#endif /* HAVE_OSF1_C2_SECURITY */
3213#ifdef USE_PIPES
3214  /* Allocate pipes for communicating with the program. */
3215  if (pipe(pin) < 0 || pipe(pout) < 0 || pipe(perr) < 0)
3216    packet_disconnect("Could not create pipes: %.100s",
3217                      strerror(errno));
3218#else /* USE_PIPES */
3219  /* Uses socket pairs to communicate with the program. */
3220  if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0 ||
3221      socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0)
3222    packet_disconnect("Could not create socket pairs: %.100s",
3223                      strerror(errno));
3224#endif /* USE_PIPES */
3225
3226  /* We no longer need the child running on user's privileges. */
3227  userfile_uninit();
3228 
3229  /* Fork the child. */
3230  if ((pid = fork()) == 0)
3231    {
3232      /* Child.  Reinitialize the log since the pid has changed. */
3233      log_init(av0, debug_flag && !inetd_flag, debug_flag,
3234               options.quiet_mode, options.log_facility);
3235
3236#ifdef HAVE_SETSID
3237#ifdef ultrix
3238      setpgrp(0, 0);
3239#else /* ultrix */
3240      if (setsid() < 0)
3241        error("setsid: %.100s", strerror(errno));
3242#endif
3243#endif /* HAVE_SETSID */
3244
3245#ifdef USE_PIPES
3246      /* Redirect stdin.  We close the parent side of the socket pair,
3247         and make the child side the standard input. */
3248      close(pin[1]);
3249      if (dup2(pin[0], 0) < 0)
3250        perror("dup2 stdin");
3251      close(pin[0]);
3252     
3253      /* Redirect stdout. */
3254      close(pout[0]);
3255      if (dup2(pout[1], 1) < 0)
3256        perror("dup2 stdout");
3257      close(pout[1]);
3258
3259      /* Redirect stderr. */
3260      close(perr[0]);
3261      if (dup2(perr[1], 2) < 0)
3262        perror("dup2 stderr");
3263      close(perr[1]);
3264#else /* USE_PIPES */
3265      /* Redirect stdin, stdout, and stderr.  Stdin and stdout will use the
3266         same socket, as some programs (particularly rdist) seem to depend
3267         on it. */
3268      close(inout[1]);
3269      close(err[1]);
3270      if (dup2(inout[0], 0) < 0) /* stdin */
3271        perror("dup2 stdin");
3272      if (dup2(inout[0], 1) < 0) /* stdout.  Note: same socket as stdin. */
3273        perror("dup2 stdout");
3274      if (dup2(err[0], 2) < 0) /* stderr */
3275        perror("dup2 stderr");
3276#endif /* USE_PIPES */
3277
3278      /* Do processing for the child (exec command etc). */
3279      do_child(command, pw, NULL, display, auth_proto, auth_data, NULL);
3280      /*NOTREACHED*/
3281    }
3282  if (pid < 0)
3283    packet_disconnect("fork failed: %.100s", strerror(errno));
3284#ifdef USE_PIPES
3285  /* We are the parent.  Close the child sides of the pipes. */
3286  close(pin[0]);
3287  close(pout[1]);
3288  close(perr[1]);
3289
3290  /* Enter the interactive session. Note server_loop will close all
3291     filedescriptors.  */
3292  server_loop(pid, pin[1], pout[0], perr[0], NULL);
3293  /* server_loop has closed pin[1], pout[1], and perr[1]. */
3294#else /* USE_PIPES */
3295  /* We are the parent.  Close the child sides of the socket pairs. */
3296  close(inout[0]);
3297  close(err[0]);
3298 
3299  /* Enter the interactive session.  Note: server_loop must be able to handle
3300     the case that fdin and fdout are the same. */
3301  server_loop(pid, inout[1], inout[1], err[1], NULL);
3302  /* server_loop has closed inout[1] and err[1]. */
3303#endif /* USE_PIPES */
3304}
3305
3306struct pty_cleanup_context
3307{
3308  const char *ttyname;
3309  int pid;
3310  int alread_cleaned;
3311};
3312
3313/* Function to perform cleanup if we get aborted abnormally (e.g., due to a
3314   dropped connection). */
3315
3316void pty_cleanup_proc(void *context)
3317{
3318  struct pty_cleanup_context *cu = context;
3319
3320  if (cu->alread_cleaned)
3321    {
3322      debug("pty_cleanup_proc called again, ignored");
3323    }
3324  else
3325    {
3326      debug("pty_cleanup_proc called");
3327     
3328      /* Record that the user has logged out. */
3329      record_logout(cu->pid, cu->ttyname);
3330     
3331      /* Release the pseudo-tty. */
3332      pty_release(cu->ttyname);
3333     
3334      cu->alread_cleaned = 1;
3335    }
3336}
3337
3338/* This is called to fork and execute a command when we have a tty.  This
3339   will call do_child from the child, and server_loop from the parent after
3340   setting up file descriptors, controlling tty, updating wtmp, utmp,
3341   lastlog, and other such operations. */
3342
3343void do_exec_pty(const char *command, int ptyfd, int ttyfd,
3344                 const char *ttyname, struct passwd *pw, const char *term,
3345                 const char *display, const char *auth_proto,
3346                 const char *auth_data)
3347{
3348  int pid, fdout;
3349  const char *hostname;
3350  time_t last_login_time = 0;
3351  char buf[100], *time_string;
3352  char line[256];
3353  struct stat st;
3354  int quiet_login;
3355  struct sockaddr_in from;
3356  int fromlen;
3357  struct pty_cleanup_context cleanup_context;
3358#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
3359  login_cap_t *lc;
3360#endif
3361#if defined (__bsdi__) && _BSDI_VERSION >= 199510
3362  struct timeval tp;
3363#endif /*  __bsdi__ && _BSDI_VERSION >= 199510 */
3364
3365#ifdef HAVE_OSF1_C2_SECURITY
3366  {
3367    const char *str;
3368    if (str = osf1c2_check_account_and_terminal(pw->pw_name, ttyname))
3369      {
3370        packet_disconnect(str);
3371      }
3372  }
3373#endif /* HAVE_OSF1_C2_SECURITY */
3374
3375  /* We no longer need the child running on user's privileges. */
3376  userfile_uninit();
3377
3378  /* Get remote host name. */
3379  hostname = get_canonical_hostname();
3380
3381  /* Get the time when the user last logged in.  Buf will be set to contain
3382     the hostname the last login was from. */
3383#ifndef USELOGIN
3384  options.use_login = 0;
3385#endif /* USELOGIN */
3386  if (!options.use_login)
3387    last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name,
3388                                          buf, sizeof(buf));
3389
3390  /* Fork the child. */
3391  if ((pid = fork()) == 0)
3392    {
3393      pid = getpid();
3394
3395      /* Child.  Reinitialize the log because the pid has changed. */
3396      log_init(av0, debug_flag && !inetd_flag, debug_flag, options.quiet_mode,
3397               options.log_facility);
3398
3399#ifdef HAVE_SETSID
3400#ifdef ultrix
3401      setpgrp(0, 0);
3402#else /* ultrix */
3403      if (setsid() < 0)
3404        error("setsid: %.100s", strerror(errno));
3405#endif
3406#endif /* HAVE_SETSID */
3407
3408      /* Close the master side of the pseudo tty. */
3409      close(ptyfd);
3410
3411      /* Make the pseudo tty our controlling tty. */
3412      pty_make_controlling_tty(&ttyfd, ttyname);
3413
3414      /* Redirect stdin from the pseudo tty. */
3415      if (dup2(ttyfd, fileno(stdin)) < 0)
3416        error("dup2 stdin failed: %.100s", strerror(errno));
3417
3418      /* Redirect stdout to the pseudo tty. */
3419      if (dup2(ttyfd, fileno(stdout)) < 0)
3420        error("dup2 stdin failed: %.100s", strerror(errno));
3421
3422      /* Redirect stderr to the pseudo tty. */
3423      if (dup2(ttyfd, fileno(stderr)) < 0)
3424        error("dup2 stdin failed: %.100s", strerror(errno));
3425
3426      /* Close the extra descriptor for the pseudo tty. */
3427      close(ttyfd);
3428
3429      /* Get IP address of client.  This is needed because we want to record
3430         where the user logged in from.  If the connection is not a socket,
3431         let the ip address be 0.0.0.0. */
3432      memset(&from, 0, sizeof(from));
3433      if (packet_get_connection_in() == packet_get_connection_out())
3434        {
3435          fromlen = sizeof(from);
3436          if (getpeername(packet_get_connection_in(),
3437                          (struct sockaddr *)&from, &fromlen) < 0)
3438            fatal("getpeername: %.100s", strerror(errno));
3439        }
3440
3441      /* Record that there was a login on that terminal. */
3442      record_login(pid, ttyname, pw->pw_name, pw->pw_uid, hostname,
3443                   &from);
3444
3445#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
3446      lc = login_getclass(pw->pw_class);
3447#endif
3448
3449      /* Check if .hushlogin exists.  Note that we cannot use userfile
3450         here because we are in the child. */
3451      sprintf(line, "%.200s/.hushlogin", pw->pw_dir);
3452      quiet_login = stat(line, &st) >= 0;
3453
3454#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
3455      quiet_login = login_getcapbool(lc, "hushlogin", quiet_login);
3456#endif
3457     
3458      /* If the user has logged in before, display the time of last login.
3459         However, don't display anything extra if a command has been
3460         specified (so that ssh can be used to execute commands on a remote
3461         machine without users knowing they are going to another machine). */
3462      if (!options.use_login && command == NULL && last_login_time != 0 &&
3463          !quiet_login)
3464        {
3465          /* Convert the date to a string. */
3466          time_string = ctime(&last_login_time);
3467          /* Remove the trailing newline. */
3468          if (strchr(time_string, '\n'))
3469            *strchr(time_string, '\n') = 0;
3470          /* Display the last login time.  Host if displayed if known. */
3471          if (strcmp(buf, "") == 0)
3472            printf("Last login: %s\r\n", time_string);
3473          else
3474            printf("Last login: %s from %s\r\n", time_string, buf);
3475        }
3476
3477#ifdef __FreeBSD__
3478      if (command == NULL && !quiet_login)
3479        {
3480#ifdef HAVE_LOGIN_CAP_H
3481          char *cw;
3482          FILE *f;
3483         
3484          cw = login_getcapstr(lc, "copyright", NULL, NULL);
3485          if (cw != NULL && (f = fopen(cw, "r")) != NULL)
3486            {
3487              while (fgets(line, sizeof(line), f))
3488                fputs(line, stdout);
3489              fclose(f);
3490            }
3491          else
3492#endif
3493            printf("%s\n\t%s  %s\n\n",
3494                   "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
3495                   "The Regents of the University of California. ",
3496                   "All rights reserved.");
3497        }
3498#endif
3499
3500      /* Print /etc/motd unless a command was specified or printing it was
3501         disabled in server options.  Note that some machines appear to
3502         print it in /etc/profile or similar. */
3503      if (!options.use_login && command == NULL && options.print_motd &&
3504          !quiet_login)
3505        {
3506          FILE *f;
3507
3508          /* Print /etc/motd if it exists. */
3509#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
3510          f = fopen(login_getcapstr(lc, "welcome", "/etc/motd", "/etc/motd"),
3511                    "r");
3512#else
3513          f = fopen("/etc/motd", "r");
3514#endif
3515          if (f)
3516            {
3517              while (fgets(line, sizeof(line), f))
3518                fputs(line, stdout);
3519              fclose(f);
3520            }
3521#if defined (__bsdi__) && _BSDI_VERSION >= 199510
3522          if (pw->pw_change || pw->pw_expire)
3523            (void)gettimeofday(&tp, (struct timezone *)NULL);
3524          if (pw->pw_change)
3525            {
3526              if (tp.tv_sec >= pw->pw_change)
3527                {
3528                  fprintf(stderr,"Sorry -- your password has expired.\n");
3529                  exit(254);
3530                }
3531              days_before_password_expires = (pw->pw_change - tp.tv_sec) /
3532                86400;
3533            }
3534          if (pw->pw_expire)
3535            {
3536              if (tp.tv_sec >= pw->pw_expire)
3537                {
3538                  fprintf(stderr,"Sorry -- your account has expired.\n");
3539                  exit(254);
3540                }
3541              days_before_account_expires = (pw->pw_expire - tp.tv_sec) /
3542                86400;
3543            }
3544#endif /* __bsdi__ & _BSDI_VERSION >= 199510   */
3545        }
3546
3547#if defined (__FreeBSD__) && defined HAVE_LOGIN_CAP_H
3548      login_close(lc);
3549#endif
3550
3551      /* Do common processing for the child, such as execing the command. */
3552      do_child(command, pw, term, display, auth_proto, auth_data, ttyname);
3553      /*NOTREACHED*/
3554    }
3555  if (pid < 0)
3556    packet_disconnect("fork failed: %.100s", strerror(errno));
3557  /* Parent.  Close the slave side of the pseudo tty. */
3558  close(ttyfd);
3559 
3560#ifdef ultrix           /* corey */
3561  setpgrp(0,0);         /* disconnect from child's process group */
3562#endif /* ultrix */
3563
3564  /* Create another descriptor of the pty master side for use as the standard
3565     input.  We could use the original descriptor, but this simplifies code
3566     in server_loop.  The descriptor is bidirectional. */
3567  fdout = dup(ptyfd);
3568  if (fdout < 0)
3569    packet_disconnect("dup failed: %.100s", strerror(errno));
3570
3571  /* Add a cleanup function to clear the utmp entry and record logout time
3572     in case we call fatal() (e.g., the connection gets closed). */
3573  cleanup_context.pid = pid;
3574  cleanup_context.ttyname = ttyname;
3575  cleanup_context.alread_cleaned = 0;
3576  fatal_add_cleanup(pty_cleanup_proc, (void *)&cleanup_context);
3577
3578  /* Enter interactive session, . */
3579  server_loop(pid, ptyfd, fdout, -1, &cleanup_context);
3580  /* server_loop has closed ptyfd and fdout. */
3581  /* server_loop has already Released the pseudo-tty. */
3582
3583  /* Cancel the cleanup function. */
3584  fatal_remove_cleanup(pty_cleanup_proc, (void *)&cleanup_context);
3585
3586  /* Record that the user has logged out. */
3587  record_logout(pid, ttyname);
3588}
3589
3590/* Sets the value of the given variable in the environment.  If the variable
3591   already exists, its value is overriden. */
3592
3593void child_set_env(char ***envp, unsigned int *envsizep, const char *name,
3594                   const char *value)
3595{
3596  unsigned int i, namelen;
3597  char **env;
3598
3599  /* Find the slot where the value should be stored.  If the variable already
3600     exists, we reuse the slot; otherwise we append a new slot at the end
3601     of the array, expanding if necessary. */
3602  env = *envp;
3603  namelen = strlen(name);
3604  for (i = 0; env[i]; i++)
3605    if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
3606      break;
3607  if (env[i])
3608    {
3609      /* Name already exists.  Reuse the slot. */
3610      xfree(env[i]);
3611    }
3612  else
3613    {
3614      /* New variable.  Expand the array if necessary. */
3615      if (i >= (*envsizep) - 1)
3616        {
3617          (*envsizep) += 50;
3618          env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));
3619        }
3620
3621      /* Need to set the NULL pointer at end of array beyond the new
3622         slot. */
3623      env[i + 1] = NULL;
3624    }
3625
3626  /* Allocate space and format the variable in the appropriate slot. */
3627  env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
3628  sprintf(env[i], "%s=%s", name, value);
3629}
3630
3631/* Reads environment variables from the given file and adds/overrides them
3632   into the environment.  If the file does not exist, this does nothing.
3633   Otherwise, it must consist of empty lines, comments (line starts with '#')
3634   and assignments of the form name=value.  No other forms are allowed. */
3635
3636void read_environment_file(char ***env, unsigned int *envsize,
3637                           const char *filename)
3638{
3639  FILE *f;
3640  char buf[4096];
3641  char *cp, *value;
3642 
3643  /* Open the environment file.  Note that this is only called on the user's
3644     uid, and thus should not cause security problems. */
3645  f = fopen(filename, "r");
3646  if (!f)
3647    return;  /* Not found. */
3648 
3649  /* Process each line. */
3650  while (fgets(buf, sizeof(buf), f))
3651    {
3652      /* Skip leading whitespace. */
3653      for (cp = buf; *cp == ' ' || *cp == '\t'; cp++)
3654        ;
3655
3656      /* Ignore empty and comment lines. */
3657      if (!*cp || *cp == '#' || *cp == '\n')
3658        continue;
3659
3660      /* Remove newline. */
3661      if (strchr(cp, '\n'))
3662        *strchr(cp, '\n') = '\0';
3663
3664      /* Find the equals sign.  Its lack indicates badly formatted line. */
3665      value = strchr(cp, '=');
3666      if (value == NULL)
3667        {
3668          fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
3669          continue;
3670        }
3671
3672      /* Replace the equals sign by nul, and advance value to the value
3673         string. */
3674      *value = '\0';
3675      value++;
3676
3677      /* Set the value in environment. */
3678      child_set_env(env, envsize, cp, value);
3679    }
3680 
3681  fclose(f);
3682}
3683
3684
3685#ifdef HAVE_ETC_DEFAULT_LOGIN
3686
3687/* Gets the value of the given variable in the environment.  If the
3688   variable does not exist, returns NULL. */
3689
3690char *child_get_env(char **env, const char *name)
3691{
3692  unsigned int i, namelen;
3693
3694  namelen = strlen(name);
3695
3696  for (i = 0; env[i]; i++)
3697    if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
3698      break;
3699  if (env[i])
3700    return &env[i][namelen + 1];
3701  else
3702    return NULL;
3703}
3704
3705/* Processes /etc/default/login; this involves things like environment
3706   settings, ulimit, etc.  This file exists at least on Solaris 2.x. */
3707
3708void read_etc_default_login(char ***env, unsigned int *envsize,
3709                            const char *user_shell, uid_t user_uid)
3710{
3711  unsigned int defenvsize;
3712  char **defenv, *def;
3713  int i;
3714
3715  /* Read /etc/default/login into a separate temporary environment. */
3716  defenvsize = 10;
3717  defenv = xmalloc(defenvsize * sizeof(char *));
3718  defenv[0] = NULL;
3719  read_environment_file(&defenv, &defenvsize, "/etc/default/login");
3720
3721  /* Set SHELL if ALTSHELL is YES. */
3722  def = child_get_env(defenv, "ALTSHELL");
3723  if (def != NULL && strcmp(def, "YES") == 0)
3724    child_set_env(env, envsize, "SHELL", user_shell);
3725
3726  /* Set PATH from SUPATH if we are logging in as root, and PATH
3727     otherwise.  If neither of these exists, we use the default ssh
3728     path. */
3729  if (user_uid == UID_ROOT)
3730    def = child_get_env(defenv, "SUPATH");
3731  else
3732    def = child_get_env(defenv, "PATH");
3733  if (def != NULL)
3734    {
3735      char *newpath;
3736      newpath = xmalloc(strlen(def) + sizeof(SSH_BINDIR) + 1);
3737      sprintf(newpath, "%s:%s", def, SSH_BINDIR);
3738      child_set_env(env, envsize, "PATH", newpath);
3739      xfree(newpath);
3740    }
3741  else
3742    child_set_env(env, envsize, "PATH", DEFAULT_PATH ":" SSH_BINDIR);
3743
3744  /* Set TZ if TIMEZONE is defined and we haven't inherited a value
3745     for TZ. */
3746  def = getenv("TZ");
3747  if (def == NULL)
3748    def = child_get_env(defenv, "TIMEZONE");
3749  if (def != NULL)
3750    child_set_env(env, envsize, "TZ", def);
3751
3752  /* Set HZ if defined. */
3753  def = child_get_env(defenv, "HZ");
3754  if (def != NULL)
3755    child_set_env(env, envsize, "HZ", def);
3756
3757  /* Set up the default umask if UMASK is defined. */
3758  def = child_get_env(defenv, "UMASK");
3759  if (def != NULL)
3760    {
3761      int i, value;
3762
3763      for (value = i = 0;
3764           def[i] && isdigit(def[i]) && def[i] != '8' && def[i] != '9';
3765           i++)
3766        value = value * 8 + def[i] - '0';
3767
3768      umask(value);
3769    }
3770
3771  /* Set up the file size ulimit if ULIMIT is set. */
3772  def = child_get_env(defenv, "ULIMIT");
3773  if (def != NULL && atoi(def) > 0)
3774    ulimit(UL_SETFSIZE, atoi(def));
3775
3776  /* Free the temporary environment. */
3777  for (i = 0; defenv[i]; i++)
3778    xfree(defenv[i]);
3779  xfree(defenv);
3780}
3781
3782#endif /* HAVE_ETC_DEFAULT_LOGIN */
3783
3784#if defined(NOLOGIN_ALLOW)
3785/* If /etc/nologin is in place, check this file for users to allow anyway.
3786   Useful for sys-admins to be able to touch nologin and still get in to do
3787   remote maintainence. */
3788int ignore_nologin(char *username)
3789{
3790  FILE *ignore_file;
3791  char buf[256], *begin, *end;
3792  int length;
3793
3794  ignore_file = fopen(NOLOGIN_ALLOW, "r");
3795  if (ignore_file == NULL)
3796    return 0;
3797 
3798  while (fgets(buf, 256, ignore_file) != NULL)
3799    {
3800      if ((end = strpbrk(buf, "# \r\t\n")) != NULL)
3801        *end='\0';
3802      begin = strpbrk(buf, "abcdefghijklmnopqrstuvwxyz0123456789");
3803      if (begin == NULL)
3804        continue;
3805      length = strspn(begin, "abcdefghijklmnopqrstuvwxyz0123456789-_");
3806      if (length > 8)
3807        continue;
3808      begin[length] = '\0';
3809      if (!strcmp(begin, username))
3810        {
3811          fprintf(stderr,"\nWARNING: /etc/nologin is in place.\n\n");
3812          fclose(ignore_file);
3813          return(1);
3814        }
3815    }
3816  fclose(ignore_file);
3817  return 0;
3818}
3819#endif /* NOLOGIN_ALLOW */
3820
3821#ifdef HAVE_SGI_PROJ_H
3822/*
3823 On a SGI, set the account number for the current process to the user's
3824 default account. If this is not done, the process will have an account
3825 of zero and accounting will not operate correctly.
3826
3827 Eivind Gjelseth
3828 Para//ab, High Performance Computing Centre
3829 eivind@ii.uib.no
3830
3831*/
3832int sgi_project_setup(char *username)
3833{
3834  int err;
3835  int naccts;
3836  projid_t pbuf;
3837
3838  /* Find default project for a particular user */
3839  if ((naccts = getprojuser(username, &pbuf, 1)) < 0)
3840    {
3841      debug("System call getprojuser failed");
3842      return(-1);
3843    }
3844
3845  /* Create a new array session and moves the current
3846     process from its original array session to the new one. */
3847  if (newarraysess() < 0)
3848    {
3849      debug("System call newarraysess failure");
3850      return(-1);
3851    }
3852
3853  /* Change the project ID for the array session. */
3854  /* Must be changed after the new array session has been created. */
3855  if (naccts)
3856    err = setprid(pbuf.proj_id);
3857
3858  if (err != 0)
3859    {
3860      debug("System call setprid failure");
3861      return(-1);
3862    }
3863
3864  return(0);
3865}
3866#endif /* HAVE_SGI_PROJ_H */
3867
3868/* Performs common processing for the child, such as setting up the
3869   environment, closing extra file descriptors, setting the user and group
3870   ids, and executing the command or shell. */
3871
3872void do_child(const char *command, struct passwd *pw, const char *term,
3873              const char *display, const char *auth_proto,
3874              const char *auth_data, const char *ttyname)
3875{
3876  const char *shell, *cp;
3877  char buf[256];
3878  FILE *f;
3879  unsigned int envsize, i;
3880  char **env;
3881  extern char **environ;
3882  struct stat st;
3883  char *argv[10];
3884  uid_t user_uid;
3885  gid_t user_gid;
3886  char *user_dir;
3887  char *user_name;
3888  char *user_shell;
3889  char *remote_ip;
3890  int remote_port;
3891#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
3892  login_cap_t *lc;
3893  char *real_shell;
3894
3895  lc = login_getclass(pw->pw_class);
3896  auth_checknologin(lc);
3897#else /* !HAVE_LOGIN_CAP_H */
3898#if defined (__bsdi__) && _BSDI_VERSION > 199510
3899  login_cap_t *lc = 0;
3900 
3901  if ((lc = login_getclass(pw->pw_class)) == NULL)
3902    {
3903      log_msg("User class %.100s for %.100s not found, assuming default",
3904              pw->pw_class, pw->pw_name);
3905      lc = login_getclass("default") ;
3906    }
3907#else /* __bsdi__  && _BSDI_VERSION >= 199510  */
3908#if defined (__bsdi__) && _BSDI_VERSION == 199510
3909  login_cap_t *lc = 0;
3910 
3911  if ((lc = login_getclass(pw)) == NULL)
3912    {
3913      log_msg("User class %.100s for %.100s not found, assuming default",
3914              pw->pw_class, pw->pw_name);
3915      pw->pw_class = "default";
3916      lc = login_getclass(pw) ;
3917    }
3918#endif /* defined (__bsdi__) && _BSDI_VERSION == 199510 */
3919#endif /* __bsdi__  && _BSDI_VERSION >= 199510  */
3920
3921  /* Print any leftover libal warnings */
3922  if (al_warnings)
3923    {
3924      int i;
3925      char *errmem;
3926
3927      for (i = 0; al_warnings[i]; i++)
3928        {
3929          fprintf(stderr, "Warning: %s\n",
3930                  al_strerror(al_warnings[i], &errmem));
3931          al_free_errmem(errmem);
3932        }
3933      free(al_warnings);
3934    }
3935
3936  /* Check /etc/nologin. */
3937  f = fopen("/etc/nologin", "r");
3938  if (f)
3939    { /* /etc/nologin exists.  Print its contents and exit. */
3940      /* Print a message about /etc/nologin existing; I am getting
3941         questions because of this every week. */
3942#if defined(NOLOGIN_ALLOW)
3943      if (pw->pw_name && ignore_nologin(pw->pw_name))
3944        {
3945          fclose(f);
3946        } else {
3947#endif
3948          fprintf(stderr, "Logins are currently denied by /etc/nologin:\n");
3949          while (fgets(buf, sizeof(buf), f))
3950            fputs(buf, stderr);
3951          fclose(f);
3952#if defined (__bsdi__) && _BSDI_VERSION >= 199510
3953          if (pw->pw_uid != UID_ROOT &&
3954              !login_getcapbool(lc, "ignorenologin", 0))
3955            exit(254);
3956#else
3957          if (pw->pw_uid != UID_ROOT)
3958            exit(254);
3959#endif /* __bsdi__  && _BSDI_VERSION >= 199510 */
3960#if defined(NOLOGIN_ALLOW)
3961        }
3962#endif
3963    }
3964#endif /* HAVE_LOGIN_CAP_H */
3965
3966  if (command != NULL)
3967    {
3968      /* If executing a command as root, log the whole command.  For normal
3969         users, don't log the command, because logging it would be a
3970         violation of the user's privacy (and even potentially illegal with
3971         respect to privacy/data protection laws in some countries). */
3972      if (pw->pw_uid == UID_ROOT)
3973        log_msg("executing remote command as root: %.200s", command);
3974      else
3975        log_msg("executing remote command as user %.200s", pw->pw_name);
3976    }
3977
3978#ifndef HAVE_LOGIN_CAP_H
3979#ifdef HAVE_SETLOGIN
3980  /* Set login name in the kernel.  Warning: setsid() must be called before
3981     this. */
3982#ifdef USELOGIN
3983  if (command != NULL || !options.use_login)
3984    if (setlogin(pw->pw_name) < 0)
3985      error("setlogin failed: %.100s", strerror(errno));
3986#else  /* USELOGIN */
3987  if (setlogin(pw->pw_name) < 0)
3988    error("setlogin failed: %.100s", strerror(errno));
3989#endif /* USELOGIN */
3990#endif /* HAVE_SETLOGIN */
3991
3992#ifdef HAVE_USERSEC_H
3993  /* On AIX, this "sets process credentials".  I am not sure what this
3994     includes, but it seems to be important.  This also does setuid
3995     (but we do it below as well just in case). */
3996  if (setpcred((char *)pw->pw_name, NULL))
3997    log_msg("setpcred %.100s: %.100s", strerror(errno));
3998#endif /* HAVE_USERSEC_H */
3999#endif /* !HAVE_LOGIN_CAP_H */
4000
4001  /* Save some data that will be needed so that we can do certain cleanups
4002     before we switch to user's uid.  (We must clear all sensitive data
4003     and access rights from memory before doing that.) */
4004  user_uid = pw->pw_uid;
4005  user_gid = pw->pw_gid;
4006  user_dir = xstrdup(pw->pw_dir);
4007  user_name = xstrdup(pw->pw_name);
4008  user_shell = xstrdup(pw->pw_shell);
4009  remote_ip = xstrdup(get_remote_ipaddr());
4010  remote_port = get_remote_port();
4011
4012  /* Close the connection descriptors; note that this is the child, and the
4013     server will still have the socket open, and it is important that we
4014     do not shutdown it.  Note that the descriptors cannot be closed before
4015     building the environment, as we call get_remote_ipaddr there. */
4016  if (packet_get_connection_in() == packet_get_connection_out())
4017    close(packet_get_connection_in());
4018  else
4019    {
4020      close(packet_get_connection_in());
4021      close(packet_get_connection_out());
4022    }
4023  /* Close all descriptors related to channels.  They will still remain
4024     open in the parent. */
4025  channel_close_all();
4026
4027  /* Close any extra file descriptors.  Note that there may still be
4028     descriptors left by system functions.  They will be closed later. */
4029  endpwent();
4030  endhostent();
4031
4032  /* Set dummy encryption key to clear information about the key from
4033     memory.  This key will never be used. */
4034  packet_set_encryption_key((void *)"0123456789ABCDEF0123456789ABCDEF", 32,
4035                            SSH_CIPHER_3DES, 0);
4036
4037  /* Clear any remaining data in the random number generator. */
4038  random_clear(&sensitive_data.random_state);
4039
4040  /* The sensitive private keys were cleared already before authentication. */
4041
4042  /* Clear the data structure, just in case. */
4043  memset(&sensitive_data, 0, sizeof(sensitive_data));
4044
4045#ifdef USELOGIN
4046  if (command != NULL || !options.use_login)
4047#endif /* USELOGIN */
4048    {
4049#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
4050      char *p, *s, **tmpenv;
4051
4052      /* Initialize the new environment.
4053       */
4054      envsize = 64;
4055      env = xmalloc(envsize * sizeof(char *));
4056      env[0] = NULL;
4057
4058      child_set_env(&env, &envsize, "PATH", DEFAULT_PATH);
4059
4060#ifdef MAIL_SPOOL_DIRECTORY
4061      sprintf(buf, "%.200s/%.50s", MAIL_SPOOL_DIRECTORY, user_name);
4062      child_set_env(&env, &envsize, "MAIL", buf);
4063#else /* MAIL_SPOOL_DIRECTORY */
4064#ifdef MAIL_SPOOL_FILE
4065      sprintf(buf, "%.200s/%.50s", user_dir, MAIL_SPOOL_FILE);
4066      child_set_env(&env, &envsize, "MAIL", buf);
4067#endif /* MAIL_SPOOL_FILE */
4068#endif /* MAIL_SPOOL_DIRECTORY */
4069
4070      /* Let it inherit timezone if we have one. */
4071      if (getenv("TZ"))
4072        child_set_env(&env, &envsize, "TZ", getenv("TZ"));
4073
4074      /* Save previous environment array
4075       */
4076      tmpenv = environ;
4077      environ = env;
4078
4079      /* Set the user's login environment
4080       */
4081      if (setusercontext(lc, pw, user_uid, LOGIN_SETALL) < 0)
4082        {
4083          perror("setusercontext");
4084          exit(1);
4085        }
4086
4087      p = getenv("PATH");
4088      s = xmalloc((p != NULL ? strlen(p) + 1 : 0) + sizeof(SSH_BINDIR));
4089      *s = '\0';
4090      if (p != NULL)
4091        {
4092          strcat(s, p);
4093          strcat(s, ":");
4094        }
4095      strcat(s, SSH_BINDIR);
4096
4097      env = environ;
4098      environ = tmpenv; /* Restore parent environment */
4099      for (envsize = 0; env[envsize] != NULL; ++envsize)
4100        ;
4101      /* Reallocate this to what is expected */
4102      envsize = (envsize < 100) ? 100 : envsize + 16;
4103      env = xrealloc(env, envsize * sizeof(char *));
4104     
4105      child_set_env(&env, &envsize, "PATH", s);
4106      xfree(s);
4107
4108#else /* !HAVE_LOGIN_CAP_H */
4109#if     (_BSDI_VERSION > 199510)
4110      if (setusercontext(lc, pw, user_uid, LOGIN_SETALL) < 0)
4111        {
4112          perror("setusercontext");
4113          exit(1);
4114        }
4115      if (auth_approve(lc, pw->pw_name, "ssh") <= 0)
4116        {
4117          perror("approval");
4118          exit(1);
4119        }
4120#else /* (_BSDI_VERSION > 199510) */
4121      /* Set uid, gid, and groups. */
4122      if (getuid() == UID_ROOT || geteuid() == UID_ROOT)
4123        {
4124          if (setgid(user_gid) < 0)
4125            {
4126              perror("setgid");
4127              exit(1);
4128            }
4129#ifdef HAVE_INITGROUPS
4130          /* Initialize the group list. */
4131          if (initgroups(user_name, user_gid) < 0)
4132            {
4133              perror("initgroups");
4134              exit(1);
4135            }
4136#endif /* HAVE_INITGROUPS */
4137         
4138          /* Close any extra open file descriptors so that we don\'t have them
4139             hanging around in clients. Note that we want to do this after
4140             initgroups, because at least on Solaris 2.3 it leaves file
4141             descriptors open. */
4142          endgrent();
4143          for (i = 3; i < 64; i++)
4144            {
4145              if (i == auth_get_fd())
4146                continue;
4147              close(i);
4148            }
4149         
4150#ifdef KERBEROS
4151          /* Chown ticket files to user */
4152          if (ticket && strcmp(ticket, "none"))
4153            {
4154              chown(ticket + 5, user_uid, user_gid);
4155              chown(tkt_string(), user_uid, user_gid);
4156            }
4157#endif
4158
4159          /* At this point, this process should no longer be holding any
4160             confidential information, as changing uid below will permit the
4161             user to attach with a debugger on some machines. */
4162         
4163#ifdef CRAY   /* set up accounting account number, job, limits, permissions  */
4164          if (cray_setup(user_uid, user_name) < 0)
4165            fatal("Failure performing Cray job setup for user %d.",
4166                  (int)user_uid);
4167#endif
4168
4169#ifdef HAVE_SETLUID
4170          /* Set login uid, if we have setluid(). */
4171          if (setluid(user_uid) < 0)
4172            fatal("setluid %d: %s", (int)user_uid, strerror(errno));
4173#endif /* HAVE_SETLUID */
4174         
4175          /* Permanently switch to the desired uid. */
4176          if (setuid(user_uid) < 0)
4177            fatal("setuid %d: %s", (int)user_uid, strerror(errno));
4178        }
4179     
4180      if (getuid() != user_uid || geteuid() != user_uid)
4181        fatal("Failed to set uids to %d.", (int)user_uid);
4182#endif /* (_BSDI_VERSION > 199510) */
4183#endif /* HAVE_LOGIN_CAP_H */
4184    }
4185 
4186  /* Reset signals to their default settings before starting the user
4187     process. */
4188  signals_reset();
4189
4190#if defined(HAVE_OSF1_C2_SECURITY)
4191  {
4192    /* jcastro@ist.utl.pt Sep 1997 */
4193    extern long osflim[8];
4194    struct rlimit rl;
4195    int i; 
4196   
4197    for (i = 0; i < 8; i++) {   
4198      if (osflim[i] != -1) {
4199        rl.rlim_cur= osflim[i];
4200        rl.rlim_max= osflim[i];
4201        setrlimit(i, &rl);
4202      }
4203    }
4204  }
4205#endif
4206
4207  /* Get the shell from the password data.  An empty shell field is legal,
4208     and means /bin/sh. */
4209  shell = (user_shell[0] == '\0') ? DEFAULT_SHELL : user_shell;
4210
4211#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
4212  real_shell = login_getcapstr(lc, "shell", (char*)shell, (char*)shell);
4213  login_close(lc);
4214#else /* !HAVE_LOGIN_CAP_H */
4215  /* Initialize the environment.  In the first part we allocate space for
4216     all environment variables. */
4217  envsize = 100;
4218  env = xmalloc(envsize * sizeof(char *));
4219  env[0] = NULL;
4220#endif /* HAVE_LOGIN_CAP_H */
4221
4222#ifdef USELOGIN
4223  if (command != NULL || !options.use_login)
4224#endif /* USELOGIN */
4225    {
4226      /* Set basic environment. */
4227      child_set_env(&env, &envsize, "HOME", user_dir);
4228      child_set_env(&env, &envsize, "USER", user_name);
4229      child_set_env(&env, &envsize, "LOGNAME", user_name);
4230
4231#ifndef HAVE_LOGIN_CAP_H
4232      child_set_env(&env, &envsize, "PATH", DEFAULT_PATH ":" SSH_BINDIR);
4233     
4234#ifdef MAIL_SPOOL_DIRECTORY
4235      sprintf(buf, "%.200s/%.50s", MAIL_SPOOL_DIRECTORY, user_name);
4236      child_set_env(&env, &envsize, "MAIL", buf);
4237#else /* MAIL_SPOOL_DIRECTORY */
4238#ifdef MAIL_SPOOL_FILE
4239      sprintf(buf, "%.200s/%.50s", user_dir, MAIL_SPOOL_FILE);
4240      child_set_env(&env, &envsize, "MAIL", buf);
4241#endif /* MAIL_SPOOL_FILE */
4242#endif /* MAIL_SPOOL_DIRECTORY */
4243#endif  /* !HAVE_LOGIN_CAP_H */
4244     
4245#ifdef HAVE_ETC_DEFAULT_LOGIN
4246      /* Read /etc/default/login; this exists at least on Solaris 2.x.  Note
4247         that we are already running on the user's uid. */
4248      read_etc_default_login(&env, &envsize, user_shell, user_uid);
4249#else /* HAVE_ETC_DEFAULT_LOGIN */
4250      /* Normal systems set SHELL by default. */
4251      child_set_env(&env, &envsize, "SHELL", shell);
4252#endif /* HAVE_ETC_DEFAULT_LOGIN */
4253    }
4254
4255  if (original_command != NULL)
4256    child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
4257                  original_command);
4258 
4259#ifndef HAVE_LOGIN_CAP_H
4260  /* Let it inherit timezone if we have one. */
4261  if (getenv("TZ"))
4262    child_set_env(&env, &envsize, "TZ", getenv("TZ"));
4263#endif /* !HAVE_LOGIN_CAP_H */
4264 
4265  /* Set custom environment options from RSA authentication. */
4266  while (custom_environment)
4267    {
4268      struct envstring *ce = custom_environment;
4269      char *s = ce->s;
4270      int i;
4271      for (i = 0; s[i] != '=' && s[i]; i++)
4272        ;
4273      if (s[i] == '=')
4274        {
4275          s[i] = 0;
4276          child_set_env(&env, &envsize, s, s + i + 1);
4277        }
4278      custom_environment = ce->next;
4279      xfree(ce->s);
4280      xfree(ce);
4281    }
4282
4283  /* Set SSH_CLIENT. */
4284  sprintf(buf, "%.50s %d %d", remote_ip, remote_port, options.port);
4285  child_set_env(&env, &envsize, "SSH_CLIENT", buf);
4286
4287  /* Set SSH_TTY if we have a pty. */
4288  if (ttyname)
4289    child_set_env(&env, &envsize, "SSH_TTY", ttyname);
4290
4291  /* Set TERM if we have a pty. */
4292  if (term)
4293    child_set_env(&env, &envsize, "TERM", term);
4294
4295  /* Set DISPLAY if we have one. */
4296  if (display)
4297    child_set_env(&env, &envsize, "DISPLAY", display);
4298
4299  /* Set REMOTEUSER if available */
4300  if (remote_user_name)
4301    child_set_env(&env, &envsize, "REMOTEUSER", remote_user_name);
4302
4303#if defined(_AIX) && defined(HAVE_AUTHENTICATE)
4304  {
4305    char *authstate, *krb5cc;
4306   
4307    /* Set AUTHSTATE if we have AUTHSTATE. */
4308    if ((authstate = getenv("AUTHSTATE")) != NULL)
4309      child_set_env(&env, &envsize, "AUTHSTATE", authstate);
4310   
4311    /* Set KRB5CCNAME if we have KRB5CCNAME. */
4312    if ((krb5cc = getenv("KRB5CCNAME")) != NULL)
4313      child_set_env(&env, &envsize, "KRB5CCNAME", krb5cc);
4314  }
4315#endif
4316
4317#ifdef KERBEROS
4318  /* Set KRBTKFILE to point to our ticket */
4319#ifdef KRB5
4320  if (ticket && strcmp(ticket, "none"))
4321    {
4322      child_set_env(&env, &envsize, "KRB5CCNAME", ticket);
4323      child_set_env(&env, &envsize, "KRBTKFILE", tkt_string());
4324    }
4325#endif /* KRB5 */
4326#endif /* KERBEROS */
4327
4328  /* Set variable for forwarded authentication connection, if we have one. */
4329  if (auth_get_socket_name() != NULL)
4330    child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME,
4331                  auth_get_socket_name());
4332
4333  /* Set XAUTHORITY to something safe. (we don't want to put the xauth
4334     cookie into AFS.) */
4335  if (auth_proto != NULL && auth_data != NULL)
4336    {
4337      sprintf(buf, "/tmp/xauth-%s-%d", user_name, (int)getpid());
4338      if (mkdir(buf, S_IRWXU) == -1)
4339        {
4340          fprintf(stderr, "Could not create xauth directory %s: %s\n"
4341                  "Disabling X forwarding.\n", buf, strerror(errno));
4342          auth_proto = auth_data = NULL;
4343        }
4344      else
4345        {
4346          strcat(buf, "/Xauthority");
4347          child_set_env(&env, &envsize, "XAUTHORITY", buf);
4348        }
4349    }     
4350
4351#ifdef USELOGIN
4352  if (command != NULL || !options.use_login)
4353#endif /* USELOGIN */
4354    {
4355      /* Read environment variable settings from /etc/environment.  (This
4356         exists at least on AIX, but could be useful also elsewhere.) */
4357      read_environment_file(&env, &envsize, "/etc/environment");
4358
4359      /* Read $HOME/.ssh/environment. */
4360      sprintf(buf, "%.200s/.ssh/environment", user_dir);
4361      read_environment_file(&env, &envsize, buf);
4362     
4363      /* Change current directory to the user\'s home directory. */
4364      if (chdir(user_dir) < 0)
4365        fprintf(stderr, "Could not chdir to home directory %s: %s\n",
4366                user_dir, strerror(errno));
4367    }
4368 
4369  /* If debugging, dump the environment to stderr. */
4370  if (debug_flag)
4371    {
4372      fprintf(stderr, "Environment:\n");
4373      for (i = 0; env[i]; i++)
4374        fprintf(stderr, "  %.200s\n", env[i]);
4375      fprintf(stderr, "\n");
4376    }
4377     
4378 
4379  /* Must take new environment into use so that .ssh/rc, /etc/sshrc and
4380     xauth are run in the proper environment. */
4381  environ = env;
4382
4383#ifdef USELOGIN
4384  if (command != NULL || !options.use_login)
4385#endif /* USELOGIN */
4386    {
4387      /* Run $HOME/.ssh/rc, /etc/sshrc, or xauth (whichever is found first
4388         in this order).  Note that we are already running on the user's
4389         uid. */
4390      if (stat(SSH_USER_RC, &st) >= 0)
4391        {
4392          sprintf(buf, "%.100s %.100s", shell, SSH_USER_RC);
4393         
4394          if (debug_flag)
4395            fprintf(stderr, "Running %s\n", buf);
4396         
4397          f = popen(buf, "w");
4398          if (f)
4399            {
4400              if (auth_proto != NULL && auth_data != NULL)
4401                fprintf(f, "%s %s\n", auth_proto, auth_data);
4402              pclose(f);
4403            }
4404          else
4405            fprintf(stderr, "Could not run %s\n", SSH_USER_RC);
4406        }
4407      else
4408        if (stat(SSH_SYSTEM_RC, &st) >= 0)
4409          {
4410            sprintf(buf, "%.100s %.100s", "/bin/sh", SSH_SYSTEM_RC);
4411           
4412            if (debug_flag)
4413              fprintf(stderr, "Running %s\n", buf);
4414           
4415            f = popen(buf, "w");
4416            if (f)
4417              {
4418                if (auth_proto != NULL && auth_data != NULL)
4419                  fprintf(f, "%s %s\n", auth_proto, auth_data);
4420                pclose(f);
4421              }
4422            else
4423              fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);
4424          }
4425#ifdef XAUTH_PATH
4426        else
4427          {
4428            /* Add authority data to .Xauthority if appropriate. */
4429            if (auth_proto != NULL && auth_data != NULL)
4430              {
4431                int i;
4432                char name[255], *p;
4433                char line[256];
4434                struct hostent *hp;
4435               
4436                strncpy(name, display, sizeof(name));
4437                name[sizeof(name) - 1] = '\0';
4438                p = strchr(name, ':');
4439                if (p)
4440                  *p = '\0';
4441               
4442                if (debug_flag)
4443                  fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",
4444                          options.xauth_path, display, auth_proto, auth_data);
4445               
4446                signal(SIGPIPE, SIG_IGN);
4447
4448                sprintf(line, "%.200s -q -", options.xauth_path);
4449                f = popen(line, "w");
4450                if (f)
4451                  {
4452                    fprintf(f, "add %s %s %s\n", display, auth_proto,
4453                            auth_data);
4454                    cp = strchr(display, ':');
4455                    if (cp)
4456                      {
4457#ifndef CRAY
4458                        /* Cray xauth cannot take host/unix:0 as displayname */
4459                        fprintf(f, "add %.*s/unix%s %s %s\n",
4460                                cp - display, display, cp, auth_proto,
4461                                auth_data);
4462#endif
4463                        hp = gethostbyname(name);
4464                        if (hp)
4465                          {
4466                            for(i = 0; hp->h_addr_list[i]; i++)
4467                              {
4468                                if (debug_flag)
4469                                  {
4470                                    fprintf(stderr, "Running %s add %s%s %s %s\n",
4471                                            options.xauth_path,
4472                                            inet_ntoa(*((struct in_addr *)
4473                                                        hp->h_addr_list[i])),
4474                                            cp, auth_proto, auth_data);
4475                                  }
4476                                fprintf(f, "add %s%s %s %s\n",
4477                                        inet_ntoa(*((struct in_addr *)
4478                                                    hp->h_addr_list[i])),
4479                                        cp, auth_proto, auth_data);
4480                              }
4481                          }
4482                      }
4483                    pclose(f);
4484                  }
4485                else
4486                  fprintf(stderr, "Could not run %s -q -\n",
4487                          options.xauth_path);
4488               
4489                signal(SIGPIPE, SIG_DFL);
4490              }
4491          }
4492#endif /* XAUTH_PATH */
4493    }
4494
4495#ifdef USELOGIN
4496  if (command != NULL || !options.use_login)
4497#endif /* USELOGIN */
4498    {
4499      /* Get the last component of the shell name. */
4500      cp = strrchr(shell, '/');
4501      if (cp)
4502        cp++;
4503      else
4504        cp = shell;
4505    }
4506 
4507  /* If we have no command, execute the shell.  In this case, the shell name
4508     to be passed in argv[0] is preceded by '-' to indicate that this is
4509     a login shell. */
4510  if (!command)
4511    {
4512#ifdef USELOGIN
4513      if (!options.use_login)
4514#endif /* USELOGIN */
4515        {
4516          char buf[256];
4517
4518          if (options.check_mail)
4519            {
4520              char *mailbox;
4521             
4522              mailbox = getenv("MAIL");
4523              if(mailbox != NULL)
4524                {
4525                  struct stat mailbuf;
4526                 
4527                  if (stat(mailbox, &mailbuf) == -1 || mailbuf.st_size == 0)
4528                    printf("No mail.\n");
4529                  else if (mailbuf.st_atime > mailbuf.st_mtime)
4530                    printf("You have mail.\n");
4531                  else
4532                    printf("You have new mail.\n");
4533                }
4534            }
4535          if (days_before_account_expires >= 0 &&
4536              days_before_account_expires <
4537              options.account_expire_warning_days)
4538            {
4539              printf("\n\tWARNING: Your account expires in %d days\n\n",
4540                     days_before_account_expires);
4541            }
4542          if (days_before_password_expires >= 0 &&
4543              days_before_password_expires <
4544              options.password_expire_warning_days)
4545            {
4546              printf("\n\tWARNING: Your password expires in %d days\n\n",
4547                     days_before_password_expires);
4548            }
4549         
4550          /* Start the shell.  Set initial character to '-'. */
4551          buf[0] = '-';
4552          strncpy(buf + 1, cp, sizeof(buf) - 1);
4553          buf[sizeof(buf) - 1] = 0;
4554          /* Execute the shell. */
4555          argv[0] = buf;
4556          argv[1] = NULL;
4557#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
4558          execve(real_shell, argv, env);
4559#else
4560          execve(shell, argv, env);
4561#endif /* HAVE_LOGIN_CAP_H */
4562          /* Executing the shell failed. */
4563          perror(shell);
4564          exit(1);
4565        }
4566#ifdef USELOGIN
4567      else
4568        {
4569          execl(PATH_LOGIN, "login", "-h", remote_ip, "-p", "-f",
4570                "--", user_name, NULL);
4571          /* NOTREACHED */
4572        }
4573#endif /* USELOGIN */
4574    }
4575
4576  /* Execute the command using the user's shell.  This uses the -c option
4577     to execute the command. */
4578  argv[0] = (char *)cp;
4579  argv[1] = "-c";
4580  argv[2] = (char *)command;
4581  argv[3] = NULL;
4582#if defined (__FreeBSD__) && defined(HAVE_LOGIN_CAP_H)
4583  execve(real_shell, argv, env);
4584#else
4585  execve(shell, argv, env);
4586#endif /* HAVE_LOGIN_CAP_H */
4587  perror(shell);
4588  exit(1);
4589}
4590
4591#ifdef CRAY
4592/*
4593 On a Cray, set the account number for the current process to the user's
4594 default account.  If this is not done, the process will have an account
4595 of zero and accounting (Cray System Accounting and/or SDSC Resource
4596 Management (realtime)) will not operate correctly.
4597
4598 This routine also calls setjob to set up an Cray Job (also known
4599 as a Session).  This is needed for CRI's Cray System Accounting
4600 and SDSC's Resource Management accounting/management system.
4601
4602 It also calls setlimit, to set up limits and permissions.
4603 
4604 Wayne Schroeder
4605 San Diego Supercomputer Center
4606 schroeder@sdsc.edu
4607 
4608*/
4609int cray_setup(uid, username)
4610uid_t uid;
4611char *username;
4612{
4613  register struct udb *p;
4614  extern struct udb *getudb();
4615  int i, j;
4616  int accts[MAXVIDS];
4617  int naccts;
4618  int err, jid;
4619  char *sr;
4620  int pid;
4621
4622  /* Find all of the accounts for a particular user */
4623  err = setudb();    /* open and rewind the Cray User DataBase */
4624  if(err != 0)
4625    {
4626      debug("UDB open failure");
4627      return(-1);
4628    }
4629  naccts = 0;
4630  while ((p = getudb()) != UDB_NULL)
4631    {
4632      if (p->ue_uid == -1) break;
4633      if(uid == p->ue_uid)
4634        {
4635          for(j = 0; p->ue_acids[j] != -1 && j < MAXVIDS; j++)
4636            {
4637              accts[naccts] = p->ue_acids[j];
4638              naccts++;
4639            }
4640        }
4641    }
4642  endudb();        /* close the udb */
4643  if (naccts == 0 || accts[0] == 0)
4644    {
4645      debug("No Cray accounts found");
4646      return(-1);
4647    }
4648 
4649  /* Perhaps someday we'll prompt users who have multiple accounts
4650     to let them pick one (like CRI's login does), but for now just set
4651     the account to the first entry. */
4652  if (acctid(0, accts[0]) < 0)
4653    {
4654      debug("System call acctid failed, accts[0]=%d",accts[0]);
4655      return(-1);
4656    }
4657 
4658  /* Now call setjob to create a new job(/session).  This assigns a new Session
4659     ID and session table entry to the calling process.  This process will be
4660     the first process in the job/session. */
4661  jid = setjob(uid, 0);
4662  if (jid < 0)
4663    {
4664      debug("System call setjob failure");
4665      return(-1);
4666    }
4667
4668  /* Now set limits, including CPU time for the (interactive) job and process,
4669     and set up permissions (for chown etc), etc.  This is via an internal CRI
4670     routine, setlimits, used by CRI's login. */
4671
4672  pid = getpid();
4673  sr = setlimits(username, C_PROC, pid, UDBRC_INTER);
4674  if (sr != NULL)
4675    {
4676      debug(sr);
4677      return(-1);
4678    }
4679  sr = setlimits(username, C_JOB, jid, UDBRC_INTER);
4680  if (sr != NULL)
4681    {
4682      debug(sr);
4683      return(-1);
4684    }
4685
4686  return(0);
4687}
4688#endif /* CRAY */
4689
4690void try_afscall(int (*func)(void))
4691{
4692#ifdef SIGSYS
4693  struct sigaction sa, osa;
4694
4695  sigemptyset(&sa.sa_mask);
4696  sa.sa_flags = 0;
4697  sa.sa_handler = SIG_IGN;
4698  sigaction(SIGSYS, &sa, &osa);
4699#endif
4700  func();
4701#ifdef SIGSYS
4702  sigaction(SIGSYS, &osa, NULL);
4703#endif
4704}
4705
4706void al_cleanup(void)
4707{
4708  al_acct_revert(al_user, getpid());
4709}
4710
4711void krb_cleanup(void)
4712{
4713  if (ticket && strcmp(ticket, "none"))
4714    {
4715      krb5_ccache ccache;
4716      if (!krb5_cc_resolve(ssh_context, ticket, &ccache))
4717          krb5_cc_destroy(ssh_context, ccache);
4718      dest_tkt();
4719      try_afscall(ktc_ForgetAllTokens);
4720    }
4721}
Note: See TracBrowser for help on using the repository browser.