summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in6
-rw-r--r--servconf.c12
-rw-r--r--servconf.h4
-rw-r--r--session.c106
-rw-r--r--sftp-server-main.c50
-rw-r--r--sftp-server.c10
-rw-r--r--sftp.h6
-rw-r--r--sshd_config3
-rw-r--r--sshd_config.554
9 files changed, 220 insertions, 31 deletions
diff --git a/Makefile.in b/Makefile.in
index 2486edc95..1f78ea9cc 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
1# $Id: Makefile.in,v 1.285 2007/06/11 04:01:42 djm Exp $ 1# $Id: Makefile.in,v 1.286 2008/02/10 11:40:12 djm Exp $
2 2
3# uncomment if you run a non bourne compatable shell. Ie. csh 3# uncomment if you run a non bourne compatable shell. Ie. csh
4#SHELL = @SH@ 4#SHELL = @SH@
@@ -156,8 +156,8 @@ ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
156ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o 156ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
157 $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) 157 $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
158 158
159sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o 159sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
160 $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 160 $(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
161 161
162sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o 162sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o
163 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) 163 $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT)
diff --git a/servconf.c b/servconf.c
index 19c286c18..d38d0bfb1 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.c,v 1.175 2008/01/01 09:27:33 dtucker Exp $ */ 1/* $OpenBSD: servconf.c,v 1.176 2008/02/08 23:24:08 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -122,6 +122,7 @@ initialize_server_options(ServerOptions *options)
122 options->permit_tun = -1; 122 options->permit_tun = -1;
123 options->num_permitted_opens = -1; 123 options->num_permitted_opens = -1;
124 options->adm_forced_command = NULL; 124 options->adm_forced_command = NULL;
125 options->chroot_directory = NULL;
125} 126}
126 127
127void 128void
@@ -291,7 +292,7 @@ typedef enum {
291 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, 292 sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
292 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, 293 sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
293 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, 294 sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
294 sMatch, sPermitOpen, sForceCommand, 295 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
295 sUsePrivilegeSeparation, 296 sUsePrivilegeSeparation,
296 sDeprecated, sUnsupported 297 sDeprecated, sUnsupported
297} ServerOpCodes; 298} ServerOpCodes;
@@ -403,6 +404,7 @@ static struct {
403 { "match", sMatch, SSHCFG_ALL }, 404 { "match", sMatch, SSHCFG_ALL },
404 { "permitopen", sPermitOpen, SSHCFG_ALL }, 405 { "permitopen", sPermitOpen, SSHCFG_ALL },
405 { "forcecommand", sForceCommand, SSHCFG_ALL }, 406 { "forcecommand", sForceCommand, SSHCFG_ALL },
407 { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
406 { NULL, sBadOption, 0 } 408 { NULL, sBadOption, 0 }
407}; 409};
408 410
@@ -1147,6 +1149,7 @@ parse_flag:
1147 case sBanner: 1149 case sBanner:
1148 charptr = &options->banner; 1150 charptr = &options->banner;
1149 goto parse_filename; 1151 goto parse_filename;
1152
1150 /* 1153 /*
1151 * These options can contain %X options expanded at 1154 * These options can contain %X options expanded at
1152 * connect time, so that you can specify paths like: 1155 * connect time, so that you can specify paths like:
@@ -1255,6 +1258,10 @@ parse_flag:
1255 options->adm_forced_command = xstrdup(cp + len); 1258 options->adm_forced_command = xstrdup(cp + len);
1256 return 0; 1259 return 0;
1257 1260
1261 case sChrootDirectory:
1262 charptr = &options->chroot_directory;
1263 goto parse_filename;
1264
1258 case sDeprecated: 1265 case sDeprecated:
1259 logit("%s line %d: Deprecated option %s", 1266 logit("%s line %d: Deprecated option %s",
1260 filename, linenum, arg); 1267 filename, linenum, arg);
@@ -1363,6 +1370,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1363 if (preauth) 1370 if (preauth)
1364 return; 1371 return;
1365 M_CP_STROPT(adm_forced_command); 1372 M_CP_STROPT(adm_forced_command);
1373 M_CP_STROPT(chroot_directory);
1366} 1374}
1367 1375
1368#undef M_CP_INTOPT 1376#undef M_CP_INTOPT
diff --git a/servconf.h b/servconf.h
index 8a5b950ea..81a68be89 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.80 2007/02/19 10:45:58 dtucker Exp $ */ 1/* $OpenBSD: servconf.h,v 1.81 2008/02/08 23:24:08 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -141,6 +141,8 @@ typedef struct {
141 int permit_tun; 141 int permit_tun;
142 142
143 int num_permitted_opens; 143 int num_permitted_opens;
144
145 char *chroot_directory;
144} ServerOptions; 146} ServerOptions;
145 147
146void initialize_server_options(ServerOptions *); 148void initialize_server_options(ServerOptions *);
diff --git a/session.c b/session.c
index a1319b384..1768c8c2f 100644
--- a/session.c
+++ b/session.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: session.c,v 1.225 2008/02/04 21:53:00 markus Exp $ */ 1/* $OpenBSD: session.c,v 1.226 2008/02/08 23:24:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved 4 * All rights reserved
@@ -84,6 +84,7 @@
84#include "sshlogin.h" 84#include "sshlogin.h"
85#include "serverloop.h" 85#include "serverloop.h"
86#include "canohost.h" 86#include "canohost.h"
87#include "misc.h"
87#include "session.h" 88#include "session.h"
88#include "kex.h" 89#include "kex.h"
89#include "monitor_wrap.h" 90#include "monitor_wrap.h"
@@ -93,6 +94,9 @@
93#include <kafs.h> 94#include <kafs.h>
94#endif 95#endif
95 96
97/* Magic name for internal sftp-server */
98#define INTERNAL_SFTP_NAME "internal-sftp"
99
96/* func */ 100/* func */
97 101
98Session *session_new(void); 102Session *session_new(void);
@@ -130,7 +134,7 @@ extern Buffer loginmsg;
130const char *original_command = NULL; 134const char *original_command = NULL;
131 135
132/* data */ 136/* data */
133#define MAX_SESSIONS 10 137#define MAX_SESSIONS 20
134Session sessions[MAX_SESSIONS]; 138Session sessions[MAX_SESSIONS];
135 139
136#define SUBSYSTEM_NONE 0 140#define SUBSYSTEM_NONE 0
@@ -688,13 +692,17 @@ do_exec(Session *s, const char *command)
688 if (options.adm_forced_command) { 692 if (options.adm_forced_command) {
689 original_command = command; 693 original_command = command;
690 command = options.adm_forced_command; 694 command = options.adm_forced_command;
691 if (s->is_subsystem) 695 if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
696 s->is_subsystem = SUBSYSTEM_INT_SFTP;
697 else if (s->is_subsystem)
692 s->is_subsystem = SUBSYSTEM_EXT; 698 s->is_subsystem = SUBSYSTEM_EXT;
693 debug("Forced command (config) '%.900s'", command); 699 debug("Forced command (config) '%.900s'", command);
694 } else if (forced_command) { 700 } else if (forced_command) {
695 original_command = command; 701 original_command = command;
696 command = forced_command; 702 command = forced_command;
697 if (s->is_subsystem) 703 if (strcmp(INTERNAL_SFTP_NAME, command) == 0)
704 s->is_subsystem = SUBSYSTEM_INT_SFTP;
705 else if (s->is_subsystem)
698 s->is_subsystem = SUBSYSTEM_EXT; 706 s->is_subsystem = SUBSYSTEM_EXT;
699 debug("Forced command (key option) '%.900s'", command); 707 debug("Forced command (key option) '%.900s'", command);
700 } 708 }
@@ -710,7 +718,6 @@ do_exec(Session *s, const char *command)
710 PRIVSEP(audit_run_command(shell)); 718 PRIVSEP(audit_run_command(shell));
711 } 719 }
712#endif 720#endif
713
714 if (s->ttyfd != -1) 721 if (s->ttyfd != -1)
715 do_exec_pty(s, command); 722 do_exec_pty(s, command);
716 else 723 else
@@ -1293,6 +1300,61 @@ do_nologin(struct passwd *pw)
1293 } 1300 }
1294} 1301}
1295 1302
1303/*
1304 * Chroot into a directory after checking it for safety: all path components
1305 * must be root-owned directories with strict permissions.
1306 */
1307static void
1308safely_chroot(const char *path, uid_t uid)
1309{
1310 const char *cp;
1311 char component[MAXPATHLEN];
1312 struct stat st;
1313
1314 if (*path != '/')
1315 fatal("chroot path does not begin at root");
1316 if (strlen(path) >= sizeof(component))
1317 fatal("chroot path too long");
1318
1319 /*
1320 * Descend the path, checking that each component is a
1321 * root-owned directory with strict permissions.
1322 */
1323 for (cp = path; cp != NULL;) {
1324 if ((cp = strchr(cp, '/')) == NULL)
1325 strlcpy(component, path, sizeof(component));
1326 else {
1327 cp++;
1328 memcpy(component, path, cp - path);
1329 component[cp - path] = '\0';
1330 }
1331
1332 debug3("%s: checking '%s'", __func__, component);
1333
1334 if (stat(component, &st) != 0)
1335 fatal("%s: stat(\"%s\"): %s", __func__,
1336 component, strerror(errno));
1337 if (st.st_uid != 0 || (st.st_mode & 022) != 0)
1338 fatal("bad ownership or modes for chroot "
1339 "directory %s\"%s\"",
1340 cp == NULL ? "" : "component ", component);
1341 if (!S_ISDIR(st.st_mode))
1342 fatal("chroot path %s\"%s\" is not a directory",
1343 cp == NULL ? "" : "component ", component);
1344
1345 }
1346
1347 if (chdir(path) == -1)
1348 fatal("Unable to chdir to chroot path \"%s\": "
1349 "%s", path, strerror(errno));
1350 if (chroot(path) == -1)
1351 fatal("chroot(\"%s\"): %s", path, strerror(errno));
1352 if (chdir("/") == -1)
1353 fatal("%s: chdir(/) after chroot: %s",
1354 __func__, strerror(errno));
1355 verbose("Changed root directory to \"%s\"", path);
1356}
1357
1296/* Set login name, uid, gid, and groups. */ 1358/* Set login name, uid, gid, and groups. */
1297void 1359void
1298do_setusercontext(struct passwd *pw) 1360do_setusercontext(struct passwd *pw)
@@ -1324,7 +1386,7 @@ do_setusercontext(struct passwd *pw)
1324 } 1386 }
1325# endif /* USE_PAM */ 1387# endif /* USE_PAM */
1326 if (setusercontext(lc, pw, pw->pw_uid, 1388 if (setusercontext(lc, pw, pw->pw_uid,
1327 (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { 1389 (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETUSER))) < 0) {
1328 perror("unable to set user context"); 1390 perror("unable to set user context");
1329 exit(1); 1391 exit(1);
1330 } 1392 }
@@ -1347,13 +1409,13 @@ do_setusercontext(struct passwd *pw)
1347 exit(1); 1409 exit(1);
1348 } 1410 }
1349 endgrent(); 1411 endgrent();
1350#ifdef GSSAPI 1412# ifdef GSSAPI
1351 if (options.gss_authentication) { 1413 if (options.gss_authentication) {
1352 temporarily_use_uid(pw); 1414 temporarily_use_uid(pw);
1353 ssh_gssapi_storecreds(); 1415 ssh_gssapi_storecreds();
1354 restore_uid(); 1416 restore_uid();
1355 } 1417 }
1356#endif 1418# endif
1357# ifdef USE_PAM 1419# ifdef USE_PAM
1358 /* 1420 /*
1359 * PAM credentials may take the form of supplementary groups. 1421 * PAM credentials may take the form of supplementary groups.
@@ -1367,15 +1429,33 @@ do_setusercontext(struct passwd *pw)
1367# endif /* USE_PAM */ 1429# endif /* USE_PAM */
1368# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) 1430# if defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)
1369 irix_setusercontext(pw); 1431 irix_setusercontext(pw);
1370# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 1432# endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1371# ifdef _AIX 1433# ifdef _AIX
1372 aix_usrinfo(pw); 1434 aix_usrinfo(pw);
1373# endif /* _AIX */ 1435# endif /* _AIX */
1374#ifdef USE_LIBIAF 1436# ifdef USE_LIBIAF
1375 if (set_id(pw->pw_name) != 0) { 1437 if (set_id(pw->pw_name) != 0) {
1376 exit(1); 1438 exit(1);
1377 } 1439 }
1378#endif /* USE_LIBIAF */ 1440# endif /* USE_LIBIAF */
1441#endif
1442
1443 if (options.chroot_directory != NULL &&
1444 strcasecmp(options.chroot_directory, "none") != 0) {
1445 char *chroot_path;
1446
1447 chroot_path = percent_expand(options.chroot_directory,
1448 "h", pw->pw_dir, "u", pw->pw_name, (char *)NULL);
1449 safely_chroot(chroot_path, pw->pw_uid);
1450 free(chroot_path);
1451 }
1452
1453#ifdef HAVE_LOGIN_CAP
1454 if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
1455 perror("unable to set user context (setuser)");
1456 exit(1);
1457 }
1458#else
1379 /* Permanently switch to the desired uid. */ 1459 /* Permanently switch to the desired uid. */
1380 permanently_set_uid(pw); 1460 permanently_set_uid(pw);
1381#endif 1461#endif
@@ -1625,7 +1705,7 @@ do_child(Session *s, const char *command)
1625 argv[i] = NULL; 1705 argv[i] = NULL;
1626 optind = optreset = 1; 1706 optind = optreset = 1;
1627 __progname = argv[0]; 1707 __progname = argv[0];
1628 exit(sftp_server_main(i, argv)); 1708 exit(sftp_server_main(i, argv, s->pw));
1629 } 1709 }
1630 1710
1631 if (options.use_login) { 1711 if (options.use_login) {
@@ -1900,7 +1980,7 @@ session_subsystem_req(Session *s)
1900 if (strcmp(subsys, options.subsystem_name[i]) == 0) { 1980 if (strcmp(subsys, options.subsystem_name[i]) == 0) {
1901 prog = options.subsystem_command[i]; 1981 prog = options.subsystem_command[i];
1902 cmd = options.subsystem_args[i]; 1982 cmd = options.subsystem_args[i];
1903 if (!strcmp("internal-sftp", prog)) { 1983 if (!strcmp(INTERNAL_SFTP_NAME, prog)) {
1904 s->is_subsystem = SUBSYSTEM_INT_SFTP; 1984 s->is_subsystem = SUBSYSTEM_INT_SFTP;
1905 } else if (stat(prog, &st) < 0) { 1985 } else if (stat(prog, &st) < 0) {
1906 error("subsystem: cannot stat %s: %s", prog, 1986 error("subsystem: cannot stat %s: %s", prog,
diff --git a/sftp-server-main.c b/sftp-server-main.c
new file mode 100644
index 000000000..1d2ea6220
--- /dev/null
+++ b/sftp-server-main.c
@@ -0,0 +1,50 @@
1/* $OpenBSD: */
2/*
3 * Copyright (c) 2008 Markus Friedl. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include "includes.h"
19
20#include <sys/types.h>
21#include <pwd.h>
22#include <stdarg.h>
23#include <stdio.h>
24#include <unistd.h>
25
26#include "log.h"
27#include "sftp.h"
28#include "misc.h"
29
30void
31cleanup_exit(int i)
32{
33 sftp_server_cleanup_exit(i);
34}
35
36int
37main(int argc, char **argv)
38{
39 struct passwd *user_pw;
40
41 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
42 sanitise_stdfd();
43
44 if ((user_pw = getpwuid(getuid())) == NULL) {
45 fprintf(stderr, "No user found for uid %lu", (u_long)getuid());
46 return 1;
47 }
48
49 return (sftp_server_main(argc, argv, user_pw));
50}
diff --git a/sftp-server.c b/sftp-server.c
index 373bd5eda..44ccefff8 100644
--- a/sftp-server.c
+++ b/sftp-server.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp-server.c,v 1.76 2008/02/04 21:53:00 markus Exp $ */ 1/* $OpenBSD: sftp-server.c,v 1.77 2008/02/08 23:24:07 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
4 * 4 *
@@ -1219,7 +1219,7 @@ sftp_server_usage(void)
1219} 1219}
1220 1220
1221int 1221int
1222sftp_server_main(int argc, char **argv) 1222sftp_server_main(int argc, char **argv, struct passwd *user_pw)
1223{ 1223{
1224 fd_set *rset, *wset; 1224 fd_set *rset, *wset;
1225 int in, out, max, ch, skipargs = 0, log_stderr = 0; 1225 int in, out, max, ch, skipargs = 0, log_stderr = 0;
@@ -1277,11 +1277,7 @@ sftp_server_main(int argc, char **argv)
1277 } else 1277 } else
1278 client_addr = xstrdup("UNKNOWN"); 1278 client_addr = xstrdup("UNKNOWN");
1279 1279
1280 if ((pw = getpwuid(getuid())) == NULL) { 1280 pw = pwcopy(user_pw);
1281 error("No user found for uid %lu", (u_long)getuid());
1282 sftp_server_cleanup_exit(255);
1283 }
1284 pw = pwcopy(pw);
1285 1281
1286 logit("session opened for local user %s from [%s]", 1282 logit("session opened for local user %s from [%s]",
1287 pw->pw_name, client_addr); 1283 pw->pw_name, client_addr);
diff --git a/sftp.h b/sftp.h
index 12b9cc056..0835da6ed 100644
--- a/sftp.h
+++ b/sftp.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.h,v 1.6 2008/02/04 21:53:00 markus Exp $ */ 1/* $OpenBSD: sftp.h,v 1.7 2008/02/08 23:24:07 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 Markus Friedl. All rights reserved. 4 * Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -91,5 +91,7 @@
91#define SSH2_FX_OP_UNSUPPORTED 8 91#define SSH2_FX_OP_UNSUPPORTED 8
92#define SSH2_FX_MAX 8 92#define SSH2_FX_MAX 8
93 93
94int sftp_server_main(int, char **); 94struct passwd;
95
96int sftp_server_main(int, char **, struct passwd *);
95void sftp_server_cleanup_exit(int) __dead; 97void sftp_server_cleanup_exit(int) __dead;
diff --git a/sshd_config b/sshd_config
index c7094e775..ddfbbe91e 100644
--- a/sshd_config
+++ b/sshd_config
@@ -1,4 +1,4 @@
1# $OpenBSD: sshd_config,v 1.76 2007/08/23 03:22:16 djm Exp $ 1# $OpenBSD: sshd_config,v 1.77 2008/02/08 23:24:07 djm Exp $
2 2
3# This is the sshd server system-wide configuration file. See 3# This is the sshd server system-wide configuration file. See
4# sshd_config(5) for more information. 4# sshd_config(5) for more information.
@@ -102,6 +102,7 @@ Protocol 2
102#PidFile /var/run/sshd.pid 102#PidFile /var/run/sshd.pid
103#MaxStartups 10 103#MaxStartups 10
104#PermitTunnel no 104#PermitTunnel no
105#ChrootDirectory none
105 106
106# no default banner path 107# no default banner path
107#Banner none 108#Banner none
diff --git a/sshd_config.5 b/sshd_config.5
index aa6720dc3..2f83bf2e1 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd_config.5,v 1.79 2008/01/01 09:27:33 dtucker Exp $ 37.\" $OpenBSD: sshd_config.5,v 1.80 2008/02/08 23:24:07 djm Exp $
38.Dd $Mdocdate: January 1 2008 $ 38.Dd $Mdocdate: February 8 2008 $
39.Dt SSHD_CONFIG 5 39.Dt SSHD_CONFIG 5
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -173,6 +173,45 @@ All authentication styles from
173are supported. 173are supported.
174The default is 174The default is
175.Dq yes . 175.Dq yes .
176.It Cm ChrootDirectory
177Specifies a path to
178.Xr chroot 2
179to after authentication.
180This path, and all its components, must be root-owned directories that are
181not writable by any other user or group.
182.Pp
183The path may contain the following tokens that are expanded at runtime once
184the connecting user has been authenticated: %% is replaced by a literal '%',
185%h is replaced by the home directory of the user being authenticated, and
186%u is replaced by the username of that user.
187.Pp
188The
189.Cm ChrootDirectory
190must contain the necessary files and directories to support the
191users' session.
192For an interactive session this requires at least a shell, typically
193.Xr sh 1 ,
194and basic
195.Pa /dev
196nodes such as
197.Xr null 4 ,
198.Xr zero 4 ,
199.Xr stdin 4 ,
200.Xr stdout 4 ,
201.Xr stderr 4 ,
202.Xr arandom 4
203and
204.Xr tty 4
205devices.
206For file transfer sessions using
207.Dq sftp ,
208no additional configuration of the environment is necessary if the
209in-process sftp server is used (see
210.Cm Subsystem
211for details.
212.Pp
213The default is not to
214.Xr chroot 2 .
176.It Cm Ciphers 215.It Cm Ciphers
177Specifies the ciphers allowed for protocol version 2. 216Specifies the ciphers allowed for protocol version 2.
178Multiple ciphers must be comma-separated. 217Multiple ciphers must be comma-separated.
@@ -740,11 +779,22 @@ The default is
740Configures an external subsystem (e.g. file transfer daemon). 779Configures an external subsystem (e.g. file transfer daemon).
741Arguments should be a subsystem name and a command (with optional arguments) 780Arguments should be a subsystem name and a command (with optional arguments)
742to execute upon subsystem request. 781to execute upon subsystem request.
782.Pp
743The command 783The command
744.Xr sftp-server 8 784.Xr sftp-server 8
745implements the 785implements the
746.Dq sftp 786.Dq sftp
747file transfer subsystem. 787file transfer subsystem.
788.Pp
789Alternately the name
790.Dq internal-sftp
791implements an in-process
792.Dq sftp
793server.
794This may simplify configurations using
795.Cm ChrootDirectory
796to force a different filesystem root on clients.
797.Pp
748By default no subsystems are defined. 798By default no subsystems are defined.
749Note that this option applies to protocol version 2 only. 799Note that this option applies to protocol version 2 only.
750.It Cm SyslogFacility 800.It Cm SyslogFacility