[BACK]Return to session.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/session.c between version 1.154 and 1.154.2.2

version 1.154, 2003/03/05 22:33:43 version 1.154.2.2, 2004/03/04 18:18:16
Line 58 
Line 58 
 #include "session.h"  #include "session.h"
 #include "monitor_wrap.h"  #include "monitor_wrap.h"
   
   #ifdef KRB5
   #include <kafs.h>
   #endif
   
   #ifdef GSSAPI
   #include "ssh-gss.h"
   #endif
   
 /* func */  /* func */
   
 Session *session_new(void);  Session *session_new(void);
 void    session_set_fds(Session *, int, int, int);  void    session_set_fds(Session *, int, int, int);
 void    session_pty_cleanup(void *);  void    session_pty_cleanup(Session *);
 void    session_proctitle(Session *);  void    session_proctitle(Session *);
 int     session_setup_x11fwd(Session *);  int     session_setup_x11fwd(Session *);
 void    do_exec_pty(Session *, const char *);  void    do_exec_pty(Session *, const char *);
Line 98 
Line 106 
 login_cap_t *lc;  login_cap_t *lc;
 #endif  #endif
   
   static int is_child = 0;
   
 /* Name and directory of socket for authentication agent forwarding. */  /* Name and directory of socket for authentication agent forwarding. */
 static char *auth_sock_name = NULL;  static char *auth_sock_name = NULL;
 static char *auth_sock_dir = NULL;  static char *auth_sock_dir = NULL;
Line 105 
Line 115 
 /* removes the agent forwarding socket */  /* removes the agent forwarding socket */
   
 static void  static void
 auth_sock_cleanup_proc(void *_pw)  auth_sock_cleanup_proc(struct passwd *pw)
 {  {
         struct passwd *pw = _pw;  
   
         if (auth_sock_name != NULL) {          if (auth_sock_name != NULL) {
                 temporarily_use_uid(pw);                  temporarily_use_uid(pw);
                 unlink(auth_sock_name);                  unlink(auth_sock_name);
Line 136 
Line 144 
         /* Allocate a buffer for the socket name, and format the name. */          /* Allocate a buffer for the socket name, and format the name. */
         auth_sock_name = xmalloc(MAXPATHLEN);          auth_sock_name = xmalloc(MAXPATHLEN);
         auth_sock_dir = xmalloc(MAXPATHLEN);          auth_sock_dir = xmalloc(MAXPATHLEN);
         strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);          strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
   
         /* Create private directory for socket */          /* Create private directory for socket */
         if (mkdtemp(auth_sock_dir) == NULL) {          if (mkdtemp(auth_sock_dir) == NULL) {
Line 152 
Line 160 
         snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",          snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
                  auth_sock_dir, (long) getpid());                   auth_sock_dir, (long) getpid());
   
         /* delete agent socket on fatal() */  
         fatal_add_cleanup(auth_sock_cleanup_proc, pw);  
   
         /* Create the socket. */          /* Create the socket. */
         sock = socket(AF_UNIX, SOCK_STREAM, 0);          sock = socket(AF_UNIX, SOCK_STREAM, 0);
         if (sock < 0)          if (sock < 0)
Line 172 
Line 177 
         restore_uid();          restore_uid();
   
         /* Start listening on the socket. */          /* Start listening on the socket. */
         if (listen(sock, 5) < 0)          if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
                 packet_disconnect("listen: %.100s", strerror(errno));                  packet_disconnect("listen: %.100s", strerror(errno));
   
         /* Allocate a channel for the authentication agent socket. */          /* Allocate a channel for the authentication agent socket. */
         nc = channel_new("auth socket",          nc = channel_new("auth socket",
             SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,              SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
             CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,              CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
             0, xstrdup("auth socket"), 1);              0, "auth socket", 1);
         strlcpy(nc->path, auth_sock_name, sizeof(nc->path));          strlcpy(nc->path, auth_sock_name, sizeof(nc->path));
         return 1;          return 1;
 }  }
Line 208 
Line 213 
         else          else
                 do_authenticated1(authctxt);                  do_authenticated1(authctxt);
   
         /* remove agent socket */          do_cleanup(authctxt);
         if (auth_sock_name != NULL)  
                 auth_sock_cleanup_proc(authctxt->pw);  
 #ifdef KRB4  
         if (options.kerberos_ticket_cleanup)  
                 krb4_cleanup_proc(authctxt);  
 #endif  
 #ifdef KRB5  
         if (options.kerberos_ticket_cleanup)  
                 krb5_cleanup_proc(authctxt);  
 #endif  
 }  }
   
 /*  /*
Line 327 
Line 322 
                                 success = 1;                                  success = 1;
                         break;                          break;
   
 #if defined(AFS) || defined(KRB5)  
                 case SSH_CMSG_HAVE_KERBEROS_TGT:  
                         if (!options.kerberos_tgt_passing) {  
                                 verbose("Kerberos TGT passing disabled.");  
                         } else {  
                                 char *kdata = packet_get_string(&dlen);  
                                 packet_check_eom();  
   
                                 /* XXX - 0x41, see creds_to_radix version */  
                                 if (kdata[0] != 0x41) {  
 #ifdef KRB5  
                                         krb5_data tgt;  
                                         tgt.data = kdata;  
                                         tgt.length = dlen;  
   
                                         if (auth_krb5_tgt(s->authctxt, &tgt))  
                                                 success = 1;  
                                         else  
                                                 verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user);  
 #endif /* KRB5 */  
                                 } else {  
 #ifdef AFS  
                                         if (auth_krb4_tgt(s->authctxt, kdata))  
                                                 success = 1;  
                                         else  
                                                 verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user);  
 #endif /* AFS */  
                                 }  
                                 xfree(kdata);  
                         }  
                         break;  
 #endif /* AFS || KRB5 */  
   
 #ifdef AFS  
                 case SSH_CMSG_HAVE_AFS_TOKEN:  
                         if (!options.afs_token_passing || !k_hasafs()) {  
                                 verbose("AFS token passing disabled.");  
                         } else {  
                                 /* Accept AFS token. */  
                                 char *token = packet_get_string(&dlen);  
                                 packet_check_eom();  
   
                                 if (auth_afs_token(s->authctxt, token))  
                                         success = 1;  
                                 else  
                                         verbose("AFS token refused for %.100s",  
                                             s->authctxt->user);  
                                 xfree(token);  
                         }  
                         break;  
 #endif /* AFS */  
   
                 case SSH_CMSG_EXEC_SHELL:                  case SSH_CMSG_EXEC_SHELL:
                 case SSH_CMSG_EXEC_CMD:                  case SSH_CMSG_EXEC_CMD:
                         if (type == SSH_CMSG_EXEC_CMD) {                          if (type == SSH_CMSG_EXEC_CMD) {
Line 398 
Line 341 
                          * Any unknown messages in this phase are ignored,                           * Any unknown messages in this phase are ignored,
                          * and a failure message is returned.                           * and a failure message is returned.
                          */                           */
                         log("Unknown packet type received after authentication: %d", type);                          logit("Unknown packet type received after authentication: %d", type);
                 }                  }
                 packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);                  packet_start(success ? SSH_SMSG_SUCCESS : SSH_SMSG_FAILURE);
                 packet_send();                  packet_send();
Line 443 
Line 386 
   
         /* Fork the child. */          /* Fork the child. */
         if ((pid = fork()) == 0) {          if ((pid = fork()) == 0) {
                 fatal_remove_all_cleanups();                  is_child = 1;
   
                 /* Child.  Reinitialize the log since the pid has changed. */                  /* Child.  Reinitialize the log since the pid has changed. */
                 log_init(__progname, options.log_level, options.log_facility, log_stderr);                  log_init(__progname, options.log_level, options.log_facility, log_stderr);
Line 551 
Line 494 
   
         /* Fork the child. */          /* Fork the child. */
         if ((pid = fork()) == 0) {          if ((pid = fork()) == 0) {
                 fatal_remove_all_cleanups();                  is_child = 1;
   
                 /* Child.  Reinitialize the log because the pid has changed. */                  /* Child.  Reinitialize the log because the pid has changed. */
                 log_init(__progname, options.log_level, options.log_facility, log_stderr);                  log_init(__progname, options.log_level, options.log_facility, log_stderr);
Line 625 
Line 568 
                 debug("Forced command '%.900s'", command);                  debug("Forced command '%.900s'", command);
         }          }
   
   #ifdef GSSAPI
           if (options.gss_authentication) {
                   temporarily_use_uid(s->pw);
                   ssh_gssapi_storecreds();
                   restore_uid();
           }
   #endif
   
         if (s->ttyfd != -1)          if (s->ttyfd != -1)
                 do_exec_pty(s, command);                  do_exec_pty(s, command);
         else          else
Line 654 
Line 605 
                 if (getpeername(packet_get_connection_in(),                  if (getpeername(packet_get_connection_in(),
                     (struct sockaddr *) & from, &fromlen) < 0) {                      (struct sockaddr *) & from, &fromlen) < 0) {
                         debug("getpeername: %.100s", strerror(errno));                          debug("getpeername: %.100s", strerror(errno));
                         fatal_cleanup();                          cleanup_exit(255);
                 }                  }
         }          }
   
Line 662 
Line 613 
         if (!use_privsep)          if (!use_privsep)
                 record_login(pid, s->tty, pw->pw_name, pw->pw_uid,                  record_login(pid, s->tty, pw->pw_name, pw->pw_uid,
                     get_remote_name_or_ip(utmp_len,                      get_remote_name_or_ip(utmp_len,
                     options.verify_reverse_mapping),                      options.use_dns),
                     (struct sockaddr *)&from, fromlen);                      (struct sockaddr *)&from, fromlen);
   
         if (check_quietlogin(s, command))          if (check_quietlogin(s, command))
Line 735 
Line 686 
  * Sets the value of the given variable in the environment.  If the variable   * Sets the value of the given variable in the environment.  If the variable
  * already exists, its value is overriden.   * already exists, its value is overriden.
  */   */
 static void  void
 child_set_env(char ***envp, u_int *envsizep, const char *name,  child_set_env(char ***envp, u_int *envsizep, const char *name,
         const char *value)          const char *value)
 {  {
         u_int i, namelen;  
         char **env;          char **env;
           u_int envsize;
           u_int i, namelen;
   
         /*          /*
          * Find the slot where the value should be stored.  If the variable           * Find the slot where the value should be stored.  If the variable
Line 757 
Line 709 
                 xfree(env[i]);                  xfree(env[i]);
         } else {          } else {
                 /* New variable.  Expand if necessary. */                  /* New variable.  Expand if necessary. */
                 if (i >= (*envsizep) - 1) {                  envsize = *envsizep;
                         if (*envsizep >= 1000)                  if (i >= envsize - 1) {
                                 fatal("child_set_env: too many env vars,"                          if (envsize >= 1000)
                                     " skipping: %.100s", name);                                  fatal("child_set_env: too many env vars");
                         (*envsizep) += 50;                          envsize += 50;
                         env = (*envp) = xrealloc(env, (*envsizep) * sizeof(char *));                          env = (*envp) = xrealloc(env, envsize * sizeof(char *));
                           *envsizep = envsize;
                 }                  }
                 /* Need to set the NULL pointer at end of array beyond the new slot. */                  /* Need to set the NULL pointer at end of array beyond the new slot. */
                 env[i + 1] = NULL;                  env[i + 1] = NULL;
Line 831 
Line 784 
         env = xmalloc(envsize * sizeof(char *));          env = xmalloc(envsize * sizeof(char *));
         env[0] = NULL;          env[0] = NULL;
   
   #ifdef GSSAPI
           /* Allow any GSSAPI methods that we've used to alter
            * the childs environment as they see fit
            */
           ssh_gssapi_do_child(&env, &envsize);
   #endif
   
         if (!options.use_login) {          if (!options.use_login) {
                 /* Set basic environment. */                  /* Set basic environment. */
                 child_set_env(&env, &envsize, "USER", pw->pw_name);                  child_set_env(&env, &envsize, "USER", pw->pw_name);
Line 893 
Line 853 
         if (original_command)          if (original_command)
                 child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",                  child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND",
                     original_command);                      original_command);
 #ifdef KRB4  
         if (s->authctxt->krb4_ticket_file)  
                 child_set_env(&env, &envsize, "KRBTKFILE",  
                     s->authctxt->krb4_ticket_file);  
 #endif  
 #ifdef KRB5  #ifdef KRB5
         if (s->authctxt->krb5_ticket_file)          if (s->authctxt->krb5_ticket_file)
                 child_set_env(&env, &envsize, "KRB5CCNAME",                  child_set_env(&env, &envsize, "KRB5CCNAME",
Line 970 
Line 925 
                 if (debug_flag) {                  if (debug_flag) {
                         fprintf(stderr,                          fprintf(stderr,
                             "Running %.500s remove %.100s\n",                              "Running %.500s remove %.100s\n",
                             options.xauth_location, s->auth_display);                              options.xauth_location, s->auth_display);
                         fprintf(stderr,                          fprintf(stderr,
                             "%.500s add %.100s %.100s %.100s\n",                              "%.500s add %.100s %.100s %.100s\n",
                             options.xauth_location, s->auth_display,                              options.xauth_location, s->auth_display,
Line 1009 
Line 964 
 #endif  #endif
         if (f) {          if (f) {
                 /* /etc/nologin exists.  Print its contents and exit. */                  /* /etc/nologin exists.  Print its contents and exit. */
                 log("User %.100s not allowed because %s exists",                  logit("User %.100s not allowed because %s exists",
                     pw->pw_name, _PATH_NOLOGIN);                      pw->pw_name, _PATH_NOLOGIN);
                 while (fgets(buf, sizeof(buf), f))                  while (fgets(buf, sizeof(buf), f))
                         fputs(buf, stderr);                          fputs(buf, stderr);
Line 1052 
Line 1007 
 }  }
   
 static void  static void
   do_pwchange(Session *s)
   {
           fprintf(stderr, "WARNING: Your password has expired.\n");
           if (s->ttyfd != -1) {
                   fprintf(stderr,
                       "You must change your password now and login again!\n");
                   execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
                   perror("passwd");
           } else {
                   fprintf(stderr,
                       "Password change required but no TTY available.\n");
           }
           exit(1);
   }
   
   static void
 launch_login(struct passwd *pw, const char *hostname)  launch_login(struct passwd *pw, const char *hostname)
 {  {
         /* Launch login(1). */          /* Launch login(1). */
Line 1065 
Line 1036 
         exit(1);          exit(1);
 }  }
   
   static void
   child_close_fds(void)
   {
           int i;
   
           if (packet_get_connection_in() == packet_get_connection_out())
                   close(packet_get_connection_in());
           else {
                   close(packet_get_connection_in());
                   close(packet_get_connection_out());
           }
           /*
            * Close all descriptors related to channels.  They will still remain
            * open in the parent.
            */
           /* XXX better use close-on-exec? -markus */
           channel_close_all();
   
           /*
            * Close any extra file descriptors.  Note that there may still be
            * descriptors left by system functions.  They will be closed later.
            */
           endpwent();
   
           /*
            * Close any extra open file descriptors so that we don\'t have them
            * hanging around in clients.  Note that we want to do this after
            * initgroups, because at least on Solaris 2.3 it leaves file
            * descriptors open.
            */
           for (i = 3; i < 64; i++)
                   close(i);
   }
   
 /*  /*
  * Performs common processing for the child, such as setting up the   * Performs common processing for the child, such as setting up the
  * environment, closing extra file descriptors, setting the user and group   * environment, closing extra file descriptors, setting the user and group
Line 1078 
Line 1083 
         char *argv[10];          char *argv[10];
         const char *shell, *shell0, *hostname = NULL;          const char *shell, *shell0, *hostname = NULL;
         struct passwd *pw = s->pw;          struct passwd *pw = s->pw;
         u_int i;  
   
         /* remove hostkey from the child's memory */          /* remove hostkey from the child's memory */
         destroy_sensitive_data();          destroy_sensitive_data();
   
           /* Force a password change */
           if (s->authctxt->force_pwchange) {
                   do_setusercontext(pw);
                   child_close_fds();
                   do_pwchange(s);
                   exit(1);
           }
   
         /* login(1) is only called if we execute the login shell */          /* login(1) is only called if we execute the login shell */
         if (options.use_login && command != NULL)          if (options.use_login && command != NULL)
                 options.use_login = 0;                  options.use_login = 0;
Line 1115 
Line 1127 
         /* we have to stash the hostname before we close our socket. */          /* we have to stash the hostname before we close our socket. */
         if (options.use_login)          if (options.use_login)
                 hostname = get_remote_name_or_ip(utmp_len,                  hostname = get_remote_name_or_ip(utmp_len,
                     options.verify_reverse_mapping);                      options.use_dns);
         /*          /*
          * Close the connection descriptors; note that this is the child, and           * Close the connection descriptors; note that this is the child, and
          * the server will still have the socket open, and it is important           * the server will still have the socket open, and it is important
Line 1123 
Line 1135 
          * closed before building the environment, as we call           * closed before building the environment, as we call
          * get_remote_ipaddr there.           * get_remote_ipaddr there.
          */           */
         if (packet_get_connection_in() == packet_get_connection_out())          child_close_fds();
                 close(packet_get_connection_in());  
         else {  
                 close(packet_get_connection_in());  
                 close(packet_get_connection_out());  
         }  
         /*  
          * Close all descriptors related to channels.  They will still remain  
          * open in the parent.  
          */  
         /* XXX better use close-on-exec? -markus */  
         channel_close_all();  
   
         /*          /*
          * Close any extra file descriptors.  Note that there may still be  
          * descriptors left by system functions.  They will be closed later.  
          */  
         endpwent();  
   
         /*  
          * Close any extra open file descriptors so that we don\'t have them  
          * hanging around in clients.  Note that we want to do this after  
          * initgroups, because at least on Solaris 2.3 it leaves file  
          * descriptors open.  
          */  
         for (i = 3; i < 64; i++)  
                 close(i);  
   
         /*  
          * Must take new environment into use so that .ssh/rc,           * Must take new environment into use so that .ssh/rc,
          * /etc/ssh/sshrc and xauth are run in the proper environment.           * /etc/ssh/sshrc and xauth are run in the proper environment.
          */           */
         environ = env;          environ = env;
   
 #ifdef AFS  #ifdef KRB5
         /* Try to get AFS tokens for the local cell. */          /*
         if (k_hasafs()) {           * 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];                  char cell[64];
   
                   debug("Getting AFS token");
   
                   k_setpag();
   
                 if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)                  if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
                         krb_afslog(cell, 0);                          krb5_afslog(s->authctxt->krb5_ctx,
                               s->authctxt->krb5_fwd_ccache, cell, NULL);
   
                 krb_afslog(0, 0);                  krb5_afslog_home(s->authctxt->krb5_ctx,
                       s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
         }          }
 #endif /* AFS */  #endif
   
         /* Change current directory to the user\'s home directory. */          /* Change current directory to the user\'s home directory. */
         if (chdir(pw->pw_dir) < 0) {          if (chdir(pw->pw_dir) < 0) {
Line 1290 
Line 1290 
         }          }
         s->authctxt = authctxt;          s->authctxt = authctxt;
         s->pw = authctxt->pw;          s->pw = authctxt->pw;
         if (s->pw == NULL)          if (s->pw == NULL || !authctxt->valid)
                 fatal("no user for session %d", s->self);                  fatal("no user for session %d", s->self);
         debug("session_open: session %d: link with channel %d", s->self, chanid);          debug("session_open: session %d: link with channel %d", s->self, chanid);
         s->chanid = chanid;          s->chanid = chanid;
Line 1412 
Line 1412 
                 n_bytes = packet_remaining();                  n_bytes = packet_remaining();
         tty_parse_modes(s->ttyfd, &n_bytes);          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)          if (!use_privsep)
                 pty_setowner(s->pw, s->tty);                  pty_setowner(s->pw, s->tty);
   
Line 1438 
Line 1433 
         int i;          int i;
   
         packet_check_eom();          packet_check_eom();
         log("subsystem request for %.100s", subsys);          logit("subsystem request for %.100s", subsys);
   
         for (i = 0; i < options.num_subsystems; i++) {          for (i = 0; i < options.num_subsystems; i++) {
                 if (strcmp(subsys, options.subsystem_name[i]) == 0) {                  if (strcmp(subsys, options.subsystem_name[i]) == 0) {
Line 1457 
Line 1452 
         }          }
   
         if (!success)          if (!success)
                 log("subsystem request for %.100s failed, subsystem not found",                  logit("subsystem request for %.100s failed, subsystem not found",
                     subsys);                      subsys);
   
         xfree(subsys);          xfree(subsys);
Line 1505 
Line 1500 
 }  }
   
 static int  static int
   session_break_req(Session *s)
   {
           u_int break_length;
   
           break_length = packet_get_int();        /* ignored */
           packet_check_eom();
   
           if (s->ttyfd == -1 ||
               tcsendbreak(s->ttyfd, 0) < 0)
                   return 0;
           return 1;
   }
   
   static int
 session_auth_agent_req(Session *s)  session_auth_agent_req(Session *s)
 {  {
         static int called = 0;          static int called = 0;
Line 1528 
Line 1537 
         Session *s;          Session *s;
   
         if ((s = session_by_channel(c->self)) == NULL) {          if ((s = session_by_channel(c->self)) == NULL) {
                 log("session_input_channel_req: no session %d req %.100s",                  logit("session_input_channel_req: no session %d req %.100s",
                     c->self, rtype);                      c->self, rtype);
                 return 0;                  return 0;
         }          }
Line 1551 
Line 1560 
                         success = session_auth_agent_req(s);                          success = session_auth_agent_req(s);
                 } else if (strcmp(rtype, "subsystem") == 0) {                  } else if (strcmp(rtype, "subsystem") == 0) {
                         success = session_subsystem_req(s);                          success = session_subsystem_req(s);
                   } else if (strcmp(rtype, "break") == 0) {
                           success = session_break_req(s);
                 }                  }
         }          }
         if (strcmp(rtype, "window-change") == 0) {          if (strcmp(rtype, "window-change") == 0) {
Line 1582 
Line 1593 
  * (e.g., due to a dropped connection).   * (e.g., due to a dropped connection).
  */   */
 void  void
 session_pty_cleanup2(void *session)  session_pty_cleanup2(Session *s)
 {  {
         Session *s = session;  
   
         if (s == NULL) {          if (s == NULL) {
                 error("session_pty_cleanup: no session");                  error("session_pty_cleanup: no session");
                 return;                  return;
Line 1616 
Line 1625 
 }  }
   
 void  void
 session_pty_cleanup(void *session)  session_pty_cleanup(Session *s)
 {  {
         PRIVSEP(session_pty_cleanup2(session));          PRIVSEP(session_pty_cleanup2(s));
 }  }
   
 static char *  static char *
Line 1687 
Line 1696 
 session_close(Session *s)  session_close(Session *s)
 {  {
         debug("session_close: session %d pid %ld", s->self, (long)s->pid);          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);                  session_pty_cleanup(s);
         }  
         if (s->term)          if (s->term)
                 xfree(s->term);                  xfree(s->term);
         if (s->display)          if (s->display)
Line 1739 
Line 1746 
                  * delay detach of session, but release pty, since                   * delay detach of session, but release pty, since
                  * the fd's to the child are already closed                   * 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);                          session_pty_cleanup(s);
                 }  
                 return;                  return;
         }          }
         /* detach by removing callback */          /* detach by removing callback */
Line 1859 
Line 1864 
 do_authenticated2(Authctxt *authctxt)  do_authenticated2(Authctxt *authctxt)
 {  {
         server_loop2(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();
   #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);
 }  }

Legend:
Removed from v.1.154  
changed lines
  Added in v.1.154.2.2