*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.175 2004/05/11 19:01:43 deraadt Exp $");
+RCSID("$OpenBSD: session.c,v 1.182 2005/06/17 02:44:33 djm Exp $");
#include "ssh.h"
#include "ssh1.h"
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);
- }
- fflush(stdout);
+ if (buffer_len(&loginmsg) > 0) {
+ buffer_append(&loginmsg, "\0", 1);
+ printf("%s", (char *)buffer_ptr(&loginmsg));
+ buffer_clear(&loginmsg);
+ }
}
void
u_int proto_len, data_len, dlen, compression_level = 0;
s = session_new();
+ if (s == NULL) {
+ error("no more sessions");
+ return;
+ }
s->authctxt = authctxt;
s->pw = authctxt->pw;
compression_level = packet_get_int();
packet_check_eom();
if (compression_level < 1 || compression_level > 9) {
- packet_send_debug("Received illegal compression level %d.",
+ packet_send_debug("Received invalid compression level %d.",
compression_level);
break;
}
close(perr[1]);
if (compat20) {
- session_set_fds(s, pin[1], pout[0], s->is_subsystem ? -1 : perr[0]);
+ if (s->is_subsystem) {
+ close(perr[0]);
+ perr[0] = -1;
+ }
+ session_set_fds(s, pin[1], pout[0], perr[0]);
} else {
/* Enter the interactive session. */
server_loop(pid, pin[1], pout[0], perr[0]);
debug("Forced command '%.900s'", command);
}
-#ifdef GSSAPI
- if (options.gss_authentication) {
- temporarily_use_uid(s->pw);
- ssh_gssapi_storecreds();
- restore_uid();
+#ifdef SSH_AUDIT_EVENTS
+ if (command != NULL)
+ PRIVSEP(audit_run_command(command));
+ else if (s->ttyfd == -1) {
+ char *shell = s->pw->pw_shell;
+
+ if (shell[0] == '\0') /* empty shell means /bin/sh */
+ shell =_PATH_BSHELL;
+ PRIVSEP(audit_run_command(shell));
}
#endif
do_exec_no_pty(s, command);
original_command = NULL;
-}
+ /*
+ * Clear loginmsg: it's the child's responsibility to display
+ * it to the user, otherwise multiple sessions may accumulate
+ * multiple copies of the login messages.
+ */
+ buffer_clear(&loginmsg);
+}
/* administrative, login(1)-like work */
void
do_login(Session *s, const char *command)
{
- char *time_string;
socklen_t fromlen;
struct sockaddr_storage from;
struct passwd * pw = s->pw;
display_loginmsg();
-#ifndef NO_SSH_LASTLOG
- if (options.print_lastlog && s->last_login_time != 0) {
- time_string = ctime(&s->last_login_time);
- if (strchr(time_string, '\n'))
- *strchr(time_string, '\n') = 0;
- if (strcmp(s->hostname, "") == 0)
- printf("Last login: %s\r\n", time_string);
- else
- printf("Last login: %s from %s\r\n", time_string,
- s->hostname);
- }
-#endif /* NO_SSH_LASTLOG */
-
do_motd();
}
}
#endif /* HAVE_ETC_DEFAULT_LOGIN */
-void copy_environment(char **source, char ***env, u_int *envsize)
+void
+copy_environment(char **source, char ***env, u_int *envsize)
{
char *var_name, *var_val;
int i;
* The Windows environment contains some setting which are
* important for a running system. They must not be dropped.
*/
- copy_environment(environ, &env, &envsize);
+ {
+ char **p;
+
+ p = fetch_windows_environment();
+ copy_environment(p, &env, &envsize);
+ free_windows_environment(p);
+ }
#endif
#ifdef GSSAPI
if (!options.use_login) {
/* Set basic environment. */
for (i = 0; i < s->num_env; i++)
- child_set_env(&env, &envsize, s->env[i].name,
+ child_set_env(&env, &envsize, s->env[i].name,
s->env[i].val);
child_set_env(&env, &envsize, "USER", pw->pw_name);
child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
#endif /* _UNICOS */
+ /*
+ * Since we clear KRB5CCNAME at startup, if it's set now then it
+ * must have been set by a native authentication method (eg AIX or
+ * SIA), so copy it to the child.
+ */
+ {
+ char *cp;
+
+ if ((cp = getenv("KRB5CCNAME")) != NULL)
+ child_set_env(&env, &envsize, "KRB5CCNAME", cp);
+ }
+
#ifdef _AIX
{
char *cp;
if ((cp = getenv("AUTHSTATE")) != NULL)
child_set_env(&env, &envsize, "AUTHSTATE", cp);
- if ((cp = getenv("KRB5CCNAME")) != NULL)
- child_set_env(&env, &envsize, "KRB5CCNAME", cp);
read_environment_file(&env, &envsize, "/etc/environment");
}
#endif
# ifdef __bsdi__
setpgid(0, 0);
# endif
+#ifdef GSSAPI
+ if (options.gss_authentication) {
+ temporarily_use_uid(pw);
+ ssh_gssapi_storecreds();
+ restore_uid();
+ }
+#endif
# ifdef USE_PAM
if (options.use_pam) {
do_pam_session();
exit(1);
}
endgrent();
+#ifdef GSSAPI
+ if (options.gss_authentication) {
+ temporarily_use_uid(pw);
+ ssh_gssapi_storecreds();
+ restore_uid();
+ }
+#endif
# ifdef USE_PAM
/*
* PAM credentials may take the form of supplementary groups.
static void
do_pwchange(Session *s)
{
+ fflush(NULL);
fprintf(stderr, "WARNING: Your password has expired.\n");
if (s->ttyfd != -1) {
- fprintf(stderr,
+ fprintf(stderr,
"You must change your password now and login again!\n");
+#ifdef PASSWD_NEEDS_USERNAME
+ execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
+ (char *)NULL);
+#else
execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
+#endif
perror("passwd");
} else {
fprintf(stderr,
#else /* HAVE_OSF_SIA */
do_nologin(pw);
do_setusercontext(pw);
+ /*
+ * PAM session modules in do_setusercontext may have
+ * generated messages, so if this in an interactive
+ * login then display them too.
+ */
+ if (!check_quietlogin(s, command))
+ display_loginmsg();
#endif /* HAVE_OSF_SIA */
}
+#ifdef USE_PAM
+ if (options.use_pam && !options.use_login && !is_pam_session_open()) {
+ debug3("PAM session not opened, exiting");
+ display_loginmsg();
+ exit(254);
+ }
+#endif
+
/*
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
packet_disconnect("Protocol error: you already have a pty.");
return 0;
}
- /* Get the time and hostname when the user last logged in. */
- if (options.print_lastlog) {
- s->hostname[0] = '\0';
- s->last_login_time = get_last_login_time(s->pw->pw_uid,
- s->pw->pw_name, s->hostname, sizeof(s->hostname));
- }
s->term = packet_get_string(&len);
u_int len;
int success = 0;
char *cmd, *subsys = packet_get_string(&len);
- int i;
+ u_int i;
packet_check_eom();
logit("subsystem request for %.100s", subsys);
success = session_auth_agent_req(s);
} else if (strcmp(rtype, "subsystem") == 0) {
success = session_subsystem_req(s);
- } else if (strcmp(rtype, "break") == 0) {
- success = session_break_req(s);
} else if (strcmp(rtype, "env") == 0) {
success = session_env_req(s);
}
}
if (strcmp(rtype, "window-change") == 0) {
success = session_window_change_req(s);
+ } else if (strcmp(rtype, "break") == 0) {
+ success = session_break_req(s);
}
+
return success;
}
void
session_close(Session *s)
{
- int i;
+ u_int i;
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
if (s->ttyfd != -1)