=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/session.c,v retrieving revision 1.224 retrieving revision 1.225 diff -u -r1.224 -r1.225 --- src/usr.bin/ssh/session.c 2007/09/11 15:47:17 1.224 +++ src/usr.bin/ssh/session.c 2008/02/04 21:53:00 1.225 @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.224 2007/09/11 15:47:17 gilles Exp $ */ +/* $OpenBSD: session.c,v 1.225 2008/02/04 21:53:00 markus Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -79,6 +79,7 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" +#include "sftp.h" #ifdef KRB5 #include @@ -121,6 +122,10 @@ #define MAX_SESSIONS 10 Session sessions[MAX_SESSIONS]; +#define SUBSYSTEM_NONE 0 +#define SUBSYSTEM_EXT 1 +#define SUBSYSTEM_INT_SFTP 2 + login_cap_t *lc; static int is_child = 0; @@ -545,10 +550,14 @@ if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; + 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 (s->is_subsystem) + s->is_subsystem = SUBSYSTEM_EXT; debug("Forced command (key option) '%.900s'", command); } @@ -1026,12 +1035,13 @@ * environment, closing extra file descriptors, setting the user and group * ids, and executing the command or shell. */ +#define ARGV_MAX 10 void do_child(Session *s, const char *command) { extern char **environ; char **env; - char *argv[10]; + char *argv[ARGV_MAX]; const char *shell, *shell0, *hostname = NULL; struct passwd *pw = s->pw; @@ -1132,6 +1142,22 @@ /* restore SIGPIPE for child */ signal(SIGPIPE, SIG_DFL); + if (s->is_subsystem == SUBSYSTEM_INT_SFTP) { + extern int optind, optreset; + int i; + char *p, *args; + + setproctitle("%s@internal-sftp-server", s->pw->pw_name); + args = strdup(command ? command : "sftp-server"); + for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) + if (i < ARGV_MAX - 1) + argv[i++] = p; + argv[i] = NULL; + optind = optreset = 1; + __progname = argv[0]; + exit(sftp_server_main(i, argv)); + } + if (options.use_login) { launch_login(pw, hostname); /* NEVERREACHED */ @@ -1404,13 +1430,16 @@ if (strcmp(subsys, options.subsystem_name[i]) == 0) { prog = options.subsystem_command[i]; cmd = options.subsystem_args[i]; - if (stat(prog, &st) < 0) { + if (!strcmp("internal-sftp", prog)) { + s->is_subsystem = SUBSYSTEM_INT_SFTP; + } else if (stat(prog, &st) < 0) { error("subsystem: cannot stat %s: %s", prog, strerror(errno)); break; + } else { + s->is_subsystem = SUBSYSTEM_EXT; } debug("subsystem: exec() %s", cmd); - s->is_subsystem = 1; do_exec(s, cmd); success = 1; break;