#!/bin/bash # # File: minus_user script # Version 1.0 July 24 2006 # # This is to be the login shell for user userdel on each experimental machine # # Author: Ed Cates (prototype by Forrest Fleming) # ReAssure project # This script is under a BSD-style license. # # We don't want to risk false positives on our LDAp search # if the user still has an "ou=People" listing. BASE="ou=Experiments,dc=cerias,dc=purdue,dc=edu" SED="/usr/bin/sed" # The username will be passed as an argument to the script USER="$USERDEL_USER" # Minimum allowable UID for experimental users uMIN="10000" # GROUP ID for experimental users GID="10000" # Used to determine which "host:" attribute $USER needs PC=`/usr/bin/hostname -f` # email recipients for error messages: ADMINS="reassure_tests@cerias.purdue.edu" # Make sure we always use the system's ldapsearch LSEARCH="/usr/bin/ldapsearch -x" # Make sure we always use the correct chown CHOWN="/usr/bin/chown" # Make sure we have the correct chmod CHMOD="/usr/bin/chmod" # Make sure we always use the correct mkdir MKDIR="/usr/bin/mkdir -p" # correct grep GREP="/bin/grep" # correct ls LS="/usr/bin/ls" # correct wc WC="/usr/bin/wc" # correct echo ECHO="/usr/bin/echo" # correct cut CUT="/usr/bin/cut" # correct awk AWK="/usr/bin/awk" # correct getent GETENT="/usr/bin/getent" # correct rm RM=/usr/bin/rm # correct cp CP="/usr/bin/cp" # correct cat CAT="/usr/bin/cat" # correct ps PS="/bin/ps" # correct kill KILL="/bin/kill" # correct su SU="/bin/su" # correct "sendmail" MAIL="/usr/sbin/sendmail" # correct logger LOGGER="/usr/bin/logger" #correct sed SED="/usr/bin/sed" # The username will be passed as an argument to the script USER=`${ECHO} "$USERDEL_USER" | sed -e 's!/!!g'` # Start with an empty result string and error message # RES="0" ERR="" ERROR="" # Define/nullify values for function results used below. ltestRES="" detectRES="" killRES="" ownzRES="" cleanRES="" ldap_test() { lconnRES="" # I guess we really should test connectivity to the LDAP server first. ${LSEARCH} "uid=${USER}" -b "${BASE}" > /dev/null 2>&1 lconnRES="$?" if [ "${lconnRES}" = "0" ] ; then RES="0" # The LDAP connection is hosed. else ERR="Error running userdel script: Could not connect to LDAP server from ${PC}!" RES="1" fi ${ECHO} "${RES};${ERR}" } detect_user() { ldapRES="" userRES="" uidRES="" uNUM="" ${GETENT} passwd ${USER} > /dev/null 2>&1 userRES="$?" if [ "${userRES}" = "0" ] ; then # We should check that we're not being called to clean up the wrong user uNUM=`${GETENT} passwd ${USER} |${GREP} "^${USER}:" | ${CUT} -d : -f 3` uidRES="$?" # We should at least be able to find the ${USER} in question. if [ "$uidRES" != "0" ] ; then ERR="Error running userdel script: Unable to determin UID for ${USER}!" RES="1" # This script should never run on a UID < 10000! elif [ "$uNUM" -lt "$uMIN" ] ; then ERR="Error running useradd script: User ${USER}'s UID is below ${uMIN}!" RES="1" else # Does ${USER} have the "host:" attribute for ${PC} set in the LDAP directory? ${LSEARCH} "(&(uid=${USER})(host=${PC}))" host -b "${BASE}" |${GREP} -qs "host: ${PC}" ldapRES="$?" # Tricky! If the above command SUCCEEDS, it means that $USER is still authorized to log # on to ${PC}, so why are we running this script? It should only be run after the # "host:" attribute for ${PC} has been removed. # So in this case, the success of the above command signifies an error situation. if [ "$ldapRES" = "0" ] ; then ERR="Error running userdel script: User ${USER} still has \"host\" attribute configured for ${PC}." RES="1" else # Else the ldapsearch failed, so everything is okay. Got that? RES="0" fi fi else ERR="Error running userdel script: User ${USER} not found on ${PC}!" RES="1" fi ${ECHO} "$RES;$ERR" } kill_userprocs() { uPROCS="" # not subtle but effective. ${KILL} -9 `${PS} -u ${USER} -o pid=` > /dev/null 2>&1 # Is $USER still running anything? uPROCS=`${PS} -u ${USER} -o pid=` if [ "$uPROCS" != "" ] ; then ERR="Error running userdel script: Could not kill all of ${USER}'s processes on ${PC}!" RES="1" # At this point we are assuming one of two things: # 1) No user processes found running, okay to proceed with file removal. # or # 2) All user processes successfully killed, okay to proceed with file removal. else RES="0" fi ${ECHO} "${RES};${ERR}" } u_r_ownzored() { dirRES="" chRES="" lckRES="" if [ -d /home/${USER} ] ; then ${CHOWN} -R ${USER}:${GID} /home/${USER} > /dev/null 2>&1 chRES="$?" # This SO should not fail, but if it does, we need to know. if [ "$chRES" != "0" ] ; then ERR="Error running userdel script: Could not change ownership of files in /home/${USER}!" RES="1" # I vote that since we will have to go in by hand anyway, we should try to lock down # any user directory where CHOWN fails, since we have already established they no # longer have any business on ${PC} anyway ${CHMOD} -R 0000 /home/${USER} > /dev/null 2>&1 lckRES="$?" if [ "$lckRES" != "0" ] ; then ERR="${ERR} ADDITIONALLY, attempts to lock down /home/${USER} with chmod have failed!" fi else RES="0" fi else RES="1" ERR="Error running userdel script: Cannot chown non-existant /home/${USER} directory!" fi ${ECHO} "${RES};${ERR}" } clean_userfiles() { homeRES="" tmpRES="" rmRES="" # This will NOT remove the user's home directory, since users can't # delete $HOME out from under themselves. # Note that since /home/$USER isn't removed, this will always return an error, # so we need some different way of checking for success. ${SU} - ${USER} -c "${RM} -rf /home/${USER}/" > /dev/null 2>&1 homeRES=`${LS} -Al /home/${USER}/ | ${GREP} -v "^total 0$" | ${WC} -l` # and anything they might have in /tmp ${SU} - ${USER} -c "${RM} -rf /tmp/" > /dev/null 2>&1 tmpRES=`${LS} -AlG /tmp/ | ${GREP} -w ${USER} | ${WC} -l` if [ "$homeRES" != "0" ] || [ "$tmpRES" != "0" ] ; then ERR="Error running userdel script: Could not delete ${USER}'s files from /home/${USER}/ or /tmp/" RES="1" else # If everything else went okay, delete their home directory as root (necessary). ${RM} -rf /home/${USER} rmRES="$?" if [ "$rmRES" != "0" ] ; then ERR="Error running userdel script: Superuser unable to delete /home/${USER}" RES="1" else RES="0" fi fi ${ECHO} "${RES};${ERR}" } process_error() { # Output will look someting like: # Dec 8 15:13:12 apok-3 USERDEL: Error running userdel script: Superuser unable to delete /home/dumby" ${LOGGER} -t USERDEL ${ERROR} # Send e-mail too, so we're all on top of the situation. ${CAT}< To: "ReAssure Admins" <${ADMINS}> Subject: Error cleaning ${USER} off of ${PC} The userdel script on ${PC} has failed with the following error: "${ERROR}" Please look into this. Regards, Your Friendly Mindless ReAssure Script EOF } # First and foremost, if $USER isn't defined somehow, we need to not delete /home/ if [ "${USER}" = "" ] ; then ERROR="Error running userdel script: USER is not defined!" process_error exit 1 fi # We're going to get cute here. The functions above return the error code result (RES) # and the error message (ERR) written into the script. We will use that to determine what to do next. # Next, make sure we can talkd to Ye Old LDAPPE Server ltestRES=`ldap_test` if [ "$ltestRES" != "0;" ] ; then ERROR=`${ECHO} "${ltestRES}" | ${CUT} -d \; -f 2` process_error exit 1 fi # RESET! ERR="" RES="0" ERROR="" # If all steps in "detect_user" succeed, checkRES will equal "0;", which # signifies a return code of 0 for all processes run, and no script-added # error messages. If there had been an error, checkRES would equal something # like: "1;Error running useradd script: User dumby's UID is below 10000! detectRES=`detect_user` if [ "$detectRES" != "0;" ] ; then ERROR=`${ECHO} "${detectRES}" | ${CUT} -d \; -f 2` process_error exit 1 fi # RESET! ERR="" RES="0" ERROR="" killRES=`kill_userprocs` if [ "$killRES" != "0;" ] ; then ERROR=`${ECHO} "${killRES}" | ${CUT} -d \; -f 2` process_error exit 1 fi # RESET! ERR="" RES="0" ERROR="" ownzRES=`u_r_ownzored` if [ "$ownzRES" != "0;" ] ; then ERROR=`${ECHO} "${ownzRES}" | ${CUT} -d \; -f 2` process_error exit 1 fi # RESET! ERR="" RES="0" ERROR="" cleanRES=`clean_userfiles` if [ "$cleanRES" != "0;" ] ; then ERROR=`${ECHO} "${cleanRES}" | ${CUT} -d \; -f 2` process_error exit 1 fi # Yay! Success! Shout it out loud! ${LOGGER} -t USERDEL Userdel script: All traces of ${USER} have been successfully removed from ${PC}. exit 0