Restricted user

A few of the other employees here need to learn "vi" in order to use crontab to schedule / unschedule jobs on one of our production servers. I tried to set up a login on one of my Linux boxes for them to use "vimtutor", but scrapped it and decided to try for something more secure, since there are expect scripts on this box to aid them in some jobs on other servers, and the passwords for the various accounts / services should not be known. I am the only person with a usable interactive account on this machine. Here are the steps I took:
In /etc/lilo.conf, I added "password=*****" and "restricted" lines, so that no one could bring the box up in single-user without a password. It does, however still have a floppy and cdrom drive that could bring it up - that is one of major weaknesses now, although there are only 5 or 6 people who could get physical access to it anyways. Let's pray that works out OK :stuck_out_tongue:
I added a user (named tutor). Here is the /etc/passwd entry:
tutor:x:1009:99:vimtutor login:/home/tutor:/bin/rbash
GID 99 is "nogroup".

Here is the contents of the /home/tutor directory:

/home/tutor$ ls -lia
total 24
 163281 drwxrwx---   3 tutor    admin        4096 Apr 18 03:01 ./
 881283 drwxrwxr-x   9 root     root         4096 Apr 17 22:02 ../
 163287 -rw-r-----   1 tutor    admin           1 Apr 18 02:52 .bash_history
 163288 -r--rw----   2 tutor    admin         457 Apr 18 03:05 .bash_profile
 163288 -r--rw----   2 tutor    admin         457 Apr 18 03:05 .bashrc
 163282 d-wxrwx---   2 tutor    admin        4096 Apr 18 03:09 tmp/
/home/tutor$ lsattr -a
-------- ./.
-------- ./..
-----a-- ./.bash_history
----i--- ./.bash_profile
-------- ./tmp
----i--- ./.bashrc

The permissions allow me (I am the admin group) to watch and modify files in the directory, but disallows editing/truncating (although it allows appending) of the .bash_history file, and makes the .bash_profile/.bashrc (they are the hardlinked) immutable. Even their own tmp dir is not listable, but more on that later.

The login shell, rbash, is a restricted bash environment that will not let you execute anything with a "/" in the path from the command line (it has to be in your path), and disallows the "cd" command. It also keeps many variables used by bash read-only, locks down the hash, set, command, enable, exec, ., and enable command, and disables the use of re-directors ( > , for example).
A common problem with restricted shells is that you can typically just type "sh" to execute a new shell and effectively "break out". To prevent this, I simply set the $PATH to null... there should be no interaction with the shell anyways. rbash will, however, allow you to specify applications by full path in the startup scripts. Check out the .bash_profile/.bashrc:

PATH=""
umask 007

export PATH

# Need this so vi works with 
# stupid Windows telnet... who the hell uses "ansi" anyways?
if [ "$TERM" = "ansi" ]; then export TERM=vt100; /usr/X11R6/bin/resize; fi

tutorial () {
TUTORCOPY=/home/tutor/tmp/tutor$$
export TUTORCOPY
/usr/bin/rvim -u NONE -c 'e $VIMRUNTIME/tutor/tutor' -c 'w! $TUTORCOPY' -c 'q'
/usr/bin/rvim -u NONE -c "set nocp" $TUTORCOPY
/bin/rm -f $TUTORCOPY
}
tutorial; /usr/bin/clear; exit

I've actually set it up to run the "vimtutor" program implemented in the .bash* rather than in a seperate script - as it exits, it should clear the screen and exit the shell. Also, vim is run in restricted mode, so no shell escapes are allowed, and it ignores the ^Z sequence to background it. It should technically not allow anyone out of vim.

I figure that nothing's perfect, so to mitigate the risk of a possible "escape", I made sure that key files (.b* and tmp/) are not able to be manipulated by the user. Even if they got "out", they couldn't even "ls", although "echo * .[a-z]*" would still give them a little info...

At one point, I was going to allow limited command access to the shell via using soft-linked commands in their own personal bin/ directory with the PATH=/home/tutor/bin . I realized very quickly though, that they could fuddle their way around a little, like using cp or cat to grap a copy of /bin/sh. I suppose I could have made bin/ non-writeable by them, but once you lock it down as much as I would have, there's no point in shell access, right? Let's just save ourselves the troubles and give shell access on a per-user basis (possibly set up a large chroot'd area for restricted users).

I think I have covered all (or at least most) of my steps...

Now the challenge! Can anyone find a way to break out?
I want this to be as tight as it reasonably can without removing the functionality altogether...

Look forward to your feedback!

The shells are programming languages with considerable power, enough to reproduce most unix commands. This is why the restricted shells fail.

xxls() { while (($#)) ; do echo "$1" ; shift ; done ; }
xxcat() { while read l ; do echo "$1" ; done < $1 ; }
xxls /etc/pass*
xxcat /etc/passwd

That's already a good start and it's only the very tip of the iceberg.