]> andersk Git - gssapi-openssh.git/blobdiff - openssh/session.c
update patch version
[gssapi-openssh.git] / openssh / session.c
index f2549e0cd7f147ef9091b10a702e552263d282ce..b06bf389b854591bc23c6ae04d5ae273e85f185d 100644 (file)
@@ -124,6 +124,11 @@ static void do_authenticated2(Authctxt *);
 
 static int session_pty_req(Session *);
 
+#ifdef SESSION_HOOKS
+static void execute_session_hook(char* prog, Authctxt *authctxt,
+                                 int startup, int save);
+#endif
+
 /* import */
 extern ServerOptions options;
 extern char *__progname;
@@ -230,6 +235,7 @@ auth_input_request_forwarding(struct passwd * pw)
        }
 
        /* Allocate a channel for the authentication agent socket. */
+       /* this shouldn't matter if its hpn or not - cjr */
        nc = channel_new("auth socket",
            SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
            CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
@@ -275,6 +281,21 @@ do_authenticated(Authctxt *authctxt)
        else
                do_authenticated1(authctxt);
 
+#ifdef SESSION_HOOKS
+        if (options.session_hooks_allow &&
+            options.session_hooks_shutdown_cmd)
+        {
+            execute_session_hook(options.session_hooks_shutdown_cmd,
+                                 authctxt,
+                                 /* startup = */ 0, /* save = */ 0);
+
+            if (authctxt->session_env_file)
+            {
+                free(authctxt->session_env_file);
+            }
+        }
+#endif
+
        do_cleanup(authctxt);
 }
 
@@ -381,7 +402,7 @@ do_authenticated1(Authctxt *authctxt)
                        }
                        debug("Received TCP/IP port forwarding request.");
                        if (channel_input_port_forward_request(s->pw->pw_uid == 0,
-                           options.gateway_ports) < 0) {
+                             options.gateway_ports) < 0) {
                                debug("Port forwarding failed.");
                                break;
                        }
@@ -802,6 +823,26 @@ do_exec(Session *s, const char *command)
                debug("Forced command (key option) '%.900s'", command);
        }
 
+#if defined(SESSION_HOOKS)
+       if (options.session_hooks_allow &&
+           (options.session_hooks_startup_cmd ||
+            options.session_hooks_shutdown_cmd))
+       {
+               char env_file[1000];
+               struct stat st;
+               do
+               {
+                       snprintf(env_file,
+                                sizeof(env_file),
+                                "/tmp/ssh_env_%d%d%d",
+                                getuid(),
+                                getpid(),
+                                rand());
+               } while (stat(env_file, &st)==0);
+               s->authctxt->session_env_file = strdup(env_file);
+       }
+#endif
+
 #ifdef SSH_AUDIT_EVENTS
        if (command != NULL)
                PRIVSEP(audit_run_command(command));
@@ -1030,6 +1071,117 @@ read_environment_file(char ***env, u_int *envsize,
        fclose(f);
 }
 
+#ifdef SESSION_HOOKS
+#define SSH_SESSION_ENV_FILE "SSH_SESSION_ENV_FILE"
+
+typedef enum { no_op, execute, clear_env, restore_env,
+               read_env, save_or_rm_env } session_action_t;
+
+static session_action_t action_order[2][5] = {
+    { clear_env, read_env, execute, save_or_rm_env, restore_env }, /*shutdown*/
+    { execute, read_env, save_or_rm_env, no_op, no_op }            /*startup */
+};
+
+static
+void execute_session_hook(char* prog, Authctxt *authctxt,
+                          int startup, int save)
+{
+    extern char **environ;
+
+    struct stat  st;
+    char         **saved_env, **tmpenv;
+    char         *env_file = authctxt->session_env_file;
+    int          i, status = 0;
+
+    for (i=0; i<5; i++)
+    {
+        switch (action_order[startup][i])
+        {
+          case no_op:
+            break;
+
+          case execute:
+            {
+                FILE* fp;
+                char  buf[1000];
+
+                snprintf(buf,
+                         sizeof(buf),
+                         "%s -c '%s'",
+                         authctxt->pw->pw_shell,
+                         prog);
+
+                debug("executing session hook: [%s]", buf);
+                setenv(SSH_SESSION_ENV_FILE, env_file, /* overwrite = */ 1);
+
+                /* flusing is recommended in the popen(3) man page, to avoid
+                   intermingling of output */
+                fflush(stdout);
+                fflush(stderr);
+                if ((fp=popen(buf, "w")) == NULL)
+                {
+                    perror("Unable to run session hook");
+                    return;
+                }
+                status = pclose(fp);
+                debug2("session hook executed, status=%d", status);
+                unsetenv(SSH_SESSION_ENV_FILE);
+            }
+            break;
+
+          case clear_env:
+            saved_env = environ;
+            tmpenv = (char**) malloc(sizeof(char*));
+            tmpenv[0] = NULL;
+            environ = tmpenv;
+            break;
+
+          case restore_env:
+            environ = saved_env;
+            free(tmpenv);
+            break;
+
+          case read_env:
+            if (status==0 && stat(env_file, &st)==0)
+            {
+                int envsize = 0;
+
+                debug("reading environment from %s", env_file);
+                while (environ[envsize++]) ;
+                read_environment_file(&environ, &envsize, env_file);
+            }
+            break;
+
+          case save_or_rm_env:
+            if (status==0 && save)
+            {
+                FILE* fp;
+                int    envcount=0;
+
+                debug2("saving environment to %s", env_file);
+                if ((fp = fopen(env_file, "w")) == NULL) /* hmm: file perms? */
+                {
+                    perror("Unable to save session hook info");
+                }
+                while (environ[envcount])
+                {
+                    fprintf(fp, "%s\n", environ[envcount++]);
+                }
+                fflush(fp);
+                fclose(fp);
+            }
+            else if (stat(env_file, &st)==0)
+            {
+                debug2("removing environment file %s", env_file);
+                remove(env_file);
+            }
+            break;
+        }
+    }
+
+}
+#endif
+
 #ifdef HAVE_ETC_DEFAULT_LOGIN
 /*
  * Return named variable from specified environment, or NULL if not present.
@@ -1193,6 +1345,23 @@ do_setup_env(Session *s, const char *shell)
        if (getenv("TZ"))
                child_set_env(&env, &envsize, "TZ", getenv("TZ"));
 
+#ifdef GSI /* GSI shared libs typically installed in non-system locations. */
+       {
+               char *cp;
+
+               if ((cp = getenv("LD_LIBRARY_PATH")) != NULL)
+                       child_set_env(&env, &envsize, "LD_LIBRARY_PATH", cp);
+               if ((cp = getenv("LIBPATH")) != NULL)
+                       child_set_env(&env, &envsize, "LIBPATH", cp);
+               if ((cp = getenv("SHLIB_PATH")) != NULL)
+                       child_set_env(&env, &envsize, "SHLIB_PATH", cp);
+               if ((cp = getenv("LD_LIBRARYN32_PATH")) != NULL)
+                       child_set_env(&env, &envsize, "LD_LIBRARYN32_PATH",cp);
+               if ((cp = getenv("LD_LIBRARY64_PATH")) != NULL)
+                       child_set_env(&env, &envsize, "LD_LIBRARY64_PATH",cp);
+       }
+#endif
+
        /* Set custom environment options from RSA authentication. */
        if (!options.use_login) {
                while (custom_environment) {
@@ -1655,6 +1824,18 @@ do_child(Session *s, const char *command)
        struct passwd *pw = s->pw;
        int r = 0;
 
+#ifdef AFS_KRB5
+/* Default place to look for aklog. */
+#ifdef AKLOG_PATH
+#define KPROGDIR AKLOG_PATH
+#else
+#define KPROGDIR "/usr/bin/aklog"
+#endif /* AKLOG_PATH */
+
+       struct stat st;
+       char *aklog_path;
+#endif /* AFS_KRB5 */
+
        /* remove hostkey from the child's memory */
        destroy_sensitive_data();
 
@@ -1767,6 +1948,41 @@ do_child(Session *s, const char *command)
        }
 #endif
 
+#ifdef AFS_KRB5
+
+       /* User has authenticated, and if a ticket was going to be
+        * passed we would have it.  KRB5CCNAME should already be set.
+        * Now try to get an AFS token using aklog.
+        */
+       if (k_hasafs()) {  /* Do we have AFS? */
+
+               aklog_path = xstrdup(KPROGDIR);
+
+               /*
+                * Make sure it exists before we try to run it
+                */
+               if (stat(aklog_path, &st) == 0) {
+                       debug("Running %s to get afs token.",aklog_path);
+                       system(aklog_path);
+               } else {
+                       debug("%s does not exist.",aklog_path);
+               }
+
+               xfree(aklog_path);
+       }
+#endif /* AFS_KRB5 */
+
+#ifdef SESSION_HOOKS
+        if (options.session_hooks_allow &&
+            options.session_hooks_startup_cmd)
+        {
+            execute_session_hook(options.session_hooks_startup_cmd,
+                                 s->authctxt,
+                                 /* startup = */ 1,
+                                 options.session_hooks_shutdown_cmd != NULL);
+        }
+#endif
+
        /* Change current directory to the user's home directory. */
        if (chdir(pw->pw_dir) < 0) {
                /* Suppress missing homedir warning for chroot case */
@@ -1837,7 +2053,7 @@ do_child(Session *s, const char *command)
                /* Execute the shell. */
                argv[0] = argv0;
                argv[1] = NULL;
-               execve(shell, argv, env);
+               execve(shell, argv, environ);
 
                /* Executing the shell failed. */
                perror(shell);
@@ -1851,7 +2067,7 @@ do_child(Session *s, const char *command)
        argv[1] = "-c";
        argv[2] = (char *) command;
        argv[3] = NULL;
-       execve(shell, argv, env);
+       execve(shell, argv, environ);
        perror(shell);
        exit(1);
 }
@@ -2301,10 +2517,16 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr, int is_tty)
         */
        if (s->chanid == -1)
                fatal("no channel for session %d", s->self);
+       if (options.hpn_disabled)
        channel_set_fds(s->chanid,
            fdout, fdin, fderr,
            fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
            1, is_tty, CHAN_SES_WINDOW_DEFAULT);
+       else 
+               channel_set_fds(s->chanid,
+                   fdout, fdin, fderr,
+                   fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+                   1, is_tty, options.hpn_buffer_size);
 }
 
 /*
This page took 0.047163 seconds and 4 git commands to generate.