]> andersk Git - openssh.git/blobdiff - session.c
[configure.ac] Make sure -lcrypto is before -lsocket for sco3. ok mouring@
[openssh.git] / session.c
index 0f8032430d3894f0685414e25ad6ee907f4782a5..864967565157ca762ba617821a1637d30d78f145 100644 (file)
--- a/session.c
+++ b/session.c
@@ -33,7 +33,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.167 2003/11/04 08:54:09 djm Exp $");
+RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -58,6 +58,10 @@ RCSID("$OpenBSD: session.c,v 1.167 2003/11/04 08:54:09 djm Exp $");
 #include "session.h"
 #include "monitor_wrap.h"
 
+#if defined(KRB5) && defined(USE_AFS)
+#include <kafs.h>
+#endif
+
 #ifdef GSSAPI
 #include "ssh-gss.h"
 #endif
@@ -177,7 +181,7 @@ auth_input_request_forwarding(struct passwd * pw)
        restore_uid();
 
        /* Start listening on the socket. */
-       if (listen(sock, 5) < 0)
+       if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
                packet_disconnect("listen: %.100s", strerror(errno));
 
        /* Allocate a channel for the authentication agent socket. */
@@ -189,6 +193,15 @@ auth_input_request_forwarding(struct passwd * pw)
        return 1;
 }
 
+static void
+display_loginmsg(void)
+{
+       if (buffer_len(&loginmsg) > 0) {
+               buffer_append(&loginmsg, "\0", 1);
+               printf("%s\n", (char *)buffer_ptr(&loginmsg));
+               buffer_clear(&loginmsg);
+       }
+}
 
 void
 do_authenticated(Authctxt *authctxt)
@@ -204,7 +217,6 @@ 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();
@@ -386,12 +398,8 @@ do_exec_no_pty(Session *s, const char *command)
        session_proctitle(s);
 
 #if defined(USE_PAM)
-       if (options.use_pam) {
+       if (options.use_pam)
                do_pam_setcred(1);
-               if (is_pam_password_change_required())
-                       packet_disconnect("Password change required but no "
-                           "TTY available");
-       }
 #endif /* USE_PAM */
 
        /* Fork the child. */
@@ -516,7 +524,8 @@ do_exec_pty(Session *s, const char *command)
 #if defined(USE_PAM)
        if (options.use_pam) {
                do_pam_set_tty(s->tty);
-               do_pam_setcred(1);
+               if (!use_privsep)
+                       do_pam_setcred(1);
        }
 #endif
 
@@ -694,9 +703,10 @@ do_login(Session *s, const char *command)
         * If password change is needed, do it now.
         * This needs to occur before the ~/.hushlogin check.
         */
-       if (options.use_pam && is_pam_password_change_required()) {
-               print_pam_messages();
+       if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
+               display_loginmsg();
                do_pam_chauthtok();
+               s->authctxt->force_pwchange = 0;
                /* XXX - signal [net] parent to enable forwardings */
        }
 #endif
@@ -704,17 +714,7 @@ do_login(Session *s, const char *command)
        if (check_quietlogin(s, command))
                return;
 
-#ifdef USE_PAM
-       if (options.use_pam && !is_pam_password_change_required())
-               print_pam_messages();
-#endif /* USE_PAM */
-
-       /* display post-login message */
-       if (buffer_len(&loginmsg) > 0) {
-               buffer_append(&loginmsg, "\0", 1);
-               printf("%s\n", (char *)buffer_ptr(&loginmsg));
-       }
-       buffer_free(&loginmsg);
+       display_loginmsg();
 
 #ifndef NO_SSH_LASTLOG
        if (options.print_lastlog && s->last_login_time != 0) {
@@ -924,11 +924,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);
-       
+
        for (i = 0; tmpenv[i] != NULL; i++)
                xfree(tmpenv[i]);
        xfree(tmpenv);
@@ -953,7 +953,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);
        }
 }
@@ -980,7 +980,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);
@@ -1012,7 +1012,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);
                }
@@ -1095,8 +1095,13 @@ do_setup_env(Session *s, const char *shell)
         * been set by PAM.
         */
        if (options.use_pam) {
-               char **p = fetch_pam_environment();
+               char **p;
+
+               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);
        }
@@ -1235,6 +1240,12 @@ do_setusercontext(struct passwd *pw)
 # ifdef __bsdi__
                setpgid(0, 0);
 # endif
+# ifdef USE_PAM
+               if (options.use_pam) {
+                       do_pam_session();
+                       do_pam_setcred(0);
+               }
+# endif /* USE_PAM */
                if (setusercontext(lc, pw, pw->pw_uid,
                    (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) {
                        perror("unable to set user context");
@@ -1261,7 +1272,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.
                 */
@@ -1288,6 +1299,22 @@ do_setusercontext(struct passwd *pw)
                fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
 }
 
+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)
 {
@@ -1309,6 +1336,40 @@ launch_login(struct passwd *pw, const char *hostname)
        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
  * environment, closing extra file descriptors, setting the user and group
@@ -1322,11 +1383,18 @@ do_child(Session *s, const char *command)
        char *argv[10];
        const char *shell, *shell0, *hostname = NULL;
        struct passwd *pw = s->pw;
-       u_int i;
 
        /* remove hostkey from the child's memory */
        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 */
        if (options.use_login && command != NULL)
                options.use_login = 0;
@@ -1377,39 +1445,39 @@ do_child(Session *s, const char *command)
         * closed before building the environment, as we call
         * get_remote_ipaddr there.
         */
-       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();
+       child_close_fds();
 
        /*
-        * Close any extra file descriptors.  Note that there may still be
-        * descriptors left by system functions.  They will be closed later.
+        * Must take new environment into use so that .ssh/rc,
+        * /etc/ssh/sshrc and xauth are run in the proper environment.
         */
-       endpwent();
+       environ = env;
 
+#if defined(KRB5) && defined(USE_AFS)
        /*
-        * 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.
+        * 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.
         */
-       for (i = 3; i < 64; i++)
-               close(i);
 
-       /*
-        * Must take new environment into use so that .ssh/rc,
-        * /etc/ssh/sshrc and xauth are run in the proper environment.
-        */
-       environ = env;
+       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) {
@@ -2028,13 +2096,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);
This page took 0.045884 seconds and 4 git commands to generate.