#!/bin/sh
#
#    Copyright (c) 2002-2007 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    File name:   logout
#    Module name: fabos/src/security/utils.c
#
#    This script will logout all sessions of specified particular users.
#    It's called by the in a number of situtaions in secure mode
#    by the FABOS code such as when passwords change or FCS role
#    change.
#
PATH=/fabos/sbin:/fabos/bin:/bin:/usr/bin:/sbin

# A common function to logout all the sessions in case of AAA config change
# or ssh session termination on zeroization
logout_all_sessions()
{
	echo "Logging out all the sessions"

	mytty=`tty|sed  -e 's/\/dev\///g'`

	for tty in `who | sed -e 's/   / /g' | sed -e 's/  / /g' | sed -e 's/  / /g' \
            | cut -d' ' -f2`
	do
    	echo "*aaa tty - $tty*" >> /var/log/user.log
#kill all other shells first
    	if [ "$tty" != "$mytty" ]; then
        	pid=`fuser /dev/$tty 2>/dev/null | sed -e "s,^/dev/[[:alnum:]/]*:[[:space:]]*,,g"`

#   echo Killing PID $pid
        	if [ "$pid" != "" ]; then
            	kill -9 $pid 2> /dev/null
        	fi
    	fi
	done
#kill my own shell (if no args supplied)
	if [ $# -eq 0 ]; then
		pid=`fuser /dev/$mytty 2>/dev/null | sed -e "s,^/dev/[[:alnum:]/]*:[[:space:]]*,,g"`
		echo "All PID's associated with Shell = $pid" >> /var/log/user.log
#		echo Killing PID $pid
		if [ "$pid" != "" ]; then
			pidarray=$(echo $pid | tr " " "\n")
			for eachpid in $pidarray
			do
			if [ "$eachpid" != "" ]; then
				shell=`ps -p $eachpid -o comm=`
				if [ "$shell" = "sh" ] || [ "$shell" = "rbash" ]; then
					echo "shell PID = $eachpid" >> /var/log/user.log
					/bin/sleep 1 
					kill -9 $eachpid 2> /dev/null
				fi
			fi
			done
		fi
	fi
}

terminate_sftp_sessions()
{

	for sftp_sess_pid in `ps -aef | grep "sftp " | sed -e 's/     / /g' | cut -d' ' -f2 2>>/dev/null`
	do
    	if [ "$sftp_sess_pid" != "" ]; then
        	kill -9 $sftp_sess_pid 2> /dev/null
    	fi
	done
}

terminate_ssh_sessions()
{
	#Terminate ssh session on standby
	#Check for chassis/pizzabos
	pizzabox=$(/fabos/cliexec/hashow | /bin/grep -c "Not supported on this platform") 
	if [[ $pizzabox -eq 0 ]]; then
		# Chassis
		otherhost=`/fabos/rbin/cipherutil get_otherhost 2>/dev/null`
		if  /bin/ping -c 2 $otherhost >& /dev/null ; then
			/usr/bin/rsh -n $otherhost "for ssh_sess_pid in \`/bin/ps -aef| /bin/grep sshd: |/bin/grep -v grep|/bin/sed -e 's/  */ /g'|/usr/bin/cut -d' ' -f2\`;
			do 
				if [ \"\$ssh_sess_pid\" != \$PPID ]; then 
					/bin/kill -9 \$ssh_sess_pid 2> /dev/null; 
				else 
					\$mysess_pid = \$PPID ; 
				fi; 
				if [ \"\$mysess_pid\" = \$PPID ]; then
					/bin/kill -9 \$mysess_pid 2> /dev/null
				fi
			done" >& /dev/null
		fi
	fi
	
	#Terminate ssh session on Active 
	for ssh_sess_pid in `ps -aef | grep "sshd: " | sed -e 's/  */ /g'|cut -d' ' -f2 2>>/dev/null`
	do
	if [ "$ssh_sess_pid" != $PPID ]; then
		kill -9 $ssh_sess_pid 2> /dev/null
	else
			$mysess_pid = $PPID
		fi
	done
	
	if [ "$mysess_pid" = $PPID ]; then
		kill -9 $mysess_pid 2> /dev/null
	fi
}

terminate_user_sessions()
{
	killown=0
	echo "Logging out all the sessions of user $1"
	username=$1
	mytty=`tty|sed  -e 's/\/dev\///g'`

	for tty in `who | grep -w "$1"|  sed -e 's/   / /g' | sed -e 's/  / /g' | sed -e 's/  / /g' \
            | cut -d' ' -f2`
	do
    	echo "*aaa tty - $tty*" >> /var/log/user.log
#kill all other shells first
    	if [ "$tty" != "$mytty" ]; then
        	pid=`fuser /dev/$tty 2>/dev/null | sed -e "s,^/dev/[[:alnum:]/]*:[[:space:]]*,,g" | sed "s/^ *//;s/ *$//"`
#   echo Killing PID $pid
        	if [ "$pid" != "" ]; then
			pidarray=$(echo $pid | tr " " "\n")
			for eachpid in $pidarray
			do
				if [ -f /proc/$eachpid/environ ]; then
					ret=$(/bin/grep -cw "AUTH_TYPE=1" /proc/$eachpid/environ 2>/dev/null)
					echo "*ret - $ret" >> /var/log/user.log
					if [[ $ret -ne 1 ]]; then
						kill -9 $eachpid 2> /dev/null
					fi
				fi
			done
        	fi
	else
	/bin/sleep 1
	killown=1
    	fi
	
	done
#kill my own shell 
if [ $killown == 1 ]; then
    if [ $username == "root" ] && [ $mytty == "ttyS0" ]; then
        pid=`ps | grep ttyS0 | grep sh | awk '{ print $1 }'`
    else
        pid=`fuser /dev/$mytty 2>/dev/null | sed -e "s,^/dev/[[:alnum:]/]*:[[:space:]]*,,g" | sed "s/^ *//;s/ *$//"`
    fi
#   echo Killing PID $pid
    if [ "$pid" != "" ]; then
        pidarray=$(echo $pid | tr " " "\n")
        for eachpid in $pidarray
        do
            if [ -f /proc/$eachpid/environ ]; then
                ret=$(/bin/grep -cw "AUTH_TYPE=1" /proc/$eachpid/environ 2>/dev/null)
                echo "*ret - $ret" >> /var/log/user.log
                if [[ $ret -ne 1 ]]; then
                    if [ "$eachpid" != "" ]; then
                        shell=`/bin/ps -p $eachpid -o comm= 2> /dev/null`
                        if [ "$shell" = "sh" ] || [ "$shell" = "rbash" ]; then
                            /bin/kill -9 $eachpid 2> /dev/null
                        fi
                    fi
                fi
            fi
        done
    fi
fi

}
if [ $# -ge 1 ]; then
# Logout Multiple Users
if [ $# -ge 2 ]; then
# Information for User
#echo Will logout user: $1
line="$*"
sw=`echo $line | cut -d' ' -f 1`
accts=`echo $line | cut -d' ' -f 2-`

if [ $1 == "-user" ]; then
	if [ "$3" == "genericmsg" ]; then
		msg="Security Policy, Password or Account Attribute Change: "
		accts=$2
		/bin/sleep 1
	elif [ "$3" == "timeout" ]; then
		msg="Time of Day Expired: "
		accts="$2"
	else
	msg="Security Policy, Password or Account Attribute Change: "
	fi
else
	msg="Security Policy, Password or Account Attribute Change: "
fi
msg=$msg$accts" will be logged out"
chassis_info=`getchassisconfig`
num_switches=`echo $chassis_info | \
	sed -n -e 's/Number of switches: //gp' | \
	sed -n -e 's/ .*//gp'`

# Only display message to user being logged out
for user_sess in `/usr/bin/who | grep -w "$accts" | awk '{print $2}'`
do
	echo "$msg" > /dev/$user_sess
	/bin/sleep 1
done

fi

if [ $# -eq 1 ]; then

# Logout Invalid Users
if [ $1 == "-invalid" ]; then
echo "Finding invalid users" >> /var/log/user.log
for logged_user in `who | cut -d' ' -f1`
do
echo "*logged_user - $logged_user* " >> /var/log/user.log
	kill_user=1
	# Check if the user is valid by searching the /etc/passwd file
	for valid_user in `grep "$logged_user" < /etc/passwd | cut -d':' -f1`
	do
		if [ "$logged_user" == "$valid_user" ]
		then
			kill_user=0
			break
		fi
	done
	# If user is invalid, add it to the list of accounts
	if [ $kill_user -eq 1 ]
	then
		accts="$logged_user $accts"
	fi
done
if [ "$accts" != "" ]; then
	wall "Active CP : Invalid users \"$accts\" will be logged out."
fi
accts=`echo $accts | cut -d' ' -f1-`

# matador fips rel v7.0, need to terminate all SSH sessions
# after zeroizing ssh public/private keys. 
elif [ $1 == "-ssh" ]; then

	msg="All SSH accounts will be logged out"
	wall "$msg"
	/bin/sleep 1 
	terminate_ssh_sessions

elif [ $1 == "-sftp" ]; then
	msg="SSH public/private Keys are Zeroized. SFTP sessions will be terminated"
	wall "$msg"
	terminate_sftp_sessions
elif [ $1 == "-saveown" ]; then
	msg="Security Policy, Password or Account Attribute Change: all accounts will be logged out"
	wall "$msg"
	logout_all_sessions 1
	/bin/sleep 1 
else

	echo "Invalid Arguments/Options for usrlogout"
fi

elif [ $1 == "-user" ]; then
	terminate_user_sessions $2
	/bin/sleep 1 
	exit 0

fi

echo "logged_users : $accts" >> /var/log/user.log
echo "" >> /var/log/user.log
echo "looping through all accounts" >> /var/log/user.log
# Loop through all accounts
for name in $accts; do
echo "$name" >> /var/log/user.log
	terminate_user_sessions $name
done


# no argument, logout all
elif [ $# -eq 0 ]; then

	msg="AAA Server Configuration Change: all accounts will be logged out"

	wall "$msg"
	logout_all_sessions
	/bin/sleep 1 

fi
