#!/bin/bash

#initialize variables
answer=""
found=0
write_mail=0
current_month=""
compare_month=""
switch_string=""
list_of_months=("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")

switch_string=$1$2$3$4
echo ""

# Check to see if the -h switch has been used. If so, display the help for the program and then exit.
if [[ "$switch_string" == *h* ]]
then
	clear
	echo "disable_user.sh is a script that is meant to be used in conjuntion with crontab. It will disable user accounts"
	echo "where the user has not logged in during the current month. The suggested use to to execute crontab -e and"
	echo "enter this line:"
	echo ""; echo "59 23 28 * * /{absolute_path_to_script}/diable_user.sh"; echo ""
	echo "By doing this, it will run this script at 11:59pm on the 28th of every month, disabling accounts as needed."
	echo ""; echo "Available command line switches:"; echo ""
	echo "-d : Delete /var/log/account_script.log before executing the rest of the script"
	echo "-e : Enable a user's account. [then exit]"
	echo "-h : This help menu (duh) [then exit]"
	echo "-r : Read the /var/log/account_script.log after the script executes"
	echo "-u : Copy /etc/passwd.bak onto /etc/passwd effectively undoing any changes made by the script [then exit]"
	echo ""; echo "Usage: source disable_user.sh -r -d -or- source disable_user.sh -rd"
	echo ""; echo "If executed in crontab it will run 'silently'. If executed with no command line switches, it will"
	echo "perform all tasks (including disabling user accounts, with some screen output."; echo ""
	return	
fi

# If the -e switch is used, have the script re-enable a user's account, if: (1) the user exists, (2) the shell is /sbin/nologin, AND
# (3) the UID is greater than 500
if [[ "$switch_string" == *e* ]]
then
        rm -f /etc/passwd.restore
        read -p "Please enter the name of the user you wish to enable: " answer

# If the person running the script simply presses ENTER for the user name, exit the script
        if [[ $answer == "" ]]
        then
                echo ""; "You did not enter a user's name."; echo ""
                return
        fi

        while read line
        do
# Cut out the username, UID, and shell
                users_name=`echo $line | cut -d: -f1`
                users_uid=`echo $line | cut -d: -f3`
                users_shell=`echo $line | cut -d: -f7`

                echo ""; echo "Processing "$users_name

# The next line says
# (1) If the user's name, as read from /etc/passwd, is the same as the one entered from the keyboard
#       AND
# (2) If the user's shell, as read from /etc/passwd, is /sbin/login
#       AND
# (3) If the user's ID, as read from /etc/passwd, is greater than 500
#       THEN
# Process the user, enabling their account by changing /sbin/nologin to /bin/bash and then write the new information to /etc/passwd.restore and set the
# found variable to 1
#       OTHERWISE (ELSE)
# Write the line read in from /etc/passwd to /etc/passwd.restore
                if [[ $users_name == $answer && $users_shell == "/sbin/nologin" && users_uid -gt 499 ]]
                then
                        echo ""; echo "Found "$users_name" with shell "$users_shell", setting shell to /bin/bash"
                        users_gid=`echo $line | cut -d: -f4`
                        users_dir=`echo $line | cut -d: -f6`
	                users_string=$users_name":x:"$users_uid":"$users_gid"::"$users_dir":/bin/bash"
                        echo $users_string >> /etc/passwd.restore
                        found=1
                else
                        echo $line >> /etc/passwd.restore
                fi
                
        done < /etc/passwd

# If the found variable is 1, write the changes from /etc/passwd.restore to /etc/passwd. OTHERWISE (ELSE) report that the user name was not found, or the
# the shell was already /bin/bash, or the UID was less than 50
        echo""
        if [[ found -eq 1 ]]
        then
                echo "Found user "$answer" and re-enabled account. Writing /etc/passwd.restore to /etc/passwd"
                /bin/cp /etc/passwd.restore /etc/passwd
        else
                echo "User "$answer" was not found, shell was already /bin/bash, or UID was less than 500. No changes to /etc/passwd"
        fi
        echo ""
        
        return
fi

# Check to see if the -u switch has been used and, if so, copy /etc/passwd.bak to /etc/passwd effectively undoing any
# changes this script may have made
if [[ "$switch_string" == *u* ]]
then    

# Check to see if /etc/passwd.bak exists, if it does not, exit script. If it does, ask the user if they're sure they
# want to copy /etc/password.bak over /etc/passwd (they must answer "yes" to do so)
	if [[ -f /etc/passwd.bak ]]
	then
		read -p "Replace /etc/passwd with /etc/passwd.bak? (yes to confirm): " answer
		if [[ $answer == "yes" ]]
		then
			/bin/cp /etc/passwd.bak /etc/passwd
			echo "/etc/passwd has been replaced with /etc/passwd.bak"; echo ""
			return
		else
			echo "'yes' was not entered -- /etc/passwd has not been replaced..."; echo ""
			return
		fi
	else
		echo "The /etc/passwd.bak file does not exist -- nothing to do..."; echo ""
		return
	fi
fi

# Copy /etc/passwd to /etc/passwd.bak and delete all temporary files that we will work with
/bin/cp /etc/passwd /etc/passwd.bak
rm -f /etc/user_list.txt
rm -f /etc/passwd.new

# Check to see if the -d switch was used when executing the script. If so, then give the user the opotion to delete 
# /var/log/account_script.log The user must enter the word "yes" in order for the file to be deleted.
if [[ "$switch_string" == *d* ]]
then
        read -p "Do you want to delete /var/log/account_script.log? (yes to delete): " answer
	if [[ $answer == "yes" ]]
	then
	        rm -f /var/log/account_script.log
		echo "/var/log/account_script.log has been deleted."
	else
		echo "'yes' was not entered, /var/log/account_script.log was NOT removed. (You endered '"$answer"')."
	fi

	echo ""; read -p "Paused..."; echo ""
fi

# 1. Read in /etc/passwd one line at a time, use cut to get user's username, UID, and shell.
# 2. Check if UID is greater then 499 -and- that the user name is not "xguest", if so go to next step, 
# 	If not, append all passwd information to /etc/passwd.new
# 3. Check to see if shell is /bin/bash, if so, append just the username to /etc/user_list.txt, 
#	If not, append all passwd information to /etc/passwd.new
while read line
do
	user_id=`echo $line | cut -d: -f3`
	shell_name=`echo $line | cut -d: -f7`
	user_name=`echo $line | cut -d: -f1`

# Check to see if the user_id variable is greater than 499 -AND- that the user_name variable is NOT xguest. If both
# BOTH conditions are TRUE, then keep processing.  If EITHER condition is FALSE, append the user's information into 
# /etc/password.new	
	if [[ $user_id -gt 499 && $user_name != "xguest" ]]
	then

# Check the user's shell. If shell_name is /bin/bash, append the user's username to /etc/user_list.txt for later processing.
# If it is something else, append the user's information to /etc/passwd.new
		if [[ $shell_name == "/bin/bash" ]]
		then
			echo $user_name >> /etc/user_list.txt
		else
			echo $line >> /etc/passwd.new		
		fi
	else
		echo $line >> /etc/passwd.new
	fi
done < /etc/passwd

# use the following command to pull the current abbreviated month from the date command (Jan, Apr, Oct., etc.)
current_month=`date | cut -d' ' -f2`

# use the following section to read the user_list.txt file, one line at a time. Use this information to get the user's 
# last login (using the last command), redirecting the result to the /etc/user_last_login_month.txt file, which 
# removes superfluous spaces
while read user_list_name
do

	echo `last $user_list_name -1` > /etc/user_last_login_month.txt

# Based on how a user logs in, the field that contains the month that the user last logged in may be in either 5 or 4.
# Compare this to a list of months to see if what has been cut is, indeed, a valid month and not some other value. Use a
# a value of 5 first, since it is more common.
	month_check=0
	check_field=5

# Continue to loop until the month_check is equal to zero, indicating that we have matched the month that the user last
# logged in to a list of months in the year.
	while [ $month_check -eq 0 ]
	do
		compare_month=`cat /etc/user_last_login_month.txt | cut -d' ' -f$check_field`

		
		echo "Last month user" $user_list_name "logged in was "$compare_month" (Check field is "$check_field")"
		
# This loops through all the months in the year, stopping when a match is found.
		for (( i=0 ; i<12 ; i++ ))
		do

			if [[ $compare_month == ${list_of_months[i]} ]]
			then

# These two values cuase the script to break out of the while and for loops when a match is found when comparing the
# current month to the user's last login month
				month_check=1
				i=13
			fi
		done
	
# check_field will be set to 4 when no match on months is found, allowing the script to go from field number 5 to field
# number 4 in the compare_month variable (retrieved from /etc/user_last_login_month.txt) and derived from the last
# command.
		check_field=4
	done

	user_string=`cat /etc/passwd | grep -w $user_list_name`
	users_name=`echo $user_string | cut -d: -f1`

# Send "new line" to /var/log/account_script.log
	echo "" >> /var/log/account_script.log

# This check to see if there is a user account where the user has never logged on, which is indicated by "wtmp" appearing
# in the first field of the last command, if so, change account_disable to 1, which them will be checked later to see if
# an account is eligble for disabling
	automatic_disable=0
	automatic_disable_name=`cat user_last_login_month.txt | cut -d' ' -f1`
	if [[ $automatic_disable_name == "wtmp" ]]
        then
        	automatic_disable=1
        fi

# Check the current month against the month the user last logged in, if they do not match (or if automatic_disable is 1)
# then reconstruct the  user's _current_ string to change their shell to /sbin/login
	if [[ $current_month != $compare_month || automatic_disable -eq 1 ]]
	then
		write_mail=1
		users_uid=`echo $user_string | cut -d: -f3`
		users_gid=`echo $user_string | cut -d: -f4`
		users_dir=`echo $user_string | cut -d: -f6`
		user_string=$users_name":x:"$users_uid":"$users_gid"::"$users_dir":/sbin/nologin"
		
# Write to /var/log/account_script.log and /var/log/mail_log.txt (changed users only) and supress screen output
		echo `date`" -- USER ACCOUNT DISABLED: "$users_name | tee -a /var/log/account_script.log /var/log/mail_log.txt > /dev/null

	else
		echo `date`" -- User unchanged: "$users_name >> /var/log/account_script.log

	fi

# Write (append) to /var/log/account_script.log and screen, then append user's new string to /etc/passwd.new
	echo "String to be written to /etc/passwd.new is "$user_string | tee -a /var/log/account_script.log
	echo ""	
	echo $user_string >> /etc/passwd.new

done < /etc/user_list.txt

# Copy the /etc/passwd.new that we've built to /etc/passwd so the changes take effect
/bin/cp /etc/passwd.new /etc/passwd

# Mail disabled accounts information to system administrator, then remove mail_log.txt so they don't get bombarded
# with old information, if write_mail is 1, which is set if user(s) have been disabled
if [[ $write_mail -eq 1 ]]
then
	mail -s "DISABLED ACCOUNTS LOG" baker.tracy@gmail.com < /var/log/mail_log.txt
	rm -f /var/log/mail_log.txt
fi

# If the script was execututed using the -r switch (as in 'source disable_user.sh -r', then show the 
# /var/log/account_script.log after pausing for 5 seconds
if [[ "$switch_string" == *r* ]]
then
	echo "Going to display /var/log/account_script.log in 5 seconds..."; sleep 5
	clear; echo "NOW DISPLAYING /var/log/account_script.log"
	cat /var/log/account_script.log
fi
