X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/02d56d325a583e46c4a23246d283def4514d12cb..HEAD:/session.c diff --git a/session.c b/session.c index f04266f7..fd7acbe0 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.246 2009/04/17 19:23:06 stevesk Exp $ */ +/* $OpenBSD: session.c,v 1.251 2010/01/12 08:33:17 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -142,9 +142,10 @@ static int sessions_first_unused = -1; static int sessions_nalloc = 0; static Session *sessions = NULL; -#define SUBSYSTEM_NONE 0 -#define SUBSYSTEM_EXT 1 -#define SUBSYSTEM_INT_SFTP 2 +#define SUBSYSTEM_NONE 0 +#define SUBSYSTEM_EXT 1 +#define SUBSYSTEM_INT_SFTP 2 +#define SUBSYSTEM_INT_SFTP_ERROR 3 #ifdef HAVE_LOGIN_CAP login_cap_t *lc; @@ -715,8 +716,8 @@ do_exec_pty(Session *s, const char *command) * Do common processing for the child, such as execing * the command. */ - do_child(s, command); - /* NOTREACHED */ + do_child(s, command); + /* NOTREACHED */ default: break; } @@ -785,17 +786,19 @@ do_exec(Session *s, const char *command) if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; - if (IS_INTERNAL_SFTP(command)) - s->is_subsystem = SUBSYSTEM_INT_SFTP; - else if (s->is_subsystem) + if (IS_INTERNAL_SFTP(command)) { + s->is_subsystem = s->is_subsystem ? + SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; + } else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (config) '%.900s'", command); } else if (forced_command) { original_command = command; command = forced_command; - if (IS_INTERNAL_SFTP(command)) - s->is_subsystem = SUBSYSTEM_INT_SFTP; - else if (s->is_subsystem) + if (IS_INTERNAL_SFTP(command)) { + s->is_subsystem = s->is_subsystem ? + SUBSYSTEM_INT_SFTP : SUBSYSTEM_INT_SFTP_ERROR; + } else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (key option) '%.900s'", command); } @@ -845,7 +848,7 @@ do_login(Session *s, const char *command) fromlen = sizeof(from); if (packet_connection_is_on_socket()) { if (getpeername(packet_get_connection_in(), - (struct sockaddr *) & from, &fromlen) < 0) { + (struct sockaddr *)&from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); cleanup_exit(255); } @@ -1374,26 +1377,32 @@ static void do_nologin(struct passwd *pw) { FILE *f = NULL; - char buf[1024]; + char buf[1024], *nl, *def_nl = _PATH_NOLOGIN; + struct stat sb; #ifdef HAVE_LOGIN_CAP - if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) - f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN, - _PATH_NOLOGIN), "r"); + if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid) + return; + nl = login_getcapstr(lc, "nologin", def_nl, def_nl); #else - if (pw->pw_uid) - f = fopen(_PATH_NOLOGIN, "r"); + if (pw->pw_uid == 0) + return; + nl = def_nl; #endif - if (f) { - /* /etc/nologin exists. Print its contents and exit. */ - logit("User %.100s not allowed because %s exists", - pw->pw_name, _PATH_NOLOGIN); - while (fgets(buf, sizeof(buf), f)) - fputs(buf, stderr); - fclose(f); - fflush(NULL); - exit(254); + if (stat(nl, &sb) == -1) { + if (nl != def_nl) + xfree(nl); + return; } + + /* /etc/nologin exists. Print its contents if we can and exit. */ + logit("User %.100s not allowed because %s exists", pw->pw_name, nl); + if ((f = fopen(nl, "r")) != NULL) { + while (fgets(buf, sizeof(buf), f)) + fputs(buf, stderr); + fclose(f); + } + exit(254); } /* @@ -1466,11 +1475,6 @@ do_setusercontext(struct passwd *pw) if (getuid() == 0 || geteuid() == 0) #endif /* HAVE_CYGWIN */ { - -#ifdef HAVE_SETPCRED - if (setpcred(pw->pw_name, (char **)NULL) == -1) - fatal("Failed to set process credentials"); -#endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP # ifdef __bsdi__ setpgid(0, 0); @@ -1538,6 +1542,10 @@ do_setusercontext(struct passwd *pw) free(chroot_path); } +#ifdef HAVE_SETPCRED + if (setpcred(pw->pw_name, (char **)NULL) == -1) + fatal("Failed to set process credentials"); +#endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) { perror("unable to set user context (setuser)"); @@ -1784,7 +1792,11 @@ do_child(Session *s, const char *command) /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); - if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { + if (s->is_subsystem == SUBSYSTEM_INT_SFTP_ERROR) { + printf("This service allows sftp connections only.\n"); + fflush(NULL); + exit(1); + } else if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { extern int optind, optreset; int i; char *p, *args; @@ -1797,9 +1809,14 @@ do_child(Session *s, const char *command) argv[i] = NULL; optind = optreset = 1; __progname = argv[0]; +#ifdef WITH_SELINUX + ssh_selinux_change_context("sftpd_t"); +#endif exit(sftp_server_main(i, argv, s->pw)); } + fflush(NULL); + if (options.use_login) { launch_login(pw, hostname); /* NEVERREACHED */ @@ -2110,16 +2127,16 @@ session_subsystem_req(Session *s) if (strcmp(subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; - if (!strcmp(INTERNAL_SFTP_NAME, prog)) { + if (strcmp(INTERNAL_SFTP_NAME, prog) == 0) { s->is_subsystem = SUBSYSTEM_INT_SFTP; - } else if (stat(prog, &st) < 0) { - error("subsystem: cannot stat %s: %s", prog, - strerror(errno)); - break; + debug("subsystem: %s", prog); } else { + if (stat(prog, &st) < 0) + debug("subsystem: cannot stat %s: %s", + prog, strerror(errno)); s->is_subsystem = SUBSYSTEM_EXT; + debug("subsystem: exec() %s", cmd); } - debug("subsystem: exec() %s", cmd); success = do_exec(s, cmd) == 0; break; }