From 502ab0eff1bba68a1d0492a9d9da3616b0301724 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Wed, 9 Jan 2013 15:57:36 +1100 Subject: [PATCH] - djm@cvs.openbsd.org 2013/01/03 12:54:49 [sftp-server.8 sftp-server.c] allow specification of an alternate start directory for sftp-server(8) "I like this" markus@ --- ChangeLog | 4 ++++ sftp-server.8 | 16 ++++++++++++++-- sftp-server.c | 23 ++++++++++++++++++----- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 67d4884d6..ab80dca45 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,6 +19,10 @@ - djm@cvs.openbsd.org 2013/01/03 12:49:01 [PROTOCOL] fix description of MAC calculation for EtM modes; ok markus@ + - djm@cvs.openbsd.org 2013/01/03 12:54:49 + [sftp-server.8 sftp-server.c] + allow specification of an alternate start directory for sftp-server(8) + "I like this" markus@ 20121217 - (dtucker) [Makefile.in] Add some scaffolding so that the new regress diff --git a/sftp-server.8 b/sftp-server.8 index bb19c15e1..4d15f1249 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.19 2010/01/09 03:36:00 jmc Exp $ +.\" $OpenBSD: sftp-server.8,v 1.20 2013/01/03 12:54:49 djm Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: January 9 2010 $ +.Dd $Mdocdate: January 3 2013 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -31,6 +31,7 @@ .Sh SYNOPSIS .Nm sftp-server .Op Fl ehR +.Op Fl d Ar start_directory .Op Fl f Ar log_facility .Op Fl l Ar log_level .Op Fl u Ar umask @@ -56,6 +57,17 @@ for more information. .Pp Valid options are: .Bl -tag -width Ds +.It Fl d +specifies an alternate starting directory for users. +The pathname may contain the following tokens that are expanded at runtime: +%% is replaced by a literal '%', +%h is replaced by the home directory of the user being authenticated, +and %u is replaced by the username of that user. +The default is to use the user's home directory. +This option is useful in conjunction with the +.Xr sshd_config 5 +.Cm ChrootDirectory +option. .It Fl e Causes .Nm diff --git a/sftp-server.c b/sftp-server.c index 9d01c7d79..c8858147a 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.94 2011/06/17 21:46:16 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.95 2013/01/03 12:54:49 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1402,7 +1402,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) int in, out, max, ch, skipargs = 0, log_stderr = 0; ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; - char *cp, buf[4*4096]; + char *cp, *homedir = NULL, buf[4*4096]; long mask; extern char *optarg; @@ -1411,7 +1411,9 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); - while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) { + pw = pwcopy(user_pw); + + while (!skipargs && (ch = getopt(argc, argv, "d:f:l:u:cehR")) != -1) { switch (ch) { case 'R': readonly = 1; @@ -1436,6 +1438,12 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) if (log_facility == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; + case 'd': + cp = tilde_expand_filename(optarg, user_pw->pw_uid); + homedir = percent_expand(cp, "d", user_pw->pw_dir, + "u", user_pw->pw_name, (char *)NULL); + free(cp); + break; case 'u': errno = 0; mask = strtol(optarg, &cp, 8); @@ -1463,8 +1471,6 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) } else client_addr = xstrdup("UNKNOWN"); - pw = pwcopy(user_pw); - logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); @@ -1489,6 +1495,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) rset = (fd_set *)xmalloc(set_size); wset = (fd_set *)xmalloc(set_size); + if (homedir != NULL) { + if (chdir(homedir) != 0) { + error("chdir to \"%s\" failed: %s", homedir, + strerror(errno)); + } + } + for (;;) { memset(rset, 0, set_size); memset(wset, 0, set_size);