#!/bin/ksh 
#
# ident "@(#)M40AuthMgr.ksh	1.40 05/06/01 SMI"
#
# Copyright 2001-2002,2004 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

#
#
# MODULE NAME: AuthMgr 
# AUTHOR     : 
# DESCRIPTION: Used for Preserving/Restoring Authmgr data
#
# The following exported variables (initialized by the master task) are 
# available (read-only) for the module:
#
# G_PROGRAM_ID    : program name
# G_MEDIA_DIR     : pathname of the install directory on the media (CD,...)
# G_PRODUCT_DIR   : pathname of the bundles directory on the media (CD,...)
# G_ADMIN_FILE    : pathname of the admin file used by pkgadd. default provided.
# G_DEBUG         : debug on/off. Possible values "yes", "no"
# G_QUICK_INSTALL : used to force a quick install (no user inputs).
#                   possible values "yes", "no"
# G_TMP_DIR       : pathname of the temporary directory 
# G_UT_PROD_NAME  : product name
# G_UT_VERSION    : product version
# G_DAEMON_LOC    : location of OS daemon scripts
# G_LOGFILE       : pathname of the log file.
# G_PID           : PID of the master task
# G_SR_CURRENT_VERSION: the currently installed SunRay version
#

#
# EditPropsFile()
# 
# Description:
#    Edits a replaces fields in Auth.props       
# 
# Parameters:
#    Key, NewKeyvalue and newfile
#
#

EditPropsFile() {
  typeset -r key="$1"
  typeset -r old_keyval="$(echo $2 | sed 's;/;\\/;g')"
  typeset -r new_keyval="$(echo $3 | sed 's;/;\\/;g')"
  typeset -r newfile="$4"

  chmod u+w $newfile 2>&-
  # the "-" after ed tells ed that this is not interactive
  ed - $newfile <<-! 2>/dev/null 1>&2
	g/^[# 	]*${key}[ 	]*\=/s/^${new_keyval}/${old_keyval}/
	w
	q
	!
  chmod u-w $newfile 2>&-
  return $?
}

#
# CreateTerminals()
#
# Description:
#    Create card reader terminals in the SRDS database.
#
# Parameters:
#    $1 the old terminals file
#

CreateTerminals() {
  typeset -r oldfile="$1"

  while read TERMINAL
  do
	${UT_DIR}/sbin/utreader -a ${TERMINAL##*.} > /dev/null 2>&1
  done < $oldfile
}

#
# SplitPolicy()
#
# Description:
#    Splits the old utpolicy format into 2 separate options for
#    the utpolicy and utreader.
#
# Parameters:
#    $* the old utpolicy options
#
SplitPolicy() {
    typeset UTP_OPT=""
    typeset UTR_OPT=""
    typeset cmd
    typeset term

    while [[ $# -gt 0 ]]
    do
	if [[ "$1" = "-t" ]]; then
	    cmd=${2%:*}
	    term=${2#*:}
	    case $cmd in
	    "add")
		UTR_OPT="-a ${term##*.}";;
	    "del")
		UTR_OPT="-d ${term##*.}";;
	    *)
		# ignore the other commands.  NOTE: we don't clear the
		# existing token readers from the datastore.
		UTR_OPT="";;
	    esac
	    shift 2
	    [[ -n "$UTR_OPT" ]] && ${UT_DIR}/sbin/utreader $UTR_OPT \
		> /dev/null 2>&1
	else
	    UTP_OPT="$UTP_OPT $1"
	    shift 1
	fi
    done

    #
    # check to see if we are upgrading the primary.
    # if $?==0, it's a secondary server, don't update the global policy.
    # if $?==1, it's a primary server, update the global policy.
    # if $?==2, utdsd.conf file missing, error - do nothing
    #
    grep -s '^pull_replica' ${UT_ETC_DIR}/srds/current/utdsd.conf \
	> /dev/null 2>&1
    if [[ $? -eq 1 ]]; then
	# primary server, update the global policy.
	# This will handle a server in non-HA environment.
	GetPreservedVersion
        presv=${_RETURN_VAL}
        if [[ $presv == "1.0" ]]; then
            [[ -n "$UTP_OPT" ]] && \
                ${UT_DIR}/sbin/utpolicy -a $UTP_OPT > /dev/null 2>&1
        else
            [[ -n "$UTP_OPT" ]] && \
                ${UT_DIR}/sbin/utpolicy $UTP_OPT > /dev/null 2>&1
        fi
    fi
}


GetJavaPath() {
   #
   # Description:
   #    prompt user for Java path
   #    usage:  GetJavaPath <prompt> <default value>
   #    Returns 0 if the user specified correct path and
   #    is a supported version.   
   #    Returns 1 if the user decides to exit.
   #
   # Parameters:
   #    $1 - a PROMPT string
   #    $2 - the default value
   #

   typeset DEFAULT=""
   typeset ANSWER=""
   typeset JAVA_VERSION=""

   if (( $# != 2 )); then
      return 1
   fi

   DEFAULT="$2"

   while true; do
      print -n "\n$1 [$DEFAULT]: "

      if [[ -n "$G_JRE" ]]; then
        ANSWER="$G_JRE"
	print "$ANSWER"
        if [[ ! -d $ANSWER ]]; then
	  Error "'$ANSWER' is not a directory"
	fi
      else
        if [[ $G_QUICK_INSTALL == "yes" ]]; then
          ANSWER=""
	  print ""
	else
          read ANSWER
	fi
	print "$ANSWER" >>$G_LOGFILE

        if [[ -z "$ANSWER" ]]; then
          ANSWER="$DEFAULT"
        fi
      fi

      JAVA_VERSION=""
      if [ -d $ANSWER ]; then
   	JAVA_VERSION=`$ANSWER/bin/java -version 2>&1 | \
		sed -n '1s/java version "\([0-9.]*\).*"/\1/p'`
      fi

      if [[ -n "$JAVA_VERSION" ]]; then
	 CompareVersion $JAVA_VERSION $_REQ_VER
	 if [[ $? -eq 2 ]]; then
		JAVA_VERSION=""
	 else
	 	_JAVA_HOME=$ANSWER
		return 0
	 fi
      fi

      if [[ -z "$JAVA_VERSION" ]]; then
	print ""
	S="Java found at specified path is not a $_REQ_VER release, continue"

	if ! YesOrNo "$S" "N"; then
          return 1
        fi
      fi
   done
}


#
# UpgradeAuthProps()
#
# Description :Upgrades field in Auth.props file 
#    
# Parameters:
#     $1 old Auth.props file, $2 new Auth.props file
#
#

UpgradeAuthProps() {
  typeset -r oldfile=$1
  typeset -r newfile=$2
#
# list of parameters whose values do not have to be changed
# (keep current value and discard the old one)
  typeset -r parameters_list="smartcardConfigSource terminalTokens"

  if [[ ! -r $newfile ]]; then
    echo "Cannot read $newfile"
    return 1
  fi

# make a backup copy of auth.props file
#
  [[ -f "${newfile}.bak" ]] && rm -f "${newfile}.bak"
  cp -p ${newfile} ${newfile}.bak

  for key in $(grep "=" $oldfile 2>&- | awk -F= '{ print $1 }' |
      sed -e 's/^#//g' -e 's/[  ]//g' | sort -u); do

    # try to set keyval to uncommented pair first
    old_keyval=$(grep "=" $oldfile 2>&- |
        grep "^[ 	]*${key}[= 	]" | tail -1)
    # if no uncommented pair, take the last commented pair
    [[ -z "$old_keyval" ]] && \
      old_keyval=$(grep "=" $oldfile 2>&- |
      grep "^[# 	]*${key}[= 	]" | tail -1)

    # try to set keyval to uncommented pair first
    new_keyval=$(grep "=" $newfile 2>&- |
        grep "^[ 	]*${key}[= 	]" | tail -1)
    # if no uncommented pair, take the last commented pair
    [[ -z "$new_keyval" ]] && \
      new_keyval=$(grep "=" $newfile 2>&- |
      grep "^[# 	]*${key}[= 	]" | tail -1)

#
# Check if this parameter does not have to be modified
    if ( echo $parameters_list | grep -w $key > /dev/null 2>&1 ); then

# if it was commented before, then comment the new one as well (keeping the
# new value)
       if ( echo $old_keyval | grep  ^# > /dev/null 2>&1 &&
            echo $new_keyval | grep -v ^# > /dev/null 2>&1 ); then

          EditPropsFile "$key" "#$new_keyval" "$new_keyval" "$newfile"

       fi
    else
#
# the old value will overwrite the new one if they are different
       if [[ -n "$old_keyval" && -n "$new_keyval" ]]; then
         if [[ "$old_keyval" != "$new_keyval" ]]; then
           EditPropsFile "$key" "$old_keyval" "$new_keyval" "$newfile"
         fi
       fi
    fi
  done
  return $?
}


#
# Module developers to provide the following functions:
# Module_Init, Module_Preserve, Module_Remove, Module_Install, Module_Restore
# Module_Abort, Module_Exit
#

#
# Module_Init()
#
# Description:
#   initialization of the module for installation, uninstallation
#
# Parameters:
#   (none)
#
# Globals used:
#

Module_Init() {

  if IsUninstallRequired; then

     return 0

  fi

  _SW_INSTALLED="no"

  if AnyPackageInstalled $UT_PKG_LIST ; then
     _SW_INSTALLED="yes"
  fi

  if IsInstallRequired ; then
       _DO_INSTALL="yes"

       S="Enter Java v$_REQ_VER (or later) location"

       if ! GetJavaPath "$S" "/usr/j2se"; then
	  return 2
       fi

       if IsDataPreserved || [[ ${_SW_INSTALLED} = "yes" ]]; then
          AddPostInitMessage "Upgrade\t [ data for Authmanager ]"
       fi
  elif IsPreserveRequired ; then
       if [[ ${_SW_INSTALLED} = "yes" ]]; then
          AddPostInitMessage "Preserve [ data for Authmanager ]"
       fi
  fi
}

#
# Module_Preserve()
#
# Description:
#   
#
# Parameters:
#   (none)
#
# Globals used:
#	G_SR_CURRENT_VERSION
#

Module_Preserve() {

   #
   # save policy in a temporary file (/var/opt/SUNWut/policyopts.tmp) and
   # preserve it
   #

   typeset VALUE
   typeset v=${G_SR_CURRENT_VERSION%%.*}
   if [[ ${v} = "1" ]]; then
	#
	# SRSS 1.x only
	#
	# SRSS 2.x and later, we no longer need to save the policy because
	# it's stored in the SR datastore.
	#
	${UT_DIR}/sbin/utpolicy \
	| sed -n 's/.*utpolicy \(.*\)/\1/p' > ${AUTHMGR_PRESERVE_POLICYOPTS}
	SaveFiles $AUTHMGR_PRESERVE_FILES_OLD
	rm -f ${AUTHMGR_PRESERVE_POLICYOPTS}
   fi

   #
   # prior to 3.0, there was no utctl.conf.  We need to generate one when
   # upgrading to 3.1 or later.
   #
   CompareVersion $G_SR_CURRENT_VERSION "3.1"
   compare_status=$?
   if [ $compare_status -eq 2 ]; then
	# need to create the utctl.conf
	if [ -L ${UT_ETC_DIR}/jre ]; then
		VALUE=`ls -l ${UT_ETC_DIR}/jre | awk '{print $NF}'`
		UpdateParam utctl.conf JRE_PATHNAME ${VALUE}
	fi
   fi
   SaveFiles $AUTHMGR_PRESERVE_FILES_ALL

   if [ $compare_status -eq 2 ]; then
	# need to cleanup the utctl.conf on the old system
	/bin/rm -f ${UT_ETC_DIR}/utctl.conf
   fi

   #
   # remove temporary file as it has been preserved
   #

   if [[ $? != 0 ]]; then
      return 2
   fi
   return 0

}

#
# Module_Remove()
#
# Description:
#
# Parameters:
#   (none)
#
# Globals used:
#

Module_Remove() {

   return 0

}

#
# Module_Install()
#
# Description:
#
# Parameters:
#   (none)
#
# Globals used:
#

Module_Install() {

  # Create symbolic link to java
  if ProductInstalled SUNWuto; then
   	if [ -z "${_JAVA_HOME}" ]; then
		# This condition shouldn't happen
         	print "Internal error, couldn't create symbolic link to java"
   	else
		# remove the old link
         	/bin/rm -rf ${UT_ETC_DIR}/jre
		#
		# we no longer create the link here.  We put JRE link info in
		# the utctl.conf file and rely on the activation framework to
		# create the link.
		#
		UpdateParam utctl.conf JRE_PATHNAME ${_JAVA_HOME}
   	fi
  fi

  return 0

}

#
# Module_Restore()
#
# Description:
#    Restore saved configuration data
#
# Parameters:
#   (none)
#
# Globals used:
#   G_SR_CURRENT_VERSION
#

Module_Restore() {

 typeset path
 typeset file

 for file in $AUTHMGR_PRESERVE_UPDATE ; do
   if GetPreservedFilePath "$file"; then
 
      path=${_RETURN_VAL}
      UpdateFields "$path" "$file"
      AppendFields "$path" "$file"
   fi   
 done


 for file in $AUTHMGR_PRESERVE_OVERWRITE ; do
   if GetPreservedFilePath "$file"; then
  
      path=${_RETURN_VAL}
      cp -p "$path" "$file"
   fi
 done

 for file in $AUTHMGR_PRESERVE_AUTHPROPS ; do
   if GetPreservedFilePath "$file"; then
   
      path=${_RETURN_VAL}
      UpgradeAuthProps "$path" "$file"
   fi
 done

 for file in $AUTHMGR_PRESERVE_AUTHPERMIT ; do
   if GetPreservedFilePath "$file"; then

      path=${_RETURN_VAL}
      UpdateFields "$path" "$file"
   fi
 done

 #
 # No need to restore the policy or terminal tokens when upgrading a Zero
 # Admin server (ie. utconfig has not been run).  We check to see if the
 # utadmin.conf file exists.  If not then this is a Zero Admin server.
 # Otherwise, this server has been configured.  So, we should try to
 # restore the policy and the terminal tokens if needed.
 #
 if [[ -f ${UT_ETC_DIR}/utadmin.conf ]]; then

     #
     # Starting in 2.0, policy and terminals are now always stored in SRDS
     # and are automatically downloaded to the local server when authd starts
     # up.  So,
     # 1. when upgrading from 2.x, there is no need to restore the policy
     #    and terminal files.
     # 2. when upgrading from 1.x, if useLocalPolicy=false, this means the
     #    global policy and terminal info are already in LDAP thus no need to
     #    restore the files.
     # 3. when upgrading from 1.x, if useLocalPolicy=true, this means the policy
     #    and terminals are stored locally.  In this case, we need to restore
     #    the policy and terminals so that they are added into SRDS.

     GetPreservedVersion
     typeset v=${_RETURN_VAL%%.*}
     if [[ ${v} = 1 ]]; then
        #
        # check the useLocalPolicy parameter in the preserved auth.props.
        #
        if GetPreservedFilePath "$AUTHMGR_PRESERVE_AUTHPROPS"; then
           path=${_RETURN_VAL}
           typeset useLocalPolicy=$(sed -n -e \
           	"s/^[ 	]*useLocalPolicy[ 	]*=[ 	]*\([^ 	][^ 	]*\)/\1/p" \
    	$path)
           if $useLocalPolicy; then
    	  #
    	  # local policy was set to "true" before, thus need to restore the
    	  # policy and terminals for card readers.
    	  #

    	  # .... Restore policy settings
    	  if GetPreservedFilePath "${AUTHMGR_PRESERVE_POLICYOPTS}"; then
    	     path=${_RETURN_VAL}                                       
    	     SplitPolicy $(cat ${path})
    	  fi

    	  # .... Restore terminals
    	  for file in $AUTHMGR_PRESERVE_TERMINALS; do
    	      if GetPreservedFilePath "$file"; then
    
    		 path=${_RETURN_VAL}
    		 CreateTerminals "$path"
    	      fi
    	  done
           fi
        fi
     fi

 fi	# utadmin.conf

 echo "Restoration of Authmgr data complete"

 return 0

}

#
# Module_Abort()
#
# Description:
#    Abort procedure
#
# Parameters:
#   (none)
#
# Globals used:
#

Module_Abort() {

   return 0

}

#
# Module_Exit()
#
# Description:
#    Exit procedure (normal termination)
#
# Parameters:
#   (none)
#
# Globals used:
#

Module_Exit() {

   return 0

}

#
# END
#

#
# MAIN STARTS HERE
#

trap "exit 2" HUP INT QUIT TERM

#
# include libraries
#

. ${G_MEDIA_DIR}/support_lib/upgrade_lib
. ${G_MEDIA_DIR}/support_lib/iu_lib
. ${G_MEDIA_DIR}/support_lib/module_lib
. ${G_MEDIA_DIR}/support_lib/util_lib

export _EVENT=$1
export _MODULE_NAME=$(basename $0)
export _VARS_LIST=""
export _EXIT_CODE=0
export _RETURN_VAL=0
export _VAR_STORAGE_FILE="${G_TMP_DIR}/.${G_PROGRAM_ID}.${_MODULE_NAME#???}"

DeclareModuleVar _DO_INSTALL="no"
DeclareModuleVar _DO_REMOVE="no"
DeclareModuleVar _SW_INSTALLED="no"
DeclareModuleVar _SW_COMPATIBLE="yes"
DeclareModuleVar _JAVA_HOME=""
DeclareModuleVar _REQ_VER="1.4"

#
# BEGIN: Developers module variables definition here
#

export UT_DIR="$($G_MEDIA_DIR/utprodinfo -r SUNWuto 2>&-)/SUNWut"
export UT_ETC_DIR="/etc/opt/SUNWut"
export UT_VAR_DIR="/var/opt/SUNWut"

export AUTHMGR_PRESERVE_OVERWRITE="${UT_ETC_DIR}/policy/utpolicy \
				${UT_ETC_DIR}/gmSignature \
				${UT_ETC_DIR}/utctl.conf"

export AUTHMGR_PRESERVE_AUTHPROPS="${UT_ETC_DIR}/auth.props"

export AUTHMGR_PRESERVE_UPDATE="${UT_ETC_DIR}/sessionTypes.props \
				${UT_ETC_DIR}/token.equiv"

export AUTHMGR_PRESERVE_AUTHPERMIT="${UT_ETC_DIR}/auth.permit"

export AUTHMGR_PRESERVE_TERMINALS="${UT_ETC_DIR}/terminals"						
export AUTHMGR_PRESERVE_POLICYOPTS="${UT_VAR_DIR}/policyopts.tmp"


export AUTHMGR_PRESERVE_FILES_OLD="
    ${AUTHMGR_PRESERVE_TERMINALS}
    ${AUTHMGR_PRESERVE_POLICYOPTS}
"

export AUTHMGR_PRESERVE_FILES_ALL="
    ${AUTHMGR_PRESERVE_OVERWRITE}
    ${AUTHMGR_PRESERVE_AUTHPROPS}
    ${AUTHMGR_PRESERVE_UPDATE}
    ${AUTHMGR_PRESERVE_AUTHPERMIT}
"

typeset -r UT_PKG_LIST="SUNWuta SUNWuto SUNWutr SUNWutk SUNWutu SUNWutps SUNWutscr"

#
# END
#

#
# FRAMEWORK CODE 
#

. ${G_MEDIA_DIR}/support_lib/framework_lib
