version 1.16, 2000/09/07 21:13:37 |
version 1.16.2.2, 2001/02/19 17:19:11 |
|
|
|
|
#include <util.h> |
#include <util.h> |
#include "pty.h" |
#include "pty.h" |
#include "ssh.h" |
#include "log.h" |
|
|
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ |
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */ |
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) |
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY) |
|
|
|
|
/* First disconnect from the old controlling tty. */ |
/* First disconnect from the old controlling tty. */ |
#ifdef TIOCNOTTY |
#ifdef TIOCNOTTY |
fd = open("/dev/tty", O_RDWR | O_NOCTTY); |
fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); |
if (fd >= 0) { |
if (fd >= 0) { |
(void) ioctl(fd, TIOCNOTTY, NULL); |
(void) ioctl(fd, TIOCNOTTY, NULL); |
close(fd); |
close(fd); |
|
|
* Verify that we are successfully disconnected from the controlling |
* Verify that we are successfully disconnected from the controlling |
* tty. |
* tty. |
*/ |
*/ |
fd = open("/dev/tty", O_RDWR | O_NOCTTY); |
fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); |
if (fd >= 0) { |
if (fd >= 0) { |
error("Failed to disconnect from controlling tty."); |
error("Failed to disconnect from controlling tty."); |
close(fd); |
close(fd); |
|
|
/* Make it our controlling tty. */ |
/* Make it our controlling tty. */ |
#ifdef TIOCSCTTY |
#ifdef TIOCSCTTY |
debug("Setting controlling tty using TIOCSCTTY."); |
debug("Setting controlling tty using TIOCSCTTY."); |
/* |
if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) |
* We ignore errors from this, because HPSUX defines TIOCSCTTY, but |
error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); |
* returns EINVAL with these arguments, and there is absolutely no |
|
* documentation. |
|
*/ |
|
ioctl(*ttyfd, TIOCSCTTY, NULL); |
|
#endif /* TIOCSCTTY */ |
#endif /* TIOCSCTTY */ |
fd = open(ttyname, O_RDWR); |
fd = open(ttyname, O_RDWR); |
if (fd < 0) |
if (fd < 0) |
|
|
close(fd); |
close(fd); |
|
|
/* Verify that we now have a controlling tty. */ |
/* Verify that we now have a controlling tty. */ |
fd = open("/dev/tty", O_WRONLY); |
fd = open(_PATH_TTY, O_WRONLY); |
if (fd < 0) |
if (fd < 0) |
error("open /dev/tty failed - could not set controlling tty: %.100s", |
error("open /dev/tty failed - could not set controlling tty: %.100s", |
strerror(errno)); |
strerror(errno)); |
|
|
struct group *grp; |
struct group *grp; |
gid_t gid; |
gid_t gid; |
mode_t mode; |
mode_t mode; |
|
struct stat st; |
|
|
/* Determine the group to make the owner of the tty. */ |
/* Determine the group to make the owner of the tty. */ |
grp = getgrnam("tty"); |
grp = getgrnam("tty"); |
|
|
mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
} |
} |
|
|
/* Change ownership of the tty. */ |
/* |
if (chown(ttyname, pw->pw_uid, gid) < 0) |
* Change owner and mode of the tty as required. |
fatal("chown(%.100s, %d, %d) failed: %.100s", |
* Warn but continue if filesystem is read-only and the uids match. |
ttyname, pw->pw_uid, gid, strerror(errno)); |
*/ |
if (chmod(ttyname, mode) < 0) |
if (stat(ttyname, &st)) |
fatal("chmod(%.100s, 0%o) failed: %.100s", |
fatal("stat(%.100s) failed: %.100s", ttyname, |
ttyname, mode, strerror(errno)); |
strerror(errno)); |
|
|
|
if (st.st_uid != pw->pw_uid || st.st_gid != gid) { |
|
if (chown(ttyname, pw->pw_uid, gid) < 0) { |
|
if (errno == EROFS && st.st_uid == pw->pw_uid) |
|
error("chown(%.100s, %d, %d) failed: %.100s", |
|
ttyname, pw->pw_uid, gid, |
|
strerror(errno)); |
|
else |
|
fatal("chown(%.100s, %d, %d) failed: %.100s", |
|
ttyname, pw->pw_uid, gid, |
|
strerror(errno)); |
|
} |
|
} |
|
|
|
if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { |
|
if (chmod(ttyname, mode) < 0) { |
|
if (errno == EROFS && |
|
(st.st_mode & (S_IRGRP | S_IROTH)) == 0) |
|
error("chmod(%.100s, 0%o) failed: %.100s", |
|
ttyname, mode, strerror(errno)); |
|
else |
|
fatal("chmod(%.100s, 0%o) failed: %.100s", |
|
ttyname, mode, strerror(errno)); |
|
} |
|
} |
} |
} |