[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [off-topic?] Chrooting ssh/telnet users?



well give credit to it to Vasil Kolev
/home/image.root is an image of what you want your users to have.


	   Ivan Dimitrov
	System Administrator
	  Bastun Networks

On Sat, 27 Oct 2001, Javier [iso-8859-1] Fernández-Sanguino Peña wrote:

>
> 	I would be interested only in the chroot patch. Is there any
> reason you have not contributed it to openssh? Do you want me to do it?
>
> 	Best regards
>
> 	Javi
>
> On Fri, Oct 26, 2001 at 05:24:13PM +0300, Ivan Dimitrov wrote:
> > recently i've worked on a small patch for openssh that chroots a user when
> > he logs in. it uses mysql for password auth. it is not posted anyware but
> > if you want it, send me a personal mail.
> >
> >
> > 	   Ivan Dimitrov
> > 	System Administrator
> > 	  Bastun Networks
> >
>
>
> --
> To UNSUBSCRIBE, email to debian-security-request@lists.debian.org
> with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
>
--- orig-session.h      Thu Oct 11 17:57:08 2001
+++ session.h   Thu Oct 11 15:41:11 2001
@@ -32,5 +32,6 @@
 void   session_input_channel_req(int id, void *arg);
 void   session_close_by_pid(pid_t pid, int status);
 void   session_close_by_channel(int id, void *arg);
+#define AM_CHROOT

 #endif
--- orig-session.c	Thu Oct 11 17:53:53 2001
+++ session.c	Fri Oct 12 15:38:24 2001
@@ -93,6 +93,12 @@
 # include <uinfo.h>
 #endif
 
+
+#ifdef AM_CHROOT
+#include <sys/file.h>
+#endif
+
+
 /* types */
 
 #define TTYSZ 64
@@ -162,6 +168,71 @@
 static login_cap_t *lc;
 #endif
 
+
+
+#ifdef AM_CHROOT
+/*
+  system() by W.Richard Stevens
+ */
+
+
+int
+system(const char *cmdstring)	/* with appropriate signal handling */
+{
+	pid_t				pid;
+	int					status;
+	struct sigaction	ignore, saveintr, savequit;
+	sigset_t			chldmask, savemask;
+
+	if (cmdstring == NULL)
+		return(1);		/* always a command processor with Unix */
+
+	ignore.sa_handler = SIG_IGN;	/* ignore SIGINT and SIGQUIT */
+	sigemptyset(&ignore.sa_mask);
+	ignore.sa_flags = 0;
+	if (sigaction(SIGINT, &ignore, &saveintr) < 0)
+		return(-1);
+	if (sigaction(SIGQUIT, &ignore, &savequit) < 0)
+		return(-1);
+
+	sigemptyset(&chldmask);			/* now block SIGCHLD */
+	sigaddset(&chldmask, SIGCHLD);
+	if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
+		return(-1);
+
+	if ( (pid = fork()) < 0) {
+		status = -1;	/* probably out of processes */
+
+	} else if (pid == 0) {			/* child */
+			/* restore previous signal actions & reset signal mask */
+		sigaction(SIGINT, &saveintr, NULL);
+		sigaction(SIGQUIT, &savequit, NULL);
+		sigprocmask(SIG_SETMASK, &savemask, NULL);
+
+		execl("/bin/sh", "sh", "-c", cmdstring, (char *) 0);
+		_exit(127);		/* exec error */
+	} else {						/* parent */
+		while (waitpid(pid, &status, 0) < 0)
+			if (errno != EINTR) {
+				status = -1; /* error other than EINTR from waitpid() */
+				break;
+			}
+	}
+
+		/* restore previous signal actions & reset signal mask */
+	if (sigaction(SIGINT, &saveintr, NULL) < 0)
+		return(-1);
+	if (sigaction(SIGQUIT, &savequit, NULL) < 0)
+		return(-1);
+	if (sigprocmask(SIG_SETMASK, &savemask, NULL) < 0)
+		return(-1);
+
+	return(status);
+}
+
+#endif
+
+
 void
 do_authenticated(Authctxt *authctxt)
 {
@@ -1049,6 +1120,12 @@
 #endif /* WITH_IRIX_ARRAY */
 #endif /* WITH_IRIX_JOBS */
 
+#ifdef AM_CHROOT
+	char *mounting,*buff;
+        int fd0,n,num;
+#endif
+
+
 	/* remove hostkey from the child's memory */
 	destroy_sensitive_data();
 
@@ -1127,6 +1204,79 @@
 			 */
 			do_pam_setcred(0);
 #  endif /* USE_PAM */
+#  ifdef AM_CHROOT
+			if (pw->pw_gid == 888)
+			{
+				mounting=(char *) malloc(1024);
+                                snprintf(mounting,1024,"/var/run/sshd/%s.mount",pw->pw_name);
+				fd0=open(mounting,O_RDWR|O_CREAT|O_EXCL,S_IRUSR |S_IWUSR);
+				if ( chdir("/home/sessions")!=0)
+				{
+				    perror("Chdir to session dir failed");
+				    exit(1);
+				}
+				if(fd0 != -1 )
+				{
+					flock(fd0,LOCK_EX);
+                                        write(fd0,"1",1);
+                                        flock(fd0,LOCK_UN);
+					close(fd0);
+
+
+					if ( (mkdir(pw->pw_name,0755)==-1) && (errno!=EEXIST) )
+					{
+						perror("session mkdir");
+                                                exit(1);
+					}
+					snprintf(mounting,1024,"mount -o loop,ro,sync /home/image.root /home/sessions/%s",pw->pw_name);
+					if (system(mounting)!=0)
+					{
+						perror("mount0");
+                                                exit(1);
+					}
+					snprintf(mounting,1024,"mount --bind /home/users/%s /home/sessions/%s/home",pw->pw_name,pw->pw_name);
+					if (system(mounting)!=0)
+					{
+						perror("mount1");
+                                                exit(1);
+					}
+
+
+				} else
+				{
+					fd0=open(mounting,O_RDWR|O_CREAT,S_IRUSR |S_IWUSR);
+					flock(fd0,LOCK_EX);
+					buff=(char *) malloc(30);
+					n=read(fd0,buff,20);
+					*(buff+n+1)=0;
+					num=atoi(buff);
+					num++;
+					snprintf(buff,20,"%d",num);
+                                        lseek(fd0,0,SEEK_SET);
+                                        write(fd0,buff,strlen(buff));
+					free(buff);
+					flock(fd0,LOCK_UN);
+
+				}
+
+				chdir(pw->pw_name);
+				free(pw->pw_dir);
+				pw->pw_dir=strdup("/home");
+
+				if (chroot(".")!=0)
+				{
+					perror("chroot");
+                                        exit(1);
+				}
+				free(mounting);
+
+			}
+
+
+
+#  endif /* AM_CHROOT */
+
+
 #  ifdef WITH_IRIX_JOBS
 			jid = jlimit_startjob(pw->pw_name, pw->pw_uid, "interactive");
 			if (jid == -1) {
@@ -1859,6 +2009,53 @@
 void
 session_pty_cleanup(Session *s)
 {
+#ifdef AM_CHROOT
+	char *temp;
+	int fd0,n,num;
+	struct passwd * pw = s->pw;
+        char *buff;
+
+	if (s == NULL )
+                return;
+	temp=(char *) malloc(1024);
+	chroot("../../../");
+	snprintf(temp,1024,"/var/run/sshd/%s.mount",pw->pw_name);
+	fd0=open(temp,O_RDWR);
+	if (fd0!=-1 )
+	{
+		flock(fd0,LOCK_EX);
+
+                buff=(char *) malloc(30);
+                n=read(fd0,buff,20);
+                *(buff+n+1)=0;
+                num=atoi(buff);
+
+		num--;
+		if (num==0)
+		{
+
+			snprintf(temp,1024,"logger \"uid %d gid %d temp %s \"",getuid(),getgid(),strerror(errno));
+			system(temp);
+			snprintf(temp,1024,"umount /home/sessions/%s/home",pw->pw_name);
+			system(temp);
+			snprintf(temp,1024,"umount /home/sessions/%s",pw->pw_name);
+			system(temp);
+			chdir("/home/sessions/");
+			rmdir(pw->pw_name);
+			snprintf(temp,1024,"/var/run/sshd/%s.mount",pw->pw_name);
+			unlink(temp);
+
+		}
+		snprintf(buff,20,"%d",num);
+                lseek(fd0,0,SEEK_SET);
+                write(fd0,buff,strlen(buff));
+		free(buff);
+		flock(fd0,LOCK_UN);
+		close(fd0);
+		free(temp);
+	}
+#endif
+
 	if (s == NULL || s->ttyfd == -1)
 		return;
 

Reply to: