[PATCH] Add a chroot_users option to sshd

James Dennis james at firstaidmusic.com
Tue Nov 5 04:37:34 EST 2002


http://chrootssh.sf.net
-James

On Tue, 5 Nov 2002 10:48:44 -0500
Gary Fernandez <GaryF at livevault.com> wrote:

> 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));
> 
> _______________________________________________
> openssh-unix-dev at mindrot.org mailing list
> http://www.mindrot.org/mailman/listinfo/openssh-unix-dev
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20021104/dc069008/attachment.bin 


More information about the openssh-unix-dev mailing list