#!/bin/sh
#
#    Copyright (c) 2016 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    Description:
#		This is a different flavor of postinstall checking script.
#		Essentially it is intended to make easier the
#		Compatibility checking of newly introduced features
#		which are introduced in new releases but also
#		back ported to Older maint/patch release versions as well
#
#		The current postinstall operation design is to always run the 
#		postinstall of the higher of the two versions.
#		This does not lend itself to checking whether
#		the new firmware being downloaded supports a given feature,
#		except through a complex specific version checking.
#
#		This scheme requires such new features to be identified by
#		a tag in postinstall script that helps identify if the new release
#		being downloaded supports the given feature or not.
#
#		If is important that each feature compatibility check
#		- Appends the corresponding error message to BOTH  ERROR/STATUS FILES
#		  STATUS_FILE and BNA_STATUS_FILE
#		- Increments the return code count (or alternately set it to non zero)
#		- return STS_ERR (this is not required but recommended for consistency)
#		This will permit a one pass checking of all features
#		And a cumulative message reflecting all corrective actions.
##############################################################################
TATOOINE_UID_SUPPORT="udrole"
PATH=/bin:/usr/bin:/sbin:/usr/sbin 

if [ "$DEBUG" = 1 ]; then
	ECHO='echo -e'
else
	ECHO=:
fi

STS_ERR=255
STS_OK=0
rc=$STS_OK
STATUS_FILE=/tmp/fwdl_err.txt
BNA_STATUS_FILE=/tmp/bna_fwdl_err.txt

MNT_POSTINST="/mnt/sbin/postinst" # This is the new firmware being downloaded
POSTINST="/sbin/postinst"		  # This is the current / running firmware


#
# Common variables
#

NULL=/dev/null

#
# swbd
#
# Retrieve the current system platform name, of the form "SWBDn", where n
# is cardinal number, assuming a sin/hinv input stream.
#
swbd() {
	sed -n -e 's/^.\+\(SWBD[[:digit:]]\{1,\}\).\+$/\1/gp'
}

# echo "Invokig Post Install Check feature Script $NEW_POSTINST_FILE" 
# cpid
#
# Retrieve the current Control Processor ID
#
cpid() {
	sed -n -e 's/^Control.\+No: \([[:digit:]]\{1,\}\)$/\1/gp'
}

# Determine the system platform identifier.
SWBD=`sin | swbd 2> ${NULL}`
CPID=`sin | cpid 2> ${NULL}`

otherhost(){
	case ${SWBD##SWBD} in
	'62')
	    printf 127.1.1.$((8 - CPID % 2))
	    ;;
	'77')
	    printf 127.1.1.$((6 - CPID % 2))
	    ;;
	'141')
		printf 127.1.$((17 - CPID % 2)).$((17 - CPID % 2))
		;;
	'142')
		printf 127.1.$((15 - CPID % 2)).$((15 - CPID % 2))
		;;
	'165' | '166')
	    printf 127.3.1.$((2 - CPID % 2))
	    ;;
	*)
	    printf 10.0.0.$((6 - CPID % 2))
	    ;;
	esac
}

correcthost() {
    if [ $ACTIVECP ]; then
	"$@"
    else
	/usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CHASSIS_ROLEID=0 CURRENT_AD=0 "$@"
    fi
}

#
# Helper functions
#

HASHOW="$(/fabos/bin/hashow)"
hashow_cmd=$(ls /fabos/cliexec/hashow)
if [ "$hashow_cmd" != "/fabos/cliexec/hashow" ]; then
       	hashow_cmd="/fabos/bin/hashow"
fi

ha_role() {
 	case "$($hashow_cmd | ( read a; echo $a ))" in
	    *Local*Active*)
	    printf "ACTIVE"
 	    ;;
	    *Local*Standby*)
	    printf "STANDBY"
 	    ;;
	    *"Not supported"*)
	    printf "ACTIVE"
 	    ;;
	    *)
	    printf "STANDBY"
	    ;;
	esac
}

if [ $(ha_role) == "ACTIVE" ]; then
    ACTIVECP=1
	STANDBYCP=0
else
	STANDBYCP=1
fi

ha_state() {
    sync=`/fabos/cliexec/hashow | sed -n -e 's/^.\+\(State sync\).\+$/\1/gp'`
    if [ "$sync" != "State sync" ]; then
	    printf "NOSYNC"
    else
	    printf "SYNC"
    fi
}


CONTEXTS=""

CHASSISCMD=""
cliidx=0
export PATH=/fabos/link_bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/link_abin:/fabos/link_sbin:/fabos/factory:/fabos/xtool
export VFROLEMAP=-1:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0
export CHASSIS_ROLEID=0
if /fabos/bin/fosconfig --show | grep "Virtual Fabric" | grep enabled > /dev/null 2>&1 ; then VF_ENABLED=$STS_ERR; else VF_ENABLED=$STS_OK; fi

glb_ls_id=-1
glb_vf_id=255
def_vf_id=128


#
# both Active and Standby have the information of
# VF and logical switches configured.
## VF case: on Standby CP, in order to login to each logical switch, 
# we need to set CHASSIS_ROLEID FABOS_SWITCHNO CURRENT_VF in rsh.
#
correcthost_to_curr_vfid() {
    if [ $ACTIVECP ] ; then
        # for_all_context already did "context_switch --switch vfid"
        "$@"
    else
        if [ $VF_ENABLED -eq $STS_OK ]; then
            # VF disabled
            /usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CURRENT_AD=0 "$@"
        else
            # VF enabled, for_all_context changed glb_ls_id and glb_vf_id to each logical switch's
            /usr/bin/rsh -n $(otherhost) ROLE_ID=root LOGIN_ID=root CHASSIS_ROLEID=0 FABOS_SWITCHNO=$glb_ls_id CURRENT_VF=$glb_vf_id CURRENT_AD=0 "$@"
        fi
    fi
}

#UID_CONVERSION="Versio Supports UID Conversion"
uid_conversion()
{
	new_fw_is_SV=$(grep -c "UID_CONVERSION" $MNT_POSTINST) # grep in postinst of New fw
	cur_fw_is_SV=$( grep -c "UID_CONVERSION" $POSTINST)    # grep in postinst of Current fw

	# 8.0.1 supports above feature but not feature tag
	# Look for special string in postinstall 
	# to detect feature support
	if [ $new_fw_is_SV -eq 0 ]; then
		new_fw_is_SV=$(grep -c $TATOOINE_UID_SUPPORT $MNT_POSTINST) # grep in postinst of New fw
	fi	
	if [ $cur_fw_is_SV -eq 0 ]; then
		cur_fw_is_SV=$(grep -c $TATOOINE_UID_SUPPORT $POSTINST) # grep in postinst of Current fw
	fi	
	
	if [ $cur_fw_is_SV -gt 0 ]; then
		#Backward Conversion
		if [ $new_fw_is_SV -eq 0 ]; then
			#Password Conversion - UID Backward Conversion
			correcthost_to_curr_vfid /fabos/libexec/passwd_convert /mnt/etc/passwd FWDL_CONVERSION UID_BACKWARD_CONVERSION > /dev/null 2>&1
			correcthost_to_curr_vfid /bin/cp /mnt/etc/passwd /etc/passwd > /dev/null 2>&1
			correcthost_to_curr_vfid /fabos/cliexec/config save /etc/passwd 
			#Group Conversion - UID Backward Conversion
			correcthost_to_curr_vfid /fabos/libexec/group_convert /mnt/etc/group FWDL_CONVERSION UID_BACKWARD_CONVERSION > /dev/null 2>&1
			correcthost_to_curr_vfid /bin/cp /mnt/etc/group /etc/group > /dev/null 2>&1
			correcthost_to_curr_vfid /fabos/cliexec/config save /etc/group
			#Permission correction for home directories
			pkgname=`/bin/rpm -qf /fabos/users/user --root /mnt`
			/usr/sbin/chroot /mnt /bin/rpm --setugids $pkgname > /dev/null 2>&1
			if [ $? -ne 0 -a "$SWBD" == "SWBD148" ]; then
				#Permission correction for home directories
				#RPM version of 2634_dev platforms doesn't support rpm --setguids, use chown instead
				/usr/sbin/chroot /mnt /bin/chown -R root:user /fabos/users/switchadmin
				/usr/sbin/chroot /mnt /bin/chown -R root:user /fabos/users/user
				/bin/grep "^factory" /mnt/etc/passwd > /dev/null 2>&1
				if [ $? -eq 0 ]; then
					if [ -d /mnt/fabos/users/diag ]; then
						/usr/sbin/chroot /mnt /bin/chown -R root:factory /fabos/users/diag
					fi
				fi
			fi
		fi
	fi
}

# Sync passwd file if / and /mnt have different files
# To resolve /passwd file overwrite during RPM installation
passwd_file_sync()
{
    #Passwd file sync
    primsum=`/usr/bin/md5sum /etc/passwd | /usr/bin/cut -d ' ' -f 1`
    secsum=`/usr/bin/md5sum /mnt/etc/passwd | /usr/bin/cut -d ' ' -f 1`
    if [ "$primsum" != "$secsum" ]; then
        /bin/cp /etc/passwd /mnt/etc/passwd
    fi
}

#Modify File Permissions as required
file_permission_modifications()
{
	#File Permission Updates
	#Change file ppermisson to security config files after upgrade to 8.0.1 or above.

	filelist_perm_400="/etc/fabos/certs/sw0/pvt_key"

	filelist_perm_600="/etc/shadow \
	/etc/passwd \
	/etc/fabos/opasswd \
	/etc/ssh_config \
	/etc/sshd_config \
	/etc/fabos/user.db \
	/etc/fabos/pwron_fips_status \
	/etc/fabos/pki/switch.0.csr \
	/etc/fabos/pki/switch.0.key \
	/etc/fabos/pki/switch.0.crt \
	/etc/fabos/pki/switch.0.pp \
	/etc/fabos/pki/switch.0.rootcrt \
	/etc/fabos/pki/tp/switch.0.csr \
	/etc/fabos/pki/tp/switch.0.key \
	/etc/fabos/pki/tp/switch.0.crt \
	/etc/fabos/pki/tp/switch.0.pp \
	/etc/fabos/pki/tp/switch.0.rootcrt \
	/root/.ssh/known_hosts \
	/etc/ssh_host_dsa_key /etc/ssh_host_dsa_key.pub /etc/ssh_host_rsa_key /etc/ssh_host_rsa_key.pub /etc/ssh_host_ecdsa_key /etc/ssh_host_ecdsa_key.pub \
	/root/.ssh/id_dsa /root/.ssh/id_dsa.pub /root/.ssh/id_rsa /root/.ssh/id_rsa.pub /root/.ssh/id_ecdsa /root/.ssh/id_ecdsa.pub \
	/etc/fabos/fips_selftests.conf \
	/etc/fabos/tacplus.conf \
	/etc/fabos/ldap.conf \
	/etc/raddb/server \
	/etc/fabos/auth.0.conf /etc/fabos/auth.1.conf /etc/fabos/auth.2.conf /etc/fabos/auth.3.conf \
	/etc/fabos/auth.4.conf /etc/fabos/auth.5.conf /etc/fabos/auth.6.conf /etc/fabos/auth.7.conf \
	/etc/fabos/authutil.0.conf /etc/fabos/authutil.1.conf /etc/fabos/authutil.2.conf /etc/fabos/authutil.3.conf \
	/etc/fabos/authutil.4.conf /etc/fabos/authutil.5.conf /etc/fabos/authutil.6.conf /etc/fabos/authutil.7.conf"

	for i in $filelist_perm_400; do
		if [ -f $i ]; then
			/bin/chmod 400 $i
			/bin/chmod 400 /mnt/$i
			correcthost_to_curr_vfid /bin/chmod 400 $i
			correcthost_to_curr_vfid /bin/chmod 400 /mnt/$i
		fi
	done
	
	for i in $filelist_perm_600; do
		if [ -f $i ]; then
			/bin/chmod 600 $i
			/bin/chmod 600 /mnt/$i
			correcthost_to_curr_vfid /bin/chmod 600 $i
			correcthost_to_curr_vfid /bin/chmod 600 /mnt/$i
		fi
	done

}

#
# main()
#
echo > $STATUS_FILE      # Clear the error file
echo > $BNA_STATUS_FILE  # Clear the BNA error file
echo "Please address the following errors encountered during postinstall of new firmware:" >> $STATUS_FILE

# Taggged features Post install updates begin here:

#*****Passwd File Sync
passwd_file_sync

#******UID Conversion
uid_conversion

#******File Permission Updates  
file_permission_modifications

exit $rc
