#!/bin/sh

##########################################################################
# eDirectory migration utility for Linux
# Copyright (c) 2007, Novell Inc.  All rights reserved.
# Utility: migedir
# Description: eDirectory migration utility for OES 2.
# 			   This utility migrates eDirectory from a NetWare server to
#			   an OES 2 Linux server. This will migrate data, eDirectory
#			   services and identity.
#
##########################################################################

##########################################################################
# Global variables #
##########################################################################
printUsage=0
verbose=0
this_file=$0
cmd_line="$@"
this_file_name=`basename $this_file`
eDirMigPath=/var/opt/novell/.edir_migrate
log_file_path="${eDirMigPath}"/log
unix_default_dibdir=/var/opt/novell/eDirectory/data/dib
unix_default_cfgdir=/etc/opt/novell/eDirectory/conf
ncp_bin_dir=/opt/novell/ncpserv/sbin
source_server=
doBackupOnly=0
doRestoreOnly=0
testOnly=0
dontPrompt=0

PATH=.:$PATH
ARCH=`uname -m`

if [ "${ARCH}" = "x86_64" ]; then
	export LD_LIBRARY_PATH=/usr/lib64:/opt/novell/lib64:/opt/novell/eDirectory/lib64:/opt/novell/eDirectory/lib64/nds-modules:$LD_LIBRARY_PATH
else
	export LD_LIBRARY_PATH=/usr/lib:/opt/novell/lib:/opt/novell/eDirectory/lib:/opt/novell/eDirectory/lib/nds-modules:$LD_LIBRARY_PATH
fi

# Message severity
FATAL="Fatal"
ERROR="Error"
WARN="Warning"
INFO="Information"

DATE=`date +%d-%m-%Y:%T`

case "${1}" in
	-h | --help | "" )
					printUsage=1
					;;
esac

##########################################################################
# String constants #
##########################################################################
str_USAGE=`gettext migrate "$0 -s <Source Server> [-t] [-i] [-A <Log Directory>] [-h] [-B] [-R]"`
str_HELP_S=`gettext migrate "-s  - Source server IP address"`
str_HELP_T=`gettext migrate "-t  - Test parameters"`
str_HELP_V=`gettext migrate "-i  - Verbose mode"`
str_HELP_A=`gettext migrate "-A  - Log directory"`
str_HELP_H=`gettext migrate "-h  - Print help"`
str_HELP_u=`gettext migrate "-u  - Unattended"`
str_HELP_a=`gettext migrate "-a  - Tree adminDN"`
str_HELP_w=`gettext migrate "-w  - Admin password"`
str_HELP_B=`gettext migrate "-B  - Do backup only"`
str_HELP_R=`gettext migrate "-R  - Do restore only "`
str_RETURN=`gettext migrate "Return value: 0 on success, 1 on failure."`

str_TITLE=`gettext migrate "eDirectory migration utility for Linux"`
str_VERSION=`gettext migrate "Version: 2.0 for OES Linux 2.0"`
str_COPYRIGHT=`gettext migrate "Copyright (c) 2013 NetIQ Corporation and its affiliates. All Rights Reserved."`

##########################################################################
# Common Functions #
##########################################################################
printTitle()
{
	echo "$str_TITLE"
	echo "$str_VERSION"
	echo "$str_COPYRIGHT"
	echo ""
}

##########################################################################
# Global printing function to the screen.
# Syntax: <DD-MM-YYYY:HH:MM:SS>:<Severity>:<Message>
# Input parameters to the function
# $1 = Severity $2 = Message
##########################################################################
printToScreen()
{
	echo "$*"
}


# Check that root only can execute this utility
validateRights()
{
	ID=`id | awk '{print $1}' | awk -F"=" '{print $2}' | awk -F"(" '{print $1}'`

	if [ $ID -ne 0 ]
	then
		str=`gettext migrate "You must be 'root' user to migrate eDirectory."`
		printToScreen "$str"
		exit 1
	fi
}


# Check if DIB is already present
checkDIB()
{
	if [ -f ${unix_default_dibdir}/nds.db ]; then
		str=`gettext migrate "An instance of eDirectory server is already present on this system. DIB files were found at '${unix_default_dibdir}'. \nUse the command 'ndsconfig rm' to remove the eDirectory server before proceeding with the migration."`
		printToScreen "$str"
		exit 1
	fi
}


# Check if SSH/SCP is setup in batch mode
checkSSHAccess()
{
	str=`gettext migrate "Checking 'ssh' access to the source server '${source_server}'..."`
	printToScreen "$str"

	ssh -o BatchMode=yes root@${source_server} 'echo "Testing SSH/SCP access..."' > /dev/null
	err=$?
	if [ $err -ne 0 ]; then
		if [ $dontPrompt -eq 1 ]; then
			str=`gettext migrate "INFO ${err}: Unable to access '${source_server}' using 'ssh' in unattended mode. Refer to man page of 'ssh' to set it up in 'BatchMode'."`
			printToScreen "$str"
			exit 1
		else
			str=`gettext migrate "INFO: User would be prompted for the 'root' password of the source server '${source_server}' during the migration when 'ssh/scp' service is necessary since it is not set in 'BatchMode' for passwordless access."`
			printToScreen "$str"
		fi
	fi
}


# Command usage
printUsageForCommandLine()
{
	str=`gettext migrate "USAGE : "`
	echo -n "$str"
	echo $str_USAGE
	echo $str_HELP_S
	echo $str_HELP_T
	echo $str_HELP_V
	echo $str_HELP_A
	echo $str_HELP_H
	echo $str_HELP_u
	echo $str_HELP_a
	echo $str_HELP_w
	echo $str_HELP_B
	echo $str_HELP_R
	echo ""
	echo $str_RETURN
}


# Check DS version for source server and store in migedir.conf file 
checkDSVersion()
{
	DS86Ver=10310
	# Get only the first 3 digits
	srcDSVer=`ndsstat -h $source_server | grep "Binary Version" | awk '{print $3}' | awk -F. '{print $1}' | awk 'BEGIN { FS = "" } {print $1 $2 $3 $4 $5}'`
	if [ $? -eq 0 ]; then
		if [ "$srcDSVer" -ge "$DS86Ver" ]; then
			echo "SOURCE_DSVER:${srcDSVer}" > "${eDirMigPath}"/migedir.conf
		elif [ "$srcDSVer" -lt "$DS86Ver" ]; then
			str=`gettext migrate "The source server '$source_server' has DS version '$srcDSVer' which is not supported for eDirectory migration."`
			printToScreen "$str"
			exit 1
		else
			echo "SOURCE_DSVER:${srcDSVer}" > "${eDirMigPath}"/migedir.conf
		fi
	else
		str=`gettext migrate "ERROR: Unable to check the DS version."`
		printToScreen "$str"
		srcDSVer=0
	fi
}

# Do ping, ndsstat and ndscheck tests and get details of the source server
getServerDetails()
{
	if [ -z "$source_server" -a $doRestoreOnly -eq 0 ]; then
		str1=`gettext migrate "Enter the IP address or the hostname of the source server that is to be migrated."`
		printToScreen "$str1"
		printUsageForCommandLine
		exit 1
	else
		checkDSVersion

		ping -q -c 1 -W 1 $source_server | grep rtt > /dev/null 2>&1
		if [ $? -ne 0 ]; then
			str=`gettext migrate "Unable to contact the host, ${source_server}!"`
			printToScreen "$str"
			exit 1
		else
			if [ $verbose -eq 1 ]; then
				str=`gettext migrate "Source server, $source_server is reachable."`
				printToScreen "$str"
			fi

			echo "SOURCE_IP:${source_server}" >> "${eDirMigPath}"/migedir.conf

			srvPlatform=`ndsstat -h $source_server | grep "Product Version"`
			if [ $? -eq 0 ]; then
				echo $srvPlatform | grep "NetWare" > /dev/null 2>&1
				if [ $? -eq 0 ]; then
					SRC_PLATFORM=NetWare
					if [ $verbose -eq 1 ]; then
						str=`gettext migrate "The source server, ${source_server} is running on NetWare platform."`
						printToScreen "$str"
					fi

					checkNetWarePlatform
				else
					echo $srvPlatform | grep "Linux"  > /dev/null 2>&1
					if [ $? -eq 0 ]; then
						SRC_PLATFORM=Linux
						str=`gettext migrate "The source server, $source_server is running on Linux platform."`
                                       		printToScreen "$str"
						checkLinuxPlatform
						if [ $testOnly -ne 1 ]; then
							checkSSHAccess
						fi
					else
						SRC_PLATFORM=UNSUPPORTED
						echo "$srvPlatform"
						str=`gettext migrate "eDirectory migration is not supported on this platform, ${srvPlatform}. The supported platforms are NetWare and OES Linux."`
						printToScreen "$str"
						exit 1
					fi
				fi
			else
				str=`gettext migrate "Unable to contact the source eDirectory server on the host, ${source_server}!"`
				printToScreen "$str"
				exit 1
			fi
		fi
	fi
}

# Validate the command line inputs to this utility
parseAndValidateCmdLine()
{
	if [ $printUsage -eq 1 ]; then
		printUsageForCommandLine
		exit 0
	fi

	while getopts A:a:BhiRs:tw:u opt
	do
		case $opt in
			h)
				printUsageForCommandLine
				exit 0
				;;

			a)
				user=$OPTARG
				;;
				
			A)
				log_file_path=$OPTARG
				;;

			B)
				doBackupOnly=1
				;;

			R)
				doRestoreOnly=1
				;;

			t)
				testOnly=1
				;;

			i)
				verbose=1
				;;

			s)
				source_server=$OPTARG
				;;

			w)
				passwd=$OPTARG
				;;

			u)
				dontPrompt=1
				;;

			*)
				str=`gettext migrate "Invalid option, ${OPTARG}!"`
				printToScreen "$str"
				printUsageForCommandLine
				exit 1
				;;
		esac
	done

	if [ $doRestoreOnly -eq 1 -a "$source_server" != "" ]; then
		str=`gettext migrate "ERROR: The server name parameter is not necessary for restore!"`
		printToScreen "$str"
		exit 1
	fi
}


createPath()
{
	dirName="$1"

	if [ -z "$dirName" ]; then
		str=`gettext migrate "INFO: createPath - No directory name is passed for creation."`
		printToScreen "$str"
		return
	fi

	if [ ! -d "$dirName" ]; then
		mkdir -p "$dirName" > /dev/null
		err=$?
		if [ $err -ne 0 ]; then
			str=`gettext migrate "ERROR ${err}: Unable to create the directory ${dirName}"`
			printToScreen "$str"
			exit 1
		fi
	fi
}


createMigPaths()
{
	str=`gettext migrate "Creating the eDirectory migration file locations..."`
	printToScreen "$str"

	# Create the log directory
	createPath "${log_file_path}"

	# Create directories necessary for backup
	if [ ${doRestoreOnly} -ne 1 ]; then
		# Create the directory to mount NetWare volume
		createPath "${eDirMigPath}/mnt"

		# Create the directory to backup NICI files
		createPath "${eDirMigPath}/nici/0"
	fi

	# Create directories necessary for restore
	if [ ${doBackupOnly} -ne 1 ]; then
		# Create the directory to mount NetWare volume
		createPath "${unix_default_dibdir}"
	fi
}


# Get the adminDN and password of the source server administrator
getCredentials()
{
	str=`gettext migrate "Get the source server administrator credentials - "`
	printToScreen "$str"

	# if [ "$user" = "" ]
	while [ -z "$user" ]
	do
		str=`gettext migrate "Enter adminDN(e.g: cn=admin.o=administrators): "`
		echo -n " $str"
		read user
	done

	if [ -z "$passwd" -a -z "$ADM_PASSWD" ]
	then
		str="Enter password: "
		echo -n " $str"
		stty_orig=`stty -g`
		stty -echo
		read passwd
		stty $stty_orig
	fi

	echo ""
	export ADMIN="$user"
	if [ ! -z "$passwd" ]; then
		export ADM_PASSWD="$passwd"
	fi
}

# Check if the NetWare version is supported
checkNetWarePlatform()
{
	${ncp_bin_dir}/ncpshell --p="$passwd" --ip="$source_server" --u="$user" --fsinfo
	NCPRETVAL=$?
	if [ "$NCPRETVAL" = "0" ] ; then
		engine_platform=`${ncp_bin_dir}/ncpshell --p="$passwd" --ip="$source_server" --u="$user" --fsinfo | grep -i "Engine Platform" | awk -F":" '{print $2}'`
		if [ "$engine_platform" -eq "0" ]; then
			str=`gettext migrate "The NetWare source server is running on OES Platform"`
			echo $str
		else
			str=`gettext migrate "The NetWare source server is not running on OES Platform"`
			echo $str
			exit
		fi
		#check DS version for NetWare to support the migeDir as below 873SP6 DS version we are not supporting for migration
		DS862Ver=10310
      	  	# Get only the first 5 digits for Binary Version 
  	      	srcDSVer_NetWare=`ndsstat -h $source_server | grep "Binary Version" | awk '{print $3}' | awk -F. '{print $1}'` 
    	       	if [ "$srcDSVer_NetWare" -lt "$DS862Ver" ]; then
			str=`gettext migrate "This DS Version of NetWare is not supported for Migration"`
			echo $str
			exit 1
		fi	
	else
		str=`gettext migrate "Unable to Communicate with the Source Server:$source_server"`
		echo $str
		exit 1
	fi
}

#check the source linux server is running on OES platform or not
checkLinuxPlatform()
{
	${ncp_bin_dir}/ncpshell --p="$passwd" --ip="$source_server" --u="$user" --fsinfo
	NCPRETVAL=$?
	if [ "$NCPRETVAL" = "0" ]; then
		engine_platform=`${ncp_bin_dir}/ncpshell --p="$passwd" --ip="$source_server" --u="$user" --fsinfo | grep "NCP Engine Platform" | awk -F":" '{print $2}'`
		if [ "$engine_platform" -eq "1" ]; then
			str=`gettext migrate "The Linux source server $source_server is running on OES platform."`
			printToScreen "$str"
		else
			str=`gettext migrate "The Linux source server $source_server is not running on OES platform."`
			printToScreen "$str"
			exit
		fi
	else
		str=`gettext migrate "Unable to detect the source server $source_server."`
		printToScreen "$str"
		exit
	fi
}
##########################################################################

main()
{
	if [ $doRestoreOnly -eq 1 ]; then
		rm -rf "${unix_default_dibdir}"/*
	fi

	printTitle
	validateRights
	parseAndValidateCmdLine "$@" 
	
	if [ $testOnly -ne 1 ]; then
		checkDIB
	fi

	createMigPaths
	getCredentials

	# Get remote server details and execute migndscheck only when there is backup to be done
	if [ $doRestoreOnly -ne 1 -o $testOnly -eq 1 ]; then
		getServerDetails

		migndscheck "$source_server" "$verbose" "$log_file_path" "$testOnly" "$dontPrompt"
		if [ $? -ne 0 ]; then
			exit 1
		fi

		if [ $testOnly -eq 1 ]; then
			exit 0
		fi
	fi

	err=$?
	if [ $err -eq 0 ]; then
		mignds "$source_server" "$verbose" "$log_file_path" "$doBackupOnly" "$doRestoreOnly" "$SRC_PLATFORM" "$dontPrompt"
	elif [ $err -ne 0 ]; then
		str=`gettext migrate "eDirectory migration failed."`
		printToScreen "$str"
		exit 1
	fi
}

main "$@"
