11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: sshpty.c,v 1.28 2007/09/11 23:49:09 stevesk Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi> 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All rights reserved 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Allocating a pseudo-terminal, and making it the controlling tty. 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose. Any derived versions of this 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell". 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/ioctl.h> 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/stat.h> 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h> 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <grp.h> 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PATHS_H 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <paths.h> 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h> 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <termios.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_UTIL_H 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <util.h> 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "sshpty.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PTY_H 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <pty.h> 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef O_NOCTTY 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define O_NOCTTY 0 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef __APPLE__ 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <AvailabilityMacros.h> 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# define __APPLE_PRIVPTY__ 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Allocates and opens a pty. Returns 0 if no pty could be allocated, or 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * nonzero if a pty was successfully allocated. On success, open file 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * descriptors for the pty and tty sides and the name of the tty side are 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * returned (the buffer must be able to hold at least 64 characters). 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* openpty(3) exists in OSF/1 and some other os'es */ 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *name; 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i < 0) { 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("openpty: %.100s", strerror(errno)); 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 751b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood#ifdef ANDROID 761b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood /* Android does not have a working ttyname() */ 771b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood name = "/dev/ptmx"; 781b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood#else 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood name = ttyname(*ttyfd); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!name) 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("openpty returns device for which ttyname fails."); 821b6cc98e30329f380546d5f22b1c9c975e3df4f8Mike Lockwood#endif 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcpy(namebuf, name, namebuflen); /* possible truncation */ 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 1; 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpty_release(const char *tty) 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef __APPLE_PRIVPTY__ 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chown(tty, (uid_t) 0, (gid_t) 0) < 0) 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno)); 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chmod(tty, (mode_t) 0666) < 0) 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno)); 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* __APPLE_PRIVPTY__ */ 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Makes the tty the process's controlling tty and sets it to sane modes. */ 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpty_make_controlling_tty(int *ttyfd, const char *tty) 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fd; 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_VHANGUP 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood void *old; 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* USE_VHANGUP */ 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _UNICOS 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setsid() < 0) 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setsid: %.100s", strerror(errno)); 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open(tty, O_RDWR|O_NOCTTY); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd != -1) { 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGHUP, SIG_IGN); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ioctl(fd, TCVHUP, (char *)NULL); 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGHUP, SIG_DFL); 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setpgid(0, 0); 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Failed to disconnect from controlling tty."); 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Setting controlling tty using TCSETCTTY."); 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ioctl(*ttyfd, TCSETCTTY, NULL); 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open("/dev/tty", O_RDWR); 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd < 0) 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%.100s: %.100s", tty, strerror(errno)); 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(*ttyfd); 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *ttyfd = fd; 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else /* _UNICOS */ 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* First disconnect from the old controlling tty. */ 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef TIOCNOTTY 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd >= 0) { 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void) ioctl(fd, TIOCNOTTY, NULL); 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* TIOCNOTTY */ 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setsid() < 0) 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setsid: %.100s", strerror(errno)); 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Verify that we are successfully disconnected from the controlling 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * tty. 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd >= 0) { 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Failed to disconnect from controlling tty."); 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Make it our controlling tty. */ 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef TIOCSCTTY 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("Setting controlling tty using TIOCSCTTY."); 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* TIOCSCTTY */ 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef NEED_SETPGRP 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setpgrp(0,0) < 0) 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("SETPGRP %s",strerror(errno)); 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* NEED_SETPGRP */ 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_VHANGUP 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood old = signal(SIGHUP, SIG_IGN); 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood vhangup(); 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGHUP, old); 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* USE_VHANGUP */ 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open(tty, O_RDWR); 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd < 0) { 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("%.100s: %.100s", tty, strerror(errno)); 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_VHANGUP 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(*ttyfd); 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *ttyfd = fd; 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else /* USE_VHANGUP */ 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* USE_VHANGUP */ 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Verify that we now have a controlling tty. */ 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open(_PATH_TTY, O_WRONLY); 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd < 0) 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("open /dev/tty failed - could not set controlling tty: %.100s", 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _UNICOS */ 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Changes the window size associated with the pty. */ 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpty_change_window_size(int ptyfd, u_int row, u_int col, 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int xpixel, u_int ypixel) 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct winsize w; 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* may truncate u_int -> u_short */ 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood w.ws_row = row; 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood w.ws_col = col; 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood w.ws_xpixel = xpixel; 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood w.ws_ypixel = ypixel; 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (void) ioctl(ptyfd, TIOCSWINSZ, &w); 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpty_setowner(struct passwd *pw, const char *tty) 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct group *grp; 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gid_t gid; 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mode_t mode; 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct stat st; 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Determine the group to make the owner of the tty. */ 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood grp = getgrnam("tty"); 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (grp) { 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gid = grp->gr_gid; 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mode = S_IRUSR | S_IWUSR | S_IWGRP; 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gid = pw->pw_gid; 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Change owner and mode of the tty as required. 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Warn but continue if filesystem is read-only and the uids match/ 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * tty is owned by root. 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stat(tty, &st)) 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("stat(%.100s) failed: %.100s", tty, 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ssh_selinux_setup_pty(pw->pw_name, tty); 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chown(tty, pw->pw_uid, gid) < 0) { 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno == EROFS && 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (st.st_uid == pw->pw_uid || st.st_uid == 0)) 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("chown(%.100s, %u, %u) failed: %.100s", 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tty, (u_int)pw->pw_uid, (u_int)gid, 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chown(%.100s, %u, %u) failed: %.100s", 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tty, (u_int)pw->pw_uid, (u_int)gid, 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (chmod(tty, mode) < 0) { 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno == EROFS && 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (st.st_mode & (S_IRGRP | S_IROTH)) == 0) 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("chmod(%.100s, 0%o) failed: %.100s", 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tty, (u_int)mode, strerror(errno)); 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("chmod(%.100s, 0%o) failed: %.100s", 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tty, (u_int)mode, strerror(errno)); 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 264