diff options
Diffstat (limited to 'pty.c')
-rw-r--r-- | pty.c | 42 |
1 files changed, 34 insertions, 8 deletions
@@ -12,7 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include "includes.h" | 14 | #include "includes.h" |
15 | RCSID("$OpenBSD: pty.c,v 1.16 2000/09/07 21:13:37 markus Exp $"); | 15 | RCSID("$OpenBSD: pty.c,v 1.18 2000/12/13 06:36:05 deraadt Exp $"); |
16 | 16 | ||
17 | #ifdef HAVE_UTIL_H | 17 | #ifdef HAVE_UTIL_H |
18 | # include <util.h> | 18 | # include <util.h> |
@@ -291,6 +291,7 @@ pty_setowner(struct passwd *pw, const char *ttyname) | |||
291 | struct group *grp; | 291 | struct group *grp; |
292 | gid_t gid; | 292 | gid_t gid; |
293 | mode_t mode; | 293 | mode_t mode; |
294 | struct stat st; | ||
294 | 295 | ||
295 | /* Determine the group to make the owner of the tty. */ | 296 | /* Determine the group to make the owner of the tty. */ |
296 | grp = getgrnam("tty"); | 297 | grp = getgrnam("tty"); |
@@ -302,11 +303,36 @@ pty_setowner(struct passwd *pw, const char *ttyname) | |||
302 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; | 303 | mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; |
303 | } | 304 | } |
304 | 305 | ||
305 | /* Change ownership of the tty. */ | 306 | /* |
306 | if (chown(ttyname, pw->pw_uid, gid) < 0) | 307 | * Change owner and mode of the tty as required. |
307 | fatal("chown(%.100s, %d, %d) failed: %.100s", | 308 | * Warn but continue if filesystem is read-only and the uids match. |
308 | ttyname, pw->pw_uid, gid, strerror(errno)); | 309 | */ |
309 | if (chmod(ttyname, mode) < 0) | 310 | if (stat(ttyname, &st)) |
310 | fatal("chmod(%.100s, 0%o) failed: %.100s", | 311 | fatal("stat(%.100s) failed: %.100s", ttyname, |
311 | ttyname, mode, strerror(errno)); | 312 | strerror(errno)); |
313 | |||
314 | if (st.st_uid != pw->pw_uid || st.st_gid != gid) { | ||
315 | if (chown(ttyname, pw->pw_uid, gid) < 0) { | ||
316 | if (errno == EROFS && st.st_uid == pw->pw_uid) | ||
317 | error("chown(%.100s, %d, %d) failed: %.100s", | ||
318 | ttyname, pw->pw_uid, gid, | ||
319 | strerror(errno)); | ||
320 | else | ||
321 | fatal("chown(%.100s, %d, %d) failed: %.100s", | ||
322 | ttyname, pw->pw_uid, gid, | ||
323 | strerror(errno)); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) { | ||
328 | if (chmod(ttyname, mode) < 0) { | ||
329 | if (errno == EROFS && | ||
330 | (st.st_mode & (S_IRGRP | S_IROTH)) == 0) | ||
331 | error("chmod(%.100s, 0%o) failed: %.100s", | ||
332 | ttyname, mode, strerror(errno)); | ||
333 | else | ||
334 | fatal("chmod(%.100s, 0%o) failed: %.100s", | ||
335 | ttyname, mode, strerror(errno)); | ||
336 | } | ||
337 | } | ||
312 | } | 338 | } |