X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/ab88181ca950e71f6ec770b323d865c2858ce08c..8fbc356de176c10b7d4503b6c6bbbe9954f95b77:/session.c diff --git a/session.c b/session.c index 0571c2f6..1e9e3228 100644 --- a/session.c +++ b/session.c @@ -9,7 +9,7 @@ * called by a name other than "ssh" or "Secure Shell". * * SSH2 support by Markus Friedl. - * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.94 2001/06/23 15:12:20 itojun Exp $"); +RCSID("$OpenBSD: session.c,v 1.100 2001/08/16 19:18:34 jakob Exp $"); #include "ssh.h" #include "ssh1.h" @@ -99,7 +99,8 @@ typedef struct Session Session; struct Session { int used; int self; - struct passwd *pw; + struct passwd *pw; + Authctxt *authctxt; pid_t pid; /* tty */ char *term; @@ -120,20 +121,21 @@ struct Session { /* func */ Session *session_new(void); -void session_set_fds(Session *, int, int, int); -static void session_pty_cleanup(void *); -void session_proctitle(Session *); -int session_setup_x11fwd(Session *); -void do_exec_pty(Session *, const char *); -void do_exec_no_pty(Session *, const char *); -void do_exec(Session *, const char *); -void do_login(Session *, const char *); -void do_child(Session *, const char *); +void session_set_fds(Session *, int, int, int); +static void session_pty_cleanup(void *); +void session_proctitle(Session *); +int session_setup_x11fwd(Session *); +void do_exec_pty(Session *, const char *); +void do_exec_no_pty(Session *, const char *); +void do_exec(Session *, const char *); +void do_login(Session *, const char *); +void do_child(Session *, const char *); void do_motd(void); +int check_quietlogin(Session *, const char *); static void do_authenticated1(Authctxt *); static void do_authenticated2(Authctxt *); - + static void session_close(Session *); static int session_pty_req(Session *); @@ -198,6 +200,14 @@ do_authenticated(Authctxt *authctxt) /* remove agent socket */ if (auth_get_socket_name()) auth_sock_cleanup_proc(authctxt->pw); +#ifdef KRB4 + if (options.kerberos_ticket_cleanup) + krb4_cleanup_proc(authctxt); +#endif +#ifdef KRB5 + if (options.kerberos_ticket_cleanup) + krb5_cleanup_proc(authctxt); +#endif } /* @@ -216,6 +226,7 @@ do_authenticated1(Authctxt *authctxt) u_int proto_len, data_len, dlen; s = session_new(); + s->authctxt = authctxt; s->pw = authctxt->pw; /* @@ -300,6 +311,58 @@ do_authenticated1(Authctxt *authctxt) if (packet_set_maxsize(packet_get_int()) > 0) success = 1; break; + +#if defined(AFS) || defined(KRB5) + case SSH_CMSG_HAVE_KERBEROS_TGT: + if (!options.kerberos_tgt_passing) { + verbose("Kerberos TGT passing disabled."); + } else { + char *kdata = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + + /* XXX - 0x41, see creds_to_radix version */ + if (kdata[0] != 0x41) { +#ifdef KRB5 + krb5_data tgt; + tgt.data = kdata; + tgt.length = dlen; + + if (auth_krb5_tgt(s->authctxt, &tgt)) + success = 1; + else + verbose("Kerberos v5 TGT refused for %.100s", s->authctxt->user); +#endif /* KRB5 */ + } else { +#ifdef AFS + if (auth_krb4_tgt(s->authctxt, kdata)) + success = 1; + else + verbose("Kerberos v4 TGT refused for %.100s", s->authctxt->user); +#endif /* AFS */ + } + xfree(kdata); + } + break; +#endif /* AFS || KRB5 */ + +#ifdef AFS + case SSH_CMSG_HAVE_AFS_TOKEN: + if (!options.afs_token_passing || !k_hasafs()) { + verbose("AFS token passing disabled."); + } else { + /* Accept AFS token. */ + char *token = packet_get_string(&dlen); + packet_integrity_check(plen, 4 + dlen, type); + + if (auth_afs_token(s->authctxt, token)) + success = 1; + else + verbose("AFS token refused for %.100s", + s->authctxt->user); + xfree(token); + } + break; +#endif /* AFS */ case SSH_CMSG_EXEC_SHELL: case SSH_CMSG_EXEC_CMD: @@ -364,6 +427,7 @@ do_exec_no_pty(Session *s, const char *command) session_proctitle(s); #if defined(USE_PAM) + do_pam_session(s->pw->pw_name, NULL); do_pam_setcred(1); #endif /* USE_PAM */ @@ -484,9 +548,9 @@ do_exec_pty(Session *s, const char *command) /* Fork the child. */ if ((pid = fork()) == 0) { + /* Child. Reinitialize the log because the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); - /* Close the master side of the pseudo tty. */ close(ptyfd); @@ -607,30 +671,6 @@ do_exec(Session *s, const char *command) original_command = NULL; } -/* - * Check for quiet login, either .hushlogin or command given. - */ -static int -check_quietlogin(Session *s, const char *command) -{ - char buf[256]; - struct passwd * pw = s->pw; - struct stat st; - - /* Return 1 if .hushlogin exists or a command given. */ - if (command != NULL) - return 1; - snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); -#ifdef HAVE_LOGIN_CAP - if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) - return 1; -#else - if (stat(buf, &st) >= 0) - return 1; -#endif - return 0; -} - /* administrative, login(1)-like work */ void do_login(Session *s, const char *command) @@ -729,6 +769,31 @@ do_motd(void) } } + +/* + * Check for quiet login, either .hushlogin or command given. + */ +int +check_quietlogin(Session *s, const char *command) +{ + char buf[256]; + struct passwd *pw = s->pw; + struct stat st; + + /* Return 1 if .hushlogin exists or a command given. */ + if (command != NULL) + return 1; + snprintf(buf, sizeof(buf), "%.200s/.hushlogin", pw->pw_dir); +#ifdef HAVE_LOGIN_CAP + if (login_getcapbool(lc, "hushlogin", 0) || stat(buf, &st) >= 0) + return 1; +#else + if (stat(buf, &st) >= 0) + return 1; +#endif + return 0; +} + /* * Sets the value of the given variable in the environment. If the variable * already exists, its value is overriden. @@ -813,7 +878,7 @@ read_environment_file(char ***env, u_int *envsize, /* * Sets any environment variables which have been specified by PAM */ -void do_pam_environment(char ***env, int *envsize) +void do_pam_environment(char ***env, u_int *envsize) { char *equals, var_name[512], var_val[512]; char **pam_env; @@ -842,7 +907,7 @@ void do_pam_environment(char ***env, int *envsize) #endif /* USE_PAM */ #ifdef HAVE_CYGWIN -void copy_environment(char ***env, int *envsize) +void copy_environment(char ***env, u_int *envsize) { char *equals, var_name[512], var_val[512]; int i; @@ -954,7 +1019,7 @@ void do_child(Session *s, const char *command) { const char *shell, *hostname = NULL, *cp = NULL; - struct passwd * pw = s->pw; + struct passwd *pw = s->pw; char buf[256]; char cmd[1024]; FILE *f = NULL; @@ -985,7 +1050,7 @@ do_child(Session *s, const char *command) if (options.use_login && command != NULL) options.use_login = 0; -#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA) +#if !defined(HAVE_OSF_SIA) if (!options.use_login) { # ifdef HAVE_LOGIN_CAP if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) @@ -1003,7 +1068,7 @@ do_child(Session *s, const char *command) exit(254); } } -#endif /* USE_PAM || HAVE_OSF_SIA */ +#endif /* HAVE_OSF_SIA */ /* Set login name, uid, gid, and groups. */ /* Login(1) does this as well, and it needs uid 0 for the "-h" @@ -1133,10 +1198,10 @@ do_child(Session *s, const char *command) /* Try to get AFS tokens for the local cell. */ if (k_hasafs()) { char cell[64]; - + if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0) krb_afslog(cell, 0); - + krb_afslog(0, 0); } #endif /* AFS */ @@ -1220,16 +1285,16 @@ do_child(Session *s, const char *command) child_set_env(&env, &envsize, "KRB5CCNAME", cp); read_environment_file(&env, &envsize, "/etc/environment"); #endif - #ifdef KRB4 - { - extern char *ticket; - - if (ticket) - child_set_env(&env, &envsize, "KRBTKFILE", ticket); - } -#endif /* KRB4 */ - + if (s->authctxt->krb4_ticket_file) + child_set_env(&env, &envsize, "KRBTKFILE", + s->authctxt->krb4_ticket_file); +#endif +#ifdef KRB5 + if (s->authctxt->krb5_ticket_file) + child_set_env(&env, &envsize, "KRB5CCNAME", + s->authctxt->krb5_ticket_file); +#endif #ifdef USE_PAM /* Pull in any environment variables that may have been set by PAM. */ do_pam_environment(&env, &envsize); @@ -1394,25 +1459,6 @@ do_child(Session *s, const char *command) if (!options.use_login) { char buf[256]; - /* - * Check for mail if we have a tty and it was enabled - * in server options. - */ - if (s->ttyfd != -1 && options.check_mail) { - char *mailbox; - struct stat mailstat; - - mailbox = getenv("MAIL"); - if (mailbox != NULL) { - 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"); - else - printf("You have new mail.\n"); - } - } /* Start the shell. Set initial character to '-'. */ buf[0] = '-'; strncpy(buf + 1, cp, sizeof(buf) - 1); @@ -1434,7 +1480,7 @@ do_child(Session *s, const char *command) #ifdef LOGIN_NEEDS_TERM s->term? s->term : "unknown", #endif - "-p", "-f", "--", pw->pw_name, NULL); + "-p", "-f", "--", pw->pw_name, (char *)NULL); /* Login couldn't be executed, die. */ @@ -1499,7 +1545,7 @@ session_dump(void) } int -session_open(int chanid) +session_open(Authctxt *authctxt, int chanid) { Session *s = session_new(); debug("session_open: channel %d", chanid); @@ -1507,7 +1553,8 @@ session_open(int chanid) error("no more sessions"); return 0; } - s->pw = auth_get_user(); + s->authctxt = authctxt; + s->pw = authctxt->pw; if (s->pw == NULL) fatal("no user for session %d", s->self); debug("session_open: session %d: link with channel %d", s->self, chanid); @@ -1895,6 +1942,22 @@ session_close_by_pid(pid_t pid, int status) session_close(s); } +int +session_have_children(void) +{ + int i; + + for(i = 0; i < MAX_SESSIONS; i++) { + Session *s = &sessions[i]; + if (s->used && s->pid != -1) { + debug("session_have_children: id %d pid %d", i, s->pid); + return 1; + } + } + debug("session_have_children: no more children"); + return 0; +} + /* * this is called when a channel dies before * the session 'child' itself dies @@ -1989,5 +2052,5 @@ session_setup_x11fwd(Session *s) static void do_authenticated2(Authctxt *authctxt) { - server_loop2(); + server_loop2(authctxt); }