#!/bin/sh
#
#    Broadcom Proprietary and Confidential.
#    Copyright © 1996-2020 Broadcom.
#    All Rights Reserved.
#    The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
#
#    static CCM restore script to restore FOS configuration for firmware downgrade
#    and firmwarerestore CLI.
#    /etc/fabos/config/scripts/restore
#

PROGRAM='restore'
cfgutil="/etc/fabos/config/scripts/cfgutil"

TTY=$(tty)
if [ "$TTY" = "not a tty" ]
then
    TTY="/dev/null"
fi

PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/link_rbin:/fabos/factory:/fabos/xtool

#export CHASSIS_ROLEID=0
#export ROLE_ID=root
#export HOME=/root
#export LOGNAME=root
#export PWD=/root
#export LOGIN_ID=root

## Security specific default configs for password config management
## Modify here, if any of these default config's value are changed in newer releases
PWCFG_MINLENGTH="8"
PWCFG_LOWERCASE="0"
PWCFG_UPPERCASE="0"
PWCFG_CHARSET="0"
PWCFG_ALLOWUSER="Yes"
PWCFG_DIGITS="0"
PWCFG_PUNCT="0"
PWCFG_HIST="1"
PWCFG_MINPASS="0"
PWCFG_MAXPASS="0"
PWCFG_WARN="0"
PWCFG_REPEAT="1"
PWCFG_SEQ="1"
PWCFG_REV="0"
PWCFG_MINDIFF="0"

#
#include cfg utility
#
if [ -e "$cfgutil" ]; then
    . $cfgutil
    rc=$?
    if [ $rc -ne 0 ]
    then
      echo "Error -- $cfgutil err=$rc"
      exit 3
    fi
else
    echo "Error -- could not locate configuration common library $cfgutil"
    exit 3
fi

# not defined yet
if [ "$TO_VERSION" == "" ]; then
  CCM_VERSION="/etc/fabos/config/scripts/ccm_version.conf"

  if [ -f "$CCM_VERSION" ]; then
    TO_MAJOR=`cat $CCM_VERSION  | grep "TO" | /bin/awk '{print $2}'`
    TO_MINOR=`cat $CCM_VERSION | grep "TO" | /bin/awk '{print $3}'`
    TO_PATCH=`cat $CCM_VERSION | grep "TO" | /bin/awk '{print $4}'`
    TO_RELEASE=`cat  $CCM_VERSION | grep "TO" | /bin/awk '{print $5}'`

    FROM_MAJOR=`cat $CCM_VERSION | grep "FROM" | /bin/awk '{print $2}'`
    FROM_MINOR=`cat $CCM_VERSION | grep "FROM" | /bin/awk '{print $3}'`
    FROM_PATCH=`cat $CCM_VERSION | grep "FROM" | /bin/awk '{print $4}'`
    FROM_RELEASE=`cat $CCM_VERSION | grep "FROM" | /bin/awk '{print $5}'`
    /bin/chmod 644 $CCM_VERSION
  fi

  /bin/chmod 644 $CCM_VERSION
  TO_VERSION="$TO_MAJOR$TO_MINOR$TO_PATCH$TO_RELEASE"
  FROM_VERSION="$FROM_MAJOR$FROM_MINOR$FROM_PATCH$FROM_RELEASE"
fi

ntp_authentication_handling() {
	
	POSTINST="/sbin/postinst"		  # This is the postinst of new firmware

	#Downgrade handling
	#Reset ts.clockServerIndex and ts.clockServerIndexList to default values	
	cfgkey="ts.clockServerIndex"
 	cfgkey_type=5
 	cfgkey_value="-1"
 	$SWITCHCMD -1 /fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
    	
	cfgkey="ts.clockServerIndexList"
	cfgkey_type=5
	cfgkey_value="-1"
	$SWITCHCMD -1 /fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
}

root_account_enable_handling() {
	
	POSTINST="/sbin/postinst"		  # This is the postinst of new firmware
	new_fw_is_SV=$(/bin/grep -c "ROOT_ACCOUNT_REMOVAL_SUPPORT" $POSTINST) # grep in postinst of New fw

	PASSWD_FILE="/etc/passwd"
	MNT_PASSWD_FILE="/mnt/etc/passwd"
	TMP_PASSWD="/tmp/passwd"
	SHADOW_FILE="/etc/shadow"
	MNT_SHADOW_FILE="/mnt/etc/shadow"
	TMP_SHADOW="/tmp/shadow"
	NTPKEYS_FILE="/etc/ntp.keys"
	MNT_NTPKEYS_FILE="/mnt/etc/ntp.keys"
	
	#Downgrade handling
	#Add config keys: passwdcfg.oldpasswd and root.access
	if [ $new_fw_is_SV -eq 0 ]; then

		pwcfg_oldpass=`/fabos/cliexec/config get passwdcfg.oldpasswd 2`
		if [ -z "$pwcfg_oldpass" ]; then
			#if empty, add config back
			cfgkey="passwdcfg.oldpasswd"
    			cfgkey_type=2
    			cfgkey_value=0
			$CHASSISCMD /fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
		fi
		root_access=`/fabos/cliexec/config get root.access 5`
		if [ -z "$root_access" ]; then
			#if empty, add config back
			cfgkey="root.access"
    			cfgkey_type=5
    			cfgkey_value="consoleonly"
			$CHASSISCMD /fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
		fi
		$CHASSISCMD /fabos/cliexec/config update
		
		#Convert /etc/passwd root entry to /bin/sh shell
		/bin/sed 's+root:/root:/bin/false+root:/root:/bin/sh+g' $PASSWD_FILE > $TMP_PASSWD
		/bin/mv $TMP_PASSWD $PASSWD_FILE
		/bin/chmod 600 $PASSWD_FILE
		/bin/sed 's+root:/root:/bin/false+root:/root:/bin/sh+g' $MNT_PASSWD_FILE > $TMP_PASSWD
		/bin/mv $TMP_PASSWD $MNT_PASSWD_FILE
		/bin/chmod 600 $MNT_PASSWD_FILE	
		
		# Change root account password to old default in shadow for pre-9.1
		/bin/awk -F: '{ if ($1 == "root") $2="$6$xk/VD29GLswzCqlC$1o6RtIdi5qwTcXCLPRuh2x3JlOEa8sjSXmtAIjdIy1tTvxCdO3Yq7Kym9lf.V3remXI7nfXN.DpwaoYxlJy2R1";}1' OFS=: $SHADOW_FILE > $TMP_SHADOW
		/bin/mv $TMP_SHADOW $SHADOW_FILE
		/bin/chmod 600 $SHADOW_FILE
		/bin/awk -F: '{ if ($1 == "root") $2="$6$xk/VD29GLswzCqlC$1o6RtIdi5qwTcXCLPRuh2x3JlOEa8sjSXmtAIjdIy1tTvxCdO3Yq7Kym9lf.V3remXI7nfXN.DpwaoYxlJy2R1";}1' OFS=:  $MNT_SHADOW_FILE > $TMP_SHADOW
		/bin/mv $TMP_SHADOW $MNT_SHADOW_FILE
		/bin/chmod 600 $MNT_SHADOW_FILE	
		
		# Remove /etc/ntp.keys
		/bin/rm -f $NTPKEYS_FILE
		/bin/rm -f $MNT_NTPKEYS_FILE
	fi
}

tls_protocol_handling() {
	
	MNT_POSTINST="/mnt/sbin/postinst"		  # This is the postinst of new firmware
	new_fw_is_SV=$(/bin/grep -c "TLS_PROTOCOL_RANGE_SUPPORT" $MNT_POSTINST) # grep in postinst of New fw
		
	#Downgrade handling
	#Select max TLS protocol supported
	if [ $new_fw_is_SV -eq 0 ]; then
		https_tls=`/fabos/cliexec/config get protocol.https 5`
		new_https_tls=`echo $https_tls | cut -d- -f2`	
		$SWITCHCMD -1 /fabos/cliexec/config set protocol.https 5 $new_https_tls
			
		ldap_tls=`/fabos/cliexec/config get protocol.ldap 5`
		new_ldap_tls=`echo $ldap_tls | cut -d- -f2`	
		$SWITCHCMD -1 /fabos/cliexec/config set protocol.ldap 5 $new_ldap_tls
		
		radius_tls=`/fabos/cliexec/config get protocol.radius 5`
		new_radius_tls=`echo $radius_tls | cut -d- -f2`	
		$SWITCHCMD -1 /fabos/cliexec/config set protocol.radius 5 $new_radius_tls
		
		syslog_tls=`/fabos/cliexec/config get protocol.syslog 5`		
		new_syslog_tls=`echo $syslog_tls | cut -d- -f2`	
		$SWITCHCMD -1 /fabos/cliexec/config set protocol.syslog 5 $new_syslog_tls
		
		$SWITCHCMD -1 /fabos/cliexec/config update
	fi	
}

maintenance_working_directory_deletion() {
	POSTINST="/sbin/postinst"		  # This is the postinst of new firmware
	MAINT_WORKING_DIR="/fabos/users/maintenance/maintwd"
	new_fw_is_SV=$(/bin/grep -c "MAINTENANCE_WORKING_DIR_REMOVAL_SUPPORT" $POSTINST) # grep in postinst of New fw

	#Downgrade handling
	#Remove maintenance working directory
	if [ $new_fw_is_SV -eq 0 ]; then
		if [ -d "$MAINT_WORKING_DIR" ]; then
			/bin/rm -rf $MAINT_WORKING_DIR
		fi
	fi
}


#MAIN
# Get the command-line options

#$CFGLOG_INIT
$CFGLOGD "$PROGRAM $@"
$CFGLOG "CURRENT_VF=$CURRENT_VF FABOS_SWITCHNO=$FABOS_SWITCHNO"

#setcontext chassis
#value=`/fabos/cliexec/config get cfgut.debug 2`
#if [ ! -z ${value+x} ]; then
#    CFGCMD="cfgcmd"
#fi  

do_910_restore ()
{
  setcontext 128
  # if unit test is enabled
  cfgut_enable=`/fabos/cliexec/config get cfgut.enable 2`

  #if [ -f "$cfgutf" ]; then
  #if [ ! -z ${cfgut_enable+x} ] && [ ! -z "$cfgut_enable" ]; then

  if [ "$cfgut_enable" == "1" ]; then

    # remove 9.1 default syslog ip
    $CFGCMD syslogadmin --remove -ip 1.2.3.4

    # change 9.1 syslog faciity to 9.0.1 default value
    $CFGCMD syslogadmin --set -facility 4
    # file operation
  else
     $CFGLOG "${FUNCNAME[0]} none CFGUT"  
  fi
  
  # remove 9.1 ntp auth config keys
  ntp_authentication_handling

  # Enable root account in pre-9.1
  root_account_enable_handling

  #Remove maintenance working directory in pre-9.1.1
  maintenance_working_directory_deletion
}

passwdcfg_status_field_handling()
{
	FABOS_SWITCHNO_TEMP=$FABOS_SWITCHNO
	FABOS_SWITCHNO=0

	pwcfg_status=`/fabos/cliexec/config get passwdcfg.status 2`
	pwcfg_lockoutthreshold=`/fabos/cliexec/config get passwdcfg.lockoutthreshold 2`
	pwcfg_adminlockout=`/fabos/cliexec/config get passwdcfg.adminlockout 2`
	pwcfg_lockoutduration=`/fabos/cliexec/config get passwdcfg.lockoutduration 2`
	pwcfg_adminlockoutconsoleaccess=`/fabos/cliexec/config get passwdcfg.adminlockoutconsoleaccess 2`
	cfgkey_value=-1

	$CFGLOG "restore: initial values: status: $pwcfg_status pwcfg_lockoutthreshold=$pwcfg_lockoutthreshold pwcfg_adminlockout=$pwcfg_adminlockout pwcfg_lockoutduration=$pwcfg_lockoutduration pwcfg_adminlockoutconsoleaccess=$pwcfg_adminlockoutconsoleaccess"

	# If these values are not at pre-9.2.0 default, 
	# then set status=1 (non-default value present)
	if [[ "$pwcfg_lockoutthreshold" -ne "0" || "$pwcfg_adminlockout" -ne "0" || "$pwcfg_lockoutduration" -ne "30" ]]; then
		if [ "$pwcfg_status" -eq "0" ]; then
			cfgkey_value=1
			$CFGLOG "restore: setting pwcfg_status=1"
		fi

	elif [[ "$pwcfg_lockoutthreshold" -eq "0" && "$pwcfg_adminlockout" -eq "0" && "$pwcfg_lockoutduration" -eq "30" && \
		"$pwcfg_status" -eq "1" ]]; then

		# If above configs are at pre-92 default and remaining passwdcfg values are 
		# also at pre-920 default, then set status to 0.

		pwcfg_minlen=`/fabos/cliexec/config get passwdcfg.minlength 2`
		pwcfg_lowercase=`/fabos/cliexec/config get passwdcfg.lowercase 2`
		pwcfg_uppercase=`/fabos/cliexec/config get passwdcfg.uppercase 2`
		pwcfg_charset=`/fabos/cliexec/config get passwdcfg.charset 2`
		pwcfg_allowuser=`/fabos/cliexec/config get passwdcfg.allowuser 5`
		pwcfg_digits=`/fabos/cliexec/config get passwdcfg.digits 2`
		pwcfg_punct=`/fabos/cliexec/config get passwdcfg.punctuation 2`
		pwcfg_hist=`/fabos/cliexec/config get 'passwdcfg.history' 2`
		pwcfg_minpass=`/fabos/cliexec/config get passwdcfg.minpasswordage 2`
		pwcfg_maxpass=`/fabos/cliexec/config get passwdcfg.maxpasswordage 2`
		pwcfg_warn=`/fabos/cliexec/config get passwdcfg.warning 2`
		pwcfg_repeat=`/fabos/cliexec/config get passwdcfg.repeat 2`
		pwcfg_seq=`/fabos/cliexec/config get passwdcfg.sequence 2`
		pwcfg_rev=`/fabos/cliexec/config get passwdcfg.reverse 2`
		pwcfg_mindif=`/fabos/cliexec/config get passwdcfg.minDiff 2`

		if [ "$pwcfg_minlen" -eq "$PWCFG_MINLENGTH" ] && [ "$pwcfg_lowercase" -eq "$PWCFG_LOWERCASE" ] && \
			[ "$pwcfg_uppercase" -eq "$PWCFG_UPPERCASE" ] && [ "$pwcfg_charset" -eq "$PWCFG_CHARSET" ] && \
			[ "$pwcfg_allowuser" == "$PWCFG_ALLOWUSER" ] && [ "$pwcfg_digits" -eq "$PWCFG_DIGITS" ] && \
			[ "$pwcfg_punct" -eq "$PWCFG_PUNCT" ] && [ "$pwcfg_hist" -eq "$PWCFG_HIST" ] && \
			[ "$pwcfg_minpass" -eq "$PWCFG_MINPASS" ] && [ "$pwcfg_maxpass" -eq "$PWCFG_MAXPASS" ] && \
			[ "$pwcfg_warn" -eq "$PWCFG_WARN" ] && [ "$pwcfg_repeat" -eq "$PWCFG_REPEAT" ] && \
			[ "$pwcfg_seq" -eq "$PWCFG_SEQ" ] && [ "$pwcfg_rev" -eq "$PWCFG_REV" ] && \
			[ "$pwcfg_mindif" -eq "$PWCFG_MINDIFF" ];then

			cfgkey_value=0
			$CFGLOG "restore: setting pwcfg_status=0"
		fi
	fi

	if [ "$cfgkey_value" -ne "-1" ]; then
		cfgkey="passwdcfg.status"
		cfgkey_type=2

		/fabos/cliexec/config set $cfgkey $cfgkey_type $cfgkey_value
	fi

	pwcfg_status=`/fabos/cliexec/config get passwdcfg.status 2`

	$CFGLOG "restore: final values: status: $pwcfg_status "
	FABOS_SWITCHNO=$FABOS_SWITCHNO_TEMP
}

do_920_restore ()
{
  setcontext 128
  
  # Set TLS protocol to max version supported in cases 
  # where TLS protocol range is specified in pre-9.2.0
  tls_protocol_handling

  # Default values of following parameters got changed in FOS 9.2.0:
  # passwdcfg.lockoutthreshold: from 0 (pre-9.2.0) -> 3 (9.2.0)
  # passwdcfg.adminlockout from 0 (pre-9.2.0) -> 1 (9.2.0)
  # passwdcfg.adminlockoutconsoleaccess from 0 (pre-9.2.0) -> 1 (9.2.0)
  # passwdcfg.lockoutduration from 30 (pre-9.2.0) ->5 (9.2.0)
  # So make sure that passwdcfg.status value is set to 1 in case the above
  # values from FOS-9.2.0 firmware are not same as pre-FOS-9.2.0 defaults
  passwdcfg_status_field_handling

}
$CFGLOG "FWDL $FROM_VERSION to $TO_VERSION"
# downgrade from 9.1.x to pre-9.1.0 but after 9.0.1a
if [[ "$FROM_VERSION" == "910" ]] || [[ "$FROM_VERSION" > "910" ]] && [[ "$TO_VERSION" < "910" ]]; then
  if [[ "$TO_VERSION" == "901a" ]] || [[ "$TO_VERSION" > "901a" ]]; then
   # build 901a sring to ivoke do_910 if from < 910
    do_910_restore
  fi
fi

# downgrade from 9.2.x to pre-9.2.0 but after 9.0.1a
if [[ "$FROM_VERSION" == "920" ]] || [[ "$FROM_VERSION" > "920" ]] && [[ "$TO_VERSION" < "920" ]]; then

  if [[ "$TO_VERSION" == "901a" ]] || [[ "$TO_VERSION" > "901a" ]]; then

   # build 901a sring to ivoke do_910 if from < 910
    do_920_restore

  fi

fi

$CFGLOGD "$PROGRAM Exit"

exit 0
