1a2eb7b567692e7a3f435b1ee8ed26c63d395d5eaGreg Hartman/* $OpenBSD: sshpty.c,v 1.30 2015/07/30 23:09:15 djm Exp $ */ 2bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 3bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Author: Tatu Ylonen <ylo@cs.hut.fi> 4bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 5bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * All rights reserved 6bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Allocating a pseudo-terminal, and making it the controlling tty. 7bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * 8bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * As far as I am concerned, the code I have written for this software 9bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * can be used freely for any purpose. Any derived versions of this 10bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * software must be clearly marked as such, and if the derived work is 11bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * incompatible with the protocol description in the RFC file, it must be 12bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * called by a name other than "ssh" or "Secure Shell". 13bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 14bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 15bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "includes.h" 16bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 17bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/types.h> 18bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/ioctl.h> 19bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <sys/stat.h> 20bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <signal.h> 21bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 22bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <errno.h> 23bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <fcntl.h> 24bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <grp.h> 25bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_PATHS_H 26bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <paths.h> 27bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 28bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <pwd.h> 29bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <stdarg.h> 30bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <string.h> 31bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <termios.h> 32bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_UTIL_H 33bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <util.h> 34bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 35bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include <unistd.h> 36bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 37bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "sshpty.h" 38bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "log.h" 39bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#include "misc.h" 40bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 41bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef HAVE_PTY_H 42bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <pty.h> 43bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 44bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 45bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifndef O_NOCTTY 46bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#define O_NOCTTY 0 47bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 48bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 49bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef __APPLE__ 50bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# include <AvailabilityMacros.h> 51bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) 52bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# define __APPLE_PRIVPTY__ 53bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman# endif 54bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 55bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 56bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* 57bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Allocates and opens a pty. Returns 0 if no pty could be allocated, or 58bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * nonzero if a pty was successfully allocated. On success, open file 59bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * descriptors for the pty and tty sides and the name of the tty side are 60bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * returned (the buffer must be able to hold at least 64 characters). 61bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 62bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 63bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanint 64bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 65bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 66bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* openpty(3) exists in OSF/1 and some other os'es */ 67bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman char *name; 68bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int i; 69bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 70bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); 71bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (i < 0) { 72bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("openpty: %.100s", strerror(errno)); 73bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 0; 74bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 75bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef ANDROID 760199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman if (ptsname_r(*ptyfd, namebuf, namebuflen)) { 770199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman fatal("openpty ptsname failed."); 780199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman close(*ptyfd); 790199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman *ptyfd = -1; 800199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman return -1; 810199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman } 820199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman return 1; 83bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else 84bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman name = ttyname(*ttyfd); 85bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (!name) 86bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("openpty returns device for which ttyname fails."); 87bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 88bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strlcpy(namebuf, name, namebuflen); /* possible truncation */ 89bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman return 1; 900199da83f61c7a951b6e05ec844dabc0d3e04cd7Greg Hartman#endif 91bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 92bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 93bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */ 94bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 95bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 96bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpty_release(const char *tty) 97bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 98a2eb7b567692e7a3f435b1ee8ed26c63d395d5eaGreg Hartman#if !defined(__APPLE_PRIVPTY__) && !defined(HAVE_OPENPTY) 99bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (chown(tty, (uid_t) 0, (gid_t) 0) < 0) 100bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno)); 101bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (chmod(tty, (mode_t) 0666) < 0) 102bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno)); 103a2eb7b567692e7a3f435b1ee8ed26c63d395d5eaGreg Hartman#endif /* !__APPLE_PRIVPTY__ && !HAVE_OPENPTY */ 104bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 105bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 106bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Makes the tty the process's controlling tty and sets it to sane modes. */ 107bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 108bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 109bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpty_make_controlling_tty(int *ttyfd, const char *tty) 110bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 111bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman int fd; 112bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 113bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef _UNICOS 114bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (setsid() < 0) 115bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("setsid: %.100s", strerror(errno)); 116bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 117bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = open(tty, O_RDWR|O_NOCTTY); 118bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fd != -1) { 119bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman signal(SIGHUP, SIG_IGN); 120bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ioctl(fd, TCVHUP, (char *)NULL); 121bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman signal(SIGHUP, SIG_DFL); 122bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman setpgid(0, 0); 123bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 124bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 125bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("Failed to disconnect from controlling tty."); 126bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 127bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 128bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Setting controlling tty using TCSETCTTY."); 129bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ioctl(*ttyfd, TCSETCTTY, NULL); 130bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = open("/dev/tty", O_RDWR); 131bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fd < 0) 132bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("%.100s: %.100s", tty, strerror(errno)); 133bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(*ttyfd); 134bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman *ttyfd = fd; 135bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#else /* _UNICOS */ 136bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 137bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* First disconnect from the old controlling tty. */ 138bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef TIOCNOTTY 139bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); 140bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fd >= 0) { 141bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (void) ioctl(fd, TIOCNOTTY, NULL); 142bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 143bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 144bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* TIOCNOTTY */ 145bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (setsid() < 0) 146bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("setsid: %.100s", strerror(errno)); 147bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 148bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 149bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Verify that we are successfully disconnected from the controlling 150bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * tty. 151bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 152bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); 153bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fd >= 0) { 154bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("Failed to disconnect from controlling tty."); 155bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 156bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 157bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Make it our controlling tty. */ 158bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef TIOCSCTTY 159bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("Setting controlling tty using TIOCSCTTY."); 160bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) 161bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); 162bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* TIOCSCTTY */ 163bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef NEED_SETPGRP 164bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (setpgrp(0,0) < 0) 165bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("SETPGRP %s",strerror(errno)); 166bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* NEED_SETPGRP */ 167bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = open(tty, O_RDWR); 168bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fd < 0) { 169bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("%.100s: %.100s", tty, strerror(errno)); 170bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } else { 171bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 172bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 173bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Verify that we now have a controlling tty. */ 174bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fd = open(_PATH_TTY, O_WRONLY); 175bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (fd < 0) 176bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman error("open /dev/tty failed - could not set controlling tty: %.100s", 177bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 178bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 179bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman close(fd); 180bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif /* _UNICOS */ 181bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 182bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 183bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman/* Changes the window size associated with the pty. */ 184bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 185bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 186bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpty_change_window_size(int ptyfd, u_int row, u_int col, 187bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman u_int xpixel, u_int ypixel) 188bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 189bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct winsize w; 190bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 191bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* may truncate u_int -> u_short */ 192bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman w.ws_row = row; 193bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman w.ws_col = col; 194bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman w.ws_xpixel = xpixel; 195bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman w.ws_ypixel = ypixel; 196bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (void) ioctl(ptyfd, TIOCSWINSZ, &w); 197bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 198bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 199bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanvoid 200bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartmanpty_setowner(struct passwd *pw, const char *tty) 201bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman{ 202bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct group *grp; 203bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman gid_t gid; 204bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman mode_t mode; 205bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman struct stat st; 206bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 207bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* Determine the group to make the owner of the tty. */ 208bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman grp = getgrnam("tty"); 209d059297112922cabb0c674840589be8db821fd9aAdam Langley gid = (grp != NULL) ? grp->gr_gid : pw->pw_gid; 210a2eb7b567692e7a3f435b1ee8ed26c63d395d5eaGreg Hartman mode = (grp != NULL) ? 0620 : 0600; 211bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 212bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman /* 213bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Change owner and mode of the tty as required. 214bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * Warn but continue if filesystem is read-only and the uids match/ 215bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman * tty is owned by root. 216bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman */ 217bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (stat(tty, &st)) 218bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("stat(%.100s) failed: %.100s", tty, 219bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 220bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 221bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#ifdef WITH_SELINUX 222bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman ssh_selinux_setup_pty(pw->pw_name, tty); 223bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman#endif 224bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 225bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (st.st_uid != pw->pw_uid || st.st_gid != gid) { 226bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (chown(tty, pw->pw_uid, gid) < 0) { 227bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (errno == EROFS && 228bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (st.st_uid == pw->pw_uid || st.st_uid == 0)) 229bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("chown(%.100s, %u, %u) failed: %.100s", 230bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman tty, (u_int)pw->pw_uid, (u_int)gid, 231bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 232bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 233bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("chown(%.100s, %u, %u) failed: %.100s", 234bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman tty, (u_int)pw->pw_uid, (u_int)gid, 235bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman strerror(errno)); 236bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 237bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 238bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman 239bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { 240bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (chmod(tty, mode) < 0) { 241bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman if (errno == EROFS && 242bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman (st.st_mode & (S_IRGRP | S_IROTH)) == 0) 243bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman debug("chmod(%.100s, 0%o) failed: %.100s", 244bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman tty, (u_int)mode, strerror(errno)); 245bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman else 246bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman fatal("chmod(%.100s, 0%o) failed: %.100s", 247bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman tty, (u_int)mode, strerror(errno)); 248bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 249bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman } 250bd77cf78387b72b7b3ea870459077672bf75c3b5Greg Hartman} 251