]> andersk Git - openssh.git/blobdiff - session.c
- stevesk@cvs.openbsd.org 2002/06/10 21:21:10
[openssh.git] / session.c
index 17227c9ffcafe75e8c8d3906fcf8080756601f6b..dcecf1ae34c115d1ba3036450ccdbe692970c349 100644 (file)
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.135 2002/05/16 22:09:59 stevesk Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -56,7 +56,6 @@ RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $");
 #include "serverloop.h"
 #include "canohost.h"
 #include "session.h"
-#include "monitor.h"
 #include "monitor_wrap.h"
 
 #ifdef HAVE_CYGWIN
@@ -65,10 +64,6 @@ RCSID("$OpenBSD: session.c,v 1.128 2002/02/16 00:51:44 markus Exp $");
 #define is_winnt       (GetVersion() < 0x80000000)
 #endif
 
-/* Imports */
-extern int use_privsep;
-extern int mm_recvfd;
-
 /* func */
 
 Session *session_new(void);
@@ -113,7 +108,7 @@ char *aixloginmsg;
 #endif /* WITH_AIXAUTHENTICATE */
 
 #ifdef HAVE_LOGIN_CAP
-static login_cap_t *lc;
+login_cap_t *lc;
 #endif
 
 void
@@ -128,18 +123,6 @@ do_authenticated(Authctxt *authctxt)
                close(startup_pipe);
                startup_pipe = -1;
        }
-#if defined(HAVE_LOGIN_CAP) && defined(HAVE_PW_CLASS_IN_PASSWD)
-       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
 #ifdef WITH_AIXAUTHENTICATE
        /* We don't have a pty yet, so just label the line as "ssh" */
        if (loginsuccess(authctxt->user,
@@ -636,10 +619,8 @@ void
 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();
 
@@ -657,17 +638,12 @@ do_login(Session *s, const char *command)
                }
        }
 
-       /* 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);
 
 #ifdef USE_PAM
        /*
@@ -692,14 +668,15 @@ do_login(Session *s, const char *command)
                printf("%s\n", aixloginmsg);
 #endif /* WITH_AIXAUTHENTICATE */
 
-       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();
@@ -894,7 +871,12 @@ do_setup_env(Session *s, const char *shell)
                 * needed for loading shared libraries. So the path better
                 * remains intact here.
                 */
+#  ifdef SUPERUSER_PATH
+               child_set_env(&env, &envsize, "PATH", 
+                   s->pw->pw_uid == 0 ? SUPERUSER_PATH : _PATH_STDPATH);
+#  else 
                child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
+#  endif /* SUPERUSER_PATH */
 # endif /* HAVE_CYGWIN */
 #endif /* HAVE_LOGIN_CAP */
 
@@ -1032,7 +1014,7 @@ do_rc_files(Session *s, const char *shell)
                /* Add authority data to .Xauthority if appropriate. */
                if (debug_flag) {
                        fprintf(stderr,
-                           "Running %.100s add "
+                           "Running %.500s add "
                            "%.100s %.100s %.100s\n",
                            options.xauth_location, s->auth_display,
                            s->auth_proto, s->auth_data);
@@ -1076,7 +1058,7 @@ do_nologin(struct passwd *pw)
 }
 
 /* Set login name, uid, gid, and groups. */
-static void
+void
 do_setusercontext(struct passwd *pw)
 {
 #ifdef HAVE_CYGWIN
@@ -1131,6 +1113,27 @@ do_setusercontext(struct passwd *pw)
                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(LOGIN_PROGRAM, "login", "-h", hostname,
+#ifdef xxxLOGIN_NEEDS_TERM
+                   (s->term ? s->term : "unknown"),
+#endif /* LOGIN_NEEDS_TERM */
+#ifdef LOGIN_NO_ENDOPT
+           "-p", "-f", pw->pw_name, (char *)NULL);
+#else
+           "-p", "-f", "--", pw->pw_name, (char *)NULL);
+#endif
+
+       /* 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
@@ -1256,18 +1259,8 @@ do_child(Session *s, const char *command)
        signal(SIGPIPE,  SIG_DFL);
 
        if (options.use_login) {
-               /* Launch login(1). */
-
-               execl(LOGIN_PROGRAM, "login", "-h", hostname,
-#ifdef LOGIN_NEEDS_TERM
-                   (s->term ? s->term : "unknown"),
-#endif /* LOGIN_NEEDS_TERM */
-                   "-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. */
@@ -1377,6 +1370,22 @@ session_open(Authctxt *authctxt, int chanid)
        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)
 {
@@ -1425,8 +1434,7 @@ session_pty_req(Session *s)
 {
        u_int len;
        int n_bytes;
-       int res;
-       
+
        if (no_pty_flag) {
                debug("Allocating a pty not permitted for this authentication.");
                return 0;
@@ -1435,6 +1443,12 @@ session_pty_req(Session *s)
                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);
 
@@ -1455,15 +1469,7 @@ session_pty_req(Session *s)
 
        /* Allocate a pty and open it. */
        debug("Allocating pty.");
-       if (!use_privsep) {
-               res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty,
-                       sizeof(s->tty));
-               if (res)
-                       pty_setowner(s->pw, s->tty);
-       } else 
-               res = mm_pty_allocown(mm_recvfd,
-                   &s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
-       if (!res) {
+       if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
                if (s->term)
                        xfree(s->term);
                s->term = NULL;
@@ -1484,6 +1490,8 @@ session_pty_req(Session *s)
         * time in case we call fatal() (e.g., the connection gets closed).
         */
        fatal_add_cleanup(session_pty_cleanup, (void *)s);
+       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);
@@ -1647,7 +1655,7 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
  * (e.g., due to a dropped connection).
  */
 void
-session_pty_cleanup(void *session)
+session_pty_cleanup2(void *session)
 {
        Session *s = session;
 
@@ -1665,7 +1673,8 @@ session_pty_cleanup(void *session)
                record_logout(s->pid, s->tty, s->pw->pw_name);
 
        /* 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
@@ -1673,12 +1682,18 @@ session_pty_cleanup(void *session)
         * 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)
 {
@@ -1791,13 +1806,17 @@ session_close_by_channel(int id, void *arg)
 }
 
 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);
+               }
        }
 }
 
This page took 0.046566 seconds and 4 git commands to generate.