Listing 1: Human

#!/bin/bash -
#----------------------------- H U M A N -------------------------------#
#
# This is a set of bash scripts to maintain and manage users on a 
# commercial computing site, for example an Internet provider.
# Human (Happy User MANager) provides the following functions:
#	- Adding usernames;
#	- Removing usernames;
#	- Disabling and enabling usernames;
#	- Displaying/modifying usernames data;
#	- Activating and deactivating username subscription;
#	- Managing username and subscription reports.
# Human uses standard /etc/passwd file plus other passwd-style files 
# containing various informations: see man pages for details.
#
# LICENSE INFORMATION
# Human is licensed under standard GNU Public License practices: 
# distribution is free provided that this License Information is supplied 
# with the code.
# (c) 1995 Luca Salvadori <lsalvadori@batman.laben.it>
#
# REGISTRATION
# Due to the above licensing policy, no registration is formally needed.
# But, only to know where human is in use and to get more information about
# its efficiency and usefulness, peoples are strongly encouraged to send
# an email with brief information on site and systems human is installed on.
# Any registered user will receive upgrade and development status 
# information.
# Registration address: Human Information <human-info@batman.laben.it>.
#
# BUGS AND SUGGESTIONS
# Please report any bug or suggestion to the development team coordinator:
# Luca Salvadori <lsalvadori@batman.laben.it>.
#
# HISTORY
# v0.0 08-Mar-95 Luca Salvadori <lsalvadori@batman.laben.it>
#	Basic functions and archive definition.
# v0.1 20-Apr-95 Luca Salvadori <lsalvadori@batman.laben.it>
#	Username modify functions added.
#	Subscription management functions added.
#	Reporting options added.
#	Dafault values in input screens added.
#	Man page added (ASCII format).
#
#----------------------------------------------------------------------#


#--------------------- I N I T I A L I Z A T I O N --------------------#

#
# Local variables definitions: put your localizations here.
#
# Default man page for the application.
MANPAGE="human"
# Default passwd file.
PASSWD="/usr/root/human/passwd"
# Default exclusion passwd file. It stores usernames (or regular expressions)
# to be excluded from username selection (i.e. system accounts, ftp etc.).
PASSWD_EXCL="/usr/root/human/passwd.excl"
# Default passwd.addr file. It stores usernames' address data.
PASSWD_ADDR="/usr/root/human/passwd.addr"
# Default passwd.subs file. It stores usernames' subscription data.
PASSWD_SUBS="/usr/root/human/passwd.subs"
# Default subscription data file. It stores subscription type codes.
SUBSDATA="/usr/root/human/subs_type.dat"
# Trusted user allowed to execute procedure for security reasons.
TRUSTEDUSER="root"
# Default gid for new users to be created.
DEFGID="100"
# Default homedir for new users to be created.
DEFHOME="/home"
# Default shell for new users to be created.
DEFSHELL="/bin/bash"
# Default country for new users to be created.
DEFCOUNTRY="Italy"
# Default skel files directory for new usernames.
SKELDIR="/etc/skel"

#-------------- E N D  O F  I N I T I A L I Z A T I O N ---------------#


#----------------------- S U B R O U T I N E S ------------------------#

# CLEANUP - Here we go at the end or if some SIG is received.
cleanup() {
ERR=${?}
rm *.$$ 2>/dev/null
exit ${ERR}
} # End of cleanup() subroutine.

# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15

# LOCKUSER - Locks selected users.
lockuser() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
dialog --title "Locking Users" --infobox \
"Locking username $1. Please wait..." 4 50
oldpassword=`grep ^$1: $PASSWD | cut -d":" -f2`
if [ `echo $oldpassword | cut -c1-5` = "#LCK#" ]
then
	dialog --title "WARNING!" --msgbox \
	"Username $1 is already locked." 4 50
	newpassword=$oldpassword
else
	newpassword="#LCK#$oldpassword"
fi
ed -s $PASSWD << !
/^$1:/s/:$oldpassword:/:$newpassword:/
w
q
!
return
} # End of lockuser() subroutine.

# UNLOCKUSER - Unlocks selected users.
unlockuser() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
dialog --title "Unlocking Users" --infobox \
"Unlocking username $1. Please wait..." 4 50
oldpassword=`grep ^$1: $PASSWD | cut -d":" -f2`
if [ `echo $oldpassword | cut -c1-5` = "#LCK#" ]
then
	newpassword=`echo $oldpassword | tr -d "^#LCK#"`
else
	dialog --title "WARNING!" --msgbox \
	"Username $1 is not locked." 4 50
	newpassword=$oldpassword
fi
ed -s $PASSWD << !
/^$1:/s/:$oldpassword:/:$newpassword:/
w
q
!
return
} # End of unlockuser() subroutine.

# GETPDATA - Asking username's personal data.
getpdata() {
# Asking for real name.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter real name [${UREALNAME}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UREALNAME=${TEMP:-${UREALNAME}}
# Asking for address.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter street address [${USTREET}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
USTREET=${TEMP:-${USTREET}}
# Asking for ZIP code.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter ZIP Code [${UZIPCODE}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UZIPCODE=${TEMP:-${UZIPCODE}}
# Asking for city.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter City [${UCITY}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UCITY=${TEMP:-${UCITY}}
# Asking for state.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter State [${USTATE}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
USTATE=${TEMP:-${USTATE}}
# Asking for country.
UCOUNTRY=${UCOUNTRY:-${DEFCOUNTRY}}
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter Country [${UCOUNTRY}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UCOUNTRY=${TEMP:-${UCOUNTRY}}
# Asking for telephone number.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter phone number [${UPHONE}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UPHONE=${TEMP:-${UPHONE}}
# Asking for FAX number.
dialog --title "${1}'s PERSONAL DATA" \
--inputbox "Enter FAX number [${UFAX}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UFAX=${TEMP:-${UFAX}}
return
} # End of getpdata() subroutine.

# GETSDATA - Asking username's system data.
getsdata() {
# Asking for home directory.
UHOMEDIR=${UHOMEDIR:-${DEFHOME}/${1}}
dialog --title "${1}'s SYSTEM DATA" \
--inputbox "Enter Home Directory [${UHOMEDIR}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UHOMEDIR=${TEMP:-${UHOMEDIR}}
# Asking for default shell.
USHELL=${USHELL:-${DEFSHELL}}
dialog --title "${1}'s SYSTEM DATA" \
--inputbox "Enter default shell [${USHELL}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
USHELL=${TEMP:-${USHELL}}
# Asking for gid.
UGID=${UGID:-${DEFGID}}
dialog --title "${1}'s SYSTEM DATA" \
--inputbox "Enter group id [${UGID})]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UGID=${TEMP:-${UGID}}
# Asking for uid in selected group.
# Defining first free uid in selected group.
DEFUID=`grep :[0-9].*:${UGID}: ${PASSWD} | cut -d":" -f3 | sort -n -u | tail -1`
DEFUID=`expr ${DEFUID} + 1`
UUID=${UUID:-${DEFUID}}
dialog --title "${1}'s SYSTEM DATA" \
--inputbox "Enter user id [${UUID}]:" 10 55 2>newuser.$$ 
TEMP=`cat newuser.$$ ; rm newuser.$$`
UUID=${TEMP:-${UUID}}
return
} # End of getsdata() subroutine.

# SELECTUSER - Selects users to act on.
selectuser() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
# Creating selection menu script.
echo -e "#! /bin/bash - \n\
# Selection menu \n\
dialog --title \"SELECT USERNAMES TO $1\" \\
--checklist \"Use Arrow Keys to move. Select/deselect usernames with SPACE BAR.\" 20 75 11 \\" > selectmenu.$$
# Extracting usernames from passwd file, excluding the ones contained in
# exclusion file (if any and not empty).
# If file is empty $FILE is set to null string.
FILE=`head -1 ${PASSWD_EXCL} 2>/dev/null | tr -d " "`
# If $FILE is null, set it to EMPTY.
FILE=${FILE:-EMPTY}
if [ -f ${PASSWD_EXCL} -a ${FILE} != "EMPTY" ]
then
	# Executing egrep on passwd file to exclude username values.
	cat $PASSWD | egrep -v -f ${PASSWD_EXCL} | cut -d":" -f1,5 > $PASSWD.$$
else
	# Take file as is.
	cat $PASSWD | cut -d":" -f1,5 > $PASSWD.$$
fi
# Append list to selection menu script.
cat $PASSWD.$$ | \
sed "
s/^/\"/
s/:/\" \"/
s/$/\" \"off\" \\\/
 " >> selectmenu.$$ 
echo -e "\n" >> selectmenu.$$
# Executing newly created main menu
sh selectmenu.$$ 2>selectmenu.err.$$
return
} # End of selectuser() subroutine.

# CHECKUSERDATA - Checks username's data.
checkuserdata() {
# Presenting data and asking for confirmation.
dialog --title "CHECKING USERNAME DATA" \
--yesno \
"\
------------------------------------------------------------\n\
Username=${1}      Password at first login=${1}\n\n\
Name=${UREALNAME}\n\
Address=${USTREET}\n\
ZIP Code=${UZIPCODE} City=${UCITY}\n\
State=${USTATE}\n\
Country=${UCOUNTRY}\n\
Phone #=${UPHONE} FAX #=${UFAX}\n\
------------------------------------------------------------\n\
Home Directory=${UHOMEDIR}\n\
Default shell=${USHELL}\n\
UID=${UUID}    GID=${UGID}\n\
------------------------------------------------------------\n\
Is it correct?" 20 70
return
} # End of checkuserdata() subroutine.

# MAKEUSER - Creates a user and initializes environment.
makeuser() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
# If no argument has been given, exit with error.
if [ $# = 0 ]
then
	dialog --title "ERROR!" \
	--msgbox "No username has been supplied. Exiting."  5 50
	return
fi
# Creating password: it will be the same as username, remember user to
# change it later.
# Salt for crypting is number of today's month.
SALT=`date +%m`
UPASSWORD=`/usr/root/chpass/crypt ${1} ${SALT}`
# Asking personal data.
getpdata ${1}
# Asking system data.
getsdata ${1}
checkuserdata ${1}
# If confirmed, add user, otherwise exit.
if [ ${?} = 0 ]
then
	# Executing all necessary procedures.
	dialog --title "Creating Users" --infobox \
	"Creating username $1. Please wait..." 3 55
	# Defining insertion date as today.
	DATE=`date +%m%d%y`
	# Adding entry to passwd file.
	echo "${1}:#LCK#${UPASSWORD}:${UUID}:${UGID}:${UREALNAME}:${UHOMEDIR}:${USHELL}" >> ${PASSWD}
	# Adding entry to passwd.addr file.
	echo "${1}:${DATE}:${UREALNAME}:${UPHONE}:${UFAX}:${USTREET}:${UZIPCODE}:${UCITY}:${USTATE}:${UCOUNTRY}" >> ${PASSWD_ADDR}
	# Creating home directory and setting ownership and protections.
	# Copying skel files.
	[ -d ${SKELDIR} ] && cp -R ${SKELDIR} ${UHOMEDIR}
	# Setting protection and ownership to default.
	chown -R ${UUID}.${UGID} ${UHOMEDIR}
	chmod -R 700 ${UHOMEDIR}
	# Remember to unlock newly created user.
	dialog --title "SUCCESS!" --msgbox \
	"Username ${1} has been successfully added\nin LOCKED status. Remember to unlock." 6 50
else
	# Cancelling operation.
	dialog --title "ERROR!" --msgbox \
	"Operation cancelled by user." 4 32
fi
return
} # End of makeuser() subroutine.

# KILLUSER - Deletes a user and (optionally) his files and directories.
killuser() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
dialog --title "Deleting Users" --infobox \
"Deleting username $1. Please wait..." 4 50
# Finding user's home.
UHOMEDIR=`grep ^${1}: ${PASSWD} | cut -d":" -f6`
# Deleting username from passwd file.
ed -s $PASSWD 2>>/dev/null << !
/^${1}:/d
w
q
!
# Deleting username from passwd.addr file.
ed -s $PASSWD_ADDR 2>>/dev/null << !
/^${1}:/d
w
q
!
# Deleting username from passwd.subs file.
ed -s $PASSWD_SUBS 2>>/dev/null << !
/^${1}:/d
w
q
!
dialog --title "Deleting User's files" --yesno \
"Delete files and directories for username $1?" 6 50
if [ ${?} = 0 ]
then
	# Deleting user's home.
	dialog --title "Deleting User's files" --infobox \
	"Deleting directory:\n${UHOMEDIR}.\n\
	Please wait...\n" 6 35
	rm -R ${UHOMEDIR} 2>>/dev/null
fi
return
} # End of killuser() subroutine.

# READPDATA - Read username's personal data from system files.
readpdata() {
# Reading entry in passwd.addr file.
LINE2=`grep ^${1}: ${PASSWD_ADDR}`
# If no entry for username in passwd.addr, set a null string.
LINE2=${LINE2:-" - : - : - : - : - : - : - : - : - : - "}
# Parsing username's personal data.
UREALNAME=`echo ${LINE2} | cut -d":" -f3`
INSDATE=`echo ${LINE2} | cut -d":" -f2`
UPHONE=`echo ${LINE2} | cut -d":" -f4`
UFAX=`echo ${LINE2} | cut -d":" -f5`
USTREET=`echo ${LINE2} | cut -d":" -f6`
UZIPCODE=`echo ${LINE2} | cut -d":" -f7`
UCITY=`echo ${LINE2} | cut -d":" -f8`
USTATE=`echo ${LINE2} | cut -d":" -f9`
UCOUNTRY=`echo ${LINE2} | cut -d":" -f10`
return
} # End of readpdata() subroutine.

# READSDATA - Read username's system data from system files.
readsdata() {
# Reading entry in passwd file.
LINE1=`grep ^${1}: ${PASSWD}`
# Parsing fields.
# Parsing username's status as locking string in password field.
UPASSWORD=`echo ${LINE1} | cut -d":" -f2`
USTATUS=`echo ${UPASSWORD} | cut -c1-5`
if [ ${USTATUS} = "#LCK#" ]
then
	USTATUS="LOCKED"
else
	USTATUS="ACTIVE"
fi
# Parsing uid and gid.
UUID=`echo ${LINE1} | cut -d":" -f3`
UGID=`echo ${LINE1} | cut -d":" -f4`
# Parsing home dir and shell
UHOMEDIR=`echo ${LINE1} | cut -d":" -f6`
USHELL=`echo ${LINE1} | cut -d":" -f7`
return
} # End of readsdata() subroutine.

# SHOWUSER - Shows usernames' data.
showuser() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
# Reading system data.
readsdata ${1}
# Reading personal data.
readpdata ${1}
# Presenting data.
dialog --title "DISPLAYING USERNAME DATA" \
--msgbox \
"\
------------------- PERSONAL DATA ------------------------\n\
Username=${1}      Status:=${USTATUS}\n\n\
Name=${UREALNAME}\n\
Address=${USTREET}\n\
ZIP Code=${UZIPCODE} City=${UCITY}\n\
State=${USTATE}\n\
Country=${UCOUNTRY}\n\
Phone #=${UPHONE} FAX #=${UFAX}\n\
-------------------- SYSTEM DATA -------------------------\n\
Home Directory=${UHOMEDIR}\n\
Default shell=${USHELL}\n\
UID=${UUID}    GID=${UGID}\n\
----------------------------------------------------------\n\
Creation date=${INSDATE}
" 20 70
return
} # End of showuser() subroutine.

# SAVEDATA - Save username's data in relevant files.
savedata() {
# 
 (BEL) is used as separator to avoid mismatch in ed.
# Writing data on passwd.addr file.
ed -s ${PASSWD_ADDR} << !
/^${1}:/s
:.*
:${INSDATE}:${UREALNAME}:${UPHONE}:${UFAX}:${USTREET}:${UZIPCODE}:${UCITY}:${USTATE}:${UCOUNTRY}
w
q
!
# Writing data on passwdfile.
ed -s ${PASSWD} << !
/^${1}:/s
:.*
:${UPASSWORD}:${UUID}:${UGID}:${UREALNAME}:${UHOMEDIR}:${USHELL}
w
q
!
return
} # End of savedata() subroutine.

# MODIFY - Modify username's data.
moduser() {
while [ 0 ]
do
# Displaying username's modification menu
dialog --title "MODIFY USERNAME ${1}" \
--menu "Use Arrow Keys to move. ENTER to select option." 20 75 3 \
"PDATA" "Modify personal data" \
"SDATA" "Modify system data" \
"QUIT" "Return to main menu" 2>modmenu.$$
# If something wrong, reset screen, wipe temp files and exit with error.
[ $? = 1 -o $? = 255 ] && return
# Read selected option and delete temp file.
MODMENUOPTION=`cat modmenu.$$ ; rm modmenu.$$ 2>/dev/null`
reset
# Read username's personal data.
readpdata ${1}
# Read username's system data.
readsdata ${1}
case $MODMENUOPTION in
	PDATA)
		# Ask for new personal data.
		getpdata ${1}
		# Check data.
		checkuserdata ${1}
		# If confirmed, save data, otherwise return to menu.
		if [ ${?} = 0 ]
		then
			savedata ${1}
		else
			# Cancelling operation.
			dialog --title "ERROR!" --msgbox \
			"Operation cancelled by user." 4 32
		fi
		;;
	SDATA)
		# Ask for new system data.
		getsdata ${1}
		checkuserdata ${1}
		# If confirmed, save data, otherwise return to menu.
		if [ ${?} = 0 ]
		then
			savedata ${1}
			# zzzz
			# Moving user's files.
		else
			# Cancelling operation.
			dialog --title "ERROR!" --msgbox \
			"Operation cancelled by user." 4 32
		fi
		;;
	QUIT)
		return
		;;
	*)
		# Something has gone wrong.
		rm modmenu.$$ 2>/dev/null
		return
		;;
esac
done
return
} # End of moduser() subroutine.

# ACTIVATE - Activate username's subscription.
activ() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
# Reading username's subscription data.
LINE=`grep ^${1}: ${PASSWD_SUBS}`
LINE=${LINE:-" - : - : - : - "}
SUBSCODE=`echo ${LINE} | cut -d":" -f2`
STARTDATE=`echo ${LINE} | cut -d":" -f3`
ENDDATE=`echo ${LINE} | cut -d":" -f4`
# Presenting data and asking for confirmation.
dialog --title "CHECKING SUBSCRIPTION DATA FOR ${1}" \
--yesno \
"\
------------------------------------------------------------\n\
Creation date: `grep "^${1}:" ${PASSWD_ADDR} | cut -d":" -f2`\n\
Subscription type: ${SUBSCODE} (`grep "^${SUBSCODE}:" ${SUBSDATA} | cut -d":" -f3`)\n\
Subscription duration: `grep "^${SUBSCODE}:" ${SUBSDATA} | cut -d":" -f2` days\n\
Start date: ${STARTDATE}\n\
End date: ${ENDDATE}\n\
------------------------------------------------------------\n\
Do you want to change it?" 12 70
# If confirmed, add user, otherwise exit.
if [ ${?} != 0 ]
then
	return
else
	# Creating activation menu.
	echo -e "\
	# Activation menu \n\
	dialog --title \"SELECT SUBSCRIPTION TYPE FOR $1\" \\
	--radiolist \"Use Arrow Keys to move. Select/deselect with SPACE BAR.\" 20 75 11 \\" > activmenu.$$
	# Append list to selection menu script. First cod is taken as default.
	cat $SUBSDATA | grep -v "^#" | cut -d":" -f1,3 | \
	sed "
	s/^/\"/
	s/:/\" \"/
	s/$/\" \"off\" \\\/
	1s/off/on/
 	" >> activmenu.$$ 
	echo -e "\n" >> activmenu.$$
	# Executing newly created menu
	sh activmenu.$$ 2>activmenu.err.$$
	# Reading selected subscription code.
	SUBSCODE=`cat activmenu.err.$$ | tr \" " "`
	# If username line exist modify it, else add new line.
	if [ "$STARTDATE" != " - " ]
	then
		# Line exists: modify subscription code and end date.
		# Start date is unchanged. End date is today + subscription duration.
		DURATION=`grep ^${SUBSCODE}: ${SUBSDATA} | cut -d":" -f2`
		ENDDATE=`date +%m%d%y -d "+ ${DURATION} days"`
		ed -s $PASSWD_SUBS 2>>/dev/null << !
		/^${1}:/s/:.*/:${SUBSCODE}:${STARTDATE}:${ENDDATE}/
		w
		q
!
	else
		# Line does not exist: add new entry.
		# Start date is today. End date is today + subscription duration.
		STARTDATE=`date +%m%d%y`
		DURATION=`grep ^${SUBSCODE}: ${SUBSDATA} | cut -d":" -f2`
		ENDDATE=`date +%m%d%y -d "+ ${DURATION} days"`
		echo "${1}:${SUBSCODE}:${STARTDATE}:${ENDDATE}" >> $PASSWD_SUBS
	fi
	# Locking user, just to be sure.
	lockuser $1
	return
fi
} # End of activ() subroutine.

# DEACTIVATE - Deactivate username's subscription.
deactiv() {
# Setting traps for SIGHUP, SIGINT, SIGQUIT, SIGTERM and normal exit (0).
trap "cleanup" 0 1 2 3 15
# Reading username's subscription data.
LINE=`grep ^${1}: ${PASSWD_SUBS}`
LINE=${LINE:-" - : - : - : - "}
SUBSCODE=`echo ${LINE} | cut -d":" -f2`
STARTDATE=`echo ${LINE} | cut -d":" -f3`
# Modify end date as today.
ENDDATE=`date +%m%d%y`
# If username line exist modify it, else add new line.
if [ "$STARTDATE" != " - " ]
then
	# Line exists: modify end date.
	ed -s $PASSWD_SUBS 2>>/dev/null << !
	/^${1}:/s/:.*/:${SUBSCODE}:${STARTDATE}:${ENDDATE}/
	w
	q
!
else
	# Line does not exist: issue a warning.
	dialog --title "WARNING!" --msgbox "Username ${1} has no subscription." 5 70
fi
# Locking user, just to be sure.
lockuser $1
return
} # End of deactiv() subroutine.



#------------------ E N D  O F  S U B R O U T I N E S -----------------#




#----------------------- M A I N  P R O G R A M ------------------------#

# MAIN - Here begins the real stuff.
#
# Checking protections on files and executable.
ME=`whoami`
if [ ${ME} != ${TRUSTEDUSER} ]
then
	dialog \
		--title "FATAL ERROR!" \
		--msgbox "${0} can be executed only by trusted user ${TRUSTEDUSER}" 6 40
	clear
	exit 1
fi
#
# Checking support files existence: if not, create them with defaults.
#
# Checking passwd.addr.
[ -f ${PASSWD_ADDR} ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${PASSWD_ADDR}` does not exist. Creating with defaults." 5 70 ; \
	echo -e "\
# passwd.addr
# Username address file for LABEN S.p.A.
#
# FORMAT:
# username:insdate:realname:phone:fax:streetaddr:ZIP:city:state:country
# EXAMPLE:
# root:022695:Luca Salvadori:0292162482:0292162482:Via Michelozzo da Forl 7:20096:Pioltello:MI:Italia
# " > ${PASSWD_ADDR} ; \
	chmod 600 ${PASSWD_ADDR} }

# Checking passwd.subs.
[ -f ${PASSWD_SUBS} ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${PASSWD_SUBS}` does not exist. Creating with defaults." 5 70 ; \
	echo -e "\
# passwd.subs
# Username subscription file for LABEN S.p.A.
#
# FORMAT:
# username:subs_type:startdate:enddate
# EXAMPLE:
# root:01:022695:032695
# " > ${PASSWD_SUBS}
	chmod 600 ${PASSWD_SUBS} }

# Checking subst_type.dat.
[ -f ${SUBSDATA} ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${SUBSDATA}` does not exist. Creating with defaults." 5 70 ; \
	echo -e "\
# subs_type.dat
# Subscription-code table file for LABEN S.p.A.
#
# FORMAT:
# subs_code:default_duration(days):description
# EXAMPLE:
# 00:14:Promotional
#
00:14:Promotional
01:30:Monthly
02:60:Bimonthly
03:90:Quarterly
04:180:Half-yearly
05:365:Yearly
06:9999:Free
# " > ${SUBSDATA} ; \
	chmod 600 ${SUBSDATA} }
#
# Checking file protection and ownership.
# Standard passwd file must be world readable, other files are to be read
# only by trusted users. Human must be owned and executable only by trusted 
# users.
[ `ls -la ${0}|tr -s " "|cut -d" " -f1` = "-rwx------" ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${0}` has incorrect protection. Fixing." 5 70 ; \
	chmod 700 ${0} ; chown ${TRUSTEDUSER} ${0} }
[ `ls -la ${PASSWD}|tr -s " "|cut -d" " -f1` = "-rw-r--r--" ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${PASSWD}` has incorrect protection. Fixing." 5 70 ; \
	chmod 644 ${PASSWD} }
[ `ls -la ${PASSWD_ADDR}|tr -s " "|cut -d" " -f1` = "-rw-------" ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${PASSWD_ADDR}` has incorrect protection. Fixing." 5 70 ; \
	chmod 600 ${PASSWD_ADDR} }
[ `ls -la ${PASSWD_SUBS}|tr -s " "|cut -d" " -f1` = "-rw-------" ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${PASSWD_SUBS}` has incorrect protection. Fixing." 5 70 ; \
	chmod 600 ${PASSWD_SUBS} }
[ `ls -la ${SUBSDATA}|tr -s " "|cut -d" " -f1` = "-rw-------" ] || \
	{ dialog --title "WARNING!" --msgbox "File `basename ${SUBSDATA}` has incorrect protection. Fixing." 5 70 ; \
	chmod 600 ${SUBSDATA} }





# MAIN MENU
# Main menu loop.
while [ 0 ] ; do
dialog --title "Happy User Manager (HUMAN) Main Menu" \
--menu "Use Arrow Keys to move. ENTER to select option." 20 75 12 \
"SHOW" "Show users characteristics" \
"NEW" "Create new users" \
"MODIFY" "Modify personal/system username data" \
"KILL" "Delete users" \
"LOCK" "Lock users (i.e. disable login)" \
"UNLOCK" "Unlock users (i.e. re-enable login of locked users)" \
"ACTIVATE" "Activate/modify username subscription" \
"DEACTIVATE" "Deactivate username subscription" \
"HELP" "Display help on HUMAN features" \
"EXIT" "Exit HUMAN" 2> mainmenu.err.$$
# If something wrong, reset screen, wipe temp files and exit with error.
[ $? = 1 -o $? = 255 ] && cleanup
# Read selected option and delete temp file.
MAINMENUOPTION=`cat mainmenu.err.$$ ; rm mainmenu.err.$$ 2>/dev/null`
reset
case $MAINMENUOPTION in
	SHOW)
		# Showing usernames' characteristics.
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			showuser $i
		done
		rm *.$$ 2>/dev/null
		;;
	NEW)
		# Creating new users.
		# Asking for new username and checking if it already exists.
		dialog --title "CREATING USERNAME" \
		--inputbox "Enter new username to be created (max 8 chars):" 10 55 2>newuser.$$ 
		NEWUSER=`cat newuser.$$ | cut -c1-8 ; rm newuser.$$`
		if [ "`grep ^${NEWUSER}: ${PASSWD}`" != "" ]
		then
			dialog --title "ERROR!" \
			--msgbox "Username ${NEWUSER} already exists." 6 55 2>/dev/null
		else
			makeuser ${NEWUSER}
		fi
		;;
	MODIFY)
		# Modify username's personal/system data.
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			moduser $i
		done
		rm *.$$ 2>/dev/null
		;;
	KILL)
		# Deleting users.
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			killuser $i
		done
		rm *.$$ 2>/dev/null
		;;
	LOCK)
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			lockuser $i
		done
		rm *.$$ 2>/dev/null
		;;
	UNLOCK)
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			unlockuser $i
		done
		rm *.$$ 2>/dev/null
		;;
	ACTIVATE)
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			activ $i
		done
		rm *.$$ 2>/dev/null
		;;
	DEACTIVATE)
		# Selecting users to act on.
		selectuser $MAINMENUOPTION
		# Acting on selected usernames
		for i in `cat selectmenu.err.$$ | tr \" " "`
		do
			deactiv $i
		done
		rm *.$$ 2>/dev/null
		;;
	HELP)
		man $MANPAGE | sed "s/-//g" | sed "s/_//g" | sed "s/[a-z,A-Z,0-9]//g" > $MANPAGE.$$
		dialog --title "HELP" \
		--textbox $MANPAGE.$$ 20 75
		rm *.$$ 2>/dev/null
		;;
	EXIT)
		dialog --title "EXITING HUMAN" --infobox \
		"Exiting. Thanks for using `basename $0`!" 6 50
		sleep 1
		reset
		exit 0
		;;
	*)
		# Something has gone wrong: exit with error.
		exit 1
		;;
esac
done


exit

#------------------ E N D  O F  M A I N  P R O G R A M ----------------------#





