#
#    Copyright (c) 1996-2007 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    System-wide environment profile for all Bourne- and Korn-
#    compatible login shells.
#

# FOS-849416
# Fork bomb
# Restrict shell function recursion.
FUNCNEST=3

# If temporary env var corresponding to ROLE_ID, CURRENT_VF and FABOS_SWITCHNO
# exist, assign original var from them and then remove the temp var. This is 
# done because these var are readonly so we can't modify them in the same 
# shell where they are defined as readonly.
if [ -n "${ROLE_ID_T+x}" ]; then
	ROLE_ID=$ROLE_ID_T
	unset ROLE_ID_T
fi

# $SWLOGNAME is the login account name $LOGNAME stripped of switch
# instance number. It replaces the usage of LOGNAME in the old
# script to keep it compatible with account name per switch instance.

# The following condition takes care of login without PAM module.
if [ "$SWLOGNAME" = "" ]; then
	SWLOGNAME="$LOGNAME"
fi

#
# Shell prompt (VxWorks-compatible)
#
#
#
# Ignore control-C when env is initializing for restricted shells
# trap will set back to default in individual user profiles.
# Following three lines should not be moved from this position.
#
# Disable interrupts for root profile also (defect 25763).
#if [ "$SWLOGNAME" != "root" ]; then
	trap "" INT
#fi

#
# Check number of successive logins in same session
#
check_login_count()
{
	login_count=0
	parent=""
	P=$PPID
	while true ; do
		item_count=0
		for item in `</proc/$P/stat` ; do
			item_count=`expr $item_count + 1`
			if [ $item_count = 2 ] ; then
        			cmd=$item
        		fi
			if [ $item_count = 4 ] ; then
        			parent=$item
        			break
        		fi
		done
		P=$parent
		if [ $cmd = "(login)" ] ; then
        		login_count=`expr $login_count + 1`
       		fi
		if [ $parent = 1 -o $parent = 0 ] ; then
        		break
        	fi
	done
	/bin/echo $login_count
}

max_telnet_sessions=4
max_maintenance_sessions=4
max_total_sessions=32
max_same_session_logins=5
safe_max_sessions_limit=125
num_logins=`check_login_count`
if [ $num_logins -gt `expr $max_same_session_logins` ] ; then
        /bin/echo "Same session logins exceeded. Autologout"
        /bin/sleep 2
        exit 2 >/dev/null
        fi
if [ $num_logins -gt `expr $max_same_session_logins - 1` ] ; then
        echo "Same session login limit reached. Logout before next login"
        fi

rolename=`/usr/bin/id -gn`

if [ "$rolename" = "nonfcsadmin" ]; then
	/fabos/libexec/secRoleCheck $FABOS_SWITCHNO $rolename
	if [ $? -ne 0 ]; then
		exit 2>/dev/null
	fi
fi

#
# set umask
#
umask 027

#
# Get the number of session by remote user with given role
#
get_remote_count()
{
	rlogin=0
	uid=`/usr/bin/id -u`
	login_list=`/bin/ps -u $uid | /bin/grep "rbash" | /bin/awk {'print $1'}` 2>/dev/null
	for l in `echo $login_list`
	do
		env=`/bin/cat /proc/$l/environ  2>/dev/null | /bin/grep 'AUTH_TYPE=1'` 2>/dev/null
		if [[ ! -z $env ]]; then
			rlogin=`expr $rlogin + 1`
		fi	
	done
	echo $rlogin
}

#
# Get the number of session the current user is logged in
#
get_user_session_count()
{
	count=0
	userlength=`expr length $LOGNAME`
	#Here console port login is also included from no_sessions
	if [ $userlength -gt 32 ]; then
		username=`echo $LOGNAME | /usr/bin/cut -c 1-32`
	else
		username=$LOGNAME
	fi
	user_list=`/usr/bin/who -u | /bin/grep $username | /usr/bin/cut -d ' ' -f1` 2>/dev/null
	for u in `echo $user_list`
	do
		if [ $u = $username ]; then
			count=`expr $count + 1`
		fi
	done
	if [ "$username" == "admin" ] || [ "$username" == "user" ]; then
		rlogin=`get_remote_count`
		if [ $rlogin  -le $count ]; then
			count=`expr $count - $rlogin`
		fi
	fi
	echo $count

}
#Here accounts logged in using switch authentication type are considered
if [[ $AUTH_TYPE = 0 ]]; then
	no_sessions=`get_user_session_count`
	if [ "$SWLOGNAME" = "maintenance" -a $no_sessions -gt $max_maintenance_sessions ]; then
		/bin/echo "Max remote sessions for login:$SWLOGNAME is $max_maintenance_sessions"
		exit 2>/dev/null
	fi
	if [ $no_sessions -gt $max_telnet_sessions ]; then
		/bin/echo "Max remote sessions for login:$SWLOGNAME is $max_telnet_sessions"
		exit 2>/dev/null
	fi
	#Checking for no. of established ssh sessions. There is a possibility of having ssh sessions that are retained even after
	#logout of the user and cleanup of the corresponding pts (such sessions will be listed in /proc/net/tcp but would not be
	#associated with any /dev/pts device in /proc/<pid>/fd/). Below logic takes care of cleaning up such sessions one at a time
	#per every new login session attempted. The cleanup logic kicks in if no. of existing sessions exceeds "max_total_sessions" and if by any other
	#means, the number of sessions crosses "safe_max_sessions_limit", then we donot allow further login sessions.
	no_ssh_established_sessions=$(expr `/bin/grep -E '{14}:0016.{14} 01' /proc/net/tcp | /usr/bin/wc -l` + `/bin/grep -E '{38}:0016.{38} 01' /proc/net/tcp6 | /usr/bin/wc -l`)
	if [ $no_ssh_established_sessions -gt $max_total_sessions ]; then
		/fabos/libexec/secUtil "KILL_STALE_SSH"
	fi
	if [ $no_ssh_established_sessions -ge $safe_max_sessions_limit ]; then
		/bin/echo "Too many ssh/telnet sessions established. Please close an existing session to establish a new one"
		exit 2> /dev/null
	fi
else
	if [ "$rolename" = "maintenance" ]; then
		#Here console port login is also included from no_sessions
		userlength=`expr length $LOGNAME`
		if [ $userlength -gt 32 ]; then
			username=`echo $LOGNAME | /usr/bin/cut -c 1-32`
			no_sessions=`/usr/bin/who -u | /bin/grep "$username" | /usr/bin/wc -l` 2>/dev/null
		else
			no_sessions=`/usr/bin/who -u | /bin/grep "$LOGNAME" | /usr/bin/wc -l` 2>/dev/null
		fi
		if [ "$SWLOGNAME" = "maintenance" -a $no_sessions -gt $max_maintenance_sessions ]; then
			/bin/echo "Max remote sessions for login:$SWLOGNAME is $max_maintenance_sessions"
			exit 2>/dev/null
		fi
	fi
fi	

total_sessions=`/usr/bin/who | /usr/bin/wc -l` 2>/dev/null
if [ $total_sessions -gt $max_total_sessions ]; then
	/bin/echo "Max remote sessions for all accounts is $max_total_sessions"
   exit 2>/dev/null
fi

# Standard search path for commands
PATH="/fabos/bin:/bin"
standby=0

/fabos/cliexec/hashow | /bin/grep Local | /bin/grep Standby > /dev/null 2>&1
if [ $? -eq 0 ]; then
	standby=1
fi

# if passwd is aged and if we are on active CP, ask for a new passwd.
if [ $passwd_aged ]; then 
	if [ $passwd_aged -eq 1 -o $passwd_aged -eq 2 ]; then
		trap "" INT
		if [ $standby -eq 0 ]; then
			/bin/echo "Your password has expired. Please change your password now."
			/fabos/bin/passwd
			if [ $? -ne 0 ]; then
				exit 2>/dev/null
			else
				unset passwd_aged
			fi
		else
			/bin/echo "Your password has expired. Please login to the ACTIVE CP and change your password now."
			exit 2>/dev/null
		fi
	fi
fi

setup_standby_profile=0

# "root" and "factory" will be allowed all commands in /fabos/bin on standby
# See Defect 9952. Reversing fix for 9952. See Defect 10338.
if [ "$SWLOGNAME" != "root" -a "$SWLOGNAME" != "factory" -a  $standby -eq 1 ]; then
	setup_standby_profile=1
fi


#
# Telnet IDLE Login Timeout
# Default Timeout is 10 minutes
# The timeout value(in seconds) is stored in system.login.timeout
# in config database in switch 0
# Must get timeout value from sw0 --- Defect 25800
#
switchno=$FABOS_SWITCHNO
FABOS_SWITCHNO=0

TMOUT=`/fabos/cliexec/config get system.login.timeout 2`
# if the timeout value is not defined we will make it to 10 minutes
[ -z $TMOUT ] && TMOUT=600


#
# CLP handling
#
/fabos/cliexec/licadmin -c 2>/dev/null

#
# EULA, login handling
#
# check EULA if switch is not in RRD state
/sbin/bootcount -c > /dev/null 2>&1
if [ $? -eq 0 ]; then
  /fabos/cliexec/eula_fal -c 2>/dev/null
  if [ $? -ne 0 ]; then
     /bin/echo "Failed to process EULA acceptance, auto-logout"
     exit 2> /dev/null
  fi
fi

#
# License LID and hash check handling. Do not do this anymore
#
#/fabos/cliexec/lic_llv -c 2>/dev/null

#
# Set man page handling for root only commands.
# Export "1r" for /fabos/man/cat1r/ to MANSECT env
#
if [ "$SWLOGNAME" == "root" ] || [ "$SWLOGNAME" == "maintenance" ]; then
	export MANSECT="1:1r:1d:1m:8:2:3:4:5:6:7:9:tcl:n:l:p:o"
fi

#
# Shell history (VxWorks-compatible)
#
unset HISTFILE
HISTSIZE_DISABLE=`/fabos/cliexec/config get system.histsize.disable 2`
if [ -z $HISTSIZE_DISABLE ] || [ $HISTSIZE_DISABLE -eq 0 ]; then
     HISTSIZE=20
else
     HISTSIZE=0
fi
# get rid of duplicate history, subject to bash version
export HISTIGNORE='&'

FABOS_SWITCHNO=$switchno; export FABOS_SWITCHNO

#
# Other miscellaneous shell aliases
#
alias h='history'		# VxWorks compatibility

enable -n help

if [ "$SWLOGNAME" != "root" ]; then
	enable -n kill   #disable access to shell builtin 'kill' for restricted shells
fi

#
# Export the switch instance to the shell
#
export_switch()
{
	case "$1" in
	    0)
		eval `/fabos/cliexec/diagenv -b writed SWITCH_ENV 0 0`
		;;
	    1)
		eval `/fabos/cliexec/diagenv -b writed SWITCH_ENV 0 1`
		;;
	    *)
		printf "Invalid Input. Logging to Switch 0...\n"
		eval `/fabos/cliexec/diagenv -b writed SWITCH_ENV 0 0`
		;;
	esac
}

#
# Set consloe switch number, based on platform
#
set_console_switch()
{
    #
    # For non-ulysses platforms, enter into switch 0.
    # Please make sure it is consistent with
    # /etc/rc.d/init.d/fabos
    #
    CHASINFO=`/bin/getchassisconfig`
    ISCHASSIS=`echo $CHASINFO | \
	/bin/sed -n -e 's/.*Chassis based system: //gp'	| \
	/bin/sed -n -e 's/ .*//gp'`
    NUM_SWITCHES=`echo $CHASINFO | \
	/bin/sed -n -e 's/Number of switches: //gp' | \
	/bin/sed -n -e 's/ .*//gp'`
    if [ "$NUM_SWITCHES" == "2" ]; then
	printf "Enter Switch Number to Login <0 or 1>: "
	read choice
	export_switch $choice
    fi
}

#
# Set switch number based on the user input
#
set_switch_inst()
{
    case "$1" in
	# If this is console
	'/dev/console' | '/dev/ttyS0' | '/dev/ttyS1')

	    set_console_switch
	    ;;
	*)
	    eval `/fabos/etc/swInst $PPID`
	    ;;
    esac
}

#
# Init switch number based on environment variable $FABOS_SWITCHNO
#
init_switch_inst()
{
	case "$1" in
	#if this is console
	'/dev/consol' | '/dev/ttyS0' | '/dev/ttyS1')

		CHASINFO=`/bin/getchassisconfig`
		ISCHASSIS=`echo $CHASINFO | \
			/bin/sed -n -e 's/.*Chassis based system: //gp' | \
			/bin/sed -n -e 's/ .*//gp'`
		NUM_SWITCHES=`echo $CHASINFO | \
			/bin/sed -n -e 's/Number of switches: //gp' | \
			/bin/sed -n -e 's/ .*//gp'`
		if [ "$NUM_SWITCHES" == "2" ]; then
			export_switch $FABOS_SWITCHNO
		fi
		;;
	*)
		eval `/fabos/etc/swInst -s $FABOS_SWITCHNO`
		;;
	esac
}

if [ $setup_standby_profile -eq 0 ]; then
	PATH="/fabos/bin"

	# Do NOT use full path or commands not available to admin
	eval `/fabos/cliexec/diagenv ALIAS`

	# only do this if PAM module failed to set it
	if [ "$FABOS_SWITCHNO" = "" ]; then
		# Set the switch number, this is used for non-PAM login.
		set_switch_inst `/usr/bin/tty`
	else
		init_switch_inst `/usr/bin/tty`
	fi

else
	PATH="/fabos/standby_bin"
fi

# Set terminal type to "vt100" (supported by all platforms)
TERMINFO=/usr/share/terminfo
TERM="vt100"

export PATH PS1 HISTSIZE TERM setup_standby_profile TERMINFO

SWNAME=`/fabos/cliexec/.sname 2>/dev/null`

# replace \ with \\ in $LOGIN_ID to prevent side-effects of \ in $LOGIN_ID
if [ "$VF_ENABLED" == 1 ]
then 
	PS1="$SWNAME:FID$CURRENT_VF:${LOGIN_ID//\\/\\\\}> "
else
	if [ "$CURRENT_AD" != 0 ]
	then
		PS1="$SWNAME:AD$CURRENT_AD:${LOGIN_ID//\\/\\\\}> "
	else
		PS1="$SWNAME:${LOGIN_ID//\\/\\\\}> "
	fi
fi

#Commenting out as this will be handled in pam session
# Skip the login_notify for ad --select 
# argv0=$0
#var=`echo ${argv0:0:1}`
#if [ "$var" == "-" ]
#then
#	/fabos/libexec/login_notify `/usr/bin/tty`
#fi

source /fabos/cliexec/tsSetEnvTZ

# tsTimeZone command sources tsTZ script to set TZ variable in the
# current session. Note that these aliases override commands of the
# same name, so that we can still use "ssh -n switch tsTimeZone Europe/London"
# to set the timezone on the switch.
tsTimeZone() {
	command "tsTimeZone" "$@"
	return $?
}

alias tstimezone=tsTimeZone



LESS="-isdePType <CR> or <SPACE BAR> to continue, <q> to stop"
PAGER="/usr/bin/less"
MANPAGER=$PAGER

export LESS
export PAGER
export MANPAGER
export LINES 

# Make sure the man pages are displayed correctly
export MANWIDTH=80

# Bill Lewis Suppress the set builtin due to defect 8805 12-19-01
enable -n set

# Make sure execlogin is available as builtin for all the users
# enable -f /fabos/lib/execlogin execlogin

# Make sure setcontext is available as builtin for all the users 
enable -f /fabos/lib/setcontext setcontext 

# set logic switch context
# 1. active cp
# 2. vf enabled
# 3. not from previous execlogin session in setcontext
if [ $standby -eq 0 -a $[$VF_ENABLED] -gt 0 -a "$CURRENT_VF" != "$SETCONTEXT" ]; then
	# get telnet/ssh connection destination ip address
	if [ -n "$SSH_CONNECTION" ]; then
		SESSION_IP_ADDR=${SSH_CONNECTION% [0-9]*}
		SESSION_IP_ADDR=${SESSION_IP_ADDR##* }
	else
		[ -n  "$TELNET_IP_ADDR" ] && SESSION_IP_ADDR=${TELNET_IP_ADDR##*:}
	fi

	# Excluding telnet from console
	if [ -n "$SESSION_IP_ADDR" -a -e /fabos/link_bin/ipaddrshow ]; then
		# get fid from ip address
		tmpstr="`export ROLE_ID=root;CURRENT_VF=255;/fabos/link_bin/ipaddrshow | /bin/grep fabric\ ID | /bin/grep ${SESSION_IP_ADDR}/`"
		[ -n "$tmpstr" ] && tmpstr=${tmpstr%%: [1-9]*} && fid=${tmpstr##* }
	fi
fi

#invoke savehistory() everytime the user prompt returns
PROMPT_COMMAND=savehistory

# for noN-root users, make RBAC/AD env variables readonly. def. 74490
if [ "$SWLOGNAME" != "root" ]; then
	readonly LOGIN_ID
	readonly CURRENT_AD
	readonly HOME_AD
	readonly ADMAP
	readonly HOME_VF
	readonly VFROLEMAP
	readonly CHASSIS_ROLEID
	readonly ROLE_ID
	readonly PROMPT_COMMAND
	readonly SWLOGNAME
	readonly SVCEXEC_FLAG
	readonly PWD_CHK_DFLT
	readonly DISP_DFLT_MSG
	readonly SPWDSKIP
	readonly OLD_PASS_CHECK
	readonly MAX_SESS_REACHED
	readonly DISP_MAX_SESS_MSG
	readonly PAMERROR
	readonly BASH_CMDS
	readonly SERVICESHELL_FLAG
	readonly FACTORYSHELL_FLAG
        readonly SS_TMP_DIR
        readonly SS_MODULE
		readonly LOCAL_IP
		readonly GREP_OPTIONS
		readonly FUNCNEST
fi

# savehistory is used to pipe every CLI to clihistory so that we are saving
# a history of what the user is typing in.
savehistory() {
	local newcmd
	newcmd=$(history 1)
	local hdel
	hdel=$(CLI_HISTORY_ADD=SET PROMPT_COMMAND_EXECUTION=SET PROMPT_COMMAND_OLD="${oldcmd#*[0-9]*  }" PROMPT_COMMAND_NEW="${newcmd#*[0-9]*  }" CMD_HISTORY_1=$newcmd clihistory --add)
	$hdel
	oldcmd=$newcmd
}

savehistoryonreboot() {
		export CLI_HISTORY_ADD="SET"
		echo "$1 $2 $3" | clihistory --add
		export CLI_HISTORY_ADD=""
}
declare -x -f savehistoryonreboot

# found mapping FID from login ip address
if [ $[$fid] -gt 0 ]; then
	setcontext $fid $SESSION_IP_ADDR
fi

# SSH Banner dispaly related
if  [ -f /etc/fabos/issue.$FABOS_SWITCHNO ] && [ -r /etc/fabos/issue.$FABOS_SWITCHNO ] && [ -s /etc/fabos/issue.$FABOS_SWITCHNO ]; then
	/bin/cat /etc/fabos/issue.$FABOS_SWITCHNO
	echo ""
	echo "-----------------------------------------------------------------"
fi

if [ -x /etc/fabos/profile ] && [ -r /etc/fabos/profile ]; then
	. /etc/fabos/profile
	if [ $standby -eq 1 ]; then
		echo "*****************************************************************"
		echo "Logging into STANDBY CP, not all commands are fully supported !!"
		echo "*****************************************************************"
	fi
fi

# Unset the function check_login_count, so that it is not exported as CLI
unset -f check_login_count

#unset the init_switch_inst
unset -f init_switch_inst

#unset get_user_session_count
unset -f get_user_session_count

#unset get_remote_count
unset -f get_remote_count
if [ $ROLE_ID != "remotedomain" ]; then
	/bin/stty susp ""
fi
