#! /usr/bin/ksh
#
# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
#

#
# This script carries out the following tasks:
#
# - Install LDoms software
# - If the Solaris Security Toolkit (SST) is already installed, perform the
#   	required hardening (with potentially with no interactive prompting).
# - Optionally launch LDoms Configuration Assistant (ldmconfig).
#
# Return Values:
#
# 0	Success
# 1	Execution error
# 2	Usage error or message
# 3	Terminated due to user request
#

export PATH=/usr/sbin:/usr/bin
unset -f command unalias
\unalias -a
COMMAND="$(basename $0)"
TMPDIR="/tmp/ldomsinstall.$$"

# Packages to install for LDoms
PKGLIST="SUNWldm.v SUNWldmp2v"

# Solaris Security Toolkit (SST) variables:
sst_installed=0
sst_driver="none"
JASS_EXECUTE="/opt/SUNWjass/bin/jass-execute"

# By default, we want to prompt the user to see if they want to run ldmconfig
# (the tty config assistant) unless they explicitly set the -c/-s command line
# switches
lca_launch=""

# Supported Solaris OS release (just S10) (from uname -r)
# *_INTEGER format is numeric RRVVMM.  For example Solaris OS 5.10 is 051000
SUPPORTED_SOLARIS_RELEASE="5.10"
SUPPORTED_SOLARIS_RELEASE_INTEGER=$(printf "%02d%02d%02d" \
	$(echo ${SUPPORTED_SOLARIS_RELEASE} | tr . ' '))
# Current Solaris OS release
CURRENT_SOLARIS_RELEASE="$(uname -r)"
CURRENT_SOLARIS_RELEASE_INTEGER=$(printf "%02d%02d%02d" \
	$(echo ${CURRENT_SOLARIS_RELEASE} | tr . ' '))

# Internationalization
export TEXTDOMAIN="SUNW_OST_LDOM"
export TEXTDOMAINDIR="/opt/SUNWldm/lib/locale"
# I18N note:
# If grepping output from commands, be sure to set the locale to "C" in a
# subshell.  Otherwise the output may be in another language (e.g., Japanese)
# and the command will fail.  E.g.,
# ( LANG=C;LC_ALL=C;export LANG LC_ALL;pkginfo -l SUNWldomr 2>&1|grep VERSION )



#############################################################################
#
# usage()
#
# Display usage message to stdout.
#
# Note: does not exit (caller is responsible for that).
#
#############################################################################
usage()
{
	# TRANSLATION_NOTE - every %s is the command name
	printf "$(gettext \
'%s: Install Oracle VM Server for SPARC software

Usage:\t%s [-h] [-c|-s] [-p] [-d <SST driver>]
Where:
	-p Perform post-package add actions only; install no packages
	-h Display help information
	-d <SST driver> specifies the Solaris Security Toolkit driver to apply.
		The default SST driver is ldm_control-secure.driver.
		Use "none" to bypass applying Solaris Security Toolkit.
	-c Run ldmconfig (the tty Config Assistant)
	-s Do not run ldmconfig (the tty Config Assistant)\\n
')" \
		"$COMMAND" "$COMMAND"

	return 0
}


#############################################################################
#
# cleanup_and_exit()
#
# Perform cleanup then exit with a given status code
#
# Parameters
# $1	return code (0-255), where 0 is OK
#
#############################################################################
cleanup_and_exit()
{
	rm -rf "$TMPDIR"
	exit $1
}


#############################################################################
#
# check_solaris_release()
#
# Check if the current release of Solaris OS is supported.
# Exit with a fatal error if not OK.
#
#############################################################################
check_solaris_release()
{
	# The current release of Solaris OS must be >= earliest supported rel.
	if (( CURRENT_SOLARIS_RELEASE_INTEGER != SUPPORTED_SOLARIS_RELEASE_INTEGER
			)) ; then
		# TRANSLATION_NOTE - the first %s is the Solaris release.
		# The second %s is the minimal Solaris OS release supported.
		printf "$(gettext \
'ERROR: the current OS release, Solaris %s, is not supported; it must be Solaris %s.'\
			)" \
			"$(echo $CURRENT_SOLARIS_RELEASE | cut -f2- -d.)" \
			"$(echo $SUPPORTED_SOLARIS_RELEASE | cut -f2- -d.)" \
			| fmt
		cleanup_and_exit 1
	fi

	return 0
}


#############################################################################
#
# verify_package_dir()
#
# Verify if the specified 'package directory' is a valid directory and
# contains the packages in $PKGLIST.  Exit with a fatal error if not OK.
#
# $1 - package directory to verify
#
#############################################################################
verify_package_dir()
{
	typeset package_dir="$1"
	typeset missing_packages=""

	if [[ -z "$package_dir" ]] ; then
		printf "$(gettext 'ERROR: Missing package directory name.\\n')"
		cleanup_and_exit 1
	fi

	if [[ ! -d "$package_dir" ]] ; then
		if [[ -f "$package_dir" ]] ; then
			# TRANSLATION_NOTE - %s is the file name
			printf \
			"$(gettext '%s is a file, not a directory.\\n')"\
				"$package_dir"
		else
			# TRANSLATION_NOTE - %s is the missing directory name
			printf "$(gettext \
			'Directory %s does not exist.\\n')" "$package_dir"
		fi
		cleanup_and_exit 1
	fi

	for i in $PKGLIST ; do
		i_dir=$(find -L "${package_dir}" -type d 2>/dev/null | \
				grep "/${i}$" | head -1)
		if [[ -z "${i_dir}" ]] ; then
			missing_packages="$missing_packages $i"
		fi
	done


	if [[ -n "$missing_packages" ]] ; then
		# More often a failure here is operator error rather than
		# a corrupted filesystem, so let the customer know. 
		usage
		# TRANSLATION_NOTE: the first %s is the directory name, the
		# second %s is the list of packages
		printf "$(gettext \
'\\nInstall directory "%s" is missing the following required packages:\
\\t%s\\n\\n')" "$package_dir" "$missing_packages"
		cleanup_and_exit 2
	fi
	return 0
}


#############################################################################
#
# verify_prereq_packages()
#
# Verify that all prerequisite packages listed in the package depend
# files are installed.
# If any are not installed, print an error and exit.
#
#############################################################################
verify_prereq_packages()
{
	typeset pkginfo_full="$TMPDIR/pkginfo_full"
	typeset not_installed=""
	typeset prereq_pkglist=""
	typeset package_prereqs=""

	# Build a list of fully-installed packages
	rm -f "$pkginfo_full"
	pkginfo -i | nawk '{print $2}' >$pkginfo_full

	first_package=`echo $PKGLIST | awk '{ print $1 }'`

	# Look for package directory
	i_dir=$(find -L "${package_dir}" -type d 2>/dev/null | \
		grep "$first_package" | head -1)
	if [[ -z "${i_dir}" ]] ; then
		printf "$(gettext \
		'Cannot verify prereq packages:  Package %s not found.\\n')" \
			"$first_package"
		cleanup_and_exit 1
	fi
	i_parent_dir="$(dirname $i_dir)"

	# Build a list of prereq packages
	for i in $PKGLIST ; do
		package_prereqs=$(grep '^P' "$i_parent_dir/$i/install/depend" \
			2>/dev/null | nawk '{print $2}')
		if [[ -n "$package_prereqs" ]] ; then
			prereq_pkglist="$prereq_pkglist $package_prereqs"
		fi
	done
	if [[ -n "$prereq_pkglist" ]] ; then
		prereq_pkglist="$(echo $prereq_pkglist \
			| tr ' ' '\n' | sort | uniq )"
	fi

	# Verify prerequisite packages are installed
	if [[ -n "$prereq_pkglist" ]] ; then
		for i in $prereq_pkglist ; do
			# Skip packages-to-install
			if print "$PKGLIST" | grep -w "$i" >/dev/null 2>&1
			then
				continue
			fi

			# If the package is not installed, add it to the list.
			if ! grep -w "$i" "$pkginfo_full" >/dev/null 2>&1
			then
				if [[ -z "$not_installed" ]] ; then
					not_installed="$i"
				else
					not_installed="$not_installed $i"
				fi
			fi
		done
	fi
	rm -f "$pkginfo_full"

	if [[ -n "$not_installed" ]] ; then
		# Some prerequisite packages are not installed

		# TRANSLATION NOTE - First %s is command, the
		# second %s is a list of package names
		printf "$(gettext 'ERROR: The following package(s) must be \
installed before running %s: %s.')" "$COMMAND" "$not_installed" | fmt
		cleanup_and_exit 1
	fi

	return 0
}


#############################################################################
#
# get_user_response
#
# Print a message, $1, and return the user response.
# The default answer is no.
#
# Return values:
# 1	yes
# 0	no
#############################################################################
get_user_response()
{
	typeset _resp_y
	typeset _resp_n
	typeset _yes
	typeset _grep
	typeset _yn

	if [ -x /usr/xpg4/bin/egrep ] ; then
		_resp_y=`locale yesstr`
		_resp_n=`locale nostr`
		_yes=`locale yesexpr`
		_no=`locale noexpr`
		_grep='/usr/xpg4/bin/egrep'

	else # Minimized system with no XPG4 egrep
		# This code is not localized. The problem is that if we can't
		# interpret a localized reponse, we shouldn't ask for it.
		_resp_y='yes'
		_resp_n='no'
		_yes='^[yY]'
		_no='^[nN]'
		_grep='grep'
	fi

	# Print question without a newline
	print -n "$* (${_resp_y}/${_resp_n})? [${_resp_n}] "

	# Prompt for an answer until a correct one is received
	while read yn ; do
		if [[ -z "$yn" ]] ; then # default NO
			return 0
		fi

		# Use locale to allow localization
		print "${yn}" | ${_grep} "${_yes}" >/dev/null 2>&1
		if (( $? == 0 )) ; then # YES
			return 1
		else
			print "${yn}" | ${_grep} "${_no}" >/dev/null 2>&1
			if (( $? == 0 )) ; then # NO
				return 0
			fi
		fi

		# Invalid answer
		gettext \
		'The response provided was not valid; please try again.\n'
		# TRANSLATION_NOTE - The first %s is yes, the second %s is no,
		# translated
		printf "$(gettext '\Please answer %s or %s: ')" \
			"${_resp_y}" "${_resp_n}" | fmt
	done
}


#############################################################################
#
# check_sst_installed()
#
# Check to see if SST is installed.
#
# Return values:
# 1	yes
# 0	no
#
#############################################################################
check_sst_installed()
{
	verify_packages_installed 0 "SUNWjass"
	if (( $? == 0 )) ; then
		sst_installed=1
		sst_driver="ask"
		return 1
	else
		# not installed
		return 0
	fi
}

#############################################################################
#
# get_sst_driver()
#
# Ask what SST driver to use.
# Called by get_sst_configuration() if the user wants to choose a specific
# or custom SST driver.
#
# Sets sst_driver to the desired SST configuration driver.
#
#############################################################################
get_sst_driver()
{
	typeset driver_menu_values="none ldm_control-secure.driver"
	typeset -i i=1
	typeset menu_ans
	typeset menu_ans_num

	for n in $(find -L "$package_dir" "/opt/SUNWjass/Drivers" \
		-name '*secure.driver' \
		-exec basename '{}' ';' 2>/dev/null | \
		grep -vw 'ldm_control-secure.driver' | sort | uniq )
	do
		driver_menu_values="$driver_menu_values $n"
	done
	set -A driver_menu $driver_menu_values

	# Get SST driver from user
	gettext 'Choose a Solaris Security Toolkit .driver configuration
profile from this list\n' | fmt

	menu_choice="${driver_menu[1]}"
	while [[ -n "$menu_choice" ]] ; do
		print "$i) $menu_choice"
		(( i += 1 ))
		menu_choice="${driver_menu[$i]}"
	done
	(( i -= 1 ))
	# TRANSLATION_NOTE - %d is the maximum list number
	printf "$(gettext '\nEnter a number 1 to %d: ')" "$i"

	while read menu_ans ; do
		# Check answer is valid
		menu_ans_num=$(echo $menu_ans | sed 's/[^0-9]//g')
		if [[ -n "$menu_ans" && "$menu_ans" == "$menu_ans_num" \
			&& "$menu_ans" -gt 0 && "$menu_ans" -le "$i" ]]
		then
			sst_driver="${driver_menu[$menu_ans]}"
			if [[ -n "$sst_driver" ]] ; then # OK
				if [[ "$sst_driver" == \
					'ldm_control-secure.driver' ]] ; then
						break
				else
					gettext \
"The driver you selected may not perform all the LDoms-specific operations
specified in the Oracle VM Server for SPARC Administration Guide." | fmt
					get_user_response \
						$(gettext 'Is this OK')
					if (( $? == 1 )) ; then # YES
						break
					fi
				fi
			fi
		fi

		gettext \
		'The response provided was not valid; please try again.\n'

		# TRANSLATION_NOTE - %d is the maximum list number
		printf "$(gettext '\nEnter a number 1 to %d: ')" "$i"
	done
}



#############################################################################
#
# get_sst_configuration()
#
# Ask what SST configuration profile (SST driver) to use.
# Called if -d was not specified.
#
# Sets sst_driver_path to the desired SST configuration driver path.
#
#############################################################################
get_sst_configuration()
{
	typeset DEFAULTANS="a"
	typeset ans

	# Get desired hardening configuration
	gettext \
'Given the capabilities of the LDoms Manager, you can now change
the security configuration of this Solaris instance using the Solaris
Security Toolkit.

Select a security profile from this list:\n\n' | fmt

	# TRANSLATION NOTE - Do not localize the answers "a", "b", or "c"
	gettext 'a) Hardened Solaris configuration for LDoms (recommended)\n'
	gettext 'b) Standard Solaris configuration\n'
	gettext 'c) Your custom-defined Solaris security configuration profile\n'
	printf "$(gettext '\nEnter a, b, or c [%s]: ')" "$DEFAULTANS"

	while read ans ; do
		# Check answer
		if [[ "$ans" == "" ]] ; then # default
			ans="$DEFAULTANS"
		fi
		if [[ "$ans" == "a" || "$ans" == "b" || "$ans" == "c"  ]]
		then # OK
			break
		fi

		gettext \
		'The response provided was not valid; please try again.\n'
		printf "$(gettext '\nEnter a, b, or c [%s]: ')" "$DEFAULTANS"
	done

	# Configure appropriately
	case "$ans" in
	a)	sst_driver="ldm_control-secure.driver"
		;;
	b)	sst_driver="none"
		;;
	c)	get_sst_driver
		;;
	*)	;;
	esac
	sst_driver_path="/opt/SUNWjass/Drivers/$(basename $sst_driver .driver).driver"

	# Warn appropriately
	case "$ans" in
	a|c)	gettext \
"The changes made by selecting this option can be undone through the
Solaris Security Toolkit's undo feature. This can be done with the
'/opt/SUNWjass/bin/jass-execute -u' command." | fmt
		;;
	b)	gettext \
"If you wish to apply a different Solaris security configuration later,
the Solaris Security Toolkit is installed in /opt/SUNWjass and can be
used to apply the recommended secure Solaris configuration for a
Control Domain with
'/opt/SUNWjass/bin/jass-execute -d ldm_control-secure.driver'." | fmt
		;;
	*)	;;
	esac

}

#############################################################################
#
# get_ldoms_config()
#
# Ask if Configuration Assistant (tty) should be launched
# after installation to configure domains.
#
# Sets lca_exec to the correct path and lca_launch to true if the user confirms
# configuration is desired.
#
#############################################################################
get_ldoms_config()
{
	typeset DEFAULTANS="y"
	typeset ans

	# Confirm if LDoms configuration is required after package installation
	gettext \
'
Oracle VM Server for SPARC Configuration

Once installed, you may configure your system for a basic LDoms deployment.
If you select "y" for the following question, the Oracle VM Server for SPARC
Configuration Assistant (tty) will be launched following a successful
installation of the packages.

(You may launch the Configuration Assistant at a later time with the command:
/usr/sbin/ldmconfig, or use the GUI Configuration Assistant which is bundled
in the Oracle VM Server for SPARC zip file - see README.GUI for more details)

Select an option for configuration:\n\n' | fmt

	# TRANSLATION NOTE - Do not localize the answers "y" or "n"
	gettext 'y) Yes, launch the Configuration Assistant after install\n'
	gettext 'n) No thanks, I will configure the system manually later\n'
	printf "$(gettext '\nEnter y or n [%s]: ')" "$DEFAULTANS"

	while read ans ; do
		# Check answer
		if [[ "$ans" == "" ]] ; then # default
			ans="$DEFAULTANS"
		fi
		if [[ "$ans" == "y" || "$ans" == "n"  ]]
		then # OK
			break
		fi

		gettext \
		'The response provided was not valid; please try again.\n'
		printf "$(gettext '\nEnter y or n [%s]: ')" "$DEFAULTANS"
	done

	# Configure appropriately
	case "$ans" in
	y|Y)	lca_launch="yes"
		lca_exec="/usr/sbin/ldmconfig"
		;;
	n|N)	lca_launch="no"
		;;
	*)	;;
	esac

}


#############################################################################
#
# verify_all_packages_absent()
#
# Verify no package in $PKGLIST is installed.  If a package is found, exit.
#
#############################################################################
verify_all_packages_absent()
{
	typeset pkginfo_all="$TMPDIR/pkginfo_all"
	typeset already_installed=""

	# Build a list of fully- and partially-installed packages
	rm -f "$pkginfo_all"
	pkginfo | nawk '{print $2}' >$pkginfo_all

	# Verify our packages are not installed
	if [[ -n "$PKGLIST" ]] ; then
		for i in $PKGLIST ; do
			i=$(basename $i \\.v) # Strip sun4v extension, if any
			if grep -w "$i" "$pkginfo_all" >/dev/null 2>&1 ; then
				already_installed="$already_installed $i"
			fi
		done
	fi
	rm -f "$pkginfo_all"

	if [[ -n "$already_installed" ]] ; then
		# TRANSLATION_NOTE - the first %s is the list of package names,
		# the second %s is the command
		printf "$(gettext 'ERROR: One or more packages are already \
installed:%s.  If SUNWldm.v and SUNWldmp2v are factory pre-installed, \
run install-ldm -p to perform post-install actions. \
Otherwise remove the package(s) and restart %s.')" \
			"$already_installed" "$COMMAND" | fmt
		cleanup_and_exit 1
	fi

	return 0
}



#############################################################################
#
# install_packages()
#
# Run pkgadd to install packages in $PKGLIST.
# Return the pkgadd return code.
#
# $1	- directory containing packages to install, $PKGLIST
#
#############################################################################
install_packages()
{
	typeset pkg_admin="$TMPDIR/pkg_admin"
	typeset package_dir="$1"
	typeset -i pkgadd_result=0

	# Create a pkgadd admin file:
	rm -f "$pkg_admin"
	cat >$pkg_admin << EOF
main=
instance=unique
partial=nocheck
runlevel=nocheck
idepend=quit
rdepend=nocheck
space=quit
setuid=nocheck
conflict=nocheck
action=nocheck
basedir=default
EOF

	gettext 'Installing LDoms packages.\n'

	for i in $PKGLIST ; do
		# Look for package directory
		i_dir=$(find -L "${package_dir}" -type d 2>/dev/null | \
				grep "/${i}$" | head -1)
		if [[ -z "${i_dir}" ]] ; then
			# TRANSLATION_NOTE - %s is the missing package name
			printf "$(gettext \
			'Package %s not found.\\n')" "${i}"
			cleanup_and_exit 1
		fi
		i_parent_dir="$(dirname $i_dir)"

		print "pkgadd -n -d \"$i_parent_dir\" -a pkg_admin $i"
		pkgadd -n -d "$i_parent_dir" -a "$pkg_admin" $i
		pkgadd_result=$?
		if (( pkgadd_result != 0 )) ; then
			break;
		fi
	done

	rm -f "$pkg_admin"
	return $pkgadd_result
}


#############################################################################
#
# verify_all_packages_installed()
#
# Verify all packages in $PKGLIST are installed.
# If a package is not found, exit.
#
#############################################################################
verify_all_packages_installed()
{
	# No terminating newline:
	gettext '\nVerifying that all packages are fully installed.'

	verify_packages_installed 1 "${PKGLIST}"
}

#############################################################################
#
# verify_packages_installed()
#
# Verify the specified packages are installed.
#
# $1	- should we print result & exit if we fail to find a package (1=yes)
# $2	- list of packages to check
#
#############################################################################
verify_packages_installed()
{
	typeset pkginfo_full="$TMPDIR/pkginfo_full"
	typeset pkginfo_partial="$TMPDIR/pkginfo_partial"
	typeset missing_packages=""

	print_warning=$1
	_PKGLIST="$2"

	# Generate lists of fully- and partially-installed packages
	rm -f "$pkginfo_full" "$pkginfo_partial"
	pkginfo -i | nawk '{print $2}' >$pkginfo_full
	pkginfo -p | nawk '{print $2}' >$pkginfo_partial

	# Verify our packages are installed
	if [[ -n "$_PKGLIST" ]] ; then
		for i in $_PKGLIST ; do
			i="$(basename $i \\.v)"  # Strip sun4v extension, if any
			# Check for partially-installed and missing packages
			if grep -w "$i" "$pkginfo_partial" >/dev/null 2>&1; then
				# Look at the LAST instance for THIS package:
				pkgname="$(grep -w "$i" "$pkginfo_partial" \
					| tail -1)"

				pkginfo -i "$pkgname"
				if (( print_warning == 1 )) ; then
					# TRANSLATION_NOTE: %s is the pkg name
					printf "$(gettext \
					'\nPackage %s is partially installed.\\n')" \
						$pkgname
				fi
				missing_packages="$missing_packages $i"

			elif ! grep -w "$i" "$pkginfo_full">/dev/null 2>&1; then
				if (( print_warning == 1 )) ; then
					# TRANSLATION_NOTE: %s is the pkg name
					printf "$(gettext \
						'\nPackage %s is not installed.\\n')" \
						$i
				fi
				missing_packages="$missing_packages $i"
			fi
		done
	fi
	rm -f "$pkginfo_full"
	rm -f "$pkginfo_partial"

	# If the caller just wanted to check for the existance of an optional
	# package, we return now. Otherwise we continue on and print a message
	# and exit if there was a package missing
	if (( print_warning == 0 )) ; then
		if [[ -n "$missing_packages" ]] ; then
			return 1
		else
			return 0
		fi
	fi

	if [[ -n "$missing_packages" ]] ; then
		# TRANSLATION_NOTE: %s is the list of packages
		printf "$(gettext \
		'\nERROR: One or more packages were not fully installed:%s.')" \
			"$missing_packages" | fmt
		cleanup_and_exit 1
	else # OK
		gettext '  OK.\n'
	fi
	return 0
}


#############################################################################
#
# enable_services()
#
# Enable one or more SMF services.
#
#############################################################################
enable_services()
{
	typeset -i svcadm_result=0

	# %s is the SMF service FMRI
	printf "$(gettext 'Enabling services: %s' )" "$*" | fmt

	while [[ -n "$1" ]] ; do
		svcadm enable "$1"
		svcadm_result=$?
		if (( svcadm_result != 0 )) ; then
			# %s is the SMF service FMRI and %d is the status value.
			printf "$(gettext \
			'ERROR: could not enable service %s (rc=%d).' )" \
				"$1" "${svcadm_result}" | fmt
			cleanup_and_exit 1
		fi

		shift
	done
}


#############################################################################
#
# sst_harden()
#
# Call jass-execute to harden the system with Solaris Security Toolkit (SST).
#
# SST must already be installed.
#
#############################################################################
sst_harden()
{
	typeset -i jass_execute_result=0
	typeset jass_log=""

	SST_VER=`( LANG=C; LC_ALL=C; export LANG LC_ALL; \
		pkginfo -l SUNWjass 2>&1 | grep VERSION | nawk '{print $2}')`
	export JASS_NOVICE_USER=0 # Suppress question and warning message

	# TRANSLATION_NOTE - the first %s is the version number. The second
	# %s is the "driver" file name.
	printf "$(gettext 'Running Solaris Security Toolkit %s driver %s.\
Please wait. . .\\n')" "${SST_VER}" "${sst_driver}"

	print "$JASS_EXECUTE -q -d $sst_driver"
	$JASS_EXECUTE -q -d "$sst_driver"
	jass_execute_result=$?
	jass_log="$(print /var/opt/SUNWjass/run/*/jass-install-log.txt \
			| nawk '{print $NF}' )"

	if (( jass_execute_result != 0 )) ; then
		# TRANSLATION_NOTE - the first %s is the status. The second
		# %s is the log file name
		printf "$(gettext \
'ERROR: A Solaris Security Toolkit error occurred (rc=%s).  Check log file %s \
for error conditions.' )" "${jass_execute_result}" "${jass_log}" | fmt
		cleanup_and_exit 1
	else
		# TRANSLATION_NOTE - %s is the log file name
		printf "$(gettext \
'Solaris Security Toolkit hardening executed successfully; log file %s. \
It will not take effect until the next reboot. \
Before rebooting, make sure SSH or the serial line is setup for \
use after the reboot.' )" "${jass_log}" | fmt
	fi

	return 0
}

#############################################################################
#
# print_welcome_msg()
#
# Prints the welcome message which explains what the script does
#
#############################################################################
print_welcome_msg()
{
	gettext \
'\nWelcome to the Oracle VM Server for SPARC installer.\n
You are about to install the LDoms Manager package, SUNWldm, that will enable
you to create, destroy and control other domains on your system. You will
also be given the option of running the Oracle VM Server for SPARC Configuration
Assistant (ldmconfig) to setup the control domain and create guest domains.\n
If the Solaris Security Toolkit (SST) is installed, you will be prompted to
optionally harden your control domain.\n\n'
}

#############################################################################
#
# Main code starts here
#
#############################################################################

#
# Setup
#

# No write or execute permission for group or others for new files
umask 033

# Temporary directory
rm -rf "$TMPDIR"
if ! mkdir "$TMPDIR" ; then
	# TRANSLATION_NOTE - %s is the temporary directory name
	printf "$(gettext 'mkdir of temporary directory %s failed.')\n" \
		"$TMPDIR"
	cleanup_and_exit 1
fi

# Check if SUNWjass is pre-installed. The SST software is no longer bundled in
# LDoms releases but we will still provide the option of configuring it
# if it is installed by the user prior to running this script.
check_sst_installed

# Parse arguments and check for a help request.
# Changes here must also be made in function usage().
while getopts 'cd:hps\?' optname $* ; do
	case "$optname" in
	c)	if [[ ${lca_launch} != "" ]] ; then
			usage
			cleanup_and_exit 2
		fi
		lca_launch="yes"
		;;
	s)	if [[ ${lca_launch} != "" ]] ; then
			usage
			cleanup_and_exit 2
		fi
		lca_launch="no"
		;;
	p)	POSTINSTALLONLY=TRUE
		;;
	d)	sst_driver="${OPTARG}"
		if [[ "$sst_driver" != 'ldm_control-secure.driver' &&
				"$sst_driver" != 'none' ]] ; then
			gettext \
"The driver you selected may not perform all the LDoms-specific operations
specified in the Oracle VM Server for SPARC Administration Guide." | fmt
		fi
		;;
	\?|h|*)
		usage
		cleanup_and_exit 2 ;;
	esac
done
shift $(( OPTIND - 1 ))
cd `dirname $0`/..
package_dir="."

print_welcome_msg

first_package=`echo $PKGLIST | awk '{ print $1 }'`
find $package_dir/Product | grep $first_package >/dev/null 2>&1
if [ $? -ne 0 ]; then
	usage
	cleanup_and_exit 2
fi

# Install interrupt handler
trap 'print "\n$COMMAND \c"; gettext "interrupted; exiting.\n"; \
	cleanup_and_exit 3' HUP INT QUIT TERM

#
# Perform checks
#
check_solaris_release
verify_prereq_packages

if [[ "$POSTINSTALLONLY" != "TRUE" ]] ; then
	verify_package_dir "$package_dir"
	verify_all_packages_absent

	#
	# Do the install
	#
	install_packages "$package_dir"
	install_result=$?

	# Do not continue if the package installation failed with a
	# fatal (1) or suspend (3) or dependency (4) error.
	if (( $install_result == 1 || $install_result == 3 || $install_result == 4 )) ; then
		# TRANSLATION NOTE - First %s is the package list,
		# second is the command
		printf "$(gettext 'ERROR: Oracle VM Server for SPARC could not be installed. \
Correct any reported issues, remove package(s) %s, and restart %s.')" \
			"$PKGLIST" "$COMMAND" | fmt
		cleanup_and_exit 1
	fi
fi

# check if user wants to run the tty config assistant (unless explicitly
# indicated on the command line by specifying -c or -s; in which case
# 'lca_launch' will not be empty)
if [[ "${lca_launch}" == "" ]] ; then
	get_ldoms_config
fi

if (( sst_installed == 1 )) ; then
	if [[ "${sst_driver}" != "none" ]] ; then
		get_sst_configuration
	elif [[ "${sst_driver}" != "none" ]] ; then
		sst_driver_path="/opt/SUNWjass/Drivers/$(basename $sst_driver .driver).driver"
	fi
fi

#
# Post-install actions
#
verify_all_packages_installed
if [[ "${sst_driver}" != "none" && ! -f "${sst_driver_path}" ]] ; then
	# TRANSLATION_NOTE - %s is the file name
	printf "$(gettext 'ERROR: Missing driver file %s.')" \
		"$sst_driver_path" | fmt
	cleanup_and_exit 2
fi

# As of LDoms 1.2, the ldmd service is enabled by default but if the package
# was installed previously, the service may have been disabled.
if [[ "$POSTINSTALLONLY" == "TRUE" ]] ; then
	enable_services "svc:/ldoms/ldmd:default"
fi

# If SUNWjass was installed prior to running this script and the
# user opted to enable it, we go ahead and do it now.
if [[ "${sst_driver}" != "none" ]] ; then
	sst_harden
fi

# If configuration flag is yes, check for the tty Configuration Assistant
# and launch
if [[ "${lca_launch}" == "yes" ]] ; then
	if [[ ! -x "${lca_exec}" ]] ; then
		printf "$(gettext 'ERROR: ldmconfig(1M) not present, or not executable %s.')" \
			"$lca_exec" | fmt
		cleanup_and_exit 2
	else
		printf "Launching the tty Configuration Assistant ... \n"
		${lca_exec}
	fi
fi

cleanup_and_exit 0

