Bugzilla – Attachment 2689 Details for
Bug 2452
sshd: Add ChangeDirectory configuration directive
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch
0001-sshd-Add-ChangeDirectory-configuration-directive.patch (text/plain), 8.50 KB, created by
Étienne Buira
on 2015-08-22 17:23:08 AEST
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Étienne Buira
Created:
2015-08-22 17:23:08 AEST
Size:
8.50 KB
patch
obsolete
>From 8b5ec8eaa0cbf5c87cc313c53d2d137525593421 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?=C3=89tienne=20Buira?= <etienne.buira@gmail.com> >Date: Sat, 13 Jun 2015 13:44:45 +0200 >Subject: [PATCH] sshd: Add ChangeDirectory configuration directive > >Directive described in sshd_config (5). > >Also remove chdir warning skip code both because this can be handled >with more flexibility with this added directive and were broken since >a56086b9903b62c1c4fdedf01b68338fe4dc90e4. >--- > regress/Makefile | 5 +++-- > regress/sftp-chdir.sh | 30 ++++++++++++++++++++++++++++++ > servconf.c | 15 ++++++++++++++- > servconf.h | 2 ++ > session.c | 23 +++++++++++++++-------- > sshd_config | 1 + > sshd_config.5 | 16 +++++++++++++++- > 7 files changed, 80 insertions(+), 12 deletions(-) > create mode 100644 regress/sftp-chdir.sh > >diff --git a/regress/Makefile b/regress/Makefile >index cba83f4..395241a 100644 >--- a/regress/Makefile >+++ b/regress/Makefile >@@ -11,7 +11,7 @@ prep: > > clean: > for F in $(CLEANFILES); do rm -f $(OBJ)$$F; done >- test -z "${SUDO}" || ${SUDO} rm -f ${SUDO_CLEAN} >+ test -z "${SUDO}" || ${SUDO} rm -df ${SUDO_CLEAN} > rm -rf $(OBJ).putty > > distclean: clean >@@ -43,6 +43,7 @@ LTESTS= connect \ > scp \ > sftp \ > sftp-chroot \ >+ sftp-chdir \ > sftp-cmds \ > sftp-badcmds \ > sftp-batch \ >@@ -107,7 +108,7 @@ CLEANFILES= t2.out t3.out t6.out1 t6.out2 t7.out t7.out.pub copy.1 copy.2 \ > key.ed25519-512.pub netcat host_krl_* host_revoked_* \ > kh.* user_*key* agent-key.* known_hosts.* hkr.* > >-SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/keycommand_${USER} >+SUDO_CLEAN+= /var/run/testdata_${USER} /var/run/testlanddir_${USER}{/testdata_${USER},} /var/run/keycommand_${USER} > > # Enable all malloc(3) randomisations and checks > TEST_ENV= "MALLOC_OPTIONS=AFGJPRX" >diff --git a/regress/sftp-chdir.sh b/regress/sftp-chdir.sh >new file mode 100644 >index 0000000..46f5759 >--- /dev/null >+++ b/regress/sftp-chdir.sh >@@ -0,0 +1,30 @@ >+# $OpenBSD: sftp-chroot.sh,v 1.4 2014/01/20 00:00:30 dtucker Exp $ >+# Placed in the Public Domain. >+ >+tid="sftp in chroot with chdir" >+ >+CHROOT=/var/run >+CHDIR=testlanddir_${USER} >+CHDIROUT=${CHROOT}/${CHDIR} >+FILENAME=testdata_${USER} >+PRIVDATA=${CHDIROUT}/${FILENAME} >+ >+if [ -z "$SUDO" ]; then >+ echo "skipped: need SUDO to create file in /var/run, test won't work without" >+ exit 0 >+fi >+ >+$SUDO sh -c "mkdir -p $CHDIROUT && echo mekmitastdigoat > $PRIVDATA" || \ >+ fatal "create $PRIVDATA failed" >+ >+start_sshd -oChrootDirectory=$CHROOT -oForceCommand="internal-sftp" -oChangeDirectory=$CHDIR >+ >+verbose "test $tid: get" >+${SFTP} -S "$SSH" -F $OBJ/ssh_config host:${FILENAME} $COPY \ >+ >>$TEST_REGRESS_LOGFILE 2>&1 || \ >+ fatal "Fetch ${FILENAME} failed" >+cmp $PRIVDATA $COPY || fail "$PRIVDATA $COPY differ" >+ >+$SUDO rm $PRIVDATA >+$SUDO rmdir $CHDIROUT >+ >diff --git a/servconf.c b/servconf.c >index eb32db0..6812c94 100644 >--- a/servconf.c >+++ b/servconf.c >@@ -167,6 +167,7 @@ initialize_server_options(ServerOptions *options) > options->ip_qos_bulk = -1; > options->version_addendum = NULL; > options->fingerprint_hash = -1; >+ options->change_directory = NULL; > } > > /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ >@@ -411,7 +412,7 @@ typedef enum { > sAuthorizedKeysCommand, sAuthorizedKeysCommandUser, > sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, > sStreamLocalBindMask, sStreamLocalBindUnlink, >- sAllowStreamLocalForwarding, sFingerprintHash, >+ sAllowStreamLocalForwarding, sFingerprintHash, sChangeDirectory, > sDeprecated, sUnsupported > } ServerOpCodes; > >@@ -549,6 +550,7 @@ static struct { > { "streamlocalbindunlink", sStreamLocalBindUnlink, SSHCFG_ALL }, > { "allowstreamlocalforwarding", sAllowStreamLocalForwarding, SSHCFG_ALL }, > { "fingerprinthash", sFingerprintHash, SSHCFG_GLOBAL }, >+ { "changedirectory", sChangeDirectory, SSHCFG_ALL }, > { NULL, sBadOption, 0 } > }; > >@@ -1826,6 +1828,15 @@ process_server_config_line(ServerOptions *options, char *line, > options->fingerprint_hash = value; > break; > >+ case sChangeDirectory: >+ arg = strdelim(&cp); >+ if (!arg || *arg == '\0') >+ fatal("%s line %d: missing directory name.", >+ filename, linenum); >+ if (*activep && !options->change_directory) >+ options->change_directory = xstrdup(arg); >+ break; >+ > case sDeprecated: > logit("%s line %d: Deprecated option %s", > filename, linenum, arg); >@@ -2007,6 +2018,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) > > M_CP_STROPT(adm_forced_command); > M_CP_STROPT(chroot_directory); >+ M_CP_STROPT(change_directory); > } > > #undef M_CP_INTOPT >@@ -2281,6 +2293,7 @@ dump_config(ServerOptions *o) > o->hostbased_key_types : KEX_DEFAULT_PK_ALG); > dump_cfg_string(sPubkeyAcceptedKeyTypes, o->pubkey_key_types ? > o->pubkey_key_types : KEX_DEFAULT_PK_ALG); >+ dump_cfg_string(sChangeDirectory, o->change_directory); > > /* string arguments requiring a lookup */ > dump_cfg_string(sLogLevel, log_level_name(o->log_level)); >diff --git a/servconf.h b/servconf.h >index 606d80c..02089e1 100644 >--- a/servconf.h >+++ b/servconf.h >@@ -194,6 +194,8 @@ typedef struct { > char *auth_methods[MAX_AUTH_METHODS]; > > int fingerprint_hash; >+ >+ char *change_directory; > } ServerOptions; > > /* Information about the incoming connection as used by Match */ >diff --git a/session.c b/session.c >index 5a64715..6955737 100644 >--- a/session.c >+++ b/session.c >@@ -1670,6 +1670,7 @@ do_child(Session *s, const char *command) > char *argv[ARGV_MAX]; > const char *shell, *shell0, *hostname = NULL; > struct passwd *pw = s->pw; >+ char *landingdir; > int r = 0; > > /* remove hostkey from the child's memory */ >@@ -1784,20 +1785,26 @@ do_child(Session *s, const char *command) > } > #endif > >- /* Change current directory to the user's home directory. */ >- if (chdir(pw->pw_dir) < 0) { >- /* Suppress missing homedir warning for chroot case */ >+ /* Change current directory to landing directory (either home or >+ * set by config). */ >+ if (!options.change_directory || !strcasecmp(options.change_directory, "none")) >+ landingdir = pw->pw_dir; >+ else >+ landingdir = percent_expand(options.change_directory, >+ "h", pw->pw_dir, "u", pw->pw_name, (char*)NULL); >+ if (chdir(landingdir) < 0) { > #ifdef HAVE_LOGIN_CAP > r = login_getcapbool(lc, "requirehome", 0); > #endif >- if (r || options.chroot_directory == NULL || >- strcasecmp(options.chroot_directory, "none") == 0) >- fprintf(stderr, "Could not chdir to home " >- "directory %s: %s\n", pw->pw_dir, >- strerror(errno)); >+ fprintf(stderr, "Could not chdir to landing " >+ "directory %s: %s\n", landingdir, >+ strerror(errno)); >+ > if (r) > exit(1); > } >+ if (options.change_directory && strcasecmp(options.change_directory, "none")) >+ free(landingdir); > > closefrom(STDERR_FILENO + 1); > >diff --git a/sshd_config b/sshd_config >index cf7d8e1..e850f0d 100644 >--- a/sshd_config >+++ b/sshd_config >@@ -118,6 +118,7 @@ UsePrivilegeSeparation sandbox # Default for new installations. > #PermitTunnel no > #ChrootDirectory none > #VersionAddendum none >+#ChangeDirectory none > > # no default banner path > #Banner none >diff --git a/sshd_config.5 b/sshd_config.5 >index 5ab4318..539c229 100644 >--- a/sshd_config.5 >+++ b/sshd_config.5 >@@ -378,6 +378,17 @@ PAM or through authentication styles supported in > .Xr login.conf 5 ) > The default is > .Dq yes . >+.It Cm ChangeDirectory >+Specifies the pathname of a directory to >+.Xr chdir 2 >+to after authentication, and after entering the chroot if >+.Cm ChrootDirectory >+were specified. >+.Pp >+The pathname may contain the following tokens that are expanded at runtime once >+the connecting user has been authenticated: %% 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. > .It Cm ChrootDirectory > Specifies the pathname of a directory to > .Xr chroot 2 >@@ -388,7 +399,9 @@ checks that all components of the pathname are root-owned directories > which are not writable by any other user or group. > After the chroot, > .Xr sshd 8 >-changes the working directory to the user's home directory. >+changes the working directory to the user's home directory (by default), or >+to directory specified with >+.Cm ChangeDirectory . > .Pp > The pathname may contain the following tokens that are expanded at runtime once > the connecting user has been authenticated: %% is replaced by a literal '%', >@@ -1041,6 +1054,7 @@ Available keywords are > .Cm AuthorizedKeysFile , > .Cm AuthorizedPrincipalsFile , > .Cm Banner , >+.Cm ChangeDirectory , > .Cm ChrootDirectory , > .Cm DenyGroups , > .Cm DenyUsers , >-- >2.0.5 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 2452
: 2689