11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: session.c,v 1.258 2010/11/25 04:10:09 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All rights reserved 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose. Any derived versions of this 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell". 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH2 support by Markus Friedl. 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h> 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_STAT_H 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/stat.h> 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/un.h> 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/wait.h> 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <arpa/inet.h> 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h> 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <grp.h> 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PATHS_H 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <paths.h> 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h> 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h" 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h" 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh1.h" 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshpty.h" 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "match.h" 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "uidswap.h" 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h" 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "channels.h" 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h" 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh-gss.h" 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "hostfile.h" 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "auth.h" 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "auth-options.h" 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "pathnames.h" 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "servconf.h" 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshlogin.h" 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "serverloop.h" 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "canohost.h" 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "session.h" 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h" 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "monitor_wrap.h" 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sftp.h" 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(KRB5) && defined(USE_AFS) 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <kafs.h> 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <selinux/selinux.h> 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define IS_INTERNAL_SFTP(c) \ 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \ 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \ 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \ 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t')) 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* func */ 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSession *session_new(void); 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid session_set_fds(Session *, int, int, int, int, int); 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid session_pty_cleanup(Session *); 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid session_proctitle(Session *); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint session_setup_x11fwd(Session *); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint do_exec_pty(Session *, const char *); 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint do_exec_no_pty(Session *, const char *); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint do_exec(Session *, const char *); 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid do_login(Session *, const char *); 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef LOGIN_NEEDS_UTMPX 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void do_pre_login(Session *s); 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid do_child(Session *, const char *); 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid do_motd(void); 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint check_quietlogin(Session *, const char *); 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void do_authenticated1(Authctxt *); 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void do_authenticated2(Authctxt *); 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int session_pty_req(Session *); 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* import */ 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern ServerOptions options; 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern char *__progname; 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int log_stderr; 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int debug_flag; 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern u_int utmp_len; 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int startup_pipe; 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern void destroy_sensitive_data(void); 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern Buffer loginmsg; 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* original command from peer. */ 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char *original_command = NULL; 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* data */ 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int sessions_first_unused = -1; 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int sessions_nalloc = 0; 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Session *sessions = NULL; 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SUBSYSTEM_NONE 0 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SUBSYSTEM_EXT 1 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SUBSYSTEM_INT_SFTP 2 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SUBSYSTEM_INT_SFTP_ERROR 3 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodlogin_cap_t *lc; 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int is_child = 0; 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Name and directory of socket for authentication agent forwarding. */ 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *auth_sock_name = NULL; 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *auth_sock_dir = NULL; 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* removes the agent forwarding socket */ 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodauth_sock_cleanup_proc(struct passwd *pw) 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (auth_sock_name != NULL) { 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood temporarily_use_uid(pw); 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unlink(auth_sock_name); 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rmdir(auth_sock_dir); 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_name = NULL; 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood restore_uid(); 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodauth_input_request_forwarding(struct passwd * pw) 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *nc; 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int sock = -1; 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_un sunaddr; 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (auth_sock_name != NULL) { 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("authentication forwarding requested twice."); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Temporarily drop privileged uid for mkdir/bind. */ 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood temporarily_use_uid(pw); 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allocate a buffer for the socket name, and format the name. */ 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_dir = xstrdup("/tmp/ssh-XXXXXXXXXX"); 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Create private directory for socket */ 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (mkdtemp(auth_sock_dir) == NULL) { 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send_debug("Agent forwarding disabled: " 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "mkdtemp() failed: %.100s", strerror(errno)); 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood restore_uid(); 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(auth_sock_dir); 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_dir = NULL; 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto authsock_err; 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xasprintf(&auth_sock_name, "%s/agent.%ld", 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_dir, (long) getpid()); 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Create the socket. */ 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sock = socket(AF_UNIX, SOCK_STREAM, 0); 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock < 0) { 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("socket: %.100s", strerror(errno)); 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood restore_uid(); 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto authsock_err; 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Bind it to the name. */ 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&sunaddr, 0, sizeof(sunaddr)); 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sunaddr.sun_family = AF_UNIX; 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path)); 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("bind: %.100s", strerror(errno)); 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood restore_uid(); 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto authsock_err; 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Restore the privileged uid. */ 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood restore_uid(); 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Start listening on the socket. */ 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("listen: %.100s", strerror(errno)); 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto authsock_err; 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allocate a channel for the authentication agent socket. */ 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nc = channel_new("auth socket", 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 0, "auth socket", 1); 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nc->path = xstrdup(auth_sock_name); 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authsock_err: 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (auth_sock_name != NULL) 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(auth_sock_name); 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (auth_sock_dir != NULL) { 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood rmdir(auth_sock_dir); 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(auth_sock_dir); 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock != -1) 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(sock); 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_name = NULL; 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_dir = NULL; 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddisplay_loginmsg(void) 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buffer_len(&loginmsg) > 0) { 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_append(&loginmsg, "\0", 1); 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("%s", (char *)buffer_ptr(&loginmsg)); 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&loginmsg); 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_authenticated(Authctxt *authctxt) 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setproctitle("%s", authctxt->pw->pw_name); 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* setup the channel layer */ 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!no_port_forwarding_flag && options.allow_tcp_forwarding) 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_permit_all_opens(); 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_debug_send(); 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_authenticated2(authctxt); 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_authenticated1(authctxt); 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_cleanup(authctxt); 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Prepares for an interactive session. This is called after the user has 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * been successfully authenticated. During this message exchange, pseudo 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * terminals are allocated, X11, TCP/IP, and authentication agent forwardings 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are requested, etc. 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_authenticated1(Authctxt *authctxt) 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s; 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *command; 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success, type, screen_flag; 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int enable_compression_after_reply = 0; 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int proto_len, data_len, dlen, compression_level = 0; 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s = session_new(); 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) { 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("no more sessions"); 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->authctxt = authctxt; 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pw = authctxt->pw; 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We stay in this loop until the client requests to execute a shell 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * or a command. 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (;;) { 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 0; 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get a packet from the client. */ 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood type = packet_read(); 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Process the packet. */ 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (type) { 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_REQUEST_COMPRESSION: 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood compression_level = packet_get_int(); 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compression_level < 1 || compression_level > 9) { 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send_debug("Received invalid compression level %d.", 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood compression_level); 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.compression == COMP_NONE) { 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("compression disabled"); 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Enable compression after we have responded with SUCCESS. */ 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enable_compression_after_reply = 1; 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_REQUEST_PTY: 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_pty_req(s); 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_X11_REQUEST_FORWARDING: 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_proto = packet_get_string(&proto_len); 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data = packet_get_string(&data_len); 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood screen_flag = packet_get_protocol_flags() & 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_PROTOFLAG_SCREEN_NUMBER; 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("SSH_PROTOFLAG_SCREEN_NUMBER: %d", screen_flag); 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_remaining() == 4) { 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!screen_flag) 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("Buggy client: " 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "X11 screen flag missing"); 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->screen = packet_get_int(); 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->screen = 0; 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_setup_x11fwd(s); 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!success) { 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_proto); 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_data); 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_proto = NULL; 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data = NULL; 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_AGENT_REQUEST_FORWARDING: 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.allow_agent_forwarding || 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood no_agent_forwarding_flag || compat13) { 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Authentication agent forwarding not permitted for this authentication."); 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Received authentication agent forwarding request."); 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = auth_input_request_forwarding(s->pw); 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_PORT_FORWARD_REQUEST: 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (no_port_forwarding_flag) { 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Port forwarding not permitted for this authentication."); 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.allow_tcp_forwarding) { 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Port forwarding not permitted."); 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Received TCP/IP port forwarding request."); 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (channel_input_port_forward_request(s->pw->pw_uid == 0, 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.gateway_ports) < 0) { 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Port forwarding failed."); 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_MAX_PACKET_SIZE: 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_set_maxsize(packet_get_int()) > 0) 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = 1; 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_EXEC_SHELL: 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case SSH_CMSG_EXEC_CMD: 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (type == SSH_CMSG_EXEC_CMD) { 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood command = packet_get_string(&dlen); 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Exec command '%.500s'", command); 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_exec(s, command) != 0) 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_disconnect( 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "command execution failed"); 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(command); 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_exec(s, NULL) != 0) 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_disconnect( 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "shell execution failed"); 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_close(s); 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Any unknown messages in this phase are ignored, 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and a failure message is returned. 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("Unknown packet type received after authentication: %d", type); 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE); 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_write_wait(); 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Enable compression now that we have replied if appropriate. */ 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (enable_compression_after_reply) { 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood enable_compression_after_reply = 0; 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start_compression(compression_level); 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define USE_PIPES 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This is called to fork and execute a command when we have no tty. This 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * will call do_child from the child, and server_loop from the parent after 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * setting up file descriptors and such. 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_exec_no_pty(Session *s, const char *command) 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid; 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PIPES 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int pin[2], pout[2], perr[2]; 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("do_exec_no_pty: no session"); 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allocate pipes for communicating with the program. */ 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pipe(pin) < 0) { 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: pipe in: %.100s", __func__, strerror(errno)); 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pipe(pout) < 0) { 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: pipe out: %.100s", __func__, strerror(errno)); 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[0]); 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[1]); 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pipe(perr) < 0) { 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: pipe err: %.100s", __func__, 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[0]); 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[1]); 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[0]); 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[1]); 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int inout[2], err[2]; 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("do_exec_no_pty: no session"); 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Uses socket pairs to communicate with the program. */ 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) < 0) { 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: socketpair #1: %.100s", __func__, strerror(errno)); 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (socketpair(AF_UNIX, SOCK_STREAM, 0, err) < 0) { 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: socketpair #2: %.100s", __func__, 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[0]); 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[1]); 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_proctitle(s); 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fork the child. */ 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch ((pid = fork())) { 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case -1: 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: fork: %.100s", __func__, strerror(errno)); 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PIPES 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[0]); 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[1]); 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[0]); 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[1]); 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(perr[0]); 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(perr[1]); 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[0]); 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[1]); 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(err[0]); 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(err[1]); 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 0: 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood is_child = 1; 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Child. Reinitialize the log since the pid has changed. */ 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood log_init(__progname, options.log_level, 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.log_facility, log_stderr); 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Create a new session and process group since the 4.4BSD 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * setlogin() affects the entire process group. 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setsid() < 0) 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setsid failed: %.100s", strerror(errno)); 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PIPES 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redirect stdin. We close the parent side of the socket 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * pair, and make the child side the standard input. 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[1]); 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(pin[0], 0) < 0) 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("dup2 stdin"); 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[0]); 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Redirect stdout. */ 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[0]); 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(pout[1], 1) < 0) 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("dup2 stdout"); 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[1]); 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Redirect stderr. */ 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(perr[0]); 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(perr[1], 2) < 0) 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("dup2 stderr"); 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(perr[1]); 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redirect stdin, stdout, and stderr. Stdin and stdout will 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * use the same socket, as some programs (particularly rdist) 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * seem to depend on it. 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[1]); 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(err[1]); 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(inout[0], 0) < 0) /* stdin */ 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("dup2 stdin"); 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(inout[0], 1) < 0) /* stdout (same as stdin) */ 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("dup2 stdout"); 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[0]); 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(err[0], 2) < 0) /* stderr */ 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("dup2 stderr"); 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(err[0]); 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cray_init_job(s->pw); /* set up cray jid and tmpdir */ 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Do processing for the child (exec command etc). */ 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_child(s, command); 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* NOTREACHED */ 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(WJSIGNAL, cray_job_termination_handler); 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _UNICOS */ 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_CYGWIN 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pid = pid; 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set interactive/non-interactive mode. */ 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_set_interactive(s->display != NULL, 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.ip_qos_interactive, options.ip_qos_bulk); 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Clear loginmsg, since it's the child's responsibility to display 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * it to the user, otherwise multiple sessions may accumulate 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * multiple copies of the login messages. 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&loginmsg); 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PIPES 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* We are the parent. Close the child sides of the pipes. */ 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pin[0]); 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(pout[1]); 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(perr[1]); 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_set_fds(s, pin[1], pout[0], perr[0], 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem, 0); 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Enter the interactive session. */ 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_loop(pid, pin[1], pout[0], perr[0]); 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* server_loop has closed pin[1], pout[0], and perr[0]. */ 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* We are the parent. Close the child sides of the socket pairs. */ 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(inout[0]); 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(err[0]); 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Enter the interactive session. Note: server_loop must be able to 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * handle the case that fdin and fdout are the same. 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_set_fds(s, inout[1], inout[1], err[1], 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem, 0); 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_loop(pid, inout[1], inout[1], err[1]); 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* server_loop has closed inout[1] and err[1]. */ 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This is called to fork and execute a command when we have a tty. This 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * will call do_child from the child, and server_loop from the parent after 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * setting up file descriptors, controlling tty, updating wtmp, utmp, 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * lastlog, and other such operations. 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_exec_pty(Session *s, const char *command) 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fdout, ptyfd, ttyfd, ptymaster; 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid; 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("do_exec_pty: no session"); 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ptyfd = s->ptyfd; 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ttyfd = s->ttyfd; 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Create another descriptor of the pty master side for use as the 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * standard input. We could use the original descriptor, but this 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * simplifies code in server_loop. The descriptor is bidirectional. 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Do this before forking (and cleanup in the child) so as to 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * detect and gracefully fail out-of-fd conditions. 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((fdout = dup(ptyfd)) < 0) { 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: dup #1: %s", __func__, strerror(errno)); 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ttyfd); 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ptyfd); 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* we keep a reference to the pty master */ 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((ptymaster = dup(ptyfd)) < 0) { 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: dup #2: %s", __func__, strerror(errno)); 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ttyfd); 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ptyfd); 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fdout); 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Fork the child. */ 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch ((pid = fork())) { 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case -1: 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: fork: %.100s", __func__, strerror(errno)); 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fdout); 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ptymaster); 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ttyfd); 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ptyfd); 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 0: 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood is_child = 1; 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fdout); 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ptymaster); 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Child. Reinitialize the log because the pid has changed. */ 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood log_init(__progname, options.log_level, 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.log_facility, log_stderr); 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Close the master side of the pseudo tty. */ 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ptyfd); 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Make the pseudo tty our controlling tty. */ 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pty_make_controlling_tty(&ttyfd, s->tty); 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Redirect stdin/stdout/stderr from the pseudo tty. */ 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(ttyfd, 0) < 0) 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("dup2 stdin: %s", strerror(errno)); 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(ttyfd, 1) < 0) 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("dup2 stdout: %s", strerror(errno)); 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(ttyfd, 2) < 0) 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("dup2 stderr: %s", strerror(errno)); 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Close the extra descriptor for the pseudo tty. */ 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ttyfd); 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* record login, etc. similar to login(1) */ 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef HAVE_OSF_SIA 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(options.use_login && command == NULL)) { 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cray_init_job(s->pw); /* set up cray jid and tmpdir */ 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _UNICOS */ 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_login(s, command); 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef LOGIN_NEEDS_UTMPX 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_pre_login(s); 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Do common processing for the child, such as execing 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the command. 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_child(s, command); 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* NOTREACHED */ 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(WJSIGNAL, cray_job_termination_handler); 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _UNICOS */ 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_CYGWIN 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pid = pid; 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Parent. Close the slave side of the pseudo tty. */ 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(ttyfd); 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Enter interactive session. */ 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ptymaster = ptymaster; 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_set_interactive(1, 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.ip_qos_interactive, options.ip_qos_bulk); 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_set_fds(s, ptyfd, fdout, -1, 1, 1); 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_loop(pid, ptyfd, fdout, -1); 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* server_loop _has_ closed ptyfd and fdout. */ 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef LOGIN_NEEDS_UTMPX 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_pre_login(Session *s) 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood socklen_t fromlen; 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_storage from; 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid = getpid(); 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Get IP address of client. If the connection is not a socket, let 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the address be 0.0.0.0. 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&from, 0, sizeof(from)); 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fromlen = sizeof(from); 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_connection_is_on_socket()) { 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getpeername(packet_get_connection_in(), 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (struct sockaddr *)&from, &fromlen) < 0) { 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("getpeername: %.100s", strerror(errno)); 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(255); 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood record_utmp_only(pid, s->tty, s->pw->pw_name, 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood get_remote_name_or_ip(utmp_len, options.use_dns), 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (struct sockaddr *)&from, fromlen); 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This is called to fork and execute a command. If another command is 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * to be forced, execute that instead. 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_exec(Session *s, const char *command) 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int ret; 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.adm_forced_command) { 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood original_command = command; 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood command = options.adm_forced_command; 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (IS_INTERNAL_SFTP(command)) { 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem = s->is_subsystem ? 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (s->is_subsystem) 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem = SUBSYSTEM_EXT; 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Forced command (config) '%.900s'", command); 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (forced_command) { 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood original_command = command; 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood command = forced_command; 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (IS_INTERNAL_SFTP(command)) { 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem = s->is_subsystem ? 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (s->is_subsystem) 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem = SUBSYSTEM_EXT; 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Forced command (key option) '%.900s'", command); 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef SSH_AUDIT_EVENTS 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (command != NULL) 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood PRIVSEP(audit_run_command(command)); 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (s->ttyfd == -1) { 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *shell = s->pw->pw_shell; 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (shell[0] == '\0') /* empty shell means /bin/sh */ 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell =_PATH_BSHELL; 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood PRIVSEP(audit_run_command(shell)); 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = do_exec_pty(s, command); 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ret = do_exec_no_pty(s, command); 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood original_command = NULL; 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Clear loginmsg: it's the child's responsibility to display 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * it to the user, otherwise multiple sessions may accumulate 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * multiple copies of the login messages. 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_clear(&loginmsg); 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ret; 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* administrative, login(1)-like work */ 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_login(Session *s, const char *command) 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood socklen_t fromlen; 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct sockaddr_storage from; 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct passwd * pw = s->pw; 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pid_t pid = getpid(); 8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Get IP address of client. If the connection is not a socket, let 8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the address be 0.0.0.0. 8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(&from, 0, sizeof(from)); 8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fromlen = sizeof(from); 8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_connection_is_on_socket()) { 8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getpeername(packet_get_connection_in(), 8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (struct sockaddr *)&from, &fromlen) < 0) { 8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("getpeername: %.100s", strerror(errno)); 8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cleanup_exit(255); 8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Record that there was a login on that tty from the remote host. */ 8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!use_privsep) 8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood record_login(pid, s->tty, pw->pw_name, pw->pw_uid, 8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood get_remote_name_or_ip(utmp_len, 8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.use_dns), 8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (struct sockaddr *)&from, fromlen); 8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PAM 8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If password change is needed, do it now. 8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This needs to occur before the ~/.hushlogin check. 8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) { 8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display_loginmsg(); 8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_pam_chauthtok(); 8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->authctxt->force_pwchange = 0; 8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX - signal [net] parent to enable forwardings */ 8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (check_quietlogin(s, command)) 8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display_loginmsg(); 8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_motd(); 8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Display the message of the day. 8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_motd(void) 8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f; 9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[256]; 9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.print_motd) { 9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = fopen(login_getcapstr(lc, "welcome", "/etc/motd", 9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "/etc/motd"), "r"); 9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = fopen("/etc/motd", "r"); 9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f) { 9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (fgets(buf, sizeof(buf), f)) 9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs(buf, stdout); 9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fclose(f); 9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Check for quiet login, either .hushlogin or command given. 9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcheck_quietlogin(Session *s, const char *command) 9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[256]; 9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct passwd *pw = s->pw; 9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Return 1 if .hushlogin exists or a command given. */ 9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (command != NULL) 9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); 9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) 9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(buf, &st) >= 0) 9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sets the value of the given variable in the environment. If the variable 9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * already exists, its value is overridden. 9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchild_set_env(char ***envp, u_int *envsizep, const char *name, 9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *value) 9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char **env; 9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int envsize; 9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, namelen; 9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If we're passed an uninitialized list, allocate a single null 9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * entry before continuing. 9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*envp == NULL && *envsizep == 0) { 9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *envp = xmalloc(sizeof(char *)); 9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *envp[0] = NULL; 9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *envsizep = 1; 9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Find the slot where the value should be stored. If the variable 9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * already exists, we reuse the slot; otherwise we append a new slot 9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * at the end of the array, expanding if necessary. 9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env = *envp; 9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood namelen = strlen(name); 9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; env[i]; i++) 9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=') 9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (env[i]) { 9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Reuse the slot. */ 9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(env[i]); 9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* New variable. Expand if necessary. */ 9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood envsize = *envsizep; 9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i >= envsize - 1) { 9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (envsize >= 1000) 9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("child_set_env: too many env vars"); 9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood envsize += 50; 9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env = (*envp) = xrealloc(env, envsize, sizeof(char *)); 9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *envsizep = envsize; 9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Need to set the NULL pointer at end of array beyond the new slot. */ 9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env[i + 1] = NULL; 9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allocate space and format the variable in the appropriate slot. */ 9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1); 9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value); 9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Reads environment variables from the given file and adds/overrides them 9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * into the environment. If the file does not exist, this does nothing. 10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Otherwise, it must consist of empty lines, comments (line starts with '#') 10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and assignments of the form name=value. No other forms are allowed. 10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodread_environment_file(char ***env, u_int *envsize, 10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *filename) 10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f; 10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[4096]; 10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp, *value; 10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int lineno = 0; 10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = fopen(filename, "r"); 10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!f) 10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (fgets(buf, sizeof(buf), f)) { 10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (++lineno > 1000) 10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Too many lines in environment file %s", filename); 10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (cp = buf; *cp == ' ' || *cp == '\t'; cp++) 10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!*cp || *cp == '#' || *cp == '\n') 10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp[strcspn(cp, "\n")] = '\0'; 10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value = strchr(cp, '='); 10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (value == NULL) { 10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Bad line %u in %.100s\n", lineno, 10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood filename); 10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Replace the equals sign by nul, and advance value to 10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the value string. 10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *value = '\0'; 10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood value++; 10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(env, envsize, cp, value); 10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fclose(f); 10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_ETC_DEFAULT_LOGIN 10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Return named variable from specified environment, or NULL if not present. 10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchild_get_env(char **env, const char *name) 10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t len; 10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = strlen(name); 10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i=0; env[i] != NULL; i++) 10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strncmp(name, env[i], len) == 0 && env[i][len] == '=') 10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(env[i] + len + 1); 10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Read /etc/default/login. 10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We pick up the PATH (or SUPATH for root) and UMASK. 10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodread_etc_default_login(char ***env, u_int *envsize, uid_t uid) 10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char **tmpenv = NULL, *var; 10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, tmpenvsize = 0; 10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_long mask; 10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * We don't want to copy the whole file to the child's environment, 10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * so we use a temporary environment and copy the variables we're 10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * interested in. 10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood read_environment_file(&tmpenv, &tmpenvsize, "/etc/default/login"); 10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tmpenv == NULL) 10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (uid == 0) 10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood var = child_get_env(tmpenv, "SUPATH"); 10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood var = child_get_env(tmpenv, "PATH"); 10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (var != NULL) 10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(env, envsize, "PATH", var); 10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((var = child_get_env(tmpenv, "UMASK")) != NULL) 10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sscanf(var, "%5lo", &mask) == 1) 10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood umask((mode_t)mask); 10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; tmpenv[i] != NULL; i++) 10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(tmpenv[i]); 10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(tmpenv); 10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* HAVE_ETC_DEFAULT_LOGIN */ 10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcopy_environment(char **source, char ***env, u_int *envsize) 11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *var_name, *var_val; 11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (source == NULL) 11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for(i = 0; source[i] != NULL; i++) { 11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood var_name = xstrdup(source[i]); 11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((var_val = strstr(var_name, "=")) == NULL) { 11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(var_name); 11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *var_val++ = '\0'; 11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("Copy environment: %s=%s", var_name, var_val); 11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(env, envsize, var_name, var_val); 11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(var_name); 11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char ** 11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_setup_env(Session *s, const char *shell) 11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[256]; 11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i, envsize; 11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char **env, *laddr; 11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct passwd *pw = s->pw; 11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN) 11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *path = NULL; 11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Initialize the environment. */ 11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood envsize = 100; 11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env = xcalloc(envsize, sizeof(char *)); 11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env[0] = NULL; 11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_CYGWIN 11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The Windows environment contains some setting which are 11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * important for a running system. They must not be dropped. 11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { 11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char **p; 11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = fetch_windows_environment(); 11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy_environment(p, &env, &envsize); 11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_windows_environment(p); 11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allow any GSSAPI methods that we've used to alter 11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the childs environment as they see fit 11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_gssapi_do_child(&env, &envsize); 11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.use_login) { 11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set basic environment. */ 11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < s->num_env; i++) 11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, s->env[i].name, 11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->env[i].val); 11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "USER", pw->pw_name); 11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); 11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _AIX 11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "LOGIN", pw->pw_name); 11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "HOME", pw->pw_dir); 11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) 11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); 11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "PATH", getenv("PATH")); 11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else /* HAVE_LOGIN_CAP */ 11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifndef HAVE_CYGWIN 11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * There's no standard path on Windows. The path contains 11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * important components pointing to the system directories, 11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * needed for loading shared libraries. So the path better 11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * remains intact here. 11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef HAVE_ETC_DEFAULT_LOGIN 11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood read_etc_default_login(&env, &envsize, pw->pw_uid); 11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood path = child_get_env(env, "PATH"); 11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* HAVE_ETC_DEFAULT_LOGIN */ 11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (path == NULL || *path == '\0') { 11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "PATH", 11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pw->pw_uid == 0 ? 11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SUPERUSER_PATH : _PATH_STDPATH); 11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* HAVE_CYGWIN */ 11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* HAVE_LOGIN_CAP */ 11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, "%.200s/%.50s", 11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _PATH_MAILDIR, pw->pw_name); 11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "MAIL", buf); 11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Normal systems set SHELL by default. */ 12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "SHELL", shell); 12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getenv("TZ")) 12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "TZ", getenv("TZ")); 12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set custom environment options from RSA authentication. */ 12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.use_login) { 12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (custom_environment) { 12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct envstring *ce = custom_environment; 12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *str = ce->s; 12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; str[i] != '=' && str[i]; i++) 12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; 12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (str[i] == '=') { 12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood str[i] = 0; 12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, str, str + i + 1); 12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood custom_environment = ce->next; 12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ce->s); 12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(ce); 12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* SSH_CLIENT deprecated */ 12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, "%.50s %d %d", 12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood get_remote_ipaddr(), get_remote_port(), get_local_port()); 12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "SSH_CLIENT", buf); 12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood laddr = get_local_ipaddr(packet_get_connection_in()); 12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, "%.50s %d %.50s %d", 12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood get_remote_ipaddr(), get_remote_port(), laddr, get_local_port()); 12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(laddr); 12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "SSH_CONNECTION", buf); 12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) 12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "SSH_TTY", s->tty); 12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->term) 12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "TERM", s->term); 12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->display) 12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "DISPLAY", s->display); 12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (original_command) 12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", 12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood original_command); 12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cray_tmpdir[0] != '\0') 12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); 12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _UNICOS */ 12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Since we clear KRB5CCNAME at startup, if it's set now then it 12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * must have been set by a native authentication method (eg AIX or 12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SIA), so copy it to the child. 12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { 12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp; 12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((cp = getenv("KRB5CCNAME")) != NULL) 12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "KRB5CCNAME", cp); 12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _AIX 12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { 12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp; 12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((cp = getenv("AUTHSTATE")) != NULL) 12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "AUTHSTATE", cp); 12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood read_environment_file(&env, &envsize, "/etc/environment"); 12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef KRB5 12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->authctxt->krb5_ccname) 12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, "KRB5CCNAME", 12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->authctxt->krb5_ccname); 12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PAM 12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Pull in any environment variables that may have 12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * been set by PAM. 12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_pam) { 12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char **p; 12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = fetch_pam_child_environment(); 12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy_environment(p, &env, &envsize); 12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_pam_environment(p); 12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = fetch_pam_environment(); 12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy_environment(p, &env, &envsize); 12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free_pam_environment(p); 12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* USE_PAM */ 12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (auth_sock_name != NULL) 12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_set_env(&env, &envsize, SSH_AUTHSOCKET_ENV_NAME, 12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_name); 12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* read $HOME/.ssh/environment. */ 12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.permit_user_env && !options.use_login) { 13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, sizeof buf, "%.200s/.ssh/environment", 13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); 13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood read_environment_file(&env, &envsize, buf); 13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (debug_flag) { 13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* dump the environment */ 13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Environment:\n"); 13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; env[i]; i++) 13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, " %.200s\n", env[i]); 13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return env; 13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Run $HOME/.ssh/rc, /etc/ssh/sshrc, or xauth (whichever is found 13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * first in this order). 13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_rc_files(Session *s, const char *shell) 13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f = NULL; 13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char cmd[1024]; 13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int do_xauth; 13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_xauth = 13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display != NULL && s->auth_proto != NULL && s->auth_data != NULL; 13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* ignore _PATH_SSH_USER_RC for subsystems and admin forced commands */ 13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!s->is_subsystem && options.adm_forced_command == NULL && 13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood !no_user_rc && stat(_PATH_SSH_USER_RC, &st) >= 0) { 13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(cmd, sizeof cmd, "%s -c '%s %s'", 13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell, _PATH_BSHELL, _PATH_SSH_USER_RC); 13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (debug_flag) 13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Running %s\n", cmd); 13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = popen(cmd, "w"); 13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f) { 13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_xauth) 13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "%s %s\n", s->auth_proto, 13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data); 13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pclose(f); 13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Could not run %s\n", 13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _PATH_SSH_USER_RC); 13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (stat(_PATH_SSH_SYSTEM_RC, &st) >= 0) { 13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (debug_flag) 13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Running %s %s\n", _PATH_BSHELL, 13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _PATH_SSH_SYSTEM_RC); 13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = popen(_PATH_BSHELL " " _PATH_SSH_SYSTEM_RC, "w"); 13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f) { 13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (do_xauth) 13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "%s %s\n", s->auth_proto, 13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data); 13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pclose(f); 13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Could not run %s\n", 13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood _PATH_SSH_SYSTEM_RC); 13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (do_xauth && options.xauth_location != NULL) { 13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Add authority data to .Xauthority if appropriate. */ 13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (debug_flag) { 13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, 13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Running %.500s remove %.100s\n", 13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.xauth_location, s->auth_display); 13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, 13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%.500s add %.100s %.100s %.100s\n", 13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.xauth_location, s->auth_display, 13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_proto, s->auth_data); 13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(cmd, sizeof cmd, "%s -q -", 13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.xauth_location); 13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood f = popen(cmd, "w"); 13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (f) { 13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "remove %s\n", 13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_display); 13741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(f, "add %s %s %s\n", 13751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_display, s->auth_proto, 13761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data); 13771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pclose(f); 13781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 13791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Could not run %s\n", 13801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmd); 13811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 13831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 13841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 13861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_nologin(struct passwd *pw) 13871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 13881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood FILE *f = NULL; 13891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[1024], *nl, *def_nl = _PATH_NOLOGIN; 13901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat sb; 13911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 13921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 13931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) 13941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 13951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nl = login_getcapstr(lc, "nologin", def_nl, def_nl); 13961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 13971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (pw->pw_uid == 0) 13981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 13991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nl = def_nl; 14001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 14011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(nl, &sb) == -1) { 14021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (nl != def_nl) 14031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(nl); 14041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 14051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* /etc/nologin exists. Print its contents if we can and exit. */ 14081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("User %.100s not allowed because %s exists", pw->pw_name, nl); 14091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((f = fopen(nl, "r")) != NULL) { 14101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (fgets(buf, sizeof(buf), f)) 14111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs(buf, stderr); 14121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fclose(f); 14131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(254); 14151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 14161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 14181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Chroot into a directory after checking it for safety: all path components 14191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * must be root-owned directories with strict permissions. 14201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 14221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsafely_chroot(const char *path, uid_t uid) 14231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 14241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *cp; 14251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char component[MAXPATHLEN]; 14261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 14271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*path != '/') 14291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chroot path does not begin at root"); 14301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlen(path) >= sizeof(component)) 14311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chroot path too long"); 14321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 14341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Descend the path, checking that each component is a 14351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * root-owned directory with strict permissions. 14361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 14371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (cp = path; cp != NULL;) { 14381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((cp = strchr(cp, '/')) == NULL) 14391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(component, path, sizeof(component)); 14401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 14411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp++; 14421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(component, path, cp - path); 14431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood component[cp - path] = '\0'; 14441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: checking '%s'", __func__, component); 14471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(component, &st) != 0) 14491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: stat(\"%s\"): %s", __func__, 14501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood component, strerror(errno)); 14511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (st.st_uid != 0 || (st.st_mode & 022) != 0) 14521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("bad ownership or modes for chroot " 14531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "directory %s\"%s\"", 14541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp == NULL ? "" : "component ", component); 14551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!S_ISDIR(st.st_mode)) 14561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chroot path %s\"%s\" is not a directory", 14571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp == NULL ? "" : "component ", component); 14581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chdir(path) == -1) 14621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Unable to chdir to chroot path \"%s\": " 14631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%s", path, strerror(errno)); 14641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chroot(path) == -1) 14651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chroot(\"%s\"): %s", path, strerror(errno)); 14661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chdir("/") == -1) 14671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: chdir(/) after chroot: %s", 14681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, strerror(errno)); 14691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood verbose("Changed root directory to \"%s\"", path); 14701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 14711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Set login name, uid, gid, and groups. */ 14731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 14741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_setusercontext(struct passwd *pw) 14751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 14761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *chroot_path, *tmp; 14771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood platform_setusercontext(pw); 14791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 14801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (platform_privileged_uidswap()) { 14811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 14821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setusercontext(lc, pw, pw->pw_uid, 14831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) { 14841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("unable to set user context"); 14851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 14861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 14881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setlogin(pw->pw_name) < 0) 14891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setlogin failed: %s", strerror(errno)); 14901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setgid(pw->pw_gid) < 0) { 14911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("setgid"); 14921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 14931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Initialize the group list. */ 14951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (initgroups(pw->pw_name, pw->pw_gid) < 0) { 14961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("initgroups"); 14971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 14981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 14991b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood#ifndef ANDROID 15001b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood /* FIXME - Android doesn't have this */ 15011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood endgrent(); 15021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15031b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood#endif 15041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood platform_setusercontext_post_groups(pw); 15061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.chroot_directory != NULL && 15081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcasecmp(options.chroot_directory, "none") != 0) { 15091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tmp = tilde_expand_filename(options.chroot_directory, 15101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pw->pw_uid); 15111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chroot_path = percent_expand(tmp, "h", pw->pw_dir, 15121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "u", pw->pw_name, (char *)NULL); 15131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood safely_chroot(chroot_path, pw->pw_uid); 15141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free(tmp); 15151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood free(chroot_path); 15161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 15191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { 15201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("unable to set user context (setuser)"); 15211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 15221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 15241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Permanently switch to the desired uid. */ 15251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood permanently_set_uid(pw); 15261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) 15301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); 15311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 15321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 15341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_pwchange(Session *s) 15351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 15361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fflush(NULL); 15371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "WARNING: Your password has expired.\n"); 15381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) { 15391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, 15401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "You must change your password now and login again!\n"); 15411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX 15421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setexeccon(NULL); 15431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PASSWD_NEEDS_USERNAME 15451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name, 15461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (char *)NULL); 15471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 15481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL); 15491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("passwd"); 15511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 15521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, 15531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "Password change required but no TTY available.\n"); 15541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 15561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 15571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 15591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodlaunch_login(struct passwd *pw, const char *hostname) 15601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 15611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Launch login(1). */ 15621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execl(LOGIN_PROGRAM, "login", "-h", hostname, 15641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef xxxLOGIN_NEEDS_TERM 15651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (s->term ? s->term : "unknown"), 15661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* LOGIN_NEEDS_TERM */ 15671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef LOGIN_NO_ENDOPT 15681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "-p", "-f", pw->pw_name, (char *)NULL); 15691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 15701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "-p", "-f", "--", pw->pw_name, (char *)NULL); 15711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 15721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Login couldn't be executed, die. */ 15741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror("login"); 15761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 15771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 15781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 15801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchild_close_fds(void) 15811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 15821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (packet_get_connection_in() == packet_get_connection_out()) 15831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(packet_get_connection_in()); 15841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 15851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(packet_get_connection_in()); 15861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(packet_get_connection_out()); 15871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 15881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Close all descriptors related to channels. They will still remain 15901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * open in the parent. 15911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* XXX better use close-on-exec? -markus */ 15931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_close_all(); 15941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 15951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 15961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Close any extra file descriptors. Note that there may still be 15971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * descriptors left by system functions. They will be closed later. 15981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 15991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood endpwent(); 16001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Close any extra open file descriptors so that we don't have them 16031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * hanging around in clients. Note that we want to do this after 16041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * initgroups, because at least on Solaris 2.3 it leaves file 16051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * descriptors open. 16061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood closefrom(STDERR_FILENO + 1); 16081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 16091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 16111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Performs common processing for the child, such as setting up the 16121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * environment, closing extra file descriptors, setting the user and group 16131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ids, and executing the command or shell. 16141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define ARGV_MAX 10 16161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 16171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_child(Session *s, const char *command) 16181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 16191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood extern char **environ; 16201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char **env; 16211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *argv[ARGV_MAX]; 16221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *shell, *shell0, *hostname = NULL; 16231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct passwd *pw = s->pw; 16241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int r = 0; 16251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* remove hostkey from the child's memory */ 16271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood destroy_sensitive_data(); 16281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Force a password change */ 16301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->authctxt->force_pwchange) { 16311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_setusercontext(pw); 16321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_close_fds(); 16331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_pwchange(s); 16341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 16351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* login(1) is only called if we execute the login shell */ 16381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_login && command != NULL) 16391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.use_login = 0; 16401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 16421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cray_setup(pw->pw_uid, pw->pw_name, command); 16431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _UNICOS */ 16441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Login(1) does this as well, and it needs uid 0 for the "-h" 16471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * switch, so we let login(1) to this for us. 16481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.use_login) { 16501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_OSF_SIA 16511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_setup_sia(pw, s->ttyfd == -1 ? NULL : s->tty); 16521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!check_quietlogin(s, command)) 16531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_motd(); 16541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else /* HAVE_OSF_SIA */ 16551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* When PAM is enabled we rely on it to do the nologin check */ 16561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.use_pam) 16571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_nologin(pw); 16581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_setusercontext(pw); 16591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * PAM session modules in do_setusercontext may have 16611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * generated messages, so if this in an interactive 16621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * login then display them too. 16631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!check_quietlogin(s, command)) 16651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display_loginmsg(); 16661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* HAVE_OSF_SIA */ 16671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PAM 16701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_pam && !options.use_login && !is_pam_session_open()) { 16711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("PAM session not opened, exiting"); 16721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood display_loginmsg(); 16731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(254); 16741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 16751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 16761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Get the shell from the password data. An empty shell field is 16791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * legal, and means /bin/sh. 16801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 16821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Make sure $SHELL points to the shell from the password file, 16851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * even if shell is overridden from login.conf 16861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 16871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood env = do_setup_env(s, shell); 16881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 16901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); 16911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 16921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 16931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* we have to stash the hostname before we close our socket. */ 16941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_login) 16951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hostname = get_remote_name_or_ip(utmp_len, 16961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.use_dns); 16971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 16981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Close the connection descriptors; note that this is the child, and 16991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the server will still have the socket open, and it is important 17001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * that we do not shutdown it. Note that the descriptors cannot be 17011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * closed before building the environment, as we call 17021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * get_remote_ipaddr there. 17031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 17041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood child_close_fds(); 17051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 17071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Must take new environment into use so that .ssh/rc, 17081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * /etc/ssh/sshrc and xauth are run in the proper environment. 17091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 17101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood environ = env; 17111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(KRB5) && defined(USE_AFS) 17131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 17141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * At this point, we check to see if AFS is active and if we have 17151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * a valid Kerberos 5 TGT. If so, it seems like a good idea to see 17161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * if we can (and need to) extend the ticket into an AFS token. If 17171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * we don't do this, we run into potential problems if the user's 17181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * home directory is in AFS and it's not world-readable. 17191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 17201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.kerberos_get_afs_token && k_hasafs() && 17221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (s->authctxt->krb5_ctx != NULL)) { 17231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char cell[64]; 17241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Getting AFS token"); 17261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood k_setpag(); 17281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) 17301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood krb5_afslog(s->authctxt->krb5_ctx, 17311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->authctxt->krb5_fwd_ccache, cell, NULL); 17321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood krb5_afslog_home(s->authctxt->krb5_ctx, 17341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir); 17351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 17371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Change current directory to the user's home directory. */ 17391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chdir(pw->pw_dir) < 0) { 17401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Suppress missing homedir warning for chroot case */ 17411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_LOGIN_CAP 17421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = login_getcapbool(lc, "requirehome", 0); 17431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 17441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (r || options.chroot_directory == NULL || 17451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strcasecmp(options.chroot_directory, "none") == 0) 17461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Could not chdir to home " 17471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "directory %s: %s\n", pw->pw_dir, 17481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 17491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (r) 17501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 17511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood closefrom(STDERR_FILENO + 1); 17541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.use_login) 17561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood do_rc_files(s, shell); 17571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* restore SIGPIPE for child */ 17591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGPIPE, SIG_DFL); 17601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { 17621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood printf("This service allows sftp connections only.\n"); 17631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fflush(NULL); 17641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 17651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { 17661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood extern int optind, optreset; 17671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 17681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *p, *args; 17691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME); 17711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args = xstrdup(command ? command : "sftp-server"); 17721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) 17731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i < ARGV_MAX - 1) 17741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[i++] = p; 17751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[i] = NULL; 17761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood optind = optreset = 1; 17771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __progname = argv[0]; 17781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX 17791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_selinux_change_context("sftpd_t"); 17801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 17811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(sftp_server_main(i, argv, s->pw)); 17821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fflush(NULL); 17851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_login) { 17871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood launch_login(pw, hostname); 17881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* NEVERREACHED */ 17891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 17901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Get the last component of the shell name. */ 17921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((shell0 = strrchr(shell, '/')) != NULL) 17931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell0++; 17941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 17951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shell0 = shell; 17961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 17971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 17981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If we have no command, execute the shell. In this case, the shell 17991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * name to be passed in argv[0] is preceded by '-' to indicate that 18001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * this is a login shell. 18011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 18021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!command) { 18031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char argv0[256]; 18041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Start the shell. Set initial character to '-'. */ 18061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv0[0] = '-'; 18071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlcpy(argv0 + 1, shell0, sizeof(argv0) - 1) 18091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood >= sizeof(argv0) - 1) { 18101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = EINVAL; 18111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror(shell); 18121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 18131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Execute the shell. */ 18161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[0] = argv0; 18171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[1] = NULL; 18181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execve(shell, argv, env); 18191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Executing the shell failed. */ 18211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror(shell); 18221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 18231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 18251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Execute the command using the user's shell. This uses the -c 18261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * option to execute the command. 18271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 18281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[0] = (char *) shell0; 18291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[1] = "-c"; 18301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[2] = (char *) command; 18311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood argv[3] = NULL; 18321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood execve(shell, argv, env); 18331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood perror(shell); 18341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 18351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 18381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_unused(int id) 18391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: session id %d unused", __func__, id); 18411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (id >= options.max_sessions || 18421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id >= sessions_nalloc) { 18431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: insane session id %d (max %d nalloc %d)", 18441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, id, options.max_sessions, sessions_nalloc); 18451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bzero(&sessions[id], sizeof(*sessions)); 18471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].self = id; 18481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].used = 0; 18491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].chanid = -1; 18501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].ptyfd = -1; 18511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].ttyfd = -1; 18521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].ptymaster = -1; 18531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].x11_chanids = NULL; 18541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions[id].next_unused = sessions_first_unused; 18551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions_first_unused = id; 18561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18581305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSession * 18591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_new(void) 18601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 18611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s, *tmp; 18621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sessions_first_unused == -1) { 18641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sessions_nalloc >= options.max_sessions) 18651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 18661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("%s: allocate (allocated %d max %d)", 18671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, sessions_nalloc, options.max_sessions); 18681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tmp = xrealloc(sessions, sessions_nalloc + 1, 18691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sizeof(*sessions)); 18701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tmp == NULL) { 18711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%s: cannot allocate %d sessions", 18721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, sessions_nalloc + 1); 18731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 18741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions = tmp; 18761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_unused(sessions_nalloc++); 18771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sessions_first_unused >= sessions_nalloc || 18801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions_first_unused < 0) { 18811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: insane first_unused %d max %d nalloc %d", 18821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, sessions_first_unused, options.max_sessions, 18831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions_nalloc); 18841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s = &sessions[sessions_first_unused]; 18871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->used) { 18881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: session %d already used", 18891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood __func__, sessions_first_unused); 18901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 18911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sessions_first_unused = s->next_unused; 18921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->used = 1; 18931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->next_unused = -1; 18941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_new: session %d", s->self); 18951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 18971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 18981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 18991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 19001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_dump(void) 19011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 19031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 19041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 19051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("dump: used %d next_unused %d session %d %p " 19071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "channel %d pid %ld", 19081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->used, 19091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->next_unused, 19101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->self, 19111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s, 19121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->chanid, 19131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long)s->pid); 19141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 19181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_open(Authctxt *authctxt, int chanid) 19191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = session_new(); 19211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_open: channel %d", chanid); 19221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) { 19231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("no more sessions"); 19241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 19251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->authctxt = authctxt; 19271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pw = authctxt->pw; 19281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->pw == NULL || !authctxt->valid) 19291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("no user for session %d", s->self); 19301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_open: session %d: link with channel %d", s->self, chanid); 19311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->chanid = chanid; 19321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 19331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19351305e95ba6ff9fa202d0818caf10405df4b0f648Mike LockwoodSession * 19361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_by_tty(char *tty) 19371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 19391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 19401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 19411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { 19421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_tty: session %d tty %s", i, tty); 19431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 19441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_tty: unknown tty %.100s", tty); 19471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_dump(); 19481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 19491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Session * 19521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_by_channel(int id) 19531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 19551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 19561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 19571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->used && s->chanid == id) { 19581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_channel: session %d channel %d", 19591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood i, id); 19601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 19611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_channel: unknown channel %d", id); 19641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_dump(); 19651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 19661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Session * 19691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_by_x11_channel(int id) 19701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i, j; 19721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 19741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 19751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->x11_chanids == NULL || !s->used) 19771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 19781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (j = 0; s->x11_chanids[j] != -1; j++) { 19791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->x11_chanids[j] == id) { 19801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_x11_channel: session %d " 19811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "channel %d", s->self, id); 19821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 19831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 19861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_x11_channel: unknown channel %d", id); 19871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_dump(); 19881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 19891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 19901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 19911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic Session * 19921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_by_pid(pid_t pid) 19931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 19941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 19951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_by_pid: pid %ld", (long)pid); 19961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 19971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 19981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->used && s->pid == pid) 19991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 20001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("session_by_pid: unknown pid %ld", (long)pid); 20021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_dump(); 20031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 20041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 20071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_window_change_req(Session *s) 20081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->col = packet_get_int(); 20101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->row = packet_get_int(); 20111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->xpixel = packet_get_int(); 20121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ypixel = packet_get_int(); 20131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 20141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 20151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 20161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 20191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_pty_req(Session *s) 20201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len; 20221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int n_bytes; 20231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (no_pty_flag) { 20251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Allocating a pty not permitted for this authentication."); 20261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 20271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) { 20291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_disconnect("Protocol error: you already have a pty."); 20301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 20311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->term = packet_get_string(&len); 20341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20) { 20361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->col = packet_get_int(); 20371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->row = packet_get_int(); 20381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 20391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->row = packet_get_int(); 20401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->col = packet_get_int(); 20411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->xpixel = packet_get_int(); 20431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ypixel = packet_get_int(); 20441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(s->term, "") == 0) { 20461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->term); 20471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->term = NULL; 20481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allocate a pty and open it. */ 20511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Allocating pty."); 20521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, 20531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sizeof(s->tty)))) { 20541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->term) 20551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->term); 20561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->term = NULL; 20571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ptyfd = -1; 20581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ttyfd = -1; 20591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("session_pty_req: session %d alloc failed", s->self); 20601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 20611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 20621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_pty_req: session %d alloc %s", s->self, s->tty); 20631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* for SSH1 the tty modes length is not given */ 20651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) 20661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood n_bytes = packet_remaining(); 20671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tty_parse_modes(s->ttyfd, &n_bytes); 20681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!use_privsep) 20701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pty_setowner(s->pw, s->tty); 20711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set window size from the packet. */ 20731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); 20741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 20761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_proctitle(s); 20771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 20781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 20791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 20811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_subsystem_req(Session *s) 20821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 20831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 20841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len; 20851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = 0; 20861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *prog, *cmd, *subsys = packet_get_string(&len); 20871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 20881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 20901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("subsystem request for %.100s by user %s", subsys, 20911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pw->pw_name); 20921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 20931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < options.num_subsystems; i++) { 20941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(subsys, options.subsystem_name[i]) == 0) { 20951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood prog = options.subsystem_command[i]; 20961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cmd = options.subsystem_args[i]; 20971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { 20981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem = SUBSYSTEM_INT_SFTP; 20991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("subsystem: %s", prog); 21001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 21011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(prog, &st) < 0) 21021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("subsystem: cannot stat %s: %s", 21031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood prog, strerror(errno)); 21041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->is_subsystem = SUBSYSTEM_EXT; 21051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("subsystem: exec() %s", cmd); 21061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = do_exec(s, cmd) == 0; 21081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 21091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!success) 21131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("subsystem request for %.100s failed, subsystem not found", 21141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood subsys); 21151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(subsys); 21171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 21181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 21211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_x11_req(Session *s) 21221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success; 21241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_proto != NULL || s->auth_data != NULL) { 21261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("session_x11_req: session %d: " 21271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "x11 forwarding already active", s->self); 21281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 21291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->single_connection = packet_get_char(); 21311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_proto = packet_get_string(NULL); 21321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data = packet_get_string(NULL); 21331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->screen = packet_get_int(); 21341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 21351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_setup_x11fwd(s); 21371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!success) { 21381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_proto); 21391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_data); 21401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_proto = NULL; 21411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data = NULL; 21421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 21441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 21471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_shell_req(Session *s) 21481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 21501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return do_exec(s, NULL) == 0; 21511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 21541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_exec_req(Session *s) 21551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len, success; 21571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *command = packet_get_string(&len); 21591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 21601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = do_exec(s, command) == 0; 21611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(command); 21621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 21631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 21661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_break_req(Session *s) 21671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_int(); /* ignored */ 21701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 21711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd == -1 || tcsendbreak(s->ttyfd, 0) < 0) 21731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 21741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 21751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 21761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 21781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_env_req(Session *s) 21791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 21801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *name, *val; 21811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int name_len, val_len, i; 21821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood name = packet_get_string(&name_len); 21841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val = packet_get_string(&val_len); 21851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 21861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Don't set too many environment variables */ 21881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->num_env > 128) { 21891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("Ignoring env request %s: too many env vars", name); 21901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto fail; 21911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 21921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 21931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < options.num_accept_env; i++) { 21941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (match_pattern(name, options.accept_env[i])) { 21951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("Setting env %d: %s=%s", s->num_env, name, val); 21961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->env = xrealloc(s->env, s->num_env + 1, 21971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sizeof(*s->env)); 21981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->env[s->num_env].name = name; 21991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->env[s->num_env].val = val; 22001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->num_env++; 22011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (1); 22021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("Ignoring env request %s: disallowed name", name); 22051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fail: 22071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(name); 22081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(val); 22091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 22101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 22131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_auth_agent_req(Session *s) 22141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 22151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static int called = 0; 22161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 22171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (no_agent_forwarding_flag || !options.allow_agent_forwarding) { 22181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_auth_agent_req: no_agent_forwarding_flag"); 22191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 22201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (called) { 22221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 22231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 22241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood called = 1; 22251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return auth_input_request_forwarding(s->pw); 22261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 22301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_input_channel_req(Channel *c, const char *rtype) 22311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 22321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int success = 0; 22331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s; 22341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((s = session_by_channel(c->self)) == NULL) { 22361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood logit("session_input_channel_req: no session %d req %.100s", 22371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood c->self, rtype); 22381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 22391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_input_channel_req: session %d req %s", s->self, rtype); 22411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 22431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * a session is in LARVAL state until a shell, a command 22441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * or a subsystem is executed 22451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 22461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->type == SSH_CHANNEL_LARVAL) { 22471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(rtype, "shell") == 0) { 22481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_shell_req(s); 22491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "exec") == 0) { 22501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_exec_req(s); 22511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "pty-req") == 0) { 22521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_pty_req(s); 22531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "x11-req") == 0) { 22541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_x11_req(s); 22551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "auth-agent-req@openssh.com") == 0) { 22561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_auth_agent_req(s); 22571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "subsystem") == 0) { 22581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_subsystem_req(s); 22591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "env") == 0) { 22601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_env_req(s); 22611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcmp(rtype, "window-change") == 0) { 22641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_window_change_req(s); 22651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (strcmp(rtype, "break") == 0) { 22661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood success = session_break_req(s); 22671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 22681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return success; 22701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 22731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_set_fds(Session *s, int fdin, int fdout, int fderr, int ignore_fderr, 22741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int is_tty) 22751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 22761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!compat20) 22771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("session_set_fds: called for proto != 2.0"); 22781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 22791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * now that have a child and a pipe to the child, 22801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * we can activate our channel and register the fd's 22811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 22821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->chanid == -1) 22831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("no channel for session %d", s->self); 22841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_set_fds(s->chanid, 22851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fdout, fdin, fderr, 22861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ, 22871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1, is_tty, CHAN_SES_WINDOW_DEFAULT); 22881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 22891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 22901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 22911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Function to perform pty cleanup. Also called if we get aborted abnormally 22921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (e.g., due to a dropped connection). 22931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 22941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 22951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_pty_cleanup2(Session *s) 22961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 22971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) { 22981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("session_pty_cleanup: no session"); 22991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 23001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 23011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd == -1) 23021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 23031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_pty_cleanup: session %d release %s", s->self, s->tty); 23051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Record that the user has logged out. */ 23071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->pid != 0) 23081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood record_logout(s->pid, s->tty, s->pw->pw_name); 23091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Release the pseudo-tty. */ 23111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getuid() == 0) 23121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood pty_release(s->tty); 23131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 23151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Close the server side of the socket pairs. We must do this after 23161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the pty cleanup, so that another process doesn't get this pty 23171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * while we're still cleaning up. 23181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 23191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ptymaster != -1 && close(s->ptymaster) < 0) 23201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("close(s->ptymaster/%d): %s", 23211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ptymaster, strerror(errno)); 23221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* unlink pty from session */ 23241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->ttyfd = -1; 23251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 23261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 23281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_pty_cleanup(Session *s) 23291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 23301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood PRIVSEP(session_pty_cleanup2(s)); 23311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 23321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 23341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsig2name(int sig) 23351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 23361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SSH_SIG(x) if (sig == SIG ## x) return #x 23371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(ABRT); 23381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(ALRM); 23391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(FPE); 23401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(HUP); 23411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(ILL); 23421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(INT); 23431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(KILL); 23441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(PIPE); 23451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(QUIT); 23461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(SEGV); 23471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(TERM); 23481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(USR1); 23491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood SSH_SIG(USR2); 23501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#undef SSH_SIG 23511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return "SIG@openssh.com"; 23521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 23531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 23551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_close_x11(int id) 23561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 23571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c; 23581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((c = channel_by_id(id)) == NULL) { 23601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_x11: x11 channel %d missing", id); 23611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 23621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Detach X11 listener */ 23631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_x11: detach x11 channel %d", id); 23641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_cancel_cleanup(id); 23651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate != CHAN_OUTPUT_CLOSED) 23661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_mark_dead(c); 23671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 23681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 23691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 23711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_close_single_x11(int id, void *arg) 23721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 23731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s; 23741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 23751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 23761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("session_close_single_x11: channel %d", id); 23771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_cancel_cleanup(id); 23781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((s = session_by_x11_channel(id)) == NULL) 23791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("session_close_single_x11: no x11 channel %d", id); 23801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; s->x11_chanids[i] != -1; i++) { 23811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_single_x11: session %d: " 23821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "closing channel %d", s->self, s->x11_chanids[i]); 23831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 23841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * The channel "id" is already closing, but make sure we 23851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * close all of its siblings. 23861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 23871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->x11_chanids[i] != id) 23881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_close_x11(s->x11_chanids[i]); 23891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 23901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->x11_chanids); 23911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->x11_chanids = NULL; 23921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->display) { 23931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->display); 23941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display = NULL; 23951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 23961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_proto) { 23971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_proto); 23981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_proto = NULL; 23991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 24001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_data) { 24011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_data); 24021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_data = NULL; 24031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 24041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_display) { 24051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_display); 24061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_display = NULL; 24071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 24081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 24091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 24111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_exit_message(Session *s, int status) 24121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 24131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Channel *c; 24141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((c = channel_lookup(s->chanid)) == NULL) 24161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("session_exit_message: session %d: no channel %d", 24171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->self, s->chanid); 24181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_exit_message: session %d channel %d pid %ld", 24191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->self, s->chanid, (long)s->pid); 24201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (WIFEXITED(status)) { 24221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(s->chanid, "exit-status", 0); 24231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_int(WEXITSTATUS(status)); 24241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 24251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (WIFSIGNALED(status)) { 24261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_request_start(s->chanid, "exit-signal", 0); 24271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(sig2name(WTERMSIG(status))); 24281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WCOREDUMP 24291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(WCOREDUMP(status)? 1 : 0); 24301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else /* WCOREDUMP */ 24311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_char(0); 24321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* WCOREDUMP */ 24331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(""); 24341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_cstring(""); 24351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 24361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 24371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Some weird exit cause. Just exit. */ 24381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_disconnect("wait returned status %04x.", status); 24391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 24401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* disconnect channel */ 24421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_exit_message: release channel %d", s->chanid); 24431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 24451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Adjust cleanup callback attachment to send close messages when 24461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the channel gets EOF. The session will be then be closed 24471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * by session_close_by_channel when the childs close their fds. 24481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 24491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_register_cleanup(c->self, session_close_by_channel, 1); 24501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 24521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * emulate a write failure with 'chan_write_failed', nobody will be 24531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * interested in data we write. 24541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Note that we must not call 'chan_read_failed', since there could 24551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * be some more data waiting in the pipe. 24561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 24571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (c->ostate != CHAN_OUTPUT_CLOSED) 24581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood chan_write_failed(c); 24591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 24601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 24621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_close(Session *s) 24631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 24641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 24651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close: session %d pid %ld", s->self, (long)s->pid); 24671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) 24681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_pty_cleanup(s); 24691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->term) 24701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->term); 24711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->display) 24721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->display); 24731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->x11_chanids) 24741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->x11_chanids); 24751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_display) 24761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_display); 24771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_data) 24781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_data); 24791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->auth_proto) 24801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->auth_proto); 24811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->env != NULL) { 24821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < s->num_env; i++) { 24831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->env[i].name); 24841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->env[i].val); 24851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 24861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(s->env); 24871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 24881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_proctitle(s); 24891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_unused(s->self); 24901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 24911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 24921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 24931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_close_by_pid(pid_t pid, int status) 24941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 24951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = session_by_pid(pid); 24961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) { 24971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_by_pid: no session for pid %ld", 24981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long)pid); 24991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 25001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->chanid != -1) 25021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_exit_message(s, status); 25031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) 25041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_pty_cleanup(s); 25051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->pid = 0; 25061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 25071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 25091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * this is called when a channel dies before 25101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the session 'child' itself dies 25111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 25121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 25131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_close_by_channel(int id, void *arg) 25141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 25151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = session_by_channel(id); 25161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 25171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s == NULL) { 25191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_by_channel: no session for id %d", id); 25201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 25211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_by_channel: channel %d child %ld", 25231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood id, (long)s->pid); 25241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->pid != 0) { 25251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("session_close_by_channel: channel %d: has child", id); 25261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 25271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * delay detach of session, but release pty, since 25281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * the fd's to the child are already closed 25291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 25301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->ttyfd != -1) 25311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_pty_cleanup(s); 25321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 25331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* detach by removing callback */ 25351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_cancel_cleanup(s->chanid); 25361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Close any X11 listeners associated with this session */ 25381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->x11_chanids != NULL) { 25391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; s->x11_chanids[i] != -1; i++) { 25401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_close_x11(s->x11_chanids[i]); 25411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->x11_chanids[i] = -1; 25421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->chanid = -1; 25461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_close(s); 25471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 25481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 25501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_destroy_all(void (*closefunc)(Session *)) 25511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 25521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 25531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 25541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 25551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->used) { 25561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (closefunc != NULL) 25571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood closefunc(s); 25581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 25591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_close(s); 25601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 25631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char * 25651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_tty_list(void) 25661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 25671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char buf[1024]; 25681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 25691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp; 25701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[0] = '\0'; 25721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < sessions_nalloc; i++) { 25731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Session *s = &sessions[i]; 25741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->used && s->ttyfd != -1) { 25751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strncmp(s->tty, "/dev/", 5) != 0) { 25771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = strrchr(s->tty, '/'); 25781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = (cp == NULL) ? s->tty : cp + 1; 25791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 25801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cp = s->tty + 5; 25811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buf[0] != '\0') 25831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, ",", sizeof buf); 25841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, cp, sizeof buf); 25851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 25871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buf[0] == '\0') 25881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(buf, "notty", sizeof buf); 25891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return buf; 25901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 25911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 25921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 25931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_proctitle(Session *s) 25941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 25951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->pw == NULL) 25961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("no user for session %d", s->self); 25971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 25981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setproctitle("%s@%s", s->pw->pw_name, session_tty_list()); 25991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 26001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 26021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsession_setup_x11fwd(Session *s) 26031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 26041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 26051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char display[512], auth_display[512]; 26061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char hostname[MAXHOSTNAMELEN]; 26071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 26081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (no_x11_forwarding_flag) { 26101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send_debug("X11 forwarding disabled in user configuration file."); 26111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.x11_forwarding) { 26141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("X11 forwarding disabled in server configuration file."); 26151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!options.xauth_location || 26181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (stat(options.xauth_location, &st) == -1)) { 26191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send_debug("No xauth program; cannot forward with spoofing."); 26201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_login) { 26231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send_debug("X11 forwarding disabled; " 26241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "not compatible with UseLogin=yes."); 26251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (s->display != NULL) { 26281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("X11 display already set."); 26291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (x11_create_display_inet(options.x11_display_offset, 26321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood options.x11_use_localhost, s->single_connection, 26331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &s->display_number, &s->x11_chanids) == -1) { 26341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("x11_create_display_inet failed."); 26351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; s->x11_chanids[i] != -1; i++) { 26381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood channel_register_cleanup(s->x11_chanids[i], 26391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_close_single_x11, 0); 26401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set up a suitable value for the DISPLAY variable. */ 26431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (gethostname(hostname, sizeof(hostname)) < 0) 26441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("gethostname: %.100s", strerror(errno)); 26451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 26461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * auth_display must be used as the displayname when the 26471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * authorization entry is added with xauth(1). This will be 26481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * different than the DISPLAY string for localhost displays. 26491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 26501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.x11_use_localhost) { 26511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(display, sizeof display, "localhost:%u.%u", 26521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display_number, s->screen); 26531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(auth_display, sizeof auth_display, "unix:%u.%u", 26541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display_number, s->screen); 26551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display = xstrdup(display); 26561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_display = xstrdup(auth_display); 26571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 26581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef IPADDR_IN_DISPLAY 26591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct hostent *he; 26601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct in_addr my_addr; 26611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood he = gethostbyname(hostname); 26631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (he == NULL) { 26641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Can't get IP address for X11 DISPLAY."); 26651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send_debug("Can't get IP address for X11 DISPLAY."); 26661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 26671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(&my_addr, he->h_addr_list[0], sizeof(struct in_addr)); 26691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(display, sizeof display, "%.50s:%u.%u", inet_ntoa(my_addr), 26701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display_number, s->screen); 26711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 26721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(display, sizeof display, "%.400s:%u.%u", hostname, 26731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display_number, s->screen); 26741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 26751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->display = xstrdup(display); 26761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s->auth_display = xstrdup(display); 26771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 26781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 26801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 26811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 26831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_authenticated2(Authctxt *authctxt) 26841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 26851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_loop2(authctxt); 26861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 26871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 26891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooddo_cleanup(Authctxt *authctxt) 26901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 26911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static int called = 0; 26921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("do_cleanup"); 26941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* no cleanup if we're in the child for login shell */ 26961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (is_child) 26971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 26981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 26991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* avoid double cleanup */ 27001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (called) 27011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 27021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood called = 1; 27031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (authctxt == NULL) 27051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 27061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_PAM 27081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.use_pam) { 27091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sshpam_cleanup(); 27101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sshpam_thread_cleanup(); 27111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 27121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 27131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!authctxt->authenticated) 27151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 27161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef KRB5 27181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (options.kerberos_ticket_cleanup && 27191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood authctxt->krb5_ctx) 27201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood krb5_cleanup_proc(authctxt); 27211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 27221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 27241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (compat20 && options.gss_cleanup_creds) 27251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_gssapi_cleanup_creds(); 27261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 27271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* remove agent socket */ 27291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood auth_sock_cleanup_proc(authctxt->pw); 27301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 27311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 27321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Cleanup ptys/utmp only if privsep is disabled, 27331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * or if running in monitor. 27341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 27351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!use_privsep || mm_is_monitor()) 27361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood session_destroy_all(session_pty_cleanup2); 27371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2738