For this discussion, the project name is testproject /usr/sbin/useradd cvs mkdir -p /home/cvs/cvsroot chown cvs.cvs /home/cvs/cvsroot chmod 700 /home/cvs/cvsroot cd /home/cvs/cvsroot mkdir bin dev etc tmp chown cvs.cvs bin dev etc tmp chmod 555 bin dev etc cvs -d /home/cvs/cvsroot/testproject init chown -R cvs.cvs testproject cd dev mknod null c 1 3 chown 0.0 null chmod 666 null cd /usr/local lynx http://ftp.cvshome.org/cvs-1.11.1/cvs-1.11.1p1.tar.gz tar zxvf cvs-1.11.1p1.tar.gz cd cvs-1.11.1p1 ./configure --disable-client cd src vi Makefile and add -Xlinker -static to the LDFLAGS line (NOT the cvs_LDFLAGS line) cd .. make cp src/cvs /home/cvs/cvsroot/bin cd /home/cvs/cvsroot chown cvs.cvs bin/cvs chmod 500 bin/cvs cd testproject/CVSROOT vi passwd Add a line of the form: login:encryptedpassword:cvs for each user where encryptedpassword is copied out of /etc/shadow vi writers Add the line of the form: login for every developer who will have the write access to the project. chown cvs.cvs passwd chown cvs.cvs writers cd /tmp vi run-cvs.c and add this content: #include #include /* change these values to suit your setup */ #define BASE "/home/cvs/cvsroot" #define OWNER_UID 513 /* Set this to the first number in the result of grep cvs /etc/passwd */ #define OWNER_GID 513 /* Set this to the first number in the result of grep cvs /etc/group */ int main(int argc, char *argv[]) { int res; res = chdir(BASE); if ( res ) exit(1); res = chroot(BASE); if ( res ) exit(2); res = setgid(OWNER_GID); if ( res ) exit(3); res = setuid(OWNER_UID); if ( res ) exit(4); /* there should be --allow-root string for every repository you are going to allow access to */ execl("/bin/cvs", "cvs", "--allow-root=/testproject", "pserver", NULL); exit(3); } gcc -o run-cvs run-cvs.c mkdir /home/cvs/sbin cp run-cvs /home/cvs/sbin vi /etc/services and add this line: cvssshpserver 2410/tcp # CVS over SSH pserver vi /etc/xinetd.d/cvssshpserver and add these lines: service cvssshpserver { socket_type = stream protocol = tcp user = root server = /home/cvs/sbin/run-cvs server_args = run-cvs type = UNLISTED wait = no } unset HOME /etc/init.d/xinetd restart cd /tmp vi zzh.c and add this content: /* * zzh.c * * Shell for the "SSH Sleeping Beauty" user. * * (c) 1999, Tim Hemel * * $Id: zzh.c,v 1.1 1999/02/19 14:57:46 tim Exp $ */ #include #include #include #include #include #include #include #include /* Timeout in seconds */ const int ZZZ = 10*60; #define MAX_CMD_LEN 255 char cmd[MAX_CMD_LEN+1]; /* simple commandline parsing */ void parse_opt(int argc, char *argv[]) { int i,done; done = 0; for (i=0; (i0 ) { /* set up a file descriptor set for select() */ FD_ZERO(&fs); FD_SET(fd,&fs); /* set the ZZZ second timeout */ to.tv_sec = ZZZ; /* wait for input and do nothing with it */ if (select(fd+1, &fs, 0, 0, &to)>0) { /* lseek(fd,0,SEEK_END); /* not necessary */ } } /* remove the temporary file */ unlink(fn); } } else /* cmd != "" && cmd != "open" */ { /* see if a file named cmd exists and is a named pipe */ if (!stat(cmd,&sb)) { if(sb.st_mode & S_IFIFO) { /* write to it */ fd = open(cmd,O_WRONLY); if (fd > 0) { write(fd, "wake up", 1); } } } else { perror("stat"); } } /* return 0; */ exit(0); } gcc -o zzh zzh.c This will report this message, ignore it: the use of `tmpnam' is dangerous, better use `mkstemp' mkdir /home/cvs/bin cp zzh /home/cvs/bin vipw Navigate to the line starting with cvs and change the /bin/bash to /home/cvs/bin/zzh Hit ZZ to exit. Answer y to editing the shadow file and remove the !! symbols between the first two colons. vi /etc/ssh/sshd_config and set the line: PermitEmptyPasswords yes /etc/init.d/sshd restart