feature request & patch submit: chroot(2) in sshd

Birger Toedtmann birger at takatukaland.de
Tue Oct 24 19:48:30 EST 2000


Hello,

whereas most people take passwd/shadow/ldap/<whatever> as the place where 
decision on a chrooted environment / sandbox for certain users is met (just
set the given usershell appropriateley), I needed a somewhat different 
approach. Below is a tiny patch to 2.2.0p1 which enhances the sshd-config
by two options and, when set, places all users / users of a certain group
immediately in their sandbox. Makes configuration and logging/tracking
much more fun than the usershell thing mentioned above, me thinks.

TODO: - parse gid in config as well, not only gidnumber
      - negation of chrootgroup in config desireable, e.g. place alle users
        !0 in a chroot envir.
      - more than one chrootgroup in config desireable
      - combinations of all above should be possible

TODO-MAKE: - as accustomed only to linux,freebsd,sunos/solaris and hpux,
             I do not quite know wether chroot(2) is working on all unices.
             Maybe #ifdefs and ./configure-guessings have to be included.

Regards,

-- 
  Birger Tödtmann
  Network/Security Engineer
  Marcant Internet Services GmbH, Bielefeld, Germany.
  00 83 E2 57 EC 60 0B 1C  D3 18 AE 2A 40 55 81 22
-------------- next part --------------
Only in openssh-2.2.0p1chroot: auth1.c.orig
Common subdirectories: openssh-2.2.0p1/contrib and openssh-2.2.0p1chroot/contrib
Only in openssh-2.2.0p1chroot: enssh-2.2.0p1chroot2.patch
diff --ignore-space-change -u openssh-2.2.0p1/servconf.c openssh-2.2.0p1chroot/servconf.c
--- openssh-2.2.0p1/servconf.c	Fri Aug 18 05:59:06 2000
+++ openssh-2.2.0p1chroot/servconf.c	Sun Oct 22 18:59:49 2000
@@ -68,6 +68,8 @@
 #endif
 	options->permit_empty_passwd = -1;
 	options->use_login = -1;
+	options->use_chroot = -1;
+	options->chroot_group = -1;
 	options->num_allow_users = 0;
 	options->num_deny_users = 0;
 	options->num_allow_groups = 0;
@@ -158,6 +160,10 @@
 		options->permit_empty_passwd = 0;
 	if (options->use_login == -1)
 		options->use_login = 0;
+	if (options->use_chroot == -1)
+		options->use_chroot = 0;
+	if (options->chroot_group == -1)
+		options->chroot_group = 0;
 	if (options->protocol == SSH_PROTO_UNKNOWN)
 		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
 	if (options->gateway_ports == -1)
@@ -189,6 +195,7 @@
 	sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
 	sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
 	sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
+	sUseChroot, sChrootGroup,
 	sIgnoreUserKnownHosts, sHostDSAKeyFile, sCiphers, sProtocol, sPidFile,
 	sGatewayPorts, sDSAAuthentication, sXAuthLocation, sSubsystem, sMaxStartups
 } ServerOpCodes;
@@ -236,6 +243,8 @@
 	{ "strictmodes", sStrictModes },
 	{ "permitemptypasswords", sEmptyPasswd },
 	{ "uselogin", sUseLogin },
+	{ "usechroot", sUseChroot },
+	{ "chrootgroup", sChrootGroup },
 	{ "randomseed", sRandomSeedFile },
 	{ "keepalive", sKeepAlives },
 	{ "allowusers", sAllowUsers },
@@ -540,6 +549,14 @@
 		case sUseLogin:
 			intptr = &options->use_login;
 			goto parse_flag;
+
+		case sUseChroot:
+			intptr = &options->use_chroot;
+			goto parse_flag;
+
+		case sChrootGroup:
+			intptr = &options->chroot_group;
+			goto parse_int;
 
 		case sGatewayPorts:
 			intptr = &options->gateway_ports;
diff --ignore-space-change -u openssh-2.2.0p1/servconf.h openssh-2.2.0p1chroot/servconf.h
--- openssh-2.2.0p1/servconf.h	Fri Aug 18 05:59:06 2000
+++ openssh-2.2.0p1chroot/servconf.h	Sun Oct 22 18:59:49 2000
@@ -87,6 +87,9 @@
 	int     permit_empty_passwd;	/* If false, do not permit empty
 					 * passwords. */
 	int     use_login;	/* If true, login(1) is used */
+	int     use_chroot;      /* If true, do a chroot to homedir */
+	int     chroot_group;      /* If nonzero, chroot only when equal 
+				      to gid */
 	unsigned int num_allow_users;
 	char   *allow_users[MAX_ALLOW_USERS];
 	unsigned int num_deny_users;
diff --ignore-space-change -u openssh-2.2.0p1/session.c openssh-2.2.0p1chroot/session.c
--- openssh-2.2.0p1/session.c	Wed Aug 30 00:21:22 2000
+++ openssh-2.2.0p1chroot/session.c	Sun Oct 22 20:20:57 2000
@@ -947,6 +947,20 @@
 		}
 	}
 #endif /* USE_PAM */
+
+	/* Do a chroot, if configured. */
+	if (options.use_chroot) {
+	  	if ((!options.chroot_group)
+	      			|| (options.chroot_group == pw->pw_gid)) {
+	    		debug("Doing chroot to %s.",pw->pw_dir);
+	    		if (chroot(pw->pw_dir)) {
+	      			log("Requested chroot failed: [%d] %s\n",
+		  		errno,strerror(errno));
+	      			exit(1);
+	    		}
+	    		pw->pw_dir = "/";
+	  	}
+	}
 
 	/* Set login name, uid, gid, and groups. */
 	/* Login(1) does this as well, and it needs uid 0 for the "-h"
Only in openssh-2.2.0p1chroot: session.c~
diff --ignore-space-change -u openssh-2.2.0p1/sshd.8 openssh-2.2.0p1chroot/sshd.8
--- openssh-2.2.0p1/sshd.8	Tue Aug 29 02:33:51 2000
+++ openssh-2.2.0p1chroot/sshd.8	Sun Oct 22 18:59:49 2000
@@ -290,6 +290,15 @@
 Only user names are valid; a numerical user ID isn't recognized.
 By default login is allowed regardless of the user name.
 .Pp
+.It Cm ChrootGroup
+Only useful when
+.Cm UseChroot
+is set to
+.Dq yes . 
+Specifies which group of users
+.Nm sshd
+should drop into a chrooted homedir (a.k.a. sandbox) upon login. 
+Only numerical gid's are allowed.
 .It Cm Ciphers
 Specifies the ciphers allowed for protocol version 2.
 Multiple ciphers must be comma-separated.
@@ -597,6 +606,12 @@
 The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
 LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
 The default is AUTH.
+.It Cm UseChroot
+Do a chroot(2) into the users homedirectory after successful login.
+If option
+.Cm ChrootGroup
+is not set, this applies for all users. The default is
+.Dq no .
 .It Cm UseLogin
 Specifies whether
 .Xr login 1


More information about the openssh-unix-dev mailing list