]> andersk Git - openssh.git/blobdiff - session.c
- (djm) Pick up LOGIN_PROGRAM from environment or PATH if not set by headers
[openssh.git] / session.c
index d65b06984a1e01ff5f8f834e9b2851c7b793eab5..82096c3abc4a1b8ebf57169b7caef0ba19b229d4 100644 (file)
--- a/session.c
+++ b/session.c
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.29 2000/08/21 16:23:31 millert Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -52,6 +52,10 @@ RCSID("$OpenBSD: session.c,v 1.25 2000/08/17 20:06:34 markus Exp $");
 # define S_UNOFILE_HARD        S_UNOFILE "_hard"
 #endif
 
+#ifdef HAVE_LOGIN_CAP
+#include <login_cap.h>
+#endif
+
 /* types */
 
 #define TTYSZ 64
@@ -117,6 +121,10 @@ Session    sessions[MAX_SESSIONS];
 char *aixloginmsg;
 #endif /* WITH_AIXAUTHENTICATE */
 
+#ifdef HAVE_LOGIN_CAP
+static login_cap_t *lc;
+#endif
+
 /*
  * Remove local Xauthority file.
  */
@@ -200,6 +208,13 @@ do_authenticated(struct passwd * pw)
        s = session_new();
        s->pw = pw;
 
+#ifdef HAVE_LOGIN_CAP
+       if ((lc = login_getclass(pw->pw_class)) == NULL) {
+               error("unable to get login class");
+               return;
+       }
+#endif
+
        /*
         * We stay in this loop until the client requests to execute a shell
         * or a command.
@@ -650,7 +665,11 @@ do_login(Session *s)
 
        /* Done if .hushlogin exists. */
        snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir);
+#ifdef HAVE_LOGIN_CAP
+       if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0)
+#else
        if (stat(buf, &st) >= 0)
+#endif
                return;
 
 #ifdef USE_PAM
@@ -677,7 +696,12 @@ do_login(Session *s)
                        printf("Last login: %s from %s\r\n", time_string, buf);
        }
        if (options.print_motd) {
+#ifdef HAVE_LOGIN_CAP
+               f = fopen(login_getcapstr(lc, "welcome", "/etc/motd",
+                   "/etc/motd"), "r");
+#else
                f = fopen("/etc/motd", "r");
+#endif
                if (f) {
                        while (fgets(buf, sizeof(buf), f))
                                fputs(buf, stdout);
@@ -887,10 +911,10 @@ do_child(const char *command, struct passwd * pw, const char *term,
         const char *display, const char *auth_proto,
         const char *auth_data, const char *ttyname)
 {
-       const char *shell, *cp = NULL;
+       const char *shell, *hostname, *cp = NULL;
        char buf[256];
        char cmd[1024];
-       FILE *f;
+       FILE *f = NULL;
        unsigned int envsize, i;
        char **env;
        extern char **environ;
@@ -905,24 +929,26 @@ do_child(const char *command, struct passwd * pw, const char *term,
                options.use_login = 0;
 
 #ifndef USE_PAM /* pam_nologin handles this */
-       f = fopen("/etc/nologin", "r");
-       if (f) {
-               /* /etc/nologin exists.  Print its contents and exit. */
-               while (fgets(buf, sizeof(buf), f))
-                       fputs(buf, stderr);
-               fclose(f);
-               if (pw->pw_uid != 0)
+       if (!options.use_login) {
+# ifdef HAVE_LOGIN_CAP
+               if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
+                       f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
+                           _PATH_NOLOGIN), "r");
+# else /* HAVE_LOGIN_CAP */
+               if (pw->pw_uid)
+                       f = fopen(_PATH_NOLOGIN, "r");
+# endif /* HAVE_LOGIN_CAP */
+               if (f) {
+                       /* /etc/nologin exists.  Print its contents and exit. */
+                       while (fgets(buf, sizeof(buf), f))
+                               fputs(buf, stderr);
+                       fclose(f);
                        exit(254);
+               }
        }
 #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. */
+       /* Set login name, 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) {
@@ -943,10 +969,18 @@ do_child(const char *command, struct passwd * pw, const char *term,
                }
 #else /* HAVE_OSF_SIA */
                if (getuid() == 0 || geteuid() == 0) {
-#if defined(HAVE_GETUSERATTR)
+# ifdef HAVE_GETUSERATTR
                        set_limits_from_userattr(pw->pw_name);
-#endif /* defined(HAVE_GETUSERATTR) */
-
+# endif /* HAVE_GETUSERATTR */
+# ifdef HAVE_LOGIN_CAP
+                       if (setusercontext(lc, pw, pw->pw_uid,
+                           (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
+                               perror("unable to set user context");
+                               exit(1);
+                       }
+# else /* HAVE_LOGIN_CAP */
+                       if (setlogin(pw->pw_name) < 0)
+                               error("setlogin failed: %s", strerror(errno));
                        if (setgid(pw->pw_gid) < 0) {
                                perror("setgid");
                                exit(1);
@@ -957,38 +991,39 @@ do_child(const char *command, struct passwd * pw, const char *term,
                                exit(1);
                        }
                        endgrent();
-
-#ifdef WITH_IRIX_ARRAY
+#  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
+#  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 */
-
+#  endif /* WITH_IRIX_PROJECT */
                        /* Permanently switch to the desired uid. */
                        permanently_set_uid(pw->pw_uid);
+# endif /* HAVE_LOGIN_CAP */
                }
+#endif /* HAVE_OSF_SIA */
+
                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
         * legal, and means /bin/sh.
         */
        shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
+#ifdef HAVE_LOGIN_CAP
+       shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell);
+#endif
 
 #ifdef AFS
        /* Try to get AFS tokens for the local cell. */
@@ -1012,7 +1047,12 @@ do_child(const char *command, struct passwd * pw, const char *term,
                child_set_env(&env, &envsize, "USER", pw->pw_name);
                child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
                child_set_env(&env, &envsize, "HOME", pw->pw_dir);
+#ifdef HAVE_LOGIN_CAP
+               (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH);
+               child_set_env(&env, &envsize, "PATH", getenv("PATH"));
+#else
                child_set_env(&env, &envsize, "PATH", _PATH_STDPATH);
+#endif
 
                snprintf(buf, sizeof buf, "%.200s/%.50s",
                         _PATH_MAILDIR, pw->pw_name);
@@ -1096,6 +1136,9 @@ do_child(const char *command, struct passwd * pw, const char *term,
                for (i = 0; env[i]; i++)
                        fprintf(stderr, "  %.200s\n", env[i]);
        }
+       /* we have to stash the hostname before we close our socket. */
+       if (options.use_login)
+               hostname = get_remote_name_or_ip();
        /*
         * Close the connection descriptors; note that this is the child, and
         * the server will still have the socket open, and it is important
@@ -1132,9 +1175,14 @@ do_child(const char *command, struct passwd * pw, const char *term,
                close(i);
 
        /* Change current directory to the user\'s home directory. */
-       if (chdir(pw->pw_dir) < 0)
+       if (chdir(pw->pw_dir) < 0) {
                fprintf(stderr, "Could not chdir to home directory %s: %s\n",
                        pw->pw_dir, strerror(errno));
+#ifdef HAVE_LOGIN_CAP
+               if (login_getcapbool(lc, "requirehome", 0))
+                       exit(1);
+#endif
+       }
 
        /*
         * Must take new environment into use so that .ssh/rc, /etc/sshrc and
@@ -1252,8 +1300,7 @@ do_child(const char *command, struct passwd * pw, const char *term,
                } else {
                        /* Launch login(1). */
 
-                       execl(LOGIN_PROGRAM, "login",
-                            "-h", get_remote_name_or_ip(),
+                       execl(LOGIN_PROGRAM, "login", "-h", hostname,
                             "-p", "-f", "--", pw->pw_name, NULL);
 
                        /* Login couldn't be executed, die. */
@@ -1790,6 +1837,8 @@ session_proctitle(Session *s)
 void
 do_authenticated2(void)
 {
+       struct passwd *pw;
+
        /*
         * Cancel the alarm we set to limit the time taken for
         * authentication.
@@ -1799,6 +1848,13 @@ do_authenticated2(void)
                close(startup_pipe);
                startup_pipe = -1;
        }
+#ifdef HAVE_LOGIN_CAP
+       pw = auth_get_user();
+       if ((lc = login_getclass(pw->pw_class)) == NULL) {
+               error("unable to get login class");
+               return;
+       }
+#endif
        server_loop2();
        if (xauthfile)
                xauthfile_cleanup_proc(NULL);
This page took 0.053946 seconds and 4 git commands to generate.