#!/bin/ksh 
#
# ident "@(#)M40AuthMgr.ksh	1.24 02/08/30 SMI"
#
# Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
#
#
# 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
}



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

  return 0
}

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

Module_Preserve() {

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

   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

   SaveFiles $AUTHMGR_PRESERVE_FILES_ALL

   #
   # 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() {

  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
 #
 # Make sure that, after the upgrade, the messages file is in the log directory
 # otherwise (if it has been removed) syslog will complain and will not
 # report any log information
 #
 touch ${UT_VAR_DIR}/log/messages
 chmod 644 ${UT_VAR_DIR}/log/messages

 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

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"

#
# BEGIN: Developers module variables definition here
#

export UT_DIR="/opt/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"

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 SUNWutj SUNWuto SUNWutr SUNWutk SUNWutu SUNWutps SUNWutscr"

#
# END
#

#
# FRAMEWORK CODE 
#

. ${G_MEDIA_DIR}/support_lib/framework_lib
