The following is a patch I've been working on to support a "ChrootUser" option in the sshd_config file. I was looking for a way to offer sftp access and at the same time restict interactive shell access. This patch is a necessary first step (IMO). It applies clean with 'patch -l'. Also attached is a shell script that helps to build a chrooted home dir on a RedHat 7.2 box. (I would appreciate some feedback from a core developer as to whether this looks to be a useful approach or not.) --- openssh-3.4p1.vanilla/servconf.c Mon Jun 24 23:22:04 2002 +++ openssh-3.4p1/servconf.c Wed Jul 3 11:23:26 2002 @@ -292,7 +292,7 @@ sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sStrictModes, sEmptyPasswd, sKeepAlives, sUseLogin, sAllowTcpForwarding, sCompression, - sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, + sAllowUsers, sDenyUsers, sChrootUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, sBanner, sVerifyReverseMapping, sHostbasedAuthentication, @@ -360,6 +360,7 @@ { "allowtcpforwarding", sAllowTcpForwarding }, { "allowusers", sAllowUsers }, { "denyusers", sDenyUsers }, + { "chrootusers", sChrootUsers }, { "allowgroups", sAllowGroups }, { "denygroups", sDenyGroups }, { "ciphers", sCiphers }, @@ -779,6 +780,16 @@ } break; + case sChrootUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_chroot_users >= MAX_CHROOT_USERS) + fatal( "%s line %d: too many chroot users.", + filename, linenum); + options->chroot_users[options->num_chroot_users++] + xstrdup(arg); + } + break; + case sAllowGroups: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_groups >= MAX_ALLOW_GROUPS) --- openssh-3.4p1.vanilla/servconf.h Thu Jun 20 21:09:47 2002 +++ openssh-3.4p1/servconf.h Wed Jul 3 11:23:26 2002 @@ -20,6 +20,7 @@ #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ #define MAX_DENY_USERS 256 /* Max # users on deny list. */ +#define MAX_CHROOT_USERS 256 /* Max # users on chroot list. */ #define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ @@ -104,6 +105,8 @@ char *allow_users[MAX_ALLOW_USERS]; u_int num_deny_users; char *deny_users[MAX_DENY_USERS]; + u_int num_chroot_users; + char *chroot_users[MAX_CHROOT_USERS]; u_int num_allow_groups; char *allow_groups[MAX_ALLOW_GROUPS]; u_int num_deny_groups; --- openssh-3.4p1.vanilla/session.c Wed Jun 26 09:51:06 2002 +++ openssh-3.4p1/session.c Wed Jul 3 16:29:01 2002 @@ -57,6 +57,8 @@ #include "canohost.h" #include "session.h" #include "monitor_wrap.h" +#include "match.h" +#include "readconf.h" #ifdef HAVE_CYGWIN #include <windows.h> @@ -64,6 +66,8 @@ #define is_winnt (GetVersion() < 0x80000000) #endif +#define CHROOT + /* func */ Session *session_new(void); @@ -1160,6 +1164,12 @@ do_setusercontext(struct passwd *pw) { char tty='\0'; + int i; +#ifdef CHROOT + char *new_root = "/"; + const char *hostname = NULL; + const char *ipaddr = NULL; +#endif /* CHROOT */ #ifdef HAVE_CYGWIN if (is_winnt) { @@ -1187,6 +1197,26 @@ if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); +#ifdef CHROOT + + if (options.num_chroot_users > 0) { + hostname = get_canonical_hostname(options.verify_reverse_mapping); + ipaddr = get_remote_ipaddr(); + for (i = 0; i < options.num_chroot_users; i++) { + if (match_user(pw->pw_name, hostname, ipaddr, + options.chroot_users[i])) { + if(chroot(pw->pw_dir) != 0) { + fatal("Couldn't chroot to user directory %s", + pw->pw_dir); + } + else + pw->pw_dir = new_root; + } + } + } + + +#endif /* CHROOT */ if (setgid(pw->pw_gid) < 0) { perror("setgid"); exit(1); Regards, -- John Furman -------------- next part -------------- A non-text attachment was scrubbed... Name: openssh-3.4p1-chroot-patch.tar.gz Type: application/x-gzip Size: 2616 bytes Desc: Shell script & patch tarball Url : http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20020703/b9a95ed0/attachment.bin
On Wed, Jul 03, 2002 at 05:47:44PM -0700, John Furman wrote:> + { "chrootusers", sChrootUsers },please pipe the patch through unexpand.> + if(chroot(pw->pw_dir) != 0) {please don't chroot into $HOME but a configurable (sub)directory, similar to the AuthorizedKeysFile option, e.g ChrootDir %h/public_html otherwise people start messing around with $HOME/.ssh/ or $HOME/.forward, etc. -m
On 2002-07-04, John Furman <john at venus.ark.com> wrote:> The following is a patch I've been working on to support a "ChrootUser" > option in the sshd_config file.[snip]> --- openssh-3.4p1.vanilla/session.c Wed Jun 26 09:51:06 2002 > +++ openssh-3.4p1/session.c Wed Jul 3 16:29:01 2002[snip]> @@ -1187,6 +1197,26 @@ > > if (setlogin(pw->pw_name) < 0) > error("setlogin failed: %s", strerror(errno)); > +#ifdef CHROOT > + > + if (options.num_chroot_users > 0) { > + hostname = [snip]Note that this like every(?) other chroot patch for openssh floating around (including the one I maintain) does not work on *BSD, that is, any system which has HAVE_LOGIN_CAP defined. All the chroot patches chroot between setlogin( ... ) and setgid(); initgroups();. The problem is, that code path is #ifdef'ed out where HAVE_LOGIN_CAP is set, and the following is used instead: if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { perror("unable to set user context"); exit(1); } This was first reported to me by lumpy at musicvision.com, who tried to get chroot working on a freebsd box. I have no FreeBSD or OpenBSD systems where chrooting sshd is important, so haven't spent much time testing a fix. I'm not sure if moving the chroot calls above the block in question, or simply replicating the chroot code inside both code paths is appropriate. -- Hank Leininger <hlein at progressive-comp.com>
On Thu, 4 Jul 2002 10:08 AM, Markus Friedl wrote:> > + if(chroot(pw->pw_dir) != 0) { > > please don't chroot into $HOME but a configurable (sub)directory, > similar to the AuthorizedKeysFile option, e.g > > ChrootDir %h/public_html > > otherwise people start messing around with $HOME/.ssh/ > or $HOME/.forward, etc. > > -mThanks! Here is the latest. It includes a ChrootDir option. diff -uNr openssh-3.4p1.vanilla/auth.c openssh-3.4p1/auth.c --- openssh-3.4p1.vanilla/auth.c Wed May 22 01:06:28 2002 +++ openssh-3.4p1/auth.c Thu Jul 4 21:47:31 2002 @@ -351,6 +351,12 @@ return expand_filename(options.authorized_keys_file2, pw); } +char * +chroot_dir(struct passwd *pw) +{ + return expand_filename(options.chroot_dir, pw); +} + /* return ok if key exists in sysfile or userfile */ HostStatus check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, diff -uNr openssh-3.4p1.vanilla/auth.h openssh-3.4p1/auth.h --- openssh-3.4p1.vanilla/auth.h Thu Jun 6 16:52:37 2002 +++ openssh-3.4p1/auth.h Thu Jul 4 21:47:31 2002 @@ -165,6 +165,7 @@ char *expand_filename(const char *, struct passwd *); char *authorized_keys_file(struct passwd *); char *authorized_keys_file2(struct passwd *); +char *chroot_dir(struct passwd *); int secure_filename(FILE *, const char *, struct passwd *, char *, size_t); diff -uNr openssh-3.4p1.vanilla/pathnames.h openssh-3.4p1/pathnames.h --- openssh-3.4p1.vanilla/pathnames.h Thu Jun 6 15:57:34 2002 +++ openssh-3.4p1/pathnames.h Thu Jul 4 22:20:42 2002 @@ -97,6 +97,9 @@ /* backward compat for protocol v2 */ #define _PATH_SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" +/* */ +#define _SSH_USER_CHROOT_DIR "chome" + /* * Per-user and system-wide ssh "rc" files. These files are executed with * /bin/sh before starting the shell or command if they exist. They will be diff -uNr openssh-3.4p1.vanilla/servconf.c openssh-3.4p1/servconf.c --- openssh-3.4p1.vanilla/servconf.c Mon Jun 24 23:22:04 2002 +++ openssh-3.4p1/servconf.c Thu Jul 4 21:47:31 2002 @@ -120,6 +120,7 @@ options->verify_reverse_mapping = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; + options->chroot_dir = NULL; options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; @@ -252,6 +253,8 @@ } if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + if (options->chroot_dir == NULL) + options->chroot_dir = _SSH_USER_CHROOT_DIR; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -292,12 +295,12 @@ sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sStrictModes, sEmptyPasswd, sKeepAlives, sUseLogin, sAllowTcpForwarding, sCompression, - sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, + sAllowUsers, sDenyUsers, sChrootUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, sBanner, sVerifyReverseMapping, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, + sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sChrootDir, sUsePrivilegeSeparation, sDeprecated } ServerOpCodes; @@ -360,6 +363,7 @@ { "allowtcpforwarding", sAllowTcpForwarding }, { "allowusers", sAllowUsers }, { "denyusers", sDenyUsers }, + { "chrootusers", sChrootUsers }, { "allowgroups", sAllowGroups }, { "denygroups", sDenyGroups }, { "ciphers", sCiphers }, @@ -375,6 +379,7 @@ { "clientalivecountmax", sClientAliveCountMax }, { "authorizedkeysfile", sAuthorizedKeysFile }, { "authorizedkeysfile2", sAuthorizedKeysFile2 }, + { "chrootdir", sChrootDir }, { "useprivilegeseparation", sUsePrivilegeSeparation}, { NULL, sBadOption } }; @@ -779,6 +784,16 @@ } break; + case sChrootUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_chroot_users >= MAX_CHROOT_USERS) + fatal( "%s line %d: too many chroot users.", + filename, linenum); + options->chroot_users[options->num_chroot_users++] + xstrdup(arg); + } + break; + case sAllowGroups: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_groups >= MAX_ALLOW_GROUPS) @@ -893,6 +908,10 @@ &options->authorized_keys_file2; goto parse_filename; + case sChrootDir: + charptr = &options->chroot_dir; + goto parse_filename; + case sClientAliveInterval: intptr = &options->client_alive_interval; goto parse_time; diff -uNr openssh-3.4p1.vanilla/servconf.h openssh-3.4p1/servconf.h --- openssh-3.4p1.vanilla/servconf.h Thu Jun 20 21:09:47 2002 +++ openssh-3.4p1/servconf.h Thu Jul 4 21:47:31 2002 @@ -20,6 +20,7 @@ #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ #define MAX_DENY_USERS 256 /* Max # users on deny list. */ +#define MAX_CHROOT_USERS 256 /* Max # users on chroot list. */ #define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ @@ -104,6 +105,8 @@ char *allow_users[MAX_ALLOW_USERS]; u_int num_deny_users; char *deny_users[MAX_DENY_USERS]; + u_int num_chroot_users; + char *chroot_users[MAX_CHROOT_USERS]; u_int num_allow_groups; char *allow_groups[MAX_ALLOW_GROUPS]; u_int num_deny_groups; @@ -130,6 +133,7 @@ char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; + char *chroot_dir; int pam_authentication_via_kbd_int; } ServerOptions; diff -uNr openssh-3.4p1.vanilla/session.c openssh-3.4p1/session.c --- openssh-3.4p1.vanilla/session.c Wed Jun 26 09:51:06 2002 +++ openssh-3.4p1/session.c Thu Jul 4 22:22:03 2002 @@ -57,6 +57,8 @@ #include "canohost.h" #include "session.h" #include "monitor_wrap.h" +#include "match.h" +#include "readconf.h" #ifdef HAVE_CYGWIN #include <windows.h> @@ -64,6 +66,8 @@ #define is_winnt (GetVersion() < 0x80000000) #endif +#define CHROOT + /* func */ Session *session_new(void); @@ -1160,6 +1164,14 @@ do_setusercontext(struct passwd *pw) { char tty='\0'; + int i; +#ifdef CHROOT + char *new_root = "/"; + char *new_home = NULL; + char *dir = NULL; + const char *hostname = NULL; + const char *ipaddr = NULL; +#endif /* CHROOT */ #ifdef HAVE_CYGWIN if (is_winnt) { @@ -1187,6 +1199,29 @@ if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); +#ifdef CHROOT + + if (options.num_chroot_users > 0) { + for (i = 0; i < options.num_chroot_users; i++) { + hostname = get_canonical_hostname(options.verify_reverse_mapping); + ipaddr = get_remote_ipaddr(); + if (match_user(pw->pw_name, hostname, ipaddr, + options.chroot_users[i])) { + dir = chroot_dir(pw); + new_home = dir; + xfree(dir); + if(chroot(new_home) != 0) { + fatal("Couldn't chroot to user directory %s", + new_home); + } + else + pw->pw_dir = new_root; + } + } + } + + +#endif /* CHROOT */ if (setgid(pw->pw_gid) < 0) { perror("setgid"); exit(1); Regards, -- John Furman <john at furman.net>
To: openssh-unix-dev at mindrot.org Subject: Re: Chroot patch (v3.4p1) On 4 Jul 2002 12:32:36 -0400 Hank Leininger <openssh-unix-dev at progressive-comp.com> wrote:>> The following is a patch I've been working on to support a "ChrootUser" >> option in the sshd_config file.[snip]>Note that this like every(?) other chroot patch for openssh floating around >(including the one I maintain) does not work on *BSD, that is, any system >which has HAVE_LOGIN_CAP defined. All the chroot patches chroot between[snip]>fix. I'm not sure if moving the chroot calls above the block in question, >or simply replicating the chroot code inside both code paths is >appropriate.>-- >Hank Leininger <hlein at progressive-comp.com>Your supposition is correct, Hank. I have moved the 'chroot' code above the HAVE_LOGIN_CAP/setusercontext call and corrected the issue you mention. (Took some doin' as I had to free up an OpenBSD 3.x box to test on. ;-) I have created a patch for OpenSSH-v3.4 that I will post as well. Below is a patch for v3.4p1. It supports two additional options in the sshd_config. ChrootDir - Configured as with AuthorizedKeysFile %T tokens etc... Defaults to a subdir named 'chome' relative to users home dir. ChrootUser - Configured as with AllowUsers. user1 user2 at 10.10.2.20 user3 at some.host.com ---------------------------------------------- diff -uNr openssh-3.4p1.vanilla/auth.c openssh-3.4p1/auth.c --- openssh-3.4p1.vanilla/auth.c Wed May 22 01:06:28 2002 +++ openssh-3.4p1/auth.c Wed Jul 10 23:48:11 2002 @@ -351,6 +351,12 @@ return expand_filename(options.authorized_keys_file2, pw); } +char * +chroot_dir(struct passwd *pw) +{ + return expand_filename(options.chroot_dir, pw); +} + /* return ok if key exists in sysfile or userfile */ HostStatus check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, diff -uNr openssh-3.4p1.vanilla/auth.h openssh-3.4p1/auth.h --- openssh-3.4p1.vanilla/auth.h Thu Jun 6 16:52:37 2002 +++ openssh-3.4p1/auth.h Wed Jul 10 23:48:11 2002 @@ -165,6 +165,7 @@ char *expand_filename(const char *, struct passwd *); char *authorized_keys_file(struct passwd *); char *authorized_keys_file2(struct passwd *); +char *chroot_dir(struct passwd *); int secure_filename(FILE *, const char *, struct passwd *, char *, size_t); diff -uNr openssh-3.4p1.vanilla/pathnames.h openssh-3.4p1/pathnames.h --- openssh-3.4p1.vanilla/pathnames.h Thu Jun 6 15:57:34 2002 +++ openssh-3.4p1/pathnames.h Wed Jul 10 23:48:11 2002 @@ -97,6 +97,9 @@ /* backward compat for protocol v2 */ #define _PATH_SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" +/* default user chroot directory */ +#define _SSH_USER_CHROOT_DIR "chome" + /* * Per-user and system-wide ssh "rc" files. These files are executed with * /bin/sh before starting the shell or command if they exist. They will be diff -uNr openssh-3.4p1.vanilla/servconf.c openssh-3.4p1/servconf.c --- openssh-3.4p1.vanilla/servconf.c Mon Jun 24 23:22:04 2002 +++ openssh-3.4p1/servconf.c Wed Jul 10 23:48:11 2002 @@ -120,6 +120,7 @@ options->verify_reverse_mapping = -1; options->client_alive_interval = -1; options->client_alive_count_max = -1; + options->chroot_dir = NULL; options->authorized_keys_file = NULL; options->authorized_keys_file2 = NULL; @@ -252,6 +253,8 @@ } if (options->authorized_keys_file == NULL) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; + if (options->chroot_dir == NULL) + options->chroot_dir = _SSH_USER_CHROOT_DIR; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -292,12 +295,12 @@ sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sStrictModes, sEmptyPasswd, sKeepAlives, sUseLogin, sAllowTcpForwarding, sCompression, - sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, + sAllowUsers, sDenyUsers, sChrootUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, sBanner, sVerifyReverseMapping, sHostbasedAuthentication, sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, - sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, + sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, sChrootDir, sUsePrivilegeSeparation, sDeprecated } ServerOpCodes; @@ -360,6 +363,7 @@ { "allowtcpforwarding", sAllowTcpForwarding }, { "allowusers", sAllowUsers }, { "denyusers", sDenyUsers }, + { "chrootusers", sChrootUsers }, { "allowgroups", sAllowGroups }, { "denygroups", sDenyGroups }, { "ciphers", sCiphers }, @@ -375,6 +379,7 @@ { "clientalivecountmax", sClientAliveCountMax }, { "authorizedkeysfile", sAuthorizedKeysFile }, { "authorizedkeysfile2", sAuthorizedKeysFile2 }, + { "chrootdir", sChrootDir }, { "useprivilegeseparation", sUsePrivilegeSeparation}, { NULL, sBadOption } }; @@ -779,6 +784,16 @@ } break; + case sChrootUsers: + while ((arg = strdelim(&cp)) && *arg != '\0') { + if (options->num_chroot_users >= MAX_CHROOT_USERS) + fatal( "%s line %d: too many chroot users.", + filename, linenum); + options->chroot_users[options->num_chroot_users++] + xstrdup(arg); + } + break; + case sAllowGroups: while ((arg = strdelim(&cp)) && *arg != '\0') { if (options->num_allow_groups >= MAX_ALLOW_GROUPS) @@ -893,6 +908,10 @@ &options->authorized_keys_file2; goto parse_filename; + case sChrootDir: + charptr = &options->chroot_dir; + goto parse_filename; + case sClientAliveInterval: intptr = &options->client_alive_interval; goto parse_time; diff -uNr openssh-3.4p1.vanilla/servconf.h openssh-3.4p1/servconf.h --- openssh-3.4p1.vanilla/servconf.h Thu Jun 20 21:09:47 2002 +++ openssh-3.4p1/servconf.h Wed Jul 10 23:48:11 2002 @@ -20,6 +20,7 @@ #define MAX_ALLOW_USERS 256 /* Max # users on allow list. */ #define MAX_DENY_USERS 256 /* Max # users on deny list. */ +#define MAX_CHROOT_USERS 256 /* Max # users on chroot list. */ #define MAX_ALLOW_GROUPS 256 /* Max # groups on allow list. */ #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ @@ -104,6 +105,8 @@ char *allow_users[MAX_ALLOW_USERS]; u_int num_deny_users; char *deny_users[MAX_DENY_USERS]; + u_int num_chroot_users; + char *chroot_users[MAX_CHROOT_USERS]; u_int num_allow_groups; char *allow_groups[MAX_ALLOW_GROUPS]; u_int num_deny_groups; @@ -130,6 +133,7 @@ char *authorized_keys_file; /* File containing public keys */ char *authorized_keys_file2; + char *chroot_dir; int pam_authentication_via_kbd_int; } ServerOptions; diff -uNr openssh-3.4p1.vanilla/session.c openssh-3.4p1/session.c --- openssh-3.4p1.vanilla/session.c Wed Jun 26 09:51:06 2002 +++ openssh-3.4p1/session.c Fri Jul 12 15:37:58 2002 @@ -57,6 +57,8 @@ #include "canohost.h" #include "session.h" #include "monitor_wrap.h" +#include "match.h" +#include "readconf.h" #ifdef HAVE_CYGWIN #include <windows.h> @@ -64,6 +66,10 @@ #define is_winnt (GetVersion() < 0x80000000) #endif +#ifndef HAVE_CYGWIN +#define CHROOT +#endif + /* func */ Session *session_new(void); @@ -1169,6 +1175,38 @@ #ifdef HAVE_SETPCRED setpcred(pw->pw_name); #endif /* HAVE_SETPCRED */ +#ifdef CHROOT + int i; + char *new_root = "/"; + char *new_home = NULL; + char *dir = NULL; + const char *hostname = NULL; + const char *ipaddr = NULL; + + if (options.num_chroot_users > 0) { + hostname = get_canonical_hostname(options.verify_reverse_mapping); + ipaddr = get_remote_ipaddr(); + for (i = 0; i < options.num_chroot_users; i++) { + if (match_user(pw->pw_name, hostname, ipaddr, + options.chroot_users[i])) { + dir = chroot_dir(pw); + new_home = dir; + xfree(dir); + if(chdir(new_home) == -1) + fatal("chdir to %s failed: %s", + new_home, strerror(errno)); + if(chroot(new_home) == -1) { + fatal("chroot to %s failed: %s", + new_home, strerror(errno)); + } + else + pw->pw_dir = new_root; + } + } + } + + +#endif /* CHROOT */ #ifdef HAVE_LOGIN_CAP #ifdef __bsdi__ setpgid(0, 0); -------------------------------- Regards, -- John Furman <john at furna.net>