                    Dial-Up Utils v2.27 for Linux and *BSD
                                by Adam McKee

Dial-Up Utils is a package designed to solve the basic problems associated with
administrating a modem pool on a Linux/*BSD system.  The functionality provided
by the package is as follows:

--- Account Management ----------------------------------------------------	

	- Automatic deletion of accounts.  Accounts may be deleted
	  automatically based on preset expiration date, or based on the
	  time since last login.
	- Subscriptions (temporarily increased access).
	- User-created accounts with call-back verification.
	- Specific users can be banned from the system temporarily or
	  indefinitely (call-back verification required).

--- Access Controls -------------------------------------------------------

	- Accounting-period time limits (i.e. time per day).
	- Session time limits.
	- Time-of-day-specific time limits.  For example, a particular user
	  can be limited to 1 hour of online time during "peak" hours.
	- Optionally, time limits can be enforced only when the system is
          busy ("Smart-Boot")
	- Optionally, at most one user may be kicked off the system per
          minute ("Boot-One").
	- User priorities.  If a choice is to be made between booting users
	  with different priorities, the user with the lowest priority will
	  be booted.  Also, as a special case, a user with priority 0 may be
	  booted even when they have time left, provided the system is busy.
	- Booting users who have been idle too long ("Idle-Boot").
	- Warning users when their time is almost up ("Warn-Boot").
	- Enforcing data transfer limits.
	- E-Mailing users to explain why they were booted ("Send-Mail").

--- Miscellaneous Utility Programs ----------------------------------------

	- Kicking a user off the system (user_kick).
	- Removing files left behind by users (clean_tmp).
	- Killing processes left behind by users (clean_proc).

--- Information Reporting -------------------------------------------------

	- Account status information is available to users.
	- Detailed account information is available to the administrator.
	- Easy report generation (user_dump + bash/Perl scripts).


Here is a quick summary of each utility:

--- Programs Used by Users ----------------------------------------------------

timeleft:
     Tells users how much time they have left before they will be
     booted from the system (i.e. all their processes killed with
     extreme prejudice ;-).


daysleft:
     Tells users how many days they have left before their account
     expires.  Upon expiration, an account may be either deleted or
     unsubscribed.

--- Programs Used by the Administrator ----------------------------------------

user_add <login>:
     Adds a new account, updating the dial-up user database as well.
     This is just a shell script that calls system-native programs to
     set up an account, then calls 'user_addrec' to create a record in the
     dial-up user database.

     NOTE: you will need to modify 'user_add' to suit your system.


user_addrec <login> <expire> <time_limit> [session_limit] [priority] [ph_no] \
	    {class_limit}:
     Creates a record in the dial-up user database.  This is normally
     called from 'user_add', and you shouldn't run it directly unless you
     know what you're doing.

	<login>:  The login name of the user to add.

	<expire>:  The expiry time for the account.  You can specify days,
		   months, or years, as follows:
			1 = 1 day, 1d = 1 day, 1m = 1 month, 1y = 1 year.
	NOTE: If <expire> = 0, the account will not be expired.
	NOTE: The 1st day/month/year will align to the end of the current
	      day/month/year.  If <expire> = 1y, for example, the account
	      will be expired at the end of the current year.

	<time_limit>:  How much time / day to give the user (in minutes).
	NOTE: if time_limit = -1, there is no time limit!

	[session_limit]:  How much time / session to give the user
			  (in minutes).  If this is not given, it defaults
			  to <time_limit>.
	NOTE: session_limit <= time_limit
	NOTE: if session_limit = -1, there is no session limit!

	[priority]:  The priority for this user (0-7, 7 being the highest).
		     If this is not given, it defaults to 4.

        [ph_no]:  The user's phone number.  If the phone number contains
		  whitespace, it must be quoted.  If "-1" is given, no phone
		  number is set.

	{class_limit}:  Up to four may be given.  The first is the limit
			(in minutes) for time class 0, the second is the
			limit for time class 1, etc...
	       o A class limit of 0 means the user will not be able to log in
                 during that time class.
	       o A class limit of -1 means the user will have no time limit
                 unique to that time class (this is the default).
	       o A class limit of -2 means the user will not have session time
	         deducted during that time class.
	       o A class limit of -3 means the user will not have session time
                 OR overall time deducted during that time class.


user_ban [-l] [-p] <expire> <login>|<phone_no>:
     Bans a phone number (or group of phone numbers).
	-l:  List all banned numbers.
        -p:  Prefix ban.  All numbers beginning with the specified prefix
             will be banned.

        <expire>:  An expiry date for the ban.  The same syntax and rules 
                   apply to <expire> here as in 'user_addrec' and others.

	<login>:  Ban a specific user.  The specified user will be kicked off
		  of the system immediately (if they are on), their account
		  deleted, and their phone number banned.  Extreme prejudice!

	NOTE:  The *first* thing you should do if you plan to use call-back
	       verification is to ban local phone numbers such as:

	       user_ban -p 0	(don't bother telco operators)
	       user_ban -p 1	(prevent long distance calls)
	       user_ban -p 911	(*definitely* don't bother 911 operators)
	       user_ban <police_dept_number>
	       user_ban <fire_dept_number>
	       <etc>

	       Of course, you won't be able to get them all...  This is the
	       draw-back of call-back verification -- there is no way to
	       totally prevent malicious people from abusing it.


user_data [login]:
     Shows a dial-up user record in a human-readable format.  If no arguments
     are given, the user record corresponding to the current uid is shown.


user_del <login>:
     Delete an account, and the associated record in the dial-up user
     database.  This is a shell script which calls other programs
     (including 'user_delrec').

     NOTE: you will need to modify 'user_del' to suit your system.


user_delrec <login>:
     Deletes a record from the dial-up user database.  This is normally
     called from 'user_del', and you shouldn't run it directly unless you
     know what you're doing.


user_dump {login}:
     Dump user records in an easily parsable format.  If login names are
     given, only those records are dumped.  Otherwise, all records are
     dumped.  'user_dump' is designed to simplify report generation.  The
     format of each line is:

<login> <ph_no> <priority> <time_left> <time_limit> <session_limit>
<data> <data_limit> <session_data_limit> <expiry_action> <expiry_date>

     NOTE: dates are in numeric (libc compatible) format.


user_expire:
     Expire accounts, subscriptions, and bans.  This should probably be run
     every day out of cron.


user_foreach <command>:
     Allows you to execute a command for each user.  If '{}' is found in the
     command, the user's login name will be substituted.  For example, to
     initialize your dial-up_users file based on your passwd file, you might
     do:

	user_foreach user_addrec \{\} 0 60

     That was the purpose I had in mind with user_foreach, but I'm sure many
     of you will find other applications for it.  :-)    

  NOTE: The '{' and '}' are escaped in order to prevent the shell from
	interpreting them specially.


user_kick <login>:
     Give a user the boot (i.e. kill all of their processes).


user_login [login]:
     Determine whether or not it is OK for a particular user to log in.
     'user_login' *must* be called whenever a user logs in or I can guarantee
     you will not like the results.  You should put the following line in the
     system-wide startup script (i.e. /etc/profile):

	user_login || logout

     Only root may specify a login name on the command line.  For non-root
     users, the uid is obtained via a call to geteuid(3).

  NOTE: If you have Smart-Boot enabled in user_updated.config, 'user_login'
        will permit a user who is out of time to login provided there is at
	least 1 free line.


user_purge <days>:
     Remove accounts which have not been used in a certain # of days.
     The <days> argument must be > 14, or the program will terminate
     with an error message.


user_renew [-c] [-d] [-t]:
     Periodically, it is necessary to renew each users's time.  This is done by
     simply calling 'user_renew' from root's crontab.  You may want to do this
     every day, every month, or not...

     -c: renew time classes (if you are making use of time classes, you should
         run "user_renew -c" every day, preferably at a time that does not fall
         within any time class.
     -d: renew data
     -t: renew time (but not time classes)

  NOTE: If no switches are given, 'user_login' will behave as though *all*
        switches were given.


user_subscribe <login> <expire> <time_limit> [session_limit] [priority] \
               {class_limit}:
     Subscribe a user.  See 'user_addrec' for a description of the
     arguments.  After a user is unsubscribed (by 'user_renew'), the
     account will be restored to its state before the subscription
     (i.e. same time limits as before).


user_sync:
     Synchronize the dial-up user file with the password file.  Any records
     with a uid field that is NOT associated with a login name in the
     password file are deleted.  Also, duplicated accounts (which, of course,
     shouldn't exist in the first place) are taken care of.  'user_sync'
     should be run periodically depending on how paranoid you happen to be.


user_time 
       <login> <expire> <time_limit> [session_limit] [priority] {class_limit}
     | <login> <+|-><SMARTBOOT>|<SSMARTBOOT>|<IBOOT>|<ISMARTBOOT>|<TCSMARTBOOT>
     | <login> <tLeft>|<tLimit>|<sLeft>|<sLimit> <+=|-=}=> <minutes>
     | <login> <cLeft>|<cLimit> <class> <+=|-=|=> <minutes>
     | <login> <bTotal>|<btLimit>|<bsLimit> <+=|-=|=> <bytes>
     | <login> priority = <priority>

     In the first usage, directly change the expiry date and time limits of
     a user.  See 'user_addrec' for a description of the arguments.

     In the second usage, flags are modified.  Flags are asserted with '+' and
     de-asserted with '-', as you might expect.

     In the third and fourth usages, specific fields are modified.  Fields may
     be incremented "+=", decremented "-=", or directly changed "=".  The
     fields are:

	tLeft	"time left"
	tLimit	"time limit"
	sLeft	"session left"
	sLimit	"session limit"
	cLeft	"class time left"
	cLimit	"class time limit"
	bTotal	"total bytes"
	btLimit	"total byte limit"
	bsLimit	"session byte limit"

  NOTE: If a user has a subscription, any changes to their record made with
        'user_time' will be undone when the subscription expires.


user_touch:
     Modify a user's "last online" field to equal the current date.  This
     is useful if you want to exempt certain users from the effects of
     'user_purge'.


user_unban <phone_no>:
     Unban a phone number previously banned with 'user_ban'.


user_unsubscribe <login>:
    Terminate a users's subscription.  This is normally called from
    'user_expire', but can be run directly.  Terminating a subscription is
    simply a matter of restoring time limits to their values before the
    subscription was given.


user_updated [-d] [-l x]:
    'user_updated' is a daemon that boots users off the system as necessary,
    and keeps user information current.  You'll probably want to have it
    started from one of your system's init scripts.  

    -d:    don't run as a daemon (normally it does).
    -l x:  set logging level - x = 0 -> no logging,
			       x = 1 -> minimal logging (default),
			       x = 9 -> maximum logging.


user_verify:
     Does call-back verification.  Allows a user to create an account after:
	- choosing a unique username.
	- choosing a legal phone number.
	- proving that it is actually their phone number.


clean_proc:
     Kills processes that, for one reason or another, were left running
     by users after they logged out.  Users can be exempted from having
     their processes killed by clean_proc (i.e. you probably don't want
     root's processes to be killed...).  You may want to run this from
     root's crontab every hour or so.


clean_tmp:
     Unlinks files in directories you specify (usually /tmp, /var/tmp, ...)
     which meet specific criteria (i.e. not owned by root, not accessed in
     the last day, ...).  If clean_tmp encounters a file with time stamp
     > the current time, it will stamp the file with the current time.  This
     is to make it more difficult to circumvent clean_tmp using 'touch'.  You
     may want to run this from root's crontab.


--- Installation Instructions -------------------------------------------------

To install Dial-Up Utils:
	- make sure you are root
	- source distribution
		BSD users: change the Makefile (you'll know what to do...)
		make dep ; make install
	- .tar.gz binary distribution:
		untar into / (*not* /usr or /usr/local or anywhere else)
		run 'ldconfig'
	- .rpm binary distribution:
		rpm -Uvh <rpm>
	- Edit /etc/profile (and/or other startup scripts...) to include a
	  call to 'user_login' as described above.
	- Edit 'user_add' and 'user_del' as required.
	- Edit configuration files and messages as required.
	- Make addition to root's crontab as outlined above to call
          'user_renew', 'user_renew -c', and 'user_expire' periodically.
        - Ensure 'user_updated' is started upon system bootup.

Other notes:

	- If your system has login names with more than 8 characters, you
	  will need to redefine MAX_LOGINCHARS in common.h to the value you
	  want and recompile the package.

	- Occasionally LOCK files will be left in /usr/lib/Dial-Up_Utils (or
	  whatever path you are using).  This is usually because a process that
          locks the dial-up_users file died an untimely death.  You may want to
	  put something like this as an hourly cron job:

    find /usr/lib/Dial-Up_Utils/ -name "LOCK*" -cmin +60 -exec rm -f "{}" \;


-------------------------------------------------------------------------------

Bug reports, and ideas for improving Dial-Up Utils will both be appreciated.
Also, feel free to let me know if the package is working great and serving
you well :-)

	- Adam McKee		<adam@broadwaynet.com>
