=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/session.c,v retrieving revision 1.74.2.5 retrieving revision 1.74.2.6 diff -u -r1.74.2.5 -r1.74.2.6 --- src/usr.bin/ssh/session.c 2002/03/09 00:20:45 1.74.2.5 +++ src/usr.bin/ssh/session.c 2002/06/02 22:56:11 1.74.2.6 @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.74.2.5 2002/03/09 00:20:45 miod Exp $"); +RCSID("$OpenBSD: session.c,v 1.74.2.6 2002/06/02 22:56:11 miod Exp $"); #include "ssh.h" #include "ssh1.h" @@ -56,40 +56,13 @@ #include "serverloop.h" #include "canohost.h" #include "session.h" +#include "monitor_wrap.h" -/* types */ - -#define TTYSZ 64 -typedef struct Session Session; -struct Session { - int used; - int self; - struct passwd *pw; - Authctxt *authctxt; - pid_t pid; - /* tty */ - char *term; - int ptyfd, ttyfd, ptymaster; - int row, col, xpixel, ypixel; - char tty[TTYSZ]; - /* X11 */ - int display_number; - char *display; - int screen; - char *auth_display; - char *auth_proto; - char *auth_data; - int single_connection; - /* proto 2 */ - int chanid; - int is_subsystem; -}; - /* func */ Session *session_new(void); void session_set_fds(Session *, int, int, int); -static void session_pty_cleanup(void *); +void session_pty_cleanup(void *); void session_proctitle(Session *); int session_setup_x11fwd(Session *); void do_exec_pty(Session *, const char *); @@ -103,7 +76,6 @@ static void do_authenticated1(Authctxt *); static void do_authenticated2(Authctxt *); -static void session_close(Session *); static int session_pty_req(Session *); /* import */ @@ -123,7 +95,7 @@ Session sessions[MAX_SESSIONS]; #ifdef HAVE_LOGIN_CAP -static login_cap_t *lc; +login_cap_t *lc; #endif void @@ -138,18 +110,6 @@ close(startup_pipe); startup_pipe = -1; } -#ifdef HAVE_LOGIN_CAP - if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL) { - error("unable to get login class"); - return; - } -#ifdef BSD_AUTH - if (auth_approval(NULL, lc, authctxt->pw->pw_name, "ssh") <= 0) { - packet_disconnect("Approval failure for %s", - authctxt->pw->pw_name); - } -#endif -#endif /* setup the channel layer */ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) channel_permit_all_opens(); @@ -583,10 +543,8 @@ do_login(Session *s, const char *command) { char *time_string; - char hostname[MAXHOSTNAMELEN]; socklen_t fromlen; struct sockaddr_storage from; - time_t last_login_time; struct passwd * pw = s->pw; pid_t pid = getpid(); @@ -604,29 +562,25 @@ } } - /* Get the time and hostname when the user last logged in. */ - if (options.print_lastlog) { - hostname[0] = '\0'; - last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, - hostname, sizeof(hostname)); - } - /* Record that there was a login on that tty from the remote host. */ - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, - get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), - (struct sockaddr *)&from); + if (!use_privsep) + record_login(pid, s->tty, pw->pw_name, pw->pw_uid, + get_remote_name_or_ip(utmp_len, + options.verify_reverse_mapping), + (struct sockaddr *)&from); if (check_quietlogin(s, command)) return; - if (options.print_lastlog && last_login_time != 0) { - time_string = ctime(&last_login_time); + if (options.print_lastlog && s->last_login_time != 0) { + time_string = ctime(&s->last_login_time); if (strchr(time_string, '\n')) *strchr(time_string, '\n') = 0; - if (strcmp(hostname, "") == 0) + if (strcmp(s->hostname, "") == 0) printf("Last login: %s\r\n", time_string); else - printf("Last login: %s from %s\r\n", time_string, hostname); + printf("Last login: %s from %s\r\n", time_string, + s->hostname); } do_motd(); @@ -947,7 +901,7 @@ } /* Set login name, uid, gid, and groups. */ -static void +void do_setusercontext(struct passwd *pw) { if (getuid() == 0 || geteuid() == 0) { @@ -979,6 +933,20 @@ fatal("Failed to set uids to %u.", (u_int) pw->pw_uid); } +static void +launch_login(struct passwd *pw, const char *hostname) +{ + /* Launch login(1). */ + + execl("/usr/bin/login", "login", "-h", hostname, + "-p", "-f", "--", pw->pw_name, (char *)NULL); + + /* Login couldn't be executed, die. */ + + perror("login"); + exit(1); +} + /* * Performs common processing for the child, such as setting up the * environment, closing extra file descriptors, setting the user and group @@ -1095,15 +1063,8 @@ signal(SIGPIPE, SIG_DFL); if (options.use_login) { - /* Launch login(1). */ - - execl("/usr/bin/login", "login", "-h", hostname, - "-p", "-f", "--", pw->pw_name, (char *)NULL); - - /* Login couldn't be executed, die. */ - - perror("login"); - exit(1); + launch_login(pw, hostname); + /* NEVERREACHED */ } /* Get the last component of the shell name. */ @@ -1213,6 +1174,22 @@ return 1; } +Session * +session_by_tty(char *tty) +{ + int i; + for (i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) { + debug("session_by_tty: session %d tty %s", i, tty); + return s; + } + } + debug("session_by_tty: unknown tty %.100s", tty); + session_dump(); + return NULL; +} + static Session * session_by_channel(int id) { @@ -1270,6 +1247,12 @@ packet_disconnect("Protocol error: you already have a pty."); return 0; } + /* Get the time and hostname when the user last logged in. */ + if (options.print_lastlog) { + s->hostname[0] = '\0'; + s->last_login_time = get_last_login_time(s->pw->pw_uid, + s->pw->pw_name, s->hostname, sizeof(s->hostname)); + } s->term = packet_get_string(&len); @@ -1290,7 +1273,7 @@ /* Allocate a pty and open it. */ debug("Allocating pty."); - if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { + if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) { if (s->term) xfree(s->term); s->term = NULL; @@ -1311,7 +1294,8 @@ * time in case we call fatal() (e.g., the connection gets closed). */ fatal_add_cleanup(session_pty_cleanup, (void *)s); - pty_setowner(s->pw, s->tty); + if (!use_privsep) + pty_setowner(s->pw, s->tty); /* Set window size from the packet. */ pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); @@ -1474,8 +1458,8 @@ * Function to perform pty cleanup. Also called if we get aborted abnormally * (e.g., due to a dropped connection). */ -static void -session_pty_cleanup(void *session) +void +session_pty_cleanup2(void *session) { Session *s = session; @@ -1493,7 +1477,8 @@ record_logout(s->pid, s->tty); /* Release the pseudo-tty. */ - pty_release(s->tty); + if (getuid() == 0) + pty_release(s->tty); /* * Close the server side of the socket pairs. We must do this after @@ -1501,12 +1486,18 @@ * while we're still cleaning up. */ if (close(s->ptymaster) < 0) - error("close(s->ptymaster): %s", strerror(errno)); + error("close(s->ptymaster/%d): %s", s->ptymaster, strerror(errno)); /* unlink pty from session */ s->ttyfd = -1; } +void +session_pty_cleanup(void *session) +{ + PRIVSEP(session_pty_cleanup2(session)); +} + static void session_exit_message(Session *s, int status) { @@ -1548,7 +1539,7 @@ s->chanid = -1; } -static void +void session_close(Session *s) { debug("session_close: session %d pid %d", s->self, s->pid); @@ -1615,13 +1606,17 @@ } void -session_destroy_all(void) +session_destroy_all(void (*closefunc)(Session *)) { int i; for (i = 0; i < MAX_SESSIONS; i++) { Session *s = &sessions[i]; - if (s->used) - session_close(s); + if (s->used) { + if (closefunc != NULL) + closefunc(s); + else + session_close(s); + } } }