#!/bin/sh
#
# Copyright (c) 2002-2004 by Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "@(#)prebackout 1.0 - 02/10/23"

stop_patch=no
cmd_torun_admin=

# Admin server first

debug() {
    if [ "x"$VERBOSE != "x" ] ; then
	echo $1
    fi
}

get_pkgname() {
    debug "get_pkgname $1"
    PKG=$1
    pkginfo -R $ROOTDIR $PKG.\* 1>/dev/null 2>&1
    if [ $? -ne 0 ]; then
	debug "No package $1 installed"
	return 1
    else
	PKGNAME=`pkginfo -R ${ROOTDIR} $1.\* | awk '{print $2}'`
    fi
    debug "get_pkgname returns $PKGNAME"
    return 0
}

get_basedir() {
    debug "get_basedir $1"    
    get_pkgname $1
    if [ $? -ne 0 ]; then
	return 1
    else
	LOCAL_BASEDIR=`pkginfo -R ${ROOTDIR} -r $PKGNAME`
	if [ ${ROOTDIR} != '/' ] ; then
	    PKGBASEDIR=${ROOTDIR}/${LOCAL_BASEDIR}
	else
	    PKGBASEDIR=${LOCAL_BASEDIR}
	fi
    fi
    debug "get_basedir returns $PKGBASEDIR"
    return 0
}

over52(){
    debug "over52"
}

over51(){
    debug "over51"
    if [ ! -f $ds52_basedir/usr/iplanet/ds5/sbin/directoryserver ] ; then
	# DS 5.1 has been installed after DS 5.2 patch 2
	# /usr/sbin/directoryserver is the DS 5.1 directoryserver command => cp to 51bak
	debug "Copying $ds52_basedir/usr/sbin/directoryserver to $ds52_basedir/usr/sbin/directoryserver.51bak"
	cp $ds52_basedir/usr/sbin/directoryserver \
	    $ds52_basedir/usr/sbin/directoryserver.51bak
    fi
}

over51p(){
    debug "over51p"
    # Save wrapper. Otherwise backout will overwrite it with a link to 5.2 command
    cp $ds52_basedir/usr/sbin/directoryserver \
	$ds52_basedir/usr/sbin/directoryserver.save
}

if [ `uname -i` = "i86pc" ] ; then
    DS51_PATCHID="114273"
    DS51_MIN_PATCHREV="04"
else
    DS51_PATCHID="113859"
    DS51_MIN_PATCHREV="04"
fi

is_51_patch(){
    debug "is_51_patch"
    current_patch=`pkgparam -R $ROOTDIR $IPLTDSU_PKG PATCHLIST`
    if [ "x$current_patch" != "x" ]; then
	for i in `echo $current_patch`
	  do
	  check_ret=`echo "$i" | \
                     awk '{ FS="-" ; \
                     if (($1 == '$DS51_PATCHID') && ($2 >= '$DS51_MIN_PATCHREV'))
                         print 0 ; \
                     else print 1;}'`
	  if [ $check_ret -eq 0 ]; then
	      break
	  fi
	done
	if [ $check_ret -eq 1 ]; then
	    debug "is_51_patch returns 1"
	    return 1
	fi
    else
	debug "is_51_patch returns 1"
	return 1
    fi    
    debug "is_51_patch returns 0"
    return 0
}

manage_directoryserver() {
    get_basedir IPLTdsu
    if [ $? -eq 0 ]; then
    # Existing installed DS 5.1
	IPLTDSU_PKG=$PKGNAME
	ds51_basedir=$PKGBASEDIR
	if [ $ds51_basedir = $ds52_basedir ]; then
	# Existing installed DS 5.1 in the same basedir
	    is_51_patch
	    if [ $? -eq 0 ] ; then
	    # DS 5.1 has been patched (case 2.2.2)
		over51p
	    else
	    # DS 5.1 has not been patched (case 2.2.1)
	    over51
	    fi
	else
	# No existing installed DS 5.1 in the same basedir (case 2.2.3)
	    over52
	fi
    else
    # No DS 5.1 (case 2.2.3)
	over52 
    fi
}

#########################################
# make_link
#
# Remove existing link at dest if necessary
# Create the link
# Set the owner id and group of the new link
# source: $1
# dest: $2
# owner id of the link: $3 and
# owner group of the link:$4
#########################################
make_link () {

	rc=0
	src=$1
	dest=$2
	USER=$3
	GROUP=$4

	# if the dest link already exists: remove it
	if [ -h $dest ]; then
		rm -f $dest
		if [ $? -ne 0 ];then
			rc=1
			echo "Removal of $dest link failed"
		fi
	fi

	# create the link
	ln -s $src $dest
	
	if [ $? -ne 0 ];then
		rc=1
		echo "Creation of $dest link failed"
	else
		if [ "x${USER}" != "x" ] || [ "x${GROUP}" != "x" ]; then
			# set the owner id and group of the link.
			chown -h $USER:$GROUP $dest
			if [ $? -ne 0 ];then
				rc=1
				echo "Update of $dest link owner failed"
			fi
		fi
	fi
	
	return $rc
}

#########################################
# backout_security_links
# go from NSS3.3.8 to NSS3.3.4
#	For both 32 and 64 bits
#	For 32 bits, check wether AS patch
#	has been applied
#########################################
backout_security_links()
{
	rc=0
	opt=$1
	if [ $opt = "64" ]; then
		ARCH=sparcv9
	else
		ARCH=
	fi
	SERVER_ROOT_LIB=${SERVER_ROOT}/lib/${ARCH}
	
	get_basedir SUNWtls
	TLS_LIBDIR=${LOCAL_BASEDIR}/usr/lib/mps/${ARCH}

	get_basedir SUNWpr
	NSPR_LIBDIR=${LOCAL_BASEDIR}/usr/lib/mps/${ARCH}

	get_basedir SUNWjss
	JSS_LIBDIR=${LOCAL_BASEDIR}/usr/lib/mps/${ARCH}
	JSS_SHARED_DIR=${LOCAL_BASEDIR}/usr/share/lib/mps/${ARCH}

	if [ $opt = "32" ]; then
		if [ -h ${SERVER_ROOT}/shared/bin/sync-version ] ; then
			#
			# It is not necessary to update the security symbolic links. AS is responsible for this update
			#
			return 
		fi
	fi

	sslLibs="
		libssl3.so
		libnss3.so
		libsmime3.so
		"
	sslLibsSparc="
		libfreebl_hybrid_3.so
		libfreebl_pure32_3.so
		"

	nsprLibs="
		libnspr4.so
		libplc4.so
		libplds4.so
		"

	for fileName in ${sslLibs}; do
		make_link ${TLS_LIBDIR}/${fileName} ${SERVER_ROOT_LIB}/${fileName} $SYSTEMUSER $SYSTEMGROUP
		if [ $? -ne 0 ]; then
			rc=1
		fi
	done

	for fileName in ${nsprLibs}; do
		make_link ${NSPR_LIBDIR}/${fileName} ${SERVER_ROOT_LIB}/${fileName} $SYSTEMUSER $SYSTEMGROUP
		if [ $? -ne 0 ]; then
			rc=1
		fi
	done

	if [ $opt = "32" ]; then
		make_link ${TLS_LIBDIR}/libnssckbi.so ${SERVER_ROOT}/alias/libnssckbi.so $SYSTEMUSER $SYSTEMGROUP
		if [ $? -ne 0 ]; then
			rc=1
		fi

		# Update the JSS links
		make_link ${JSS_LIBDIR}/libjss3.so ${SERVER_ROOT}/lib/jss/libjss3.so $SYSTEMUSER $SYSTEMGROUP
		if [ $? -ne 0 ]; then
			rc=1
		fi

		make_link ${JSS_SHARED_DIR}/jss3.jar ${SERVER_ROOT}/java/jss3.jar $SYSTEMUSER $SYSTEMGROUP
		if [ $? -ne 0 ]; then
			rc=1
		fi
	fi

	if [ `uname -p` = "sparc" ] && [ $opt = "32" ] ; then
		for fileName in ${sslLibsSparc}; do
			make_link ${TLS_LIBDIR}/${fileName} ${SERVER_ROOT_LIB}/${fileName} $SYSTEMUSER $SYSTEMGROUP
			if [ $? -ne 0 ]; then
				rc=1
			fi
		done
	fi
	return $rc
}

#########################################
# backout_links
#
#########################################
backout_links() 
{
	rc=0
	ssusersConfFile=${SERVER_ROOT}/shared/config/ssusers.conf
	if [ -f $ssusersConfFile ]; then
		SYSTEMUSER=`cat $ssusersConfFile | awk '/^SuiteSpotUser/ { print $2; }' `
		SYSTEMGROUP=`cat $ssusersConfFile | awk '/^SuiteSpotGroup/ { print $2; }' `
	fi

	# updating links for NSS3.3.4 => NSS3.3.6 for 32  bits
	backout_security_links 32
	if [ $? -ne 0 ]; then
		rc=1
	fi

	# Regarding 64 bits, it makes sense to check wether SUNWdsvx has been installed
	# before doing anything ...
	if [ `uname -p` = "sparc" ]; then
		get_pkgname SUNWdsvx
		if [ $? -eq 0 ]; then
			backout_security_links 64
			if [ $? -ne 0 ]; then
				rc=1
			fi
		fi
	fi

	# Remove the symbolic link to sync-directory in <SR>/shared/bin
	if [ -h ${SERVER_ROOT}/shared/bin/sync-directory ]; then
		rm -f ${SERVER_ROOT}/shared/bin/sync-directory
		if [ $? -ne 0 ];then
			rc=1
			echo "Removal of ${SERVER_ROOT}/shared/bin/sync-directory link failed"
		fi
	fi

	# remove links under <server root>/java/jars/ for the jar files ds522.jar and ds522_en.jar
	jar_list=`ls ${SERVER_ROOT}/java/jars/ds522*.jar`
	if [ "x$jar_list" != "x" ]; then
		rm -f ${jar_list}
		if [ $? -ne 0 ];then
			rc=1
		fi
	fi
	if [ -f ${SERVER_ROOT}/java/jars/ds522.icon ];then
		rm -f ${SERVER_ROOT}/java/jars/ds522.icon
		if [ $? -ne 0 ];then
			rc=1
		fi
	fi

	# remove manual hierarchy and restore the link
	LOCAL_USR_ADM=$AS_LOCAL_BASEDIR/usr/sadm/mps/admin/v5.2
	ETC_ADM=$AS_BASEDIR/etc/mps/admin/v5.2
	VAR_ADM=$AS_BASEDIR/var/mps/serverroot
	if [ -f $ETC_ADM/shared/config/serverroot.conf ]; then
		VAR_ADM=$ROOTDIR/`cat $ETC_ADM/shared/config/serverroot.conf`
	fi
	if [ ! -h $VAR_ADM/manual ]; then
		rm -rf $VAR_ADM/manual
                if [ $? -ne 0 ];then
        		rc=1
                        echo "Removal of $VAR_ADM/manual failed"
		fi
		make_link $LOCAL_USR_ADM/manual $VAR_ADM/manual $SYSTEMUSER $SYSTEMGROUP
     		if [ $? -ne 0 ]; then
       			rc=1
		fi
	fi

	return $rc
}

#####################################
#
# Setup the variables for AS and DS 
#
#####################################

# For AS

get_basedir SUNWasvu
if [ $? -ne 0 ]; then
    exit 1
fi
AS_BASEDIR=${PKGBASEDIR}
AS_LOCAL_BASEDIR=${LOCAL_BASEDIR}

# For DS

get_basedir SUNWdsvu
DS_BASEDIR=${PKGBASEDIR}
ds52_basedir=$DS_BASEDIR
DS_LOCAL_BASEDIR=${LOCAL_BASEDIR}

####################################
#
# If DS is not configured, then there
# is nothing to do. Just exit 0 
#
####################################

DS_is_configured=no
if [ -f ${AS_BASEDIR}/etc/mps/admin/v5.2/shared/config/serverroot.conf ] ; then
    SERVER_ROOT=${ROOTDIR}/`cat ${AS_BASEDIR}/etc/mps/admin/v5.2/shared/config/serverroot.conf`
    instance_list=`ls -d ${SERVER_ROOT}/slapd-* 2>/dev/null`
    if [ ! "x${instance_list}" = "x" ]
    then
	DS_is_configured=yes
    fi

fi

if [ "${DS_is_configured}" = "no" ]; then
    manage_directoryserver
    exit 0
fi

############################
#
# First step:
#	 stop slapd servers
#
############################


PATHNUM=`env | grep PatchNum`
stop_patch=no
cmd_torun_ds=
instance_list=`ls -d ${SERVER_ROOT}/slapd-* 2>/dev/null`
if [ ! "x${instance_list}" = "x" ] ; then
    for i in `ls -d ${SERVER_ROOT}/slapd-*`
    do
	servername=`/bin/basename $i | /bin/awk '{ print substr($0,7,length($0)-6) }'` 
	if [ -f /var/tmp/.shouldRestart_DS_${servername}_${PATHNUM} ]; then
	    rm -f /var/tmp/.shouldRestart_DS_${servername}_${PATHNUM}
	fi
	if [ -f ${i}/logs/pid ] ; then
            if [ "x${ROOTDIR}" = "x" ] || [ "x${ROOTDIR}" = "x/" ] ; then
           	echo "Prebackout script is stopping Directory Server instance ${i}..."
	    	cmd_torun_ds="${DS_LOCAL_BASEDIR}/usr/ds/v5.2/sbin/directoryserver -s ${servername} stop"
		eval ${cmd_torun_ds}
		if [ $? -eq 1 ];then
			echo "Directory Server instance could not be stopped"
			exit 1
		else
			echo "Directory Server instance stopped"
		fi
        	touch /var/tmp/.shouldRestart_DS_${servername}_${PATHNUM}
            else
		stop_patch=yes
		cmd_torun_ds="${cmd_torun_ds} ${DS_LOCAL_BASEDIR}/usr/sbin/directoryserver -u 5.2 -s ${servername} stop\n"
    	    fi
	fi
    done
fi

if [ ${stop_patch} = "yes" ]
then
	echo "You need to stop the servers before removing this patch."
	echo "Please log on the machine on which this patch is to be"
	echo "removed and run the following commands:"
	echo ${cmd_torun_admin}
	echo ${cmd_torun_ds}
	exit 1
fi

###############################################
#
# Second step:
#	Perform the data downgrade for all ldap 
#	instances if necessary
# 	If at least one of the instance data 
#	downgrade is not successfull, then
# 	the backout is stopped 	
#
###############################################
echo "Starting data backout for all instances..."
if [ -h ${SERVER_ROOT}/shared/bin/sync-directory ]
then
	get_basedir SUNWtls
	TLS_LIBS=${PKGBASEDIR}/usr/lib/mps/secv1

	get_basedir SUNWpr
	PR_LIBS=${PKGBASEDIR}/usr/lib/mps/secv1

	get_basedir SUNWsasl
	SASL_LIBS=${PKGBASEDIR}/usr/lib/mps/sasl2

	get_basedir SUNWicu
	ICU_LIBS=${PKGBASEDIR}/lib

	get_basedir SUNWldk
	LDK_LIBS=${PKGBASEDIR}/usr/lib/mps

	get_basedir SUNWdsvu
	DSVU_LIBS=${PKGBASEDIR}/usr/ds/v5.2/lib

	REMOTE_LD_LIBRARY_PATH=${TLS_LIBS}:${ICU_LIBS}:${DSVU_LIBS}:${SASL_LIBS}:${LDK_LIBS}:${PR_LIBS}:${LD_LIBRARY_PATH}

	env LD_LIBRARY_PATH=${REMOTE_LD_LIBRARY_PATH} ${DS_BASEDIR}/usr/ds/v5.2/sbin/sync-directory -downgrade -s ${SERVER_ROOT}
	if [ $? -ne 0 ] ; then
		echo "Data backout for all instances partially complete"
	else
		echo "Data backout for all instances complete"
	fi
else
	# This should never happen
	echo "The backout of data cannot occur because the sync-directory binary is missing."
	echo "Please contact your Sun Support"
	exit 1
fi

################################################
#
# Third step:
#	Update the symbolic links
#
################################################

backout_links

################################################
#
# Fourth step:
#	Manage the directoryserver command
#
################################################

manage_directoryserver
################################################

