[PATCH] Add a chroot_users option to sshd
Gary Fernandez
GaryF at livevault.com
Wed Nov 6 02:48:44 EST 2002
This patch adds a new option to sshd, chroot_users. It has the effect of
chroot()ing incoming ssh users to their home directory. Note: this option
does not work if UsePrivilegeSeparation is enabled.
Patch is based on OpenSSH 3.4p1.
*** servconf.h@@\main\1 Tue Oct 1 17:25:32 2002
--- servconf.h Wed Oct 2 06:17:48 2002
***************
*** 131,136 ****
--- 131,137 ----
char *authorized_keys_file; /* File containing public keys */
char *authorized_keys_file2;
int pam_authentication_via_kbd_int;
+ int chroot_users;
} ServerOptions;
void initialize_server_options(ServerOptions *);
*** servconf.c@@\main\1 Tue Oct 1 17:25:26 2002
--- servconf.c Wed Oct 2 06:09:06 2002
***************
*** 122,127 ****
--- 122,128 ----
options->client_alive_count_max = -1;
options->authorized_keys_file = NULL;
options->authorized_keys_file2 = NULL;
+ options->chroot_users = -1;
/* Needs to be accessable in many places */
use_privsep = -1;
***************
*** 253,258 ****
--- 254,262 ----
if (options->authorized_keys_file == NULL)
options->authorized_keys_file =
_PATH_SSH_USER_PERMITTED_KEYS;
+ if (options->chroot_users == -1)
+ options->chroot_users = 0;
+
/* Turn privilege separation on by default */
if (use_privsep == -1)
use_privsep = 1;
***************
*** 298,304 ****
sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
! sUsePrivilegeSeparation,
sDeprecated
} ServerOpCodes;
--- 302,308 ----
sBanner, sVerifyReverseMapping, sHostbasedAuthentication,
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
! sUsePrivilegeSeparation, sChrootUsers,
sDeprecated
} ServerOpCodes;
***************
*** 375,380 ****
--- 379,385 ----
{ "clientalivecountmax", sClientAliveCountMax },
{ "authorizedkeysfile", sAuthorizedKeysFile },
{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
+ { "chrootusers", sChrootUsers },
{ "useprivilegeseparation", sUsePrivilegeSeparation},
{ NULL, sBadOption }
};
***************
*** 900,905 ****
--- 905,914 ----
case sClientAliveCountMax:
intptr = &options->client_alive_count_max;
goto parse_int;
+
+ case sChrootUsers:
+ intptr = &options->chroot_users;
+ goto parse_flag;
case sDeprecated:
log("%s line %d: Deprecated option %s",
*** session.c@@\main\1 Tue Oct 1 17:25:48 2002
--- session.c Tue Nov 5 09:59:14 2002
***************
*** 99,104 ****
--- 99,111 ----
/* original command from peer. */
const char *original_command = NULL;
+ /* option to use filesystem snapshot */
+ /* #define DO_SNAPSHOTS */
+ #ifdef DO_SNAPSHOTS
+ /* snapshot name */
+ char *snapshot = NULL;
+ #endif
+
/* data */
#define MAX_SESSIONS 10
Session sessions[MAX_SESSIONS];
***************
*** 1255,1260 ****
--- 1262,1268 ----
const char *shell, *shell0, *hostname = NULL;
struct passwd *pw = s->pw;
u_int i;
+ char *idx = NULL;
/* remove hostkey from the child's memory */
destroy_sensitive_data();
***************
*** 1274,1279 ****
--- 1282,1330 ----
do_motd();
#else /* HAVE_OSF_SIA */
do_nologin(pw);
+ #ifdef DO_SNAPSHOTS
+ #define SNAPSHOT "snapshot!"
+ if ((snapshot == NULL || (snapshot != NULL && snapshot[0] ==
'\0')) && command != NULL && !strncmp(command, SNAPSHOT, strlen(SNAPSHOT)))
{
+ idx = strchr(command, ',');
+ if (snapshot == NULL)
+ snapshot = xmalloc(128);
+ strncpy(snapshot, command+strlen(SNAPSHOT), idx -
(command + strlen(SNAPSHOT)));
+ }
+ if (snapshot != NULL && snapshot[0] != '\0') {
+ char home[MAXPATHLEN];
+ char *current;
+ current = strstr(pw->pw_dir, "current");
+ if (current != NULL) {
+ strncpy(home, pw->pw_dir, current -
pw->pw_dir);
+ home[current-pw->pw_dir] = '\0';
+ strcat(home, snapshot);
+ strcat(home, current + strlen("current") );
+ }
+ else
+ strcpy(home, pw->pw_dir);
+ if (chroot(home) < 0) {
+ fprintf(stderr, "Could not chroot to home
directory %s: %s\n",
+ home, strerror(errno));
+ strcpy(home, pw->pw_dir);
+ if (chroot(home) < 0) {
+ fprintf(stderr, "Could not chroot to
home directory %s: %s\n",
+ home, strerror(errno));
+ }
+ }
+ if (idx != NULL)
+ command = idx + 1;
+ }
+ else {
+ #endif /* DO_SNAPSHOTS */
+ if (options.chroot_users) {
+ if (chroot(pw->pw_dir) < 0) {
+ fprintf(stderr, "Could not chroot to
home directory %s: %s\n",
+ pw->pw_dir,
strerror(errno));
+ }
+ }
+ #ifdef DO_SNAPSHOTS
+ }
+ #endif
do_setusercontext(pw);
#endif /* HAVE_OSF_SIA */
}
***************
*** 1347,1353 ****
#endif /* AFS */
/* Change current directory to the user\'s home directory. */
! if (chdir(pw->pw_dir) < 0) {
fprintf(stderr, "Could not chdir to home directory %s:
%s\n",
pw->pw_dir, strerror(errno));
#ifdef HAVE_LOGIN_CAP
--- 1398,1411 ----
#endif /* AFS */
/* Change current directory to the user\'s home directory. */
! if (options.chroot_users) {
! if (chdir("/") < 0) {
! fprintf(stderr, "Could not chdir to home directory %s: %s\n",
! pw->pw_dir, strerror(errno));
! }
! }
! else {
! if (chdir(pw->pw_dir) < 0) {
fprintf(stderr, "Could not chdir to home directory %s:
%s\n",
pw->pw_dir, strerror(errno));
#ifdef HAVE_LOGIN_CAP
***************
*** 1354,1359 ****
--- 1412,1418 ----
if (login_getcapbool(lc, "requirehome", 0))
exit(1);
#endif
+ }
}
if (!options.use_login)
***************
*** 1613,1618 ****
--- 1672,1678 ----
int success = 0;
char *cmd, *subsys = packet_get_string(&len);
int i;
+ char *idx;
packet_check_eom();
log("subsystem request for %.100s", subsys);
***************
*** 1620,1625 ****
--- 1680,1697 ----
for (i = 0; i < options.num_subsystems; i++) {
if (strcmp(subsys, options.subsystem_name[i]) == 0) {
cmd = options.subsystem_command[i];
+ #ifdef DO_SNAPSHOTS
+ if (snapshot == NULL)
+ snapshot = xmalloc(128);
+ snapshot[0] = '\0';
+ if (!strncmp(cmd, SNAPSHOT, strlen(SNAPSHOT))) {
+ idx = strchr(cmd, ',');
+ strncpy(snapshot, cmd + strlen(SNAPSHOT),
+ idx - (cmd + strlen(SNAPSHOT)));
+ snapshot[idx - (cmd + strlen(SNAPSHOT))] = '\0';
+ cmd = idx + 1;
+ }
+ #endif
if (stat(cmd, &st) < 0) {
error("subsystem: cannot stat %s: %s", cmd,
strerror(errno));
More information about the openssh-unix-dev
mailing list