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: