Accidently removed XXX comment. New patch below. Regards Magnus --- openssh-3.6.1p2/sftp-server.c.org 2003-08-11 22:07:47.098650000 +0200 +++ openssh-3.6.1p2/sftp-server.c 2003-08-16 19:07:14.273582000 +0200 @@ -24,15 +24,24 @@ #include "includes.h" RCSID("$OpenBSD: sftp-server.c,v 1.41 2003/03/26 04:02:51 deraadt Exp $"); +#define CHROOT #include "buffer.h" #include "bufaux.h" #include "getput.h" #include "log.h" #include "xmalloc.h" - #include "sftp.h" #include "sftp-common.h" +#ifdef CHROOT +#include "uidswap.h" +#include <pwd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <unistd.h> +#endif /* CHROOT */ + /* helper */ #define get_int64() buffer_get_int64(&iqueue); #define get_int() buffer_get_int(&iqueue); @@ -62,6 +71,51 @@ Attrib attrib; }; +#ifdef CHROOT +static void +chroot_init(void) +{ + gid_t gidset[1]; + struct passwd *pw; + struct stat st; + + /* Sanity checking before chroot */ + if ((pw = getpwuid(getuid())) == NULL) + fatal("getpwuid failed for %u", (u_int)pw->pw_uid ); + + /* Sets passwd pointer to null */ + memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); + endpwent(); + + if (geteuid() != 0) + fatal("must be SUID root to use chroot feature"); + + if ((stat(pw->pw_dir, &st)) == -1) + fatal("cannot stat chroot directory %s: %s", pw->pw_dir, strerror(errno)); + + if (!S_ISDIR(st.st_mode)) + fatal("%s is not a directory: %s", pw->pw_dir, strerror(errno)); + + /* Drop our privileges */ + debug3("chroot user:group %u:%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); + + /* Change our root directory */ + if (chroot(pw->pw_dir) == -1) + fatal("chroot(\"%s\"): %s", pw->pw_dir, strerror(errno)); + + /* Change dir to prevent chroot break */ + if (chdir("/") == -1) + fatal("chdir(\"/\"): %s", strerror(errno)); + + gidset[0] = pw->pw_gid; + if (setgid(pw->pw_gid) < 0) + fatal("setgid failed for %u", (u_int)pw->pw_gid ); + if (setgroups(1, gidset) < 0) + fatal("setgroups: %.100s", strerror(errno)); + permanently_set_uid(pw); +} +#endif /* CHROOT */ + static int errno_to_portable(int unixerrno) { @@ -1028,15 +1082,19 @@ int in, out, max; ssize_t len, olen, set_size; +#ifdef DEBUG_SFTP-SERVER + log_init("sftp-server", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); +#endif + +#ifdef CHROOT + chroot_init(); +#endif + /* XXX should use getopt */ __progname = get_progname(av[0]); handle_init(); -#ifdef DEBUG_SFTP_SERVER - log_init("sftp-server", SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 0); -#endif - in = dup(STDIN_FILENO); out = dup(STDOUT_FILENO);