]> andersk Git - gssapi-openssh.git/blobdiff - openssh/session.c
Re-import of OpenSSH 3.7.1p2 (Chase\!)
[gssapi-openssh.git] / openssh / session.c
index 03a5ec5704c18ea76fb53f550ce76a564f5bd03d..2898ac5185f0b84cf64dc5e8709815aa1550e715 100644 (file)
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.170 2003/12/23 16:12:10 jakob Exp $");
+RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -66,7 +66,7 @@ RCSID("$OpenBSD: session.c,v 1.170 2003/12/23 16:12:10 jakob Exp $");
 
 Session *session_new(void);
 void   session_set_fds(Session *, int, int, int);
-void   session_pty_cleanup(Session *);
+void   session_pty_cleanup(void *);
 void   session_proctitle(Session *);
 int    session_setup_x11fwd(Session *);
 void   do_exec_pty(Session *, const char *);
@@ -106,8 +106,6 @@ Session     sessions[MAX_SESSIONS];
 login_cap_t *lc;
 #endif
 
-static int is_child = 0;
-
 /* Name and directory of socket for authentication agent forwarding. */
 static char *auth_sock_name = NULL;
 static char *auth_sock_dir = NULL;
@@ -115,8 +113,10 @@ static char *auth_sock_dir = NULL;
 /* removes the agent forwarding socket */
 
 static void
-auth_sock_cleanup_proc(struct passwd *pw)
+auth_sock_cleanup_proc(void *_pw)
 {
+       struct passwd *pw = _pw;
+
        if (auth_sock_name != NULL) {
                temporarily_use_uid(pw);
                unlink(auth_sock_name);
@@ -144,7 +144,7 @@ auth_input_request_forwarding(struct passwd * pw)
        /* Allocate a buffer for the socket name, and format the name. */
        auth_sock_name = xmalloc(MAXPATHLEN);
        auth_sock_dir = xmalloc(MAXPATHLEN);
-       strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
+       strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
 
        /* Create private directory for socket */
        if (mkdtemp(auth_sock_dir) == NULL) {
@@ -160,6 +160,9 @@ auth_input_request_forwarding(struct passwd * pw)
        snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
                 auth_sock_dir, (long) getpid());
 
+       /* delete agent socket on fatal() */
+       fatal_add_cleanup(auth_sock_cleanup_proc, pw);
+
        /* Create the socket. */
        sock = socket(AF_UNIX, SOCK_STREAM, 0);
        if (sock < 0)
@@ -177,7 +180,7 @@ auth_input_request_forwarding(struct passwd * pw)
        restore_uid();
 
        /* Start listening on the socket. */
-       if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
+       if (listen(sock, 5) < 0)
                packet_disconnect("listen: %.100s", strerror(errno));
 
        /* Allocate a channel for the authentication agent socket. */
@@ -204,6 +207,7 @@ do_authenticated(Authctxt *authctxt)
                close(startup_pipe);
                startup_pipe = -1;
        }
+
        /* setup the channel layer */
        if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
                channel_permit_all_opens();
@@ -213,7 +217,13 @@ do_authenticated(Authctxt *authctxt)
        else
                do_authenticated1(authctxt);
 
-       do_cleanup(authctxt);
+       /* remove agent socket */
+       if (auth_sock_name != NULL)
+               auth_sock_cleanup_proc(authctxt->pw);
+#ifdef KRB5
+       if (options.kerberos_ticket_cleanup)
+               krb5_cleanup_proc(authctxt);
+#endif
 }
 
 /*
@@ -395,7 +405,7 @@ do_exec_no_pty(Session *s, const char *command)
 
        /* Fork the child. */
        if ((pid = fork()) == 0) {
-               is_child = 1;
+               fatal_remove_all_cleanups();
 
                /* Child.  Reinitialize the log since the pid has changed. */
                log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -521,7 +531,7 @@ do_exec_pty(Session *s, const char *command)
 
        /* Fork the child. */
        if ((pid = fork()) == 0) {
-               is_child = 1;
+               fatal_remove_all_cleanups();
 
                /* Child.  Reinitialize the log because the pid has changed. */
                log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -617,7 +627,7 @@ do_pre_login(Session *s)
                if (getpeername(packet_get_connection_in(),
                    (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
-                       cleanup_exit(255);
+                       fatal_cleanup();
                }
        }
 
@@ -677,7 +687,7 @@ do_login(Session *s, const char *command)
                if (getpeername(packet_get_connection_in(),
                    (struct sockaddr *) & from, &fromlen) < 0) {
                        debug("getpeername: %.100s", strerror(errno));
-                       cleanup_exit(255);
+                       fatal_cleanup();
                }
        }
 
@@ -905,7 +915,7 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
 {
        char **tmpenv = NULL, *var;
        u_int i, tmpenvsize = 0;
-       u_long mask;
+       mode_t mask;
 
        /*
         * We don't want to copy the whole file to the child's environment,
@@ -923,11 +933,11 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
                var = child_get_env(tmpenv, "PATH");
        if (var != NULL)
                child_set_env(env, envsize, "PATH", var);
-
+       
        if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
                if (sscanf(var, "%5lo", &mask) == 1)
-                       umask((mode_t)mask);
-
+                       umask(mask);
+       
        for (i = 0; tmpenv[i] != NULL; i++)
                xfree(tmpenv[i]);
        xfree(tmpenv);
@@ -952,7 +962,7 @@ void copy_environment(char **source, char ***env, u_int *envsize)
 
                debug3("Copy environment: %s=%s", var_name, var_val);
                child_set_env(env, envsize, var_name, var_val);
-
+               
                xfree(var_name);
        }
 }
@@ -979,7 +989,7 @@ do_setup_env(Session *s, const char *shell)
 #endif
 
 #ifdef GSSAPI
-       /* Allow any GSSAPI methods that we've used to alter
+       /* Allow any GSSAPI methods that we've used to alter 
         * the childs environment as they see fit
         */
        ssh_gssapi_do_child(&env, &envsize);
@@ -1011,7 +1021,7 @@ do_setup_env(Session *s, const char *shell)
                path = child_get_env(env, "PATH");
 #  endif /* HAVE_ETC_DEFAULT_LOGIN */
                if (path == NULL || *path == '\0') {
-                       child_set_env(&env, &envsize, "PATH",
+                       child_set_env(&env, &envsize, "PATH", 
                            s->pw->pw_uid == 0 ?
                                SUPERUSER_PATH : _PATH_STDPATH);
                }
@@ -1094,13 +1104,8 @@ do_setup_env(Session *s, const char *shell)
         * been set by PAM.
         */
        if (options.use_pam) {
-               char **p;
+               char **p = fetch_pam_environment();
 
-               p = fetch_pam_child_environment();
-               copy_environment(p, &env, &envsize);
-               free_pam_environment(p);
-
-               p = fetch_pam_environment();
                copy_environment(p, &env, &envsize);
                free_pam_environment(p);
        }
@@ -1173,7 +1178,7 @@ do_rc_files(Session *s, const char *shell)
                if (debug_flag) {
                        fprintf(stderr,
                            "Running %.500s remove %.100s\n",
-                           options.xauth_location, s->auth_display);
+                           options.xauth_location, s->auth_display);
                        fprintf(stderr,
                            "%.500s add %.100s %.100s %.100s\n",
                            options.xauth_location, s->auth_display,
@@ -1265,7 +1270,7 @@ do_setusercontext(struct passwd *pw)
                endgrent();
 # ifdef USE_PAM
                /*
-                * PAM credentials may take the form of supplementary groups.
+                * PAM credentials may take the form of supplementary groups. 
                 * These will have been wiped by the above initgroups() call.
                 * Reestablish them here.
                 */
@@ -1415,32 +1420,6 @@ do_child(Session *s, const char *command)
         */
        environ = env;
 
-#ifdef KRB5
-       /*
-        * At this point, we check to see if AFS is active and if we have
-        * a valid Kerberos 5 TGT. If so, it seems like a good idea to see
-        * if we can (and need to) extend the ticket into an AFS token. If
-        * we don't do this, we run into potential problems if the user's
-        * home directory is in AFS and it's not world-readable.
-        */
-
-       if (options.kerberos_get_afs_token && k_hasafs() &&
-            (s->authctxt->krb5_ctx != NULL)) {
-               char cell[64];
-
-               debug("Getting AFS token");
-
-               k_setpag();
-
-               if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
-                       krb5_afslog(s->authctxt->krb5_ctx,
-                           s->authctxt->krb5_fwd_ccache, cell, NULL);
-
-               krb5_afslog_home(s->authctxt->krb5_ctx,
-                   s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
-       }
-#endif
-
        /* Change current directory to the user\'s home directory. */
        if (chdir(pw->pw_dir) < 0) {
                fprintf(stderr, "Could not chdir to home directory %s: %s\n",
@@ -1562,7 +1541,7 @@ session_open(Authctxt *authctxt, int chanid)
        }
        s->authctxt = authctxt;
        s->pw = authctxt->pw;
-       if (s->pw == NULL || !authctxt->valid)
+       if (s->pw == NULL)
                fatal("no user for session %d", s->self);
        debug("session_open: session %d: link with channel %d", s->self, chanid);
        s->chanid = chanid;
@@ -1684,6 +1663,11 @@ session_pty_req(Session *s)
                n_bytes = packet_remaining();
        tty_parse_modes(s->ttyfd, &n_bytes);
 
+       /*
+        * Add a cleanup function to clear the utmp entry and record logout
+        * 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);
 
@@ -1865,8 +1849,10 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
  * (e.g., due to a dropped connection).
  */
 void
-session_pty_cleanup2(Session *s)
+session_pty_cleanup2(void *session)
 {
+       Session *s = session;
+
        if (s == NULL) {
                error("session_pty_cleanup: no session");
                return;
@@ -1897,9 +1883,9 @@ session_pty_cleanup2(Session *s)
 }
 
 void
-session_pty_cleanup(Session *s)
+session_pty_cleanup(void *session)
 {
-       PRIVSEP(session_pty_cleanup2(s));
+       PRIVSEP(session_pty_cleanup2(session));
 }
 
 static char *
@@ -1972,8 +1958,10 @@ void
 session_close(Session *s)
 {
        debug("session_close: session %d pid %ld", s->self, (long)s->pid);
-       if (s->ttyfd != -1)
+       if (s->ttyfd != -1) {
+               fatal_remove_cleanup(session_pty_cleanup, (void *)s);
                session_pty_cleanup(s);
+       }
        if (s->term)
                xfree(s->term);
        if (s->display)
@@ -2022,8 +2010,10 @@ session_close_by_channel(int id, void *arg)
                 * delay detach of session, but release pty, since
                 * the fd's to the child are already closed
                 */
-               if (s->ttyfd != -1)
+               if (s->ttyfd != -1) {
+                       fatal_remove_cleanup(session_pty_cleanup, (void *)s);
                        session_pty_cleanup(s);
+               }
                return;
        }
        /* detach by removing callback */
@@ -2058,13 +2048,13 @@ session_tty_list(void)
        for (i = 0; i < MAX_SESSIONS; i++) {
                Session *s = &sessions[i];
                if (s->used && s->ttyfd != -1) {
-
+                       
                        if (strncmp(s->tty, "/dev/", 5) != 0) {
                                cp = strrchr(s->tty, '/');
                                cp = (cp == NULL) ? s->tty : cp + 1;
                        } else
                                cp = s->tty + 5;
-
+                       
                        if (buf[0] != '\0')
                                strlcat(buf, ",", sizeof buf);
                        strlcat(buf, cp, sizeof buf);
@@ -2164,51 +2154,8 @@ static void
 do_authenticated2(Authctxt *authctxt)
 {
        server_loop2(authctxt);
-}
-
-void
-do_cleanup(Authctxt *authctxt)
-{
-       static int called = 0;
-
-       debug("do_cleanup");
-
-       /* no cleanup if we're in the child for login shell */
-       if (is_child)
-               return;
-
-       /* avoid double cleanup */
-       if (called)
-               return;
-       called = 1;
-
-       if (authctxt == NULL)
-               return;
-#ifdef KRB5
-       if (options.kerberos_ticket_cleanup &&
-           authctxt->krb5_ctx)
-               krb5_cleanup_proc(authctxt);
-#endif
-
-#ifdef GSSAPI
-       if (compat20 && options.gss_cleanup_creds)
-               ssh_gssapi_cleanup_creds();
+#if defined(GSSAPI)
+       if (options.gss_cleanup_creds)
+               ssh_gssapi_cleanup_creds(NULL);
 #endif
-
-#ifdef USE_PAM
-       if (options.use_pam) {
-               sshpam_cleanup();
-               sshpam_thread_cleanup();
-       }
-#endif
-
-       /* remove agent socket */
-       auth_sock_cleanup_proc(authctxt->pw);
-
-       /*
-        * Cleanup ptys/utmp only if privsep is disabled,
-        * or if running in monitor.
-        */
-       if (!use_privsep || mm_is_monitor())
-               session_destroy_all(session_pty_cleanup2);
 }
This page took 0.620368 seconds and 4 git commands to generate.