[comp.sources.unix] v14i088: Quota system for non-BSD systems

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.