From c7d8dbbb0dfdeb3f854d58c9bf084db2b72ded77 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 2 Mar 2000 23:30:53 +1100 Subject: - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de --- ChangeLog | 1 + pty.c | 32 ++++++++++++++++++-- pty.h | 4 ++- sshd.c | 102 +++++++++++++++++++++++++++++--------------------------------- 4 files changed, 80 insertions(+), 59 deletions(-) diff --git a/ChangeLog b/ChangeLog index e118a3364..12edfc444 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,7 @@ - Rewrote OpenSSL detection code. Now uses AC_TRY_RUN with a test program to detect library and header location _and_ ensure library has proper RSA support built in (this is a problem with OpenSSL 0.9.5). + - Applied pty cleanup patch from markus.friedl@informatik.uni-erlangen.de 20000207 - Removed SOCKS code. Will support through a ProxyCommand. diff --git a/pty.c b/pty.c index b3a0535ee..de6f751d8 100644 --- a/pty.c +++ b/pty.c @@ -14,7 +14,7 @@ */ #include "includes.h" -RCSID("$Id: pty.c,v 1.11 1999/12/21 00:18:08 damien Exp $"); +RCSID("$Id: pty.c,v 1.12 2000/03/02 12:30:53 damien Exp $"); #ifdef HAVE_UTIL_H # include @@ -188,9 +188,9 @@ void pty_release(const char *ttyname) { if (chown(ttyname, (uid_t) 0, (gid_t) 0) < 0) - debug("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); + error("chown %.100s 0 0 failed: %.100s", ttyname, strerror(errno)); if (chmod(ttyname, (mode_t) 0666) < 0) - debug("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); + error("chmod %.100s 0666 failed: %.100s", ttyname, strerror(errno)); } /* Makes the tty the processes controlling tty and sets it to sane modes. */ @@ -259,3 +259,29 @@ pty_change_window_size(int ptyfd, int row, int col, w.ws_ypixel = ypixel; (void) ioctl(ptyfd, TIOCSWINSZ, &w); } + +void +pty_setowner(struct passwd *pw, const char *ttyname) +{ + struct group *grp; + gid_t gid; + mode_t mode; + + /* Determine the group to make the owner of the tty. */ + grp = getgrnam("tty"); + if (grp) { + gid = grp->gr_gid; + mode = S_IRUSR | S_IWUSR | S_IWGRP; + } else { + gid = pw->pw_gid; + 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)); +} diff --git a/pty.h b/pty.h index 186cb3c98..4d0e5f12b 100644 --- a/pty.h +++ b/pty.h @@ -13,7 +13,7 @@ * tty. */ -/* RCSID("$Id: pty.h,v 1.4 1999/12/07 04:38:32 damien Exp $"); */ +/* RCSID("$Id: pty.h,v 1.5 2000/03/02 12:30:53 damien Exp $"); */ #ifndef PTY_H #define PTY_H @@ -43,4 +43,6 @@ void pty_change_window_size(int ptyfd, int row, int col, int xpixel, int ypixel); +void pty_setowner(struct passwd *pw, const char *ttyname); + #endif /* PTY_H */ diff --git a/sshd.c b/sshd.c index 0a6045e7f..f49b45368 100644 --- a/sshd.c +++ b/sshd.c @@ -1622,6 +1622,37 @@ xauthfile_cleanup_proc(void *ignore) } } +struct pty_cleanup_context { + const char *ttyname; + int pid; +}; + +/* + * Function to perform cleanup if we get aborted abnormally (e.g., due to a + * dropped connection). + */ +void +pty_cleanup_proc(void *context) +{ + struct pty_cleanup_context *cu = context; + + debug("pty_cleanup_proc called"); + + /* Record that the user has logged out. */ + record_logout(cu->pid, cu->ttyname); + + /* Release the pseudo-tty. */ + pty_release(cu->ttyname); +} + +/* simple cleanup: chown tty slave back to root */ +static void +pty_release_proc(void *tty) +{ + char *ttyname = tty; + pty_release(ttyname); +} + /* * Prepares for an interactive session. This is called after the user has * been successfully authenticated. During this message exchange, pseudo @@ -1636,11 +1667,7 @@ do_authenticated(struct passwd * pw) int have_pty = 0, ptyfd = -1, ttyfd = -1, xauthfd = -1; int row, col, xpixel, ypixel, screen; char ttyname[64]; - char *command, *term = NULL, *display = NULL, *proto = NULL, - *data = NULL; - struct group *grp; - gid_t tty_gid; - mode_t tty_mode; + char *command, *term = NULL, *display = NULL, *proto = NULL, *data = NULL; int n_bytes; /* @@ -1698,33 +1725,20 @@ do_authenticated(struct passwd * pw) error("Failed to allocate pty."); goto fail; } - /* Determine the group to make the owner of the tty. */ - grp = getgrnam("tty"); - if (grp) { - tty_gid = grp->gr_gid; - tty_mode = S_IRUSR | S_IWUSR | S_IWGRP; - } else { - tty_gid = pw->pw_gid; - tty_mode = S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH; - } - - /* Change ownership of the tty. */ - if (chown(ttyname, pw->pw_uid, tty_gid) < 0) - fatal("chown(%.100s, %d, %d) failed: %.100s", - ttyname, pw->pw_uid, tty_gid, strerror(errno)); - if (chmod(ttyname, tty_mode) < 0) - fatal("chmod(%.100s, 0%o) failed: %.100s", - ttyname, tty_mode, strerror(errno)); + fatal_add_cleanup(pty_release_proc, (void *)ttyname); + pty_setowner(pw, ttyname); /* Get TERM from the packet. Note that the value may be of arbitrary length. */ term = packet_get_string(&dlen); packet_integrity_check(dlen, strlen(term), type); - /* packet_integrity_check(plen, 4 + dlen + 4*4 + n_bytes, type); */ + /* Remaining bytes */ n_bytes = plen - (4 + dlen + 4 * 4); - if (strcmp(term, "") == 0) + if (strcmp(term, "") == 0) { + xfree(term); term = NULL; + } /* Get window size from the packet. */ row = packet_get_int(); @@ -1998,29 +2012,6 @@ do_exec_no_pty(const char *command, struct passwd * pw, #endif /* USE_PIPES */ } -struct pty_cleanup_context { - const char *ttyname; - int pid; -}; - -/* - * Function to perform cleanup if we get aborted abnormally (e.g., due to a - * dropped connection). - */ -void -pty_cleanup_proc(void *context) -{ - struct pty_cleanup_context *cu = context; - - debug("pty_cleanup_proc called"); - - /* Record that the user has logged out. */ - record_logout(cu->pid, cu->ttyname); - - /* Release the pseudo-tty. */ - pty_release(cu->ttyname); -} - /* * This is called to fork and execute a command when we have a tty. This * will call do_child from the child, and server_loop from the parent after @@ -2166,6 +2157,15 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, /* Parent. Close the slave side of the pseudo tty. */ close(ttyfd); + /* + * Add a cleanup function to clear the utmp entry and record logout + * time in case we call fatal() (e.g., the connection gets closed). + */ + cleanup_context.pid = pid; + cleanup_context.ttyname = ttyname; + fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); + fatal_remove_cleanup(pty_release_proc, (void *) ttyname); + /* * Create another descriptor of the pty master side for use as the * standard input. We could use the original descriptor, but this @@ -2175,14 +2175,6 @@ do_exec_pty(const char *command, int ptyfd, int ttyfd, if (fdout < 0) packet_disconnect("dup failed: %.100s", strerror(errno)); - /* - * Add a cleanup function to clear the utmp entry and record logout - * time in case we call fatal() (e.g., the connection gets closed). - */ - cleanup_context.pid = pid; - cleanup_context.ttyname = ttyname; - fatal_add_cleanup(pty_cleanup_proc, (void *) &cleanup_context); - /* Enter interactive session. */ server_loop(pid, ptyfd, fdout, -1); /* server_loop has not closed ptyfd and fdout. */ -- cgit v1.2.3