diff options
author | Kevin Steves <stevesk@pobox.com> | 2000-12-15 18:39:12 +0000 |
---|---|---|
committer | Kevin Steves <stevesk@pobox.com> | 2000-12-15 18:39:12 +0000 |
commit | fa72ddac73e3549cf5d399fae31bfb5a293ed0cc (patch) | |
tree | 9fc0dd554a432c2ea7151e95482f5fd81175995a /pty.c | |
parent | de41bc6caaa986f6e65629f5e926ea5ce140d8e7 (diff) |
- (stevesk) OpenBSD CVS updates:
- markus@cvs.openbsd.org 2000/12/13 16:26:53
[ssh-keyscan.c]
fatal already adds \n; from stevesk@pobox.com
- markus@cvs.openbsd.org 2000/12/13 16:25:44
[ssh-agent.c]
remove redundant spaces; from stevesk@pobox.com
- ho@cvs.openbsd.org 2000/12/12 15:50:21
[pty.c]
When failing to set tty owner and mode on a read-only filesystem, don't
abort if the tty already has correct owner and reasonably sane modes.
Example; permit 'root' to login to a firewall with read-only root fs.
(markus@ ok)
- deraadt@cvs.openbsd.org 2000/12/13 06:36:05
[pty.c]
KNF
Diffstat (limited to 'pty.c')
-rw-r--r-- | pty.c | 42 |
1 files changed, 34 insertions, 8 deletions
@@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: pty.c,v 1.16 2000/09/07 21:13:37 markus Exp $"); +RCSID("$OpenBSD: pty.c,v 1.18 2000/12/13 06:36:05 deraadt Exp $"); #ifdef HAVE_UTIL_H # include <util.h> @@ -291,6 +291,7 @@ pty_setowner(struct passwd *pw, const char *ttyname) struct group *grp; gid_t gid; mode_t mode; + struct stat st; /* Determine the group to make the owner of the tty. */ grp = getgrnam("tty"); @@ -302,11 +303,36 @@ pty_setowner(struct passwd *pw, const char *ttyname) mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; } - /* Change ownership of the tty. */ - if (chown(ttyname, pw->pw_uid, gid) < 0) - fatal("chown(%.100s, %d, %d) failed: %.100s", - ttyname, pw->pw_uid, gid, strerror(errno)); - if (chmod(ttyname, mode) < 0) - fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, mode, strerror(errno)); + /* + * Change owner and mode of the tty as required. + * Warn but continue if filesystem is read-only and the uids match. + */ + if (stat(ttyname, &st)) + fatal("stat(%.100s) failed: %.100s", ttyname, + 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)); + } + } } |