#!/bin/bash # File: plus_user # Version 1.0 July 24 2006 # # This is to be the login shell for user useradd 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" # The username will be passed as an argument to the script USER="$USERADD_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 always use the correct mkdir MKDIR="/usr/bin/mkdir -p" # correct grep GREP="/bin/grep" # correct echo ECHO="/usr/bin/echo" # correct cut CUT="/usr/bin/cut" # 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 "sendmail" MAIL="/usr/sbin/sendmail" # correct logger LOGGER="/usr/bin/logger" # Start with an empty result string and error message RES="0" ERR="" ERROR="" ltestRES="" checkRES="" setRES="" 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() { # Clear our process-specific return codes uRES="" uidRES="" #ldapRES="" # Run getent for the user to make sure they have an appropiate uidNumber ${GETENT} passwd ${USER} > /dev/null 2>&1 uRES="$?" if [ "${uRES}" != "0" ] ; then ERR="Error running useradd script: User ${USER} doesn't exist on ${PC}!" else # If they are in there, check their UID number to make sure they're legit uNUM=`${GETENT} passwd ${USER} |${GREP} "^${USER}:" | ${CUT} -d : -f 3` uidRES="$?" if [ "${uNUM}" -lt "${uMIN}" ] ; then ERR="Error running useradd script: User ${USER}'s UID is below ${uMIN}!" RES="1" fi fi # Run ldapsearch for the user to make sure they are authorized to connect to this host. # EXAMPLE: ldapsearch -x "(&(uid=test)(host=apok-3.cerias.purdue.edu))" \ # host -b "ou=Experiments,dc=cerias,dc=purdue,dc=edu" | grep -qs \ # "host: apok-3.cerias.purdue.edu" ${LSEARCH} "(&(uid=$USER)(host=$PC))" host -b "${BASE}" | ${GREP} -qs "host: ${PC}" ldapRES="$?" if [ "${ldapRES}" != "0" ] ; then ERR="Error running useradd script: User ${USER} not authorized for ${PC}!" RES="1" fi ${ECHO} "${RES};${ERR}" } setup_user() { # Clear our process-specific return codes mkRES="" cpRES="" chRES="" # If we're running this and the directory already exists, something is weird. if [ ! -d /home/${USER}/images ] && [ ! -d /home/${USER} ] ; then # Create it ${MKDIR} -m 0700 -p /home/${USER}/images > /dev/null 2>&1 mkRES="$?" # If mkdir succeeds, try to copy /etc/skel over . . . if [ "$mkRES" = "0" ] ; then # Copy skel files ${CP} -a /etc/skel/.[A-z]* /home/${USER}/ > /dev/null 2>&1 cpRES="$?" # . . . otherwise, cry foul. else ERR="Error running useradd script: Could not create ${USER}'s home directory!" RES="1" fi # If no errors so far, it's time to give the user ownership . . . if [ "$cpRES" = "0" ] && [ "$RES" != "1" ] ; then # Lastly, set ownership ${CHOWN} -R ${USER}:${GID} /home/${USER} > /dev/null 2>&1 chRES="$?" # . . . otherwise, cry foul. else ERR="Error running useradd script: Could not copy /etc/skel to /home/${USER}/!" RES="1" fi # If chowning went bad, cry foul. if [ "${chRES}" != "0" ] ; then ERR="Error running useradd script: Could not change ownership for /home/${USER}/!" RES="1" fi # Lastly, if there were any problems, we should tidy up after ourselves. if [ "${RES}" = "1" ] ; then #Let's not leave a mess! ${RM} -rf /home/${USER} > /dev/null 2>&1 else RES="0" fi else ERR="Error running useradd script: Home directory already exists for user ${USER}!" RES="1" fi ${ECHO} "$RES;$ERR" } process_error() { # Output will look someting like: # Dec 8 15:13:12 apok-3 USERADD: Error running useradd script: User dumby's UID is below 10000! ${LOGGER} -t USERADD ${ERROR} # Send e-mail too, so we're all on top of the situation. ${CAT}< To: "ReAssure Admins" <${ADMINS}> Subject: Error setting up ${PC} for user ${USER} The useradd script on ${PC} has failed with the following error: "${ERROR}" Please look into this. Regards, Your Friendly Mindless ReAssure Script EOF } # 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. # First, 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! checkRES=`detect_user` # If we detect anything but a RES of 0, log it and e-mail it. # Otherwise, proceed with the user setup. if [ "$checkRES" != "0;" ] ; then ERROR=`${ECHO} "$checkRES" | ${CUT} -d \; -f 2` process_error exit 1 fi # Make sure setRES starts with a clean palate. RES="0" ERR="" ERROR="" # The exact same logic applies for setRES as for checkRES. setRES=`setup_user` if [ "$setRES" != "0;" ] ; then ERROR=`${ECHO} "$setRES" | ${CUT} -d \; -f 2` process_error exit 1 fi # Yay! Success! Shout it out loud! ${LOGGER} -t USERADD Useradd script: Setup for user ${USER} completed successfully. exit 0