#! /bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2002,2007 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
#*===================================================================*/
#*                                                                   */
#* Module Name:  ctcasctrl                                           */
#*                                                                   */
#* Description:                                                      */
#*      Script to manage the ctcasd daemon as an SRC subsyst         */
#*                                                                   */
#*===================================================================*/
# @(#)03    1.16.2.1 src/rsct/security/CAS/bin/ctcasctrl.sh, ctsec, rsct_relgh, relghs001a 3/22/07 09:46:24 

# Set path to known value
PATH=/usr/sbin/rsct/bin:/usr/bin:/usr/sbin:/bin
export PATH

SS_PATH=/usr/sbin/rsct/bin		# path to subsystem daemons
SUBSYS=ctcas					# name of subsystem
SUBSYSGRP=rsct					# name of subsystem's group
DAEMON=ctcasd_start				# name of subsystem daemon
CTSKEYGEN=ctskeygen				# name of key generation command
CTSTHL=ctsthl					# name of the THL command
WAITTIME=30						# value of -w flag on mkssys
TMP=/tmp/.sec$$					# temporary file name for commands error/output
CONFIG_PATH="/var/ct/cfg /usr/sbin/rsct/cfg"
IW_PATH="/var/ct/IW"
DEFAULT_THL="/var/ct/cfg/ct_has.thl"

CMD=$(basename $0)
CTMSG=${SS_PATH}/ctdspmsg
MSGMAPPATH=/usr/sbin/rsct/msgmaps
export MSGMAPPATH

# sed string to extract subsystem state from "lssrc -s <subsys>" output
PARSE_SRC_STATE="-e1d;s/.* \([a-zA-Z0-9]*\)$/\1/"

# miscellaneous variables
typeset ctcasthl=""
integer ctcasadd=0
integer ctcasdel=0
integer ctcasforce=0
integer ctcasremove=0
integer rc=0

function thlfile
{
	typeset configdir
	typeset fname

	for configdir in $CONFIG_PATH
	do
		if [[ -f $configdir/ctcasd.cfg ]]
		then
			fname=$(awk -F'=' '/^HBA_THLFILE/{print \$2}' \
			        $configdir/ctcasd.cfg 2> /dev/null)
			break
		fi
	done
	if [[ -z $fname ]]
	then
		fname=$DEFAULT_THL
	fi
	print $fname
}

# mainline code

# Parse command line

Argcount=0
while getopts ":adfhr" opt
do
	case $opt in
		a ) Op=add; ctcasadd=1; Argcount=$((Argcount + 1));;
		d ) Op=delete; ctcasdel=1; Argcount=$((Argcount + 1));;
		f ) ctcasforce=1; Argcount=$((Argcount + 1));;
		r ) Op=remove; ctcasremove=1; Argcount=$((Argcount + 1));;
		h ) $CTMSG ctcasctrl cthba.cat INFOctcasctrl_usage $CMD
				 exit 0;;
		? ) $CTMSG ctcasctrl cthba.cat INFOctcasctrl_usage $CMD
				 exit 1;;
	esac
done

if ((Argcount == 0))
then
	$CTMSG ctcasctrl cthba.cat INFOctcasctrl_usage $CMD
	exit 1
fi

if (( ((ctcasadd == 1) && (ctcasdel == 1 || ctcasremove == 1)) || \
		((ctcasdel == 1) && (ctcasremove == 1)) || \
		((ctcasadd == 0) && (ctcasdel == 0) && (ctcasremove == 0)) ))
then
	$CTMSG ctcasctrl cthba.cat INFOctcasctrl_usage $CMD
	exit 1
fi

case $Op in

# Add subsystem to SRC
add )
	# Ensure subsystem is stopped if it is already in SRC and active
	state=$(LC_ALL=C lssrc -s "$SUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -n "$state" && "$state" = "active" ]]
	then
		stopsrc -c -s $SUBSYS
	fi

	if [[ ! -x $SS_PATH/$DAEMON ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGctcasd_not_executable $CMD \
		       $SS_PATH/$DAEMON
		exit 1
	fi

	# Remove subsystem from SRC first
	rmssys -s $SUBSYS >/dev/null 2>&1

	# Ensure that the /var/ct/IW directory exists
	if [[ ! -L $IW_PATH ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGIWpath_doesnot_exist $CMD
		exit 1
	fi

	# Add subsystem to SRC
	ODMDIR=/etc/objrepos mkssys -s $SUBSYS -p $SS_PATH/$DAEMON -u 0 \
			-i /dev/null -o /dev/null -e $TMP \
			-R -Q -S -f 15 -n 15 -d -w $WAITTIME -G $SUBSYSGRP
	# If error, exit
	if [[ $? -ne 0 ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGerror_adding_ctcas_to_SRC $CMD $SUBSYS
		cat $TMP
		rm -f $TMP >/dev/null 2>&1
		exit 1
	fi

	# Create the /var/ct/IW/soc/ctcasd/client directory
	mkdir -p /var/ct/IW/soc/ctcas/client/
	chmod 1777 /var/ct/IW/soc/ctcas/client/
	chmod 755 /var/ct/IW/soc/ctcas

	# Check the host's private and public key files
	if [[ ! -x $SS_PATH/$CTSKEYGEN ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGctskeygen_not_executable $CMD \
		       $SS_PATH/$CTSKEYGEN
		rm -f $TMP >/dev/null 2>&1
		exit 2
	fi
	ctskeygen -d > $TMP 2>&1
	if [[ $? -ne 0 ]]
	then
		# Host's key files are either missing or corrupted. Re/generate 
		# them.
		if (( ctcasforce == 1 ))
		then
			# The force option was provided: blast them all!
			ctskeygen -n -m rsa512 -f > $TMP 2>&1
			rc=$?
			if [[ $rc -ne 0 ]]
			then
				$CTMSG ctcasctrl cthba.cat EMSGerror_creating_key_files $CMD $rc
				cat $TMP
				rm  -f $TMP > /dev/null 2>&1
				exit 2
			fi
		else
			# The force option was not provided: be gentle like the
			# summer breeze...
			ctskeygen -n -m rsa512 > $TMP 2>&1
			rc=$?
			if [[ $rc -ne 0 ]]
			then
				$CTMSG ctcasctrl cthba.cat EMSGerror_creating_key_files $CMD $rc
				cat $TMP
				rm -f $TMP > /dev/null 2>&1
				exit 2
			fi
		fi	
	else
		# Host's key files are okay.  If the FORCE flag was provided,
		# generate new key files.
		if (( ctcasforce == 1))
		then
			ctskeygen -n -m rsa512 -f > $TMP 2>&1
			rc=$?
			if [[ $rc -ne 0 ]]
			then
				$CTMSG ctcasctrl cthba.cat EMSGerror_creating_key_files $CMD $rc
				cat $TMP
				rm -f $TMP > /dev/null 2>&1
				exit 2
			fi
		else
			# The FORCE flag was not provided and the host's key files
			# already exist.  Make an attempt to convert the private key to
			# PKCS format, in the event that they were generated by a back-
			# level version.  If it fails, don't worry, because the new code
			# can make do with the back-level keyfile (we're just converting
			# the key for our later convenience).  The public key is not
			# modified, so we don't need to update the THL if the private key
			# gets converted.  If the private key is already in this format,
			# the command won't alter their contents.
			rm -f $TMP > /dev/null 2>&1
			ctskeygen -c > /dev/null 2>&1
			exit 0
		fi
	fi

	# Add the new host's keys to the THL file
	if [[ ! -x $SS_PATH/$CTSTHL ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGctsthl_not_executable $CMD $SS_PATH/$CTSTHL
		rm -f $TMP > /dev/null 2>&1
		exit 3
	fi
	ctcasthl=$(thlfile)
	ctsthl -s >$TMP 2>&1
	rc=$?
	if [[ $rc -ne 0 ]]
	then
		case $rc in
			10)		# cannot query network interfaces - create blank THL and
					# set indicator for ctcasd to initialize blank THL
					touch $ctcasthl
					touch $ctcasthl.cir
					rm -f $TMP > /dev/null 2>&1
					;;
			*)		# other failures - no recovery
					$CTMSG ctcasctrl cthba.cat EMSGerror_adding_keys_to_thl \
					       $CMD $rc
					cat $TMP
					rm -f $TMP > /dev/null 2>&1
					;;
		esac
		exit 3
	else
		rm -f $ctcasthl.cir 2> /dev/null
	fi

	;;

# Remove subsystem from SRC
delete )
	# Stop the subsystem if active
	state=$(LC_ALL=C lssrc -s "$SUBSYS" | sed "$PARSE_SRC_STATE")
	if [[ -n "$state" && "$state" = "active" ]]
	then
		stopsrc -c -s $SUBSYS
	fi

	# remove subsystem from SRC
	rmssys -s $SUBSYS >/dev/null 2>&1

	;;

#Cleanup option to remove public/private keyfiles and THL file
remove )
	#Remove the public & private keyfiles
	if [[ ! -x $SS_PATH/$CTSKEYGEN ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGctskeygen_not_executable \
				$CMD $SS_PATH/$CTSKEYGEN
		rm -f $TMP >/dev/null 2>&1
		exit 2
	fi

	ctskeygen -r >$TMP 2>&1
	rc=$?
	if [[ $rc -ne 0 ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGerror_deleting_key_files \
				$CMD $rc
		cat $TMP
		rm -f $TMP > /dev/null 2>&1
		exit 2
	fi

	#Remove the THL file
	if [[ ! -x $SS_PATH/$CTSTHL ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGctsthl_not_executable \
				$CMD $SS_PATH/$CTSTHL
		rm -f $TMP > /dev/null 2>&1
		exit 3
	fi

	ctsthl -r >$TMP 2>&1
	rc=$?
	if [[ $rc -ne 0 ]]
	then
		$CTMSG ctcasctrl cthba.cat EMSGerror_deleting_thl_file \
				$CMD $rc
		cat $TMP
		rm -f $TMP > /dev/null 2>&1
		exit 2
	fi

	;;

esac

rm -f $TMP >/dev/null 2>&1
exit 0
