rsalz@uunet.uu.net (Rich Salz) (05/10/88)
Submitted-by: Dave Settle <oscar.smb.co.uk!dave> Posting-number: Volume 14, Issue 88 Archive-name: diskhog [ Be very careful before installing this... --r$ ] I'm submitting a System V disk quota system, which encourages users to keep their disk usage within a given limit. If they fail to do this, they get a restricted login shell, which only allows them to remove/backup files. Basically it consists of a check script, run once per night, and a restricted shell invoked if a user exceeds their disk quota for too long. The whole system is called 'diskhog'. P.S.: I'm leaving my job here... My mail address will continue to operate for the next couple of months. ------------------------------ CUT HERE ----------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # README # Makefile # configure # dcheck # diskhog # nohog.c # csh_hog.c # diskhog.h # allowed # dcheck.1 # diskhog.1 # nohog.1 # alternate # README.nr export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'README'" '(6529 characters)' if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' Page 1 February 10, 1988 1. Disk Quotas for System V. I've found this very useful on my system, where it encourages people to keep their disk usage down, without all the hassle of having to complain to them personally. The package runs a check each night on each user, and sends mail to those anti-social people exceeding their allowance. If, after a suitable number of warnings, these people do not remove their extra files, their next login receives a restricted shell, where the only available commands are those for removing and backing up files. You can decide on the range of commands available, and place these in the directories "/diskhog" and "/usr/diskhog", so the restricted shell can be as nasty as you like. (You could be really vicious and just have "rm", but it's probably advisable to have some commands to save to tape and/or floppies). Make sure that any shell scripts set PATH appropriately, if they use commands outside "/diskhog" and "/usr/diskhog". It counts up (using 'du') all the blocks used in the user's sub-tree, and then compares this against the allowable maximum for that user. Users with no specified maximum are assumed to have unlimited disk allocations. All the files, irrespective of owner, are counted in the user's subtree, which is perhaps a little unfair ... 2. How it works. Basically, there is a file called "allowed", which has a list of the number of disk blocks (as per "du") which each user is allowed. The format of this file is <user> <allowance> where <user> is the user's login name, and <allowance> is the maximum number of block they are allowed (as per "du"). Each night, the script "dcheck" is run from the root crontab entry, and checks each user's allowance. If the user has more than the allowance, a mail message is sent to the user asking them to remove some files. If after a certain number of days the user has not removed enough files, then a diskhog "tag" is created. The next time the user logs on, the shell notices this tag, and spawns a restricted shell via the script "diskhog". Page 2 February 10, 1988 When running via "diskhog", the user's PATH is set to "/diskhog:/usr/diskhog", so that you can restrict the commands which are available. On my system, all the commands in these directories relate to removing files, and formatting floppy disks to put them on. When the user logs out of the restricted shell, another disk check is performed, and if enough blocks have been removed, the login is allowed to proceed. If not, "diskhog" is run again. "Diskhog" is interrupt-proof, but can be killed by a SIGHUP signal (i.e. turning off the terminal). In order to prevent the user from removing the diskhog "tag" file, the tag file is placed in a directory owned by root, which is not writeable by anyone else. The tag file is removed by a special command "nohog", which is executed by "diskhog" when enough files have been removed. "Nohog" runs suid root, and is (hopefully) immune from fraud: it always removes the tag of the login user. Obviously, you should not put "nohog" in the restricted PATH, or the user would be able to remove their own diskhog tag! All you need to run disk quotas is: 1. An "allowed" file, containing disk allowances. 2. If your system has "csh", then you need to type "make csh", since csh does not have a system-wide init file. A small program is provided, which makes the relevant check, and then calls the real csh. 3. Add a line to the beginning of the file "/etc/profile" which reads: if [ -f DQUOTAS/hogs/$LOGNAME ] ; then diskhog ; fi where DQUTOAS is replaced by your disk quota admin directory (see Makefile). 4. Make yourself an entry in the root crontab, which runs the program "dcheck" sometime during the night. This will read something like: 03 01 * * * /usr/bin/dcheck to run at 01:30 am every night. Page 3 February 10, 1988 5. Check the definitions at the start of the script 'dcheck', and make sure they reflect your system. 3. Using csh with diskhog Since my "csh" doesn't have a system-wide initialisation file, it's difficult to intercept the logins of people using the c-shell. I decided to intercept /bin/csh itself, so I moved the real csh to /etc/csh, and wrote a stub program which just checks for a tag file, and calls diskhog if it finds it. Then it calls the real csh. This works fine on my system, but make sure it's not going to interfere with things on your system before you install it. 4. Watch out Watch out for people who move their stuff to another directory! 'dcheck' only checks things in the $HOME subtree. Make sure that you put a correct PATH specification in any shell scripts in '/diskhog' and '/usr/diskhog', otherwise they won't work! Have fun. Dave Settle, SMB Business Software, Thorn EMI Datasolve UUCP: dave@smb.co.uk ...!mcvax!ukc!nott-cs!smb!dave SMAIL: Voice: SMB Business Software +44 623 651651 High Street Mansfield Telex: Nottingham NG18 1ES 37392 TECSMG England Fax: +44 623 659947 SHAR_EOF if test 6529 -ne "`wc -c < 'README'`" then echo shar: "error transmitting 'README'" '(should have been 6529 characters)' fi fi echo shar: "extracting 'Makefile'" '(798 characters)' if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' # BIN=/usr/bin # directory for binaries DQUOTAS=/usr/lib/disk # directory containing all the info # SRC=README Makefile configure dcheck diskhog nohog.c csh_hog.c \ diskhog.h allowed dcheck.1 diskhog.1 nohog.1 alternate README.nr config: .config .config: sh configure @touch .config install: nohog dcheck diskhog allowed ${DQUOTAS}/hogs @echo "If your system has csh, maybe you need to 'make csh'" @echo "Try 'make -n csh' first." chown root nohog chmod 4111 nohog cp nohog ${BIN} chmod +x dcheck diskhog cp dcheck diskhog ${BIN} cp allowed ${DQUOTAS} csh: csh_hog if [ ! -f /etc/csh ] ; then mv /bin/csh /etc/csh ; fi cp csh_hog /bin/csh ${DQUOTAS}/hogs: mkdir ${DQUOTAS}/hogs shar: ${SRC} shar -cv ${SRC} > diskhog.shar README: README.nr nroff -cm README.nr > README SHAR_EOF if test 798 -ne "`wc -c < 'Makefile'`" then echo shar: "error transmitting 'Makefile'" '(should have been 798 characters)' fi fi echo shar: "extracting 'configure'" '(1606 characters)' if test -f 'configure' then echo shar: "will not over-write existing file 'configure'" else cat << \SHAR_EOF > 'configure' # # shell script to install diskhog # DQUOTAS="/usr/lib/disk" BIN="/usr/bin" echo "Hi there, just a few questions about your system ..." cat << EOF I need a place to hold all the information about disk usage and allowances. I would suggest using the directory $DQUOTAS. EOF echo "If you want a different one, enter it here: \c" read ANS if [ "$ANS" != "" ] then DQUOTAS=$ANS echo "OK, using $DQUOTAS" fi if [ -f $DQUOTAS ] then echo "Oh dear, that seems to be a file" echo "That won't do at all ..." exit 0 else if [ -d $DQUOTAS ] then echo "That directory already exists - I hope it's empty\n" else echo "Making a new directory" mkdir $DQUOTAS $DQUOTAS/hogs chmod 755 $DQUOTAS/hogs chown root $DQUOTAS/hogs fi fi cat << EOF Where do you intend to install the programs? I would suggest $BIN, but you might use another directory. EOF echo "If you want a different directory, enter it here: \c" read ANS if [ "$ANS" != "" ] then BIN=$ANS echo "OK - using $BIN" fi echo "OK - reconfiguring the system ... \c" cat << EOF > diskhog.h #define DQUOTAS "$DQUOTAS" #define BIN "$BIN" EOF ed dcheck << EOF > /dev/null /^DQUOTAS=/c DQUOTAS=$DQUOTAS # directory containing all the info -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.