#!/bin/ksh -p
#
# ident "@(#)M40AuthMgr.ksh	1.49 08/06/11 SMI"
#
# Copyright 2008 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
#

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

function 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 $?
}

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

function CreateTerminals {
  typeset -r oldfile="$1"
  typeset terminal

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

#
# function SplitPolicy
#
# Description:
#    Splits the old utpolicy format into 2 separate options for
#    the utpolicy and utreader.
#
# Parameters:
#    $* the old utpolicy options
#
function 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
}

function GetJAVA_VERSION {
  $1/bin/java -version 2>&1 |
  sed -n '1s/java version "\([0-9.]*\).*"/\1/p'
}

function 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

      case "$answer" in
      /*) ;; # ok
      *)
        Error "'$answer' must begin with '/'"
	;;
      esac

      java_version=""
      if [ -d $answer ]; then
   	java_version="$(GetJAVA_VERSION $answer)"
      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
}


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

function 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
#

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

function 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/java"; 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
}

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

function 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

}

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

function Module_Remove {

   return 0

}

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

function 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

}

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

function GetUseLocalPolicy {
  sed -n '/^[ 	]*useLocalPolicy[ 	]*=[ 	]*/s///p' $1
}

function 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=$(GetUseLocalPolicy $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
}

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

function Module_Abort {

   return 0

}

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

function 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.5"

#
# 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"

# Currently only JRE_PATHNAME is stored in utctl.conf.
# During upgrade, installer prompts for JRE path to user and
# should use the path entered by user instead of using the
# stored path in utctl.conf file.  Hence there is no need to
# restore this file at this time.
export AUTHMGR_PRESERVE_UTCTLCONF="${UT_ETC_DIR}/utctl.conf"

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

export AUTHMGR_PRESERVE_UPDATE="${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
