#!/bin/sh
#
#    Copyright (c) 2005-2006 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    File name:   timeout.sh.in 
#    Module name: fabos/src/utils/sys
#     
#    This program can be used to change the IDLE Timeout
#    value for a login session
#

SSHD_CONFIG_FILE=/etc/sshd_config
ECHO=/bin/echo
GREP=/fabos/link_bin/grep
CUT=/usr/bin/cut
SED=/bin/sed
CAT=/bin/cat
RM=/bin/rm
TR=/usr/bin/tr
AWK=/bin/awk
KILLALL=/usr/bin/killall
RSH=/usr/bin/rsh
TMP_SSHD_CONFIG_FILE=/tmp/sshd_tmp_file
WALL=/usr/bin/wall
PING=/bin/ping
CONFIG=/fabos/cliexec/config
EXPR=/usr/bin/expr

setswitch () 
{ 
    eval `/fabos/cliexec/diagenv -b writed SWITCH_ENV 0 $1`
}

setcontext () 
{ 
    if [ "$1" != "chassis" ]
    then
    	eval `/fabos/cliexec/lscfg_util --switch $1`
    else
    	eval `/fabos/cliexec/lscfg_util --chassis`
    fi
}

setBashTimeout() 
{
	choice=$1
	if [ -z "$choice" ]
	then
		choice=invalid
	fi
	nchoice=`$ECHO $choice | $TR -cd "[0-9]\n"`
	if [ "$nchoice" != "$choice" ]
	then
		printf "Please specify a numeric timeout value in minutes\n"
		usage
		exit 1
	fi
	if [ $nchoice -gt 99999 ]
	then
		printf "Please specify a timeout value in [0-99999]minutes\n"
		usage
		exit 1
	fi
	TIMESEC=`$EXPR $nchoice \* 60`
	if [ $TIMESEC -lt 0 ]
	then
		printf "Please specify a timeout value in [0-99999]minutes\n"
		usage
		exit 1
	fi
	$CONFIG set system.login.timeout 2 $TIMESEC
	
	$CONFIG update > /dev/null
	$ECHO Shell Idle Timeout Changed to $nchoice minutes
	$ECHO The modified Idle Timeout will be in effect after NEXT login
	exit

}


sshTimeoutPreCheck() {
	pizzabox=$(/fabos/cliexec/hashow | $GREP -c "Not supported on this platform")
	if [[ $pizzabox -eq 0 ]]; then
		# Chassis 
		# Check standby cp version
		otherhost=`/fabos/rbin/cipherutil get_otherhost 2>/dev/null`
		if  $PING -c 2 $otherhost >& /dev/null ; then
			STANDBY_MAJOR=`$RSH -n $otherhost /sbin/getfabosver 2>/dev/null  | $SED -n -e 's/Major://gp' 2> /dev/null`
			
			# Blocked session configuration in mixed cp case when standby is < 9 
			if  [[ $STANDBY_MAJOR -lt 9 ]];then
				#Standby is less then 9, we should only allow disabling session timeout feature
				if [[ $1 -eq 0 ]];then
					setSessionTimeout $@
				else
					# Report Error and exit
					$ECHO "Error : Session timeout feature is not supported on Standby CP."
					$ECHO "Please upgrade Standby CP to 9.0.0 or greater version."
					exit 1
				fi	
			else
				#Standby Is also >=9 We are good to go
				setSessionTimeout $@
			fi
		else
			# Standby is not up. We should block session timeout configuration.

			# We can only allow disabling session feature if standby is down.
			if [[ $1 -eq 0 ]];then
				setSessionTimeout $@
			else
				# Throw error and exit
				$ECHO "Error : Standby CP is down. Failed to get standby CP version"
				$ECHO "Please retry when Standby CP is up."
				exit 1
			fi	
		fi
	else
		#Pizza box.
		setSessionTimeout $@ 
 fi
} 

setSSHTimeout() {

	choice=$1
	nchoice=`$ECHO $choice | $TR -cd "[0-9]\n"`
	if [ "$nchoice" != "$choice" ]
	then
		printf "Please specify a numeric timeout value in minutes\n"
		usage
		exit 1
	fi
	if [ $nchoice -gt 99999 ]
	then
		printf "Please specify a timeout value in [0-99999]minutes\n"
		usage
		exit 1
	fi

	SSH_CLIENT_ALIVE_INT=`$GREP ClientAliveInterval $SSHD_CONFIG_FILE 2>/dev/null | $GREP -v '#'| $AWK '{print $2}'`

	if [[ ! -z $SSH_CLIENT_ALIVE_INT  &&  `$EXPR $SSH_CLIENT_ALIVE_INT \/ 60` -eq $1 ]] ||
	   				[[ -z $SSH_CLIENT_ALIVE_INT  &&  $1 -eq 0 ]] ;then
		if [[ $1 -eq 0 ]];then
			$ECHO "Session Timeout is already disabled."
		else
			$ECHO "Session Idle Timeout is already configured with $1."
		fi
		exit 0 	
	else
		$ECHO "SSH daemon will be restarted and all SSH session will be terminated"
		$ECHO -n "Do you want to proceed(yes, y, no, n)[no]? "
		while :
		do
			read input
			input=`$ECHO $input | $TR "[:upper:]" "[:lower:]"`
			if [ -z "$input" ]; then
				input="no"
			elif [ "$input" != "yes" ] && [ "$input" != "no" ] \
				&& [ "$input" != "y" ] && [ "$input" != "n" ]; then
				$ECHO -n "input should be either (yes, y, no, n)[no]? " 
				continue
			else
				break
			fi
		done
	fi

	if [ "$input" == "yes" ] || [ "$input" == "y" ]; then
		sshTimeoutPreCheck $@
	else
		exit 0
	fi
}

setSessionTimeout()
{
	ssh_restart_flag=0
	# Finds out whether ClientAliveInterval exists or not.
	SSH_CLIENT_ALIVE_CNT=`$GREP "ClientAliveInterval" $SSHD_CONFIG_FILE 2>/dev/null | wc -l` 
	if [[ $SSH_CLIENT_ALIVE_CNT -gt 0 ]] ; then
		if [[ $1 -eq 0 ]] ; then
			$SED -e "s/^ClientAliveInterval/#&/" $SSHD_CONFIG_FILE > $TMP_SSHD_CONFIG_FILE &&
			$CAT $TMP_SSHD_CONFIG_FILE > $SSHD_CONFIG_FILE
			$RM -f $TMP_SSHD_CONFIG_FILE
		else
			$SED -e "s/.*ClientAliveInterval.*/ClientAliveInterval `$EXPR $1 \* 60`/" $SSHD_CONFIG_FILE > $TMP_SSHD_CONFIG_FILE &&
			$CAT $TMP_SSHD_CONFIG_FILE > $SSHD_CONFIG_FILE
			$RM -f $TMP_SSHD_CONFIG_FILE
		fi
	else
	
		$ECHO "ClientAliveInterval `$EXPR $1 \* 60`" >> $SSHD_CONFIG_FILE
	fi
	# Finds out whether ClientAliveCountMax exists or not.
	SSH_CLIENT_MAX_CNT=`$GREP "ClientAliveCountMax" $SSHD_CONFIG_FILE 2>/dev/null | wc -l` 
	if [[ $SSH_CLIENT_MAX_CNT -gt 0 ]] ; then
		if [ $1 -eq 0 ] ; then
			$SED -e "s/^ClientAliveCountMax/#&/" $SSHD_CONFIG_FILE > $TMP_SSHD_CONFIG_FILE &&
			$CAT $TMP_SSHD_CONFIG_FILE > $SSHD_CONFIG_FILE
			$RM -f $TMP_SSHD_CONFIG_FILE
		else
			$SED -e "s/.*ClientAliveCountMax.*/ClientAliveCountMax 0/" $SSHD_CONFIG_FILE > $TMP_SSHD_CONFIG_FILE &&
			$CAT $TMP_SSHD_CONFIG_FILE > $SSHD_CONFIG_FILE
			$RM -f $TMP_SSHD_CONFIG_FILE
		fi
	else
	
           	$ECHO "ClientAliveCountMax 0" >> $SSHD_CONFIG_FILE
	fi

	# Re-validate if values are updated sucessfully
	if [ $1 -eq 0 ];then
		SSH_CLIENT_ALIVE_INT=` $GREP ClientAliveInterval $SSHD_CONFIG_FILE 2>/dev/null | $GREP '#'| wc -l`
		SSH_CLIENT_COUNT_MAX=` $GREP ClientAliveCountMax $SSHD_CONFIG_FILE 2>/dev/null | $GREP '#'| wc -l`
		if  [[ $SSH_CLIENT_ALIVE_INT -eq 1 ]] && [[ $SSH_CLIENT_COUNT_MAX -eq 1 ]] ; then
			$ECHO "Session Timeout is disabled"
			ssh_restart_flag=1
		else
			$ECHO "Error in updating session timeout. Please retry."
			exit 1
		fi
	else
		SSH_CLIENT_ALIVE_INT=`$GREP ClientAliveInterval $SSHD_CONFIG_FILE 2>/dev/null | $GREP -v '#' | $AWK '{print $2}'`
		SSH_CLIENT_COUNT_MAX=`$GREP ClientAliveCountMax $SSHD_CONFIG_FILE 2>/dev/null | $GREP -v '#' | $AWK '{print $2}'`
		if [[ `$EXPR $SSH_CLIENT_ALIVE_INT \/ 60` -eq $1 ]] && [[ $SSH_CLIENT_COUNT_MAX -eq 0 ]];then
			$ECHO "Session Idle Timeout changed to $1 minutes"
			ssh_restart_flag=1
		else
			$ECHO "Error in updating session timeout. Please retry."
			exit 1	
		fi			
	fi
	if [[ ssh_restart_flag -eq 1 ]];then
		# Push updated sshd_config to standby as well 
		$CONFIG save $SSHD_CONFIG_FILE

                #Reload sshd
                /fabos/rbin/cipherutil reloadssh  &>/dev/null
                if [[ $? -eq 1 ]];then
                        echo "Failed to restart ssh deamon"
                        exit 1
                fi
                #Terminate all exisiting ssh connection
                /fabos/libexec/usrlogout -ssh &> /dev/null
                if [[ $? -eq 1 ]]; then
                        echo "Failed to terminate ssh sessions"
                        exit 1
                fi
	fi	
}


usage() {
  $ECHO " "
	$ECHO "Usage: "
	$ECHO " Please specify timeout values in minutes in below format."
	$ECHO "		To set bash timeout : "
	$ECHO "			timeout <0 | 99999>"		
	$ECHO "		To set session timeout : "
	$ECHO "			timeout --session <0 | 99999>"
	$ECHO "		To show configured timeout values :"
	$ECHO "			timeout --show"
	$ECHO "		To disable session timeout :"
	$ECHO "			timeout --session 0"
	$ECHO "		To disable bash timeout :"
	$ECHO "			timeout  0"
	$ECHO " "
}

show() {
	TIMESEC=`$CONFIG get system.login.timeout 2`
	# if the timeout value is not defined we will make it to 10 minutes
	# as default value -- Defect 12101
	[ -z $TIMESEC ] && TIMESEC=600
	TIMEMIN=`$EXPR $TIMESEC \/ 60`
	$ECHO "Shell Idle Timeout is $TIMEMIN minutes"
	SSH_CLIENT_ALIVE_INT=` $GREP ClientAliveInterval $SSHD_CONFIG_FILE | $GREP -v '#'| $AWK '{print $2}'`
	if [[ -z $SSH_CLIENT_ALIVE_INT ]] ; then
		$ECHO "Session Idle Timeout is disabled."
	else
		TIMEMIN=`$EXPR $SSH_CLIENT_ALIVE_INT \/ 60`
		$ECHO "Session Idle Timeout is $TIMEMIN minutes."
	fi
	exit 0
}
export PATH=/fabos/sbin:/fabos/bin:/bin:/usr/bin:/sbin:/fabos/cliexec

#make sure the command only accessible on active CP
#retCode=`hashow | $GREP Local | $GREP -c Standby`

#if [ $retCode -eq 1 ]; then
#	$ECHO WARNING: Illegal command on Standby!
#	exit
#fi

# let us set our switch to switch 0 -- timeout value always stored in sw0
setswitch 0
#USERNAME=`/usr/bin/whoami`

if [ $# -eq 0 ]; then
	# Check RBAC permission on command
	/fabos/libexec/rbac_check `/bin/basename $0`
else
	# Check RBAC permission on identified options
	/fabos/libexec/rbac_check `/bin/basename $0` $1
fi

if [ $? -ne 0 ]; then
	exit 127
fi


if [ $# -eq 0 ] ; then
	show
fi

# with RBAC , we dont need this check below anymore.
# if we are here and role is other than root, admin, factory
# exit with error
#if [ "$USERNAME" != "root" -a "$USERNAME" != "admin" -a "$USERNAME" != "factory" -a "$USERNAME" !=  "switchadmin" ]
#then
#	$ECHO Permission denied for this account
#    exit
#fi

if [ $# -ge 3 ]; then
	$ECHO "Invalid Number of arguments."
	usage
	exit 1
fi

if [ $# -eq 1 ];then
	if [ "$1" == "--show" ];then
		show
	fi
	if [ "$1" == "--help" ];then
		usage
		exit 0
	fi
	#set Bash timeout value
	setBashTimeout $@
fi

if [ $# -eq 2 ] && [ "$1" == "--session" ];then
	#set SSH timeout value
	setSSHTimeout $2
else
	$ECHO "Invalid Input."
	usage
	exit 1
fi
