]> andersk Git - openssh.git/blobdiff - session.c
- (djm) OpenBSD CVS updates:
[openssh.git] / session.c
index 23c5660508af82098b38f9ed80d53b86df8b3150..96a2d3b52fa0cd826845a29741d90a7399389598 100644 (file)
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.22 2000/07/05 20:18:07 deraadt Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -26,6 +26,20 @@ RCSID("$OpenBSD: session.c,v 1.12 2000/05/03 18:03:07 markus Exp $");
 #include "bufaux.h"
 #include "ssh2.h"
 #include "auth.h"
+#include "auth-options.h"
+
+#ifdef WITH_IRIX_PROJECT
+#include <proj.h>
+#endif /* WITH_IRIX_PROJECT */
+
+#if defined(HAVE_USERSEC_H)
+#include <usersec.h>
+#endif
+
+#ifdef HAVE_OSF_SIA
+# include <sia.h>
+# include <siad.h>
+#endif
 
 /* types */
 
@@ -77,6 +91,8 @@ static const char *__progname = "sshd";
 extern int log_stderr;
 extern int debug_flag;
 
+extern int startup_pipe;
+
 /* Local Xauthority file. */
 static char *xauthfile;
 
@@ -88,18 +104,6 @@ Session     sessions[MAX_SESSIONS];
 char *aixloginmsg;
 #endif /* WITH_AIXAUTHENTICATE */
 
-/* Flags set in auth-rsa from authorized_keys flags.  These are set in auth-rsa.c. */
-int no_port_forwarding_flag = 0;
-int no_agent_forwarding_flag = 0;
-int no_x11_forwarding_flag = 0;
-int no_pty_flag = 0;
-
-/* RSA authentication "command=" option. */
-char *forced_command = NULL;
-
-/* RSA authentication "environment=" options. */
-struct envstring *custom_environment = NULL;
-
 /*
  * Remove local Xauthority file.
  */
@@ -165,6 +169,7 @@ do_authenticated(struct passwd * pw)
         * authentication.
         */
        alarm(0);
+       close(startup_pipe);
 
        /*
         * Inform the channel mechanism that we are the server side and that
@@ -257,7 +262,10 @@ do_authenticated(struct passwd * pw)
                                packet_send_debug("X11 forwarding disabled in server configuration file.");
                                break;
                        }
-#ifdef XAUTH_PATH
+                       if (!options.xauth_location) {
+                               packet_send_debug("No xauth program; cannot forward with spoofing.");
+                               break;
+                       }
                        if (no_x11_forwarding_flag) {
                                packet_send_debug("X11 forwarding not permitted for this authentication.");
                                break;
@@ -298,10 +306,6 @@ do_authenticated(struct passwd * pw)
                        fatal_add_cleanup(xauthfile_cleanup_proc, NULL);
                        success = 1;
                        break;
-#else /* XAUTH_PATH */
-                       packet_send_debug("No xauth program; cannot forward with spoofing.");
-                       break;
-#endif /* XAUTH_PATH */
 
                case SSH_CMSG_AGENT_REQUEST_FORWARDING:
                        if (no_agent_forwarding_flag || compat13) {
@@ -309,8 +313,7 @@ do_authenticated(struct passwd * pw)
                                break;
                        }
                        debug("Received authentication agent forwarding request.");
-                       auth_input_request_forwarding(pw);
-                       success = 1;
+                       success = auth_input_request_forwarding(pw);
                        break;
 
                case SSH_CMSG_PORT_FORWARD_REQUEST:
@@ -645,7 +648,8 @@ do_exec_pty(Session *s, const char *command, struct passwd * pw)
                }
 #endif
                /* Do common processing for the child, such as execing the command. */
-               do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty);
+               do_child(command, pw, s->term, s->display, s->auth_proto,
+                   s->auth_data, s->tty);
                /* NOTREACHED */
        }
        if (pid < 0)
@@ -749,7 +753,10 @@ read_environment_file(char ***env, unsigned int *envsize,
                        fprintf(stderr, "Bad line in %.100s: %.200s\n", filename, buf);
                        continue;
                }
-               /* Replace the equals sign by nul, and advance value to the value string. */
+               /*
+                * Replace the equals sign by nul, and advance value to
+                * the value string.
+                */
                *value = '\0';
                value++;
                child_set_env(env, envsize, cp, value);
@@ -789,6 +796,85 @@ void do_pam_environment(char ***env, int *envsize)
 }
 #endif /* USE_PAM */
 
+#if defined(HAVE_GETUSERATTR)
+/*
+ * AIX-specific login initialisation
+ */
+void set_limit(char *user, char *soft, char *hard, int resource, int mult)
+{
+       struct rlimit rlim;
+       int slim, hlim;
+
+       getrlimit(resource, &rlim);
+
+       slim = 0;
+       if (getuserattr(user, soft, &slim, SEC_INT) != -1) {
+               if (slim < 0) {
+                       rlim.rlim_cur = RLIM_INFINITY;
+               } else if (slim != 0) {
+                       /* See the wackiness below */
+                       if (rlim.rlim_cur == slim * mult)
+                               slim = 0;
+                       else
+                               rlim.rlim_cur = slim * mult;
+               }
+       }
+
+       hlim = 0;
+       if (getuserattr(user, hard, &hlim, SEC_INT) != -1) {
+               if (hlim < 0) {
+                       rlim.rlim_max = RLIM_INFINITY;
+               } else if (hlim != 0) {
+                       rlim.rlim_max = hlim * mult;
+               }
+       }
+
+       /*
+        * XXX For cpu and fsize the soft limit is set to the hard limit
+        * if the hard limit is left at its default value and the soft limit
+        * is changed from its default value, either by requesting it
+        * (slim == 0) or by setting it to the current default.  At least
+        * that's how rlogind does it.  If you're confused you're not alone.
+        * Bug or feature? AIX 4.3.1.2
+        */
+       if ((!strcmp(soft, "fsize") || !strcmp(soft, "cpu"))
+           && hlim == 0 && slim != 0)
+               rlim.rlim_max = rlim.rlim_cur;
+       /* A specified hard limit limits the soft limit */
+       else if (hlim > 0 && rlim.rlim_cur > rlim.rlim_max)
+               rlim.rlim_cur = rlim.rlim_max;
+       /* A soft limit can increase a hard limit */
+       else if (rlim.rlim_cur > rlim.rlim_max)
+               rlim.rlim_max = rlim.rlim_cur;
+
+       if (setrlimit(resource, &rlim) != 0)
+               error("setrlimit(%.10s) failed: %.100s", soft, strerror(errno));
+}
+
+void set_limits_from_userattr(char *user)
+{
+       int mask;
+       char buf[16];
+
+       set_limit(user, S_UFSIZE, S_UFSIZE_HARD, RLIMIT_FSIZE, 512);
+       set_limit(user, S_UCPU, S_UCPU_HARD, RLIMIT_CPU, 1);
+       set_limit(user, S_UDATA, S_UDATA_HARD, RLIMIT_DATA, 512);
+       set_limit(user, S_USTACK, S_USTACK_HARD, RLIMIT_STACK, 512);
+       set_limit(user, S_URSS, S_URSS_HARD, RLIMIT_RSS, 512);
+       set_limit(user, S_UCORE, S_UCORE_HARD, RLIMIT_CORE, 512);
+#if defined(S_UNOFILE)
+       set_limit(user, S_UNOFILE, S_UNOFILE_HARD, RLIMIT_NOFILE, 1);
+#endif
+
+       if (getuserattr(user, S_UMASK, &mask, SEC_INT) != -1) {
+               /* Convert decimal to octal */
+               (void) snprintf(buf, sizeof(buf), "%d", mask);
+               if (sscanf(buf, "%o", &mask) == 1)
+                       umask(mask);
+       }
+}
+#endif /* defined(HAVE_GETUSERATTR) */
+
 /*
  * Performs common processing for the child, such as setting up the
  * environment, closing extra file descriptors, setting the user and group
@@ -801,12 +887,20 @@ do_child(const char *command, struct passwd * pw, const char *term,
 {
        const char *shell, *cp = NULL;
        char buf[256];
+       char cmd[1024];
        FILE *f;
        unsigned int envsize, i;
        char **env;
        extern char **environ;
        struct stat st;
        char *argv[10];
+#ifdef WITH_IRIX_PROJECT
+       prid_t projid;
+#endif /* WITH_IRIX_PROJECT */
+
+       /* login(1) is only called if we execute the login shell */
+       if (options.use_login && command != NULL)
+               options.use_login = 0;
 
 #ifndef USE_PAM /* pam_nologin handles this */
        f = fopen("/etc/nologin", "r");
@@ -820,15 +914,37 @@ do_child(const char *command, struct passwd * pw, const char *term,
        }
 #endif /* USE_PAM */
 
+#ifndef HAVE_OSF_SIA
        /* Set login name in the kernel. */
        if (setlogin(pw->pw_name) < 0)
                error("setlogin failed: %s", strerror(errno));
+#endif
 
        /* Set uid, gid, and groups. */
        /* Login(1) does this as well, and it needs uid 0 for the "-h"
           switch, so we let login(1) to this for us. */
        if (!options.use_login) {
+#ifdef HAVE_OSF_SIA
+               extern char **saved_argv;
+               extern int saved_argc;
+               char *host = get_canonical_hostname ();
+
+               if (sia_become_user(NULL, saved_argc, saved_argv, host,
+                   pw->pw_name, ttyname, 0, NULL, NULL, SIA_BEU_SETLUID) !=
+                   SIASUCCESS) {
+                       perror("sia_become_user");
+                       exit(1);
+               }
+               if (setreuid(geteuid(), geteuid()) < 0) {
+                       perror("setreuid");
+                       exit(1);
+               }
+#else /* HAVE_OSF_SIA */
                if (getuid() == 0 || geteuid() == 0) {
+#if defined(HAVE_GETUSERATTR)
+                       set_limits_from_userattr(pw->pw_name);
+#endif /* defined(HAVE_GETUSERATTR) */
+
                        if (setgid(pw->pw_gid) < 0) {
                                perror("setgid");
                                exit(1);
@@ -840,11 +956,31 @@ do_child(const char *command, struct passwd * pw, const char *term,
                        }
                        endgrent();
 
+#ifdef WITH_IRIX_ARRAY
+                       /* initialize array session */
+                       if (newarraysess() != 0)
+                               fatal("Failed to set up new array session: %.100s",
+                                     strerror(errno));
+#endif /* WITH_IRIX_ARRAY */
+
+#ifdef WITH_IRIX_PROJECT
+                       /* initialize irix project info */
+                       if ((projid = getdfltprojuser(pw->pw_name)) == -1) {
+                         debug("Failed to get project id, using projid 0");
+                         projid = 0;
+                       }
+                       
+                       if (setprid(projid))
+                         fatal("Failed to initialize project %d for %s: %.100s",
+                               (int)projid, pw->pw_name, strerror(errno));
+#endif /* WITH_IRIX_PROJECT */
+
                        /* Permanently switch to the desired uid. */
                        permanently_set_uid(pw->pw_uid);
                }
                if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
                        fatal("Failed to set uids to %d.", (int) pw->pw_uid);
+#endif /* HAVE_OSF_SIA */
        }
        /*
         * Get the shell from the password data.  An empty shell field is
@@ -948,7 +1084,8 @@ do_child(const char *command, struct passwd * pw, const char *term,
 
        /* read $HOME/.ssh/environment. */
        if (!options.use_login) {
-               snprintf(buf, sizeof buf, "%.200s/.ssh/environment", pw->pw_dir);
+               snprintf(buf, sizeof buf, "%.200s/.ssh/environment",
+                   pw->pw_dir);
                read_environment_file(&env, &envsize, buf);
        }
        if (debug_flag) {
@@ -1010,9 +1147,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
        if (!options.use_login) {
                if (stat(SSH_USER_RC, &st) >= 0) {
                        if (debug_flag)
-                               fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC);
+                               fprintf(stderr, "Running "_PATH_BSHELL" %s\n", SSH_USER_RC);
 
-                       f = popen("/bin/sh " SSH_USER_RC, "w");
+                       f = popen(_PATH_BSHELL " " SSH_USER_RC, "w");
                        if (f) {
                                if (auth_proto != NULL && auth_data != NULL)
                                        fprintf(f, "%s %s\n", auth_proto, auth_data);
@@ -1021,34 +1158,47 @@ do_child(const char *command, struct passwd * pw, const char *term,
                                fprintf(stderr, "Could not run %s\n", SSH_USER_RC);
                } else if (stat(SSH_SYSTEM_RC, &st) >= 0) {
                        if (debug_flag)
-                               fprintf(stderr, "Running /bin/sh %s\n", SSH_SYSTEM_RC);
+                               fprintf(stderr, "Running "_PATH_BSHELL" %s\n", SSH_SYSTEM_RC);
 
-                       f = popen("/bin/sh " SSH_SYSTEM_RC, "w");
+                       f = popen(_PATH_BSHELL " " SSH_SYSTEM_RC, "w");
                        if (f) {
                                if (auth_proto != NULL && auth_data != NULL)
                                        fprintf(f, "%s %s\n", auth_proto, auth_data);
                                pclose(f);
                        } else
                                fprintf(stderr, "Could not run %s\n", SSH_SYSTEM_RC);
-               }
-#ifdef XAUTH_PATH
-               else {
+               } else if (options.xauth_location != NULL) {
                        /* Add authority data to .Xauthority if appropriate. */
                        if (auth_proto != NULL && auth_data != NULL) {
-                               if (debug_flag)
-                                       fprintf(stderr, "Running %.100s add %.100s %.100s %.100s\n",
-                                               XAUTH_PATH, display, auth_proto, auth_data);
-
-                               f = popen(XAUTH_PATH " -q -", "w");
+                               char *screen = strchr(display, ':');
+                               if (debug_flag) {
+                                       fprintf(stderr,
+                                           "Running %.100s add %.100s %.100s %.100s\n",
+                                           options.xauth_location, display,
+                                           auth_proto, auth_data);
+                                       if (screen != NULL)
+                                               fprintf(stderr,
+                                                   "Adding %.*s/unix%s %s %s\n",
+                                                   screen-display, display,
+                                                   screen, auth_proto, auth_data);
+                               }
+                               snprintf(cmd, sizeof cmd, "%s -q -",
+                                   options.xauth_location);
+                               f = popen(cmd, "w");
                                if (f) {
-                                       fprintf(f, "add %s %s %s\n", display, auth_proto, auth_data);
+                                       fprintf(f, "add %s %s %s\n", display,
+                                           auth_proto, auth_data);
+                                       if (screen != NULL) 
+                                               fprintf(f, "add %.*s/unix%s %s %s\n",
+                                                   screen-display, display,
+                                                   screen, auth_proto, auth_data);
                                        pclose(f);
-                               } else
-                                       fprintf(stderr, "Could not run %s -q -\n", XAUTH_PATH);
+                               } else {
+                                       fprintf(stderr, "Could not run %s\n",
+                                           cmd);
+                               }
                        }
                }
-#endif /* XAUTH_PATH */
-
                /* Get the last component of the shell name. */
                cp = strrchr(shell, '/');
                if (cp)
@@ -1074,7 +1224,8 @@ do_child(const char *command, struct passwd * pw, const char *term,
                                struct stat mailstat;
                                mailbox = getenv("MAIL");
                                if (mailbox != NULL) {
-                                       if (stat(mailbox, &mailstat) != 0 || mailstat.st_size == 0)
+                                       if (stat(mailbox, &mailstat) != 0 ||
+                                           mailstat.st_size == 0)
                                                printf("No mail.\n");
                                        else if (mailstat.st_mtime < mailstat.st_atime)
                                                printf("You have mail.\n");
@@ -1099,7 +1250,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
                } else {
                        /* Launch login(1). */
 
-                       execl("/usr/bin/login", "login", "-h", get_remote_ipaddr(),
+                       execl(LOGIN_PROGRAM, "login", "-h", get_remote_ipaddr(),
                              "-p", "-f", "--", pw->pw_name, NULL);
 
                        /* Login couldn't be executed, die. */
@@ -1238,6 +1389,8 @@ session_pty_req(Session *s)
        unsigned int len;
        char *term_modes;       /* encoded terminal modes */
 
+       if (no_pty_flag)
+               return 0;
        if (s->ttyfd != -1)
                return 0;
        s->term = packet_get_string(&len);
@@ -1285,10 +1438,22 @@ session_subsystem_req(Session *s)
        unsigned int len;
        int success = 0;
        char *subsys = packet_get_string(&len);
+       int i;
 
        packet_done();
        log("subsystem request for %s", subsys);
 
+       for (i = 0; i < options.num_subsystems; i++) {
+               if(strcmp(subsys, options.subsystem_name[i]) == 0) {
+                       debug("subsystem: exec() %s", options.subsystem_command[i]);
+                       do_exec_no_pty(s, options.subsystem_command[i], s->pw);
+                       success = 1;
+               }
+       }
+
+       if (!success)
+               log("subsystem request for %s failed, subsystem not found", subsys);
+
        xfree(subsys);
        return success;
 }
@@ -1296,6 +1461,10 @@ session_subsystem_req(Session *s)
 int
 session_x11_req(Session *s)
 {
+       if (no_x11_forwarding_flag) {
+               debug("X11 forwarding disabled in user configuration file.");
+               return 0;
+       }
        if (!options.x11_forwarding) {
                debug("X11 forwarding disabled in server configuration file.");
                return 0;
@@ -1342,6 +1511,41 @@ session_x11_req(Session *s)
        return 1;
 }
 
+int
+session_shell_req(Session *s)
+{
+       /* if forced_command == NULL, the shell is execed */
+       char *shell = forced_command;
+       packet_done();
+       s->extended = 1;
+       if (s->ttyfd == -1)
+               do_exec_no_pty(s, shell, s->pw);
+       else
+               do_exec_pty(s, shell, s->pw);
+       return 1;
+}
+
+int
+session_exec_req(Session *s)
+{
+       unsigned int len;
+       char *command = packet_get_string(&len);
+       packet_done();
+       if (forced_command) {
+               xfree(command);
+               command = forced_command;
+               debug("Forced command '%.500s'", forced_command);
+       }
+       s->extended = 1;
+       if (s->ttyfd == -1)
+               do_exec_no_pty(s, command, s->pw);
+       else
+               do_exec_pty(s, command, s->pw);
+       if (forced_command == NULL)
+               xfree(command);
+       return 1;
+}
+
 void
 session_input_channel_req(int id, void *arg)
 {
@@ -1371,23 +1575,9 @@ session_input_channel_req(int id, void *arg)
         */
        if (c->type == SSH_CHANNEL_LARVAL) {
                if (strcmp(rtype, "shell") == 0) {
-                       packet_done();
-                       s->extended = 1;
-                       if (s->ttyfd == -1)
-                               do_exec_no_pty(s, NULL, s->pw);
-                       else
-                               do_exec_pty(s, NULL, s->pw);
-                       success = 1;
+                       success = session_shell_req(s);
                } else if (strcmp(rtype, "exec") == 0) {
-                       char *command = packet_get_string(&len);
-                       packet_done();
-                       s->extended = 1;
-                       if (s->ttyfd == -1)
-                               do_exec_no_pty(s, command, s->pw);
-                       else
-                               do_exec_pty(s, command, s->pw);
-                       xfree(command);
-                       success = 1;
+                       success = session_exec_req(s);
                } else if (strcmp(rtype, "pty-req") == 0) {
                        success =  session_pty_req(s);
                } else if (strcmp(rtype, "x11-req") == 0) {
@@ -1558,6 +1748,8 @@ session_close_by_channel(int id, void *arg)
                session_close(s);
        } else {
                /* notify child, delay session cleanup */
+               if (s->pid <= 1) 
+                       fatal("session_close_by_channel: Unsafe s->pid = %d", s->pid);
                if (kill(s->pid, (s->ttyfd == -1) ? SIGTERM : SIGHUP) < 0)
                        error("session_close_by_channel: kill %d: %s",
                            s->pid, strerror(errno));
@@ -1600,6 +1792,7 @@ do_authenticated2(void)
         * authentication.
         */
        alarm(0);
+       close(startup_pipe);
        server_loop2();
        if (xauthfile)
                xauthfile_cleanup_proc(NULL);
This page took 0.050496 seconds and 4 git commands to generate.