#!/bin/sh
ATJOBDIR="/var/at/jobs"
CRONJOBDIR="/var/cron/tabs"
MAILSPOOL="/var/mail"
SIGKILL="-KILL"
TEMPDIRS="/tmp /var/tmp"
THISCMD=`/usr/bin/basename $0`
PWCMD="${PWCMD:-/usr/sbin/pw}"
err() {
echo 1>&2 ${THISCMD}: $*
}
verbose() {
[ -n "$vflag" ] && return 0 || return 1
}
rm_files() {
[ -n $1 ] && login=$1 || return
totalcount=0
for _dir in ${TEMPDIRS} ; do
filecount=0
if [ ! -d $_dir ]; then
err "$_dir is not a valid directory."
continue
fi
verbose && echo -n "Removing files owned by ($login) in $_dir:"
filecount=`find 2>/dev/null "$_dir" -user "$login" -delete -print |
wc -l | sed 's/ *//'`
verbose && echo " $filecount removed."
totalcount=$(($totalcount + $filecount))
done
! verbose && [ $totalcount -ne 0 ] && echo -n " files($totalcount)"
}
rm_mail() {
[ -n $1 ] && login=$1 || return
verbose && echo -n "Removing mail spool(s) for ($login):"
if [ -f ${MAILSPOOL}/$login ]; then
verbose && echo -n " ${MAILSPOOL}/$login" ||
echo -n " mailspool"
rm ${MAILSPOOL}/$login
fi
if [ -f ${MAILSPOOL}/.${login}.pop ]; then
verbose && echo -n " ${MAILSPOOL}/.${login}.pop" ||
echo -n " pop3"
rm ${MAILSPOOL}/.${login}.pop
fi
verbose && echo '.'
}
kill_procs() {
[ -n $1 ] && login=$1 || return
verbose && echo -n "Terminating all processes owned by ($login):"
killcount=0
proclist=`ps 2>/dev/null -U $login | grep -v '^\ *PID' | awk '{print $1}'`
for _pid in $proclist ; do
kill 2>/dev/null ${SIGKILL} $_pid
killcount=$(($killcount + 1))
done
verbose && echo " ${SIGKILL} signal sent to $killcount processes."
! verbose && [ $killcount -ne 0 ] && echo -n " processes(${killcount})"
}
rm_at_jobs() {
[ -n $1 ] && login=$1 || return
atjoblist=`find 2>/dev/null ${ATJOBDIR} -maxdepth 1 -user $login -print`
jobcount=0
verbose && echo -n "Removing at(1) jobs owned by ($login):"
for _atjob in $atjoblist ; do
rm -f $_atjob
jobcount=$(($jobcount + 1))
done
verbose && echo " $jobcount removed."
! verbose && [ $jobcount -ne 0 ] && echo -n " at($jobcount)"
}
rm_crontab() {
[ -n $1 ] && login=$1 || return
verbose && echo -n "Removing crontab for ($login):"
if [ -f ${CRONJOBDIR}/$login ]; then
verbose && echo -n " ${CRONJOBDIR}/$login" || echo -n " crontab"
rm -f ${CRONJOBDIR}/$login
fi
verbose && echo '.'
}
rm_ipc() {
verbose && echo -n "Removing IPC mechanisms"
for i in s m q; do
ipcs -$i |
awk -v i=$i -v login=$1 '$1 == i && $5 == login { print $2 }' |
xargs -n 1 ipcrm -$i
done
verbose && echo '.'
}
rm_user() {
[ -n $1 ] && login=$1 || return
verbose && echo -n "Removing user ($login)"
[ -n "$pw_rswitch" ] && {
verbose && echo -n " (including home directory)"
! verbose && echo -n " home"
}
! verbose && echo -n " passwd"
verbose && echo -n " from the system:"
${PWCMD} userdel -n $login $pw_rswitch
verbose && echo ' Done.'
}
prompt_yesno() {
[ -n "$1" ] && msg="$1" || return
while : ; do
echo -n "$msg"
read _ans
case $_ans in
[Nn][Oo]|[Nn])
return 1
;;
[Yy][Ee][Ss]|[Yy][Ee]|[Yy])
return 0
;;
*)
;;
esac
done
}
show_usage() {
echo "usage: ${THISCMD} [-yv] [-f file] [user ...]"
echo " if the -y switch is used, either the -f switch or"
echo " one or more user names must be given"
}
ffile=
fflag=
procowner=
pw_rswitch=
userlist=
yflag=
vflag=
procowner=`/usr/bin/id -u`
if [ "$procowner" != "0" ]; then
err 'you must be root (0) to use this utility.'
exit 1
fi
args=`getopt 2>/dev/null yvf: $*`
if [ "$?" != "0" ]; then
show_usage
exit 1
fi
set -- $args
for _switch ; do
case $_switch in
-y)
yflag=1
shift
;;
-v)
vflag=1
shift
;;
-f)
fflag=1
ffile="$2"
shift; shift
;;
--)
shift
break
;;
esac
done
if [ $fflag ]; then
_insecure=`find $ffile ! -user 0 -or -perm +0022`
if [ -n "$_insecure" ]; then
err "file ($ffile) must be owned by and writeable only by root."
exit 1
fi
if [ -r "$ffile" ]; then
userlist=`cat $ffile | while read _user _junk ; do
case $_user in
\#*|'')
;;
*)
echo -n "$userlist $_user"
;;
esac
done`
fi
else
while [ $1 ] ; do
userlist="$userlist $1"
shift
done
fi
if [ ! "$userlist" ]; then
if [ $fflag ]; then
err "($ffile) does not exist or does not contain any user names."
exit 1
elif [ $yflag ]; then
show_usage
exit 1
else
echo -n "Please enter one or more usernames, or press enter to exit: "
read userlist
fi
fi
_user=
_uid=
for _user in $userlist ; do
userrec=`pw 2>/dev/null usershow -n $_user`
if [ "$?" != "0" ]; then
err "user ($_user) does not exist in the password database."
continue
fi
_uid=`echo $userrec | awk -F: '{print $3}'`
if [ "$_uid" = "0" ]; then
err "user ($_user) has uid 0. You may not remove this user."
continue
fi
if [ -z "$yflag" ]; then
echo "Matching password entry:"
echo
echo $userrec
echo
if ! prompt_yesno "Is this the entry you wish to remove? (yes/no): " ; then
continue
fi
_homedir=`echo $userrec | awk -F: '{print $9}'`
if prompt_yesno "Remove user's home directory? [$_homedir] (yes/no): "; then
pw_rswitch="-r"
fi
else
pw_rswitch="-r"
fi
${PWCMD} 2>/dev/null lock $_user
! verbose && echo -n "Removing user ($_user):"
rm_crontab $_user
rm_at_jobs $_user
rm_ipc $_user
kill_procs $_user
rm_files $_user
rm_mail $_user
rm_user $_user
! verbose && echo "."
done