#!/bin/sh
################################################################################
# Domain Services for Windows Domain Controller Deconfiguration Tool
#
# See the file LICENSE for redistribution information.
#
# Copyright (c) 2001-2008
#	Novell, Inc.  All rights reserved.
################################################################################

PRINTCONFIGFILE="/opt/novell/xad/share/dcinit/printConfigKey.pl"
PATH=/opt/novell/xad/sbin:/opt/novell/xad/bin:/opt/novell/xad/share/dcinit:/opt/novell/eDirectory/bin:$PATH
export PATH

_LIB=`"$PRINTCONFIGFILE" "_Lib"`

LD_LIBRARY_PATH=/opt/novell/xad/$_LIB:/opt/novell/xad/$_LIB/nds-modules:/opt/novell/eDirectory/$_LIB:/opt/novell/eDirectory/$_LIB/nds-modules:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH

SASL_PATH=/opt/novell/xad/$_LIB/sasl2
export SASL_PATH

TEXTDOMAINDIR=/opt/novell/xad/share/locale
TEXTDOMAIN=xad
export TEXTDOMAINDIR TEXTDOMAIN

PREFIX=/opt/novell/xad
SYSTEM_CONFIG=/etc$PREFIX/xad.ini
LDAPSEARCH="/opt/novell/eDirectory/bin/ldapsearch"
LDAPMODIFY="/opt/novell/eDirectory/bin/ldapmodify"
LDAPDELETE="/opt/novell/eDirectory/bin/ldapdelete"
LDAPCONFIG="/opt/novell/eDirectory/bin/ldapconfig"
NDSSTAT="/opt/novell/eDirectory/bin/ndsstat"
NDSCONFIG="/opt/novell/eDirectory/bin/ndsconfig"
NDSLOGIN="/opt/novell/eDirectory/bin/ndslogin"
LOG="/var/opt/novell/xad/log/ndsdcrm.log"
SMBCONF="/etc/samba/smb.conf"
SMBCONF_BKP="/var/opt/novell/xad/ds/backup/smb.conf.org"
KEYTAB_FILE="/var/opt/novell/xad/ds/krb5kdc/krb5.keytab"
KRB5_FILE_DEFAULT="/etc/krb5.conf"
KRB5_FILE="/etc/opt/novell/xad/krb5.conf"
GETCERT_COMMAND="/opt/novell/oes-install/util/getSSCert"
LDAP_PORT=389
LDAPS_PORT=636
SERVER_CERT=/etc/opt/novell/certs/SSCert.der
FRD=0
NM_FRD=0
CHILD=0
NM_CHILD=0
NM_ADC=0
ADC=0
DNSROOT=`"$PRINTCONFIGFILE" "DNS Root"`		
STAGEDIR=`"$PRINTCONFIGFILE" "STAGEDIR"`
LIVE_LOCALSTATEDIR=`"$PRINTCONFIGFILE" "LIVE_LOCALSTATEDIR"`
LIVE_LOCALSTATEDIR="$LIVE_LOCALSTATEDIR/tmp"
KRB_TEMP=`"$PRINTCONFIGFILE" "TEMPLATEDIR"`
KRB_TEMP="$KRB_TEMP/stage_krb5"
PARTIAL=0
DNS_SERVER_IP=""
object_removal_passed="true" # Default value
all_objects_removal_passed="true" # Default value
#This varibale will be set to "1" when TDO's belong to the same forest exists in this domain
SAME_FOREST_TDO=0
###################
# Fucntions 
###################
writeLog()
{
	dirn=`dirname $LOG`
	if [ ! -d $dirn ]
	then
		mkdir -p $dirn 2>/dev/null
        fi
	if [ -n "$LOG" ]
	then
		echo -n `date '+%d/%m/%y:%H:%M:%S'` >>$LOG
		echo $* >> $LOG
	fi
}
writeScreenAndLog()
{
	Message=`echo "$*" | sed "s/%TREEROOT_IP%/$TREEROOT_IP/g" | sed "s/%SERVERNAME%/$SERVERNAME/g" | sed "s/%DOMAINFULLNAME%/$DOMAINFULLNAME/g" | sed "s/%DOMAINNC%/$DOMAINNC/g" | sed "s/%MAPPEDDOMAINNC%/$MAPPEDDOMAINNC/g"`;
	gettext -s "$Message"
	writeLog "$Message"
}

checkForServer()
{
	writeLog "Inside checkForServer"
	if [ ! -e "$SYSTEM_CONFIG" ]
	then
		writeScreenAndLog "No domain is configured on this machine."
		exit 1
	fi
	
	# Start ndsd, if it is not running.
	$NDSSTAT --config-file /etc/opt/novell/eDirectory/conf/nds.conf >> $LOG 2>&1
	if [ $? != 0 ]
	then
		writeScreenAndLog ">>> Starting eDirectory in order to deconfigure the Domain Services for Windows server."
		/etc/init.d/ndsd start
	fi
	INSTALLMACHINENAME=`"$PRINTCONFIGFILE" "Install_DCName"`
	/opt/novell/xad/sbin/provision -m $INSTALLMACHINENAME -l 10 --locate-dc $DNSROOT >>$LOG 2>&1 
	provision_ret=$?

	if [ $provision_ret != 0 ]
	then
		writeScreenAndLog ">>> The Domain Services for Windows server may not be configured properly. Do you wish to remove a partially installed server? [y/n] "
		read user_confirmation

		if [ "X$user_confirmation" = "Xy" -o "X$user_confirmation" = "XY" ]
		then
			PARTIAL=1
		elif [ "X$user_confirmation" = "Xn" -o "X$user_confirmation" = "XN" ]
		then
			# Aborting on user input
			exit -1
		else
			writeScreenAndLog ">>> Invalid user input. Exiting."
			exit -1
		fi
	fi	
}
printUsage()
{
	echo -e "Usage:\nndsdcrm [-p <IP Address>] [-a <administrator's fully distinguished name>] [-w <password>][-h]"
	echo -e "For primary domain controller of forest root domain (name-mapped) server.\n\t-p\tSpecifies the IP address of the existing eDirectory server\n\t-a\tSpecifies the tree root admin name (FDN) of the existing eDirectory server. For example: cn=admin,o=novell\n\t-w\tSpecifies the tree root administrator password of the existing eDirectory server\n"
	echo -e "For primary domain controller of forest root domain (non-name mapped) server.\n\t-p\tSpecifies the IP address of the same DSfW server\n\t-w\tSpecifies the forest root domain administrator's password\n"
	echo -e "For all other installation (except primary domain controller of forest root domain).\n\t-p\tSpecifies the IP address of the server hosting the immediate parent domain\n\t-w\tSpecifies the forest root domain administrator's password\n"
	exit 1 	
}
echo "-----------------------------------------------------------------"
writeScreenAndLog "Deconfiguration utility for Domain Services for Windows 1.0"
echo "-----------------------------------------------------------------"

if [ "X$1" == "X--help" -o "X$1" == "X-?" -o "X$1" == "X--h" -o "X$1" == "X--he" -o "X$1" == "X--hel" ]
then
	 printUsage
fi

while getopts p:a:w:h OPTION;
do
	case $OPTION in
		p) TREEROOT_IP=$OPTARG ;;
		a) ADMINNAME=$OPTARG ;;
		w) ADMINPASSWD=$OPTARG ;;
		o) PREFERRED_DNS=$OPTARG ;;
		h) printUsage ;;
		*) printUsage ;;
	esac
done
checkForServer

####################
# Computed Variables
####################
NETBIOS=`"$PRINTCONFIGFILE" "Netbios Name"`
IPADDRESS=`"$PRINTCONFIGFILE" "IP Address"`
DOMAINNC=`"$PRINTCONFIGFILE" "Domain NC"|tr "[:upper:]" "[:lower:]"`
DOMAINADMIN="cn=Administrator,cn=Users,"$DOMAINNC""
DOMAINADMINNDS=`echo $DOMAINADMIN |sed 's/,/\./g'`
IS_SECOND=`"$PRINTCONFIGFILE" "Is Replica"`
MAPPEDDOMAINNC=`"$PRINTCONFIGFILE" "Mapped Domain NC"|tr "[:upper:]" "[:lower:]"`
IS_REPLICA=`"$PRINTCONFIGFILE" "Is Replica"`
DEFAULTROOTDOMAIN="$MAPPEDDOMAINNC"
SERVERNAME=`uname -n |tr "[:upper:]" "[:lower:]"`
DCNAME="OU=Domain Controllers,"
DCFULLNAME="$DCNAME$DEFAULTROOTDOMAIN"
RIDMANAGERNAME="CN=RID Manager$,CN=System,"
RIDMANAGERFULLNAME="$RIDMANAGERNAME$DEFAULTROOTDOMAIN"
ADMPRINCIPAL=`"$PRINTCONFIGFILE" "Domain Administrator Principal"`
XADROOT=`"$PRINTCONFIGFILE" "Prefix"`
TREENAME=`/opt/novell/xad/share/dcinit/ndsConfigGet.sh "n4u.base.tree-name"`
DOMAINNAME=`echo "$DEFAULTROOTDOMAIN" | sed 's/,/\./g' | tr "[:upper:]" "[:lower:]"`
$LDAPSEARCH -x -b "$DCFULLNAME" -s one cn  2>/dev/null | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | grep -i "dn: " |  grep -v -i "cn=$SERVERNAME," >/dev/null
if [ "$?" = 0 ]
then
	IS_REPLICA="TRUE"
else
	if [ "$IS_SECOND" = "TRUE" ]
	then
		IS_REPLICA="TRUE"
	else
		IS_REPLICA="FALSE"
	fi	
fi

if [ "$IS_REPLICA" = "TRUE" -a "$DOMAINNC" != "$MAPPEDDOMAINNC" ]
then
	NM_ADC=1
fi
if [ "$IS_REPLICA" = "TRUE" -a "$DOMAINNC" = "$MAPPEDDOMAINNC"  ]
then
	ADC=1
fi
FORESTNC=`"$PRINTCONFIGFILE" "Forest NC"|tr "[:upper:]" "[:lower:]"`
FORESTROOT=`"$PRINTCONFIGFILE" "Forest Root"`
MAPPEDDOMAINNCNDS=`echo $MAPPEDDOMAINNC | sed 's/,/\./g'`
DOMAINFULLNAME=`"$PRINTCONFIGFILE" "DNS Root"`
DEFAULTCONTAINER=`/opt/novell/xad/share/dcinit/provisionTools.sh get-default-container`
test -z $DEFAULTCONTAINER && DEFAULTCONTAINER="ou=OESSystemObjects" && writeLog "Using the DEFAULTCONTAINER as ou=OESSystemObjects"
SERVEROBJLOCATION="$SERVERNAME,$DEFAULTCONTAINER,$MAPPEDDOMAINNC"

if [ "$DEBUG_INFO" = 1 ]
then
	echo "$DEFAULTROOTDOMAIN"
	echo "Servername = $SERVERNAME"
	echo "DCFULLNAME = $DCFULLNAME"
	echo "Admprincipal = $ADMPRINCIPAL"
	echo "XADROOT = $XADROOT"
	echo "Lib = $_LIB"
	echo "TREENAME = $TREENAME"
	echo "DomainName = $DOMAINNAME"
	echo "DOMAINFULLNAME = $DOMAINFULLNAME"
fi

######################
# Functions
######################

checkIfObjectPresent()
{
	MACHINE="$1"
	OBJECT_DN="$2"
	writeLog "checkIfObjectPresent: object="$OBJECT_DN" from Machine=$MACHINE" 
	test -z "$MACHINE" && return 2
	test -z "$OBJECT_DN" && return 2 
	
	OBJECT_RETURNED=""
	OBJECT_EXPECTED=`echo "$OBJECT_DN" | tr "[:upper:]" "[:lower:]"`  

	OBJECT_RETURNED=`$LDAPSEARCH -LLL -x -h "$MACHINE" -s base -b "$OBJECT_DN" dn 2>/dev/null | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | grep "dn:" 2>/dev/null | awk -F"dn: " '{print $2}' | tr "[:upper:]" "[:lower:]"`

	writeLog "checkIfObjectPresent: OBJECT_EXPECTED=$OBJECT_EXPECTED and OBJECT_RETURNED=$OBJECT_RETURNED" 

	if [ "$OBJECT_RETURNED" = "$OBJECT_EXPECTED" ] ; then
		return 0
	else
		return 1
	fi
}

deleteIfObjectPresent()
{
	MACHINE="$1"
	OBJECT_DN="$2"
	writeLog "deleteIfObjectPresent: object="$OBJECT_DN" from Machine=$MACHINE"
	test -z "$MACHINE" && return 2
	test -z "$OBJECT_DN" && return 2 

	DeleteAttempt=0
	object_present=0 # Default assumption is that the object is present.

	object_removal_passed=""
	while [ $DeleteAttempt -lt 5 ] ; do
		writeLog "Delete attempt=$DeleteAttempt"
		checkIfObjectPresent "$MACHINE" "$OBJECT_DN"
		object_present=$?
		if [ $object_present -eq 0 ]
		then
			$LDAPDELETE -h "$MACHINE" -D "$ADMINNAME" -w $ADMINPASSWD -e $SERVER_CERT -r "$OBJECT_DN" >>$LOG 2>&1
			sleep 1
		else
			object_removal_passed=true
			break
		fi
		
		DeleteAttempt=`expr $DeleteAttempt + 1`
	done
	
	if [ $object_present -eq 0 ] ; then
		object_removal_passed=false
		all_objects_removal_passed=false
	fi
	writeLog "Removal of $OBJECT_DN passed=$object_removal_passed"
}

checkIfObjectIsPartitionRoot()
{
	MACHINE="$1"
	OBJECT_DN="$2"
	writeLog "checkIfObjectIsPartitionRoot: object="$OBJECT_DN" from Machine=$MACHINE" 
	test -z "$MACHINE" && return 2
	test -z "$OBJECT_DN" && return 2 

	#Default assumption is that the object is at partition root
	OBJECT_IS_PARTITION_ROOT=0
	
	$LDAPSEARCH -LLL -x -h "$MACHINE" -s base -b "$OBJECT_DN" objectClass 2>/dev/null | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | grep -i "objectClass: Partition" >/dev/null 2>&1

	OBJECT_IS_PARTITION_ROOT=$?

	writeLog "checkIfObjectIsPartitionRoot: OBJECT_IS_PARTITION_ROOT=$OBJECT_IS_PARTITION_ROOT" 

	# 0 indicates true and 1 indicates false
	return $OBJECT_IS_PARTITION_ROOT
}


analyzeScenario()
{
	writeLog "Inside analyzeScenario" 
	if [ $FORESTNC = $DOMAINNC ]
	then
		if [ $DOMAINNC = $MAPPEDDOMAINNC ]
		then
			FRD=1
		else
			NM_FRD=1
		fi
	else
		if [ $DOMAINNC = $MAPPEDDOMAINNC ]
		then
			CHILD=1
		else
			NM_CHILD=1
		fi
	fi	
}
ComputeVariables()
{
	writeLog "Inside ComputeVariables"
	FORESTNDSNC=`ADM_PASSWD="$ADMINPASSWD" /opt/novell/xad/share/dcinit/ndsConfigServerContext.sh --add-dc "$FORESTROOT" "$ADMINNAME" "$TREEROOT_IP" 2>>$LOG`
	FORESTNDSNC=`echo "$FORESTNDSNC" | sed 's/^'$DEFAULTCONTAINER'.//'`
	CONFIGURATIONNDSNAME="CN=Configuration.$FORESTNDSNC"
	CONFIGURATIONLDAPNAME=`echo $CONFIGURATIONNDSNAME | sed 's/\./,/g'`
	SCHEMANDSNAME="CN=Schema.$CONFIGURATIONNDSNAME"
	SCHEMALDAPNAME=`echo $SCHEMANDSNAME |sed 's/\./,/g'`
	CONFIGURATIONNDSFULLNAME=".$CONFIGURATIONNDSNAME.T=$TREENAME."
	SCHEMANDSFULLNAME=".$SCHEMANDSNAME.T=$TREENAME."
	
	if [ "$DEBUG_INFO" = 1 ]
	then
		echo "CONFIGURATIONLDAPNAME = $CONFIGURATIONLDAPNAME"
		echo "SCHEMALDAPNAME = $SCHEMALDAPNAME"
		echo "CONFIGURATIONNDSNAME = $CONFIGURATIONNDSNAME"
		echo "SCHEMANDSNAME = $SCHEMANDSNAME"
		echo "CONFIGURATIONNDSFULLNAME = $CONFIGURATIONNDSFULLNAME"
		echo "SCHEMANDSFULLNAME = $SCHEMANDSFULLNAME"
	fi
}

promptForAdminCredentials()
{
	writeLog "Inside promptForAdminCredentials"
	if [ -z "$TREEROOT_IP" ]
	then
		if [ $NM_FRD = 1 -o $NM_ADC = 1 ]
		then
			read -er -p ">>> Enter existing eDirectory server's IP address: " TREEROOT_IP	 
		elif [ $FRD = 1 ]
		then
			read -er -p ">>> Enter IP address of the domain controller of forest root domain: " TREEROOT_IP
		elif [ $ADC = 1 ]
		then
			read -er -p ">>> Enter IP address of another domain controller for the domain '$DOMAINFULLNAME': " TREEROOT_IP
		else
			read -er -p ">>> Enter IP address of the domain controller of the immediate parent domain: " TREEROOT_IP
		fi
	fi
		
		validateIP	
		if [ -z "$TREEROOT_IP" ]
		then
			writeScreenAndLog ">>> IP address must be specified."
			exit 3
		fi
	
		if [ -z "$ADMINNAME" ]
		then
			if [ $NM_CHILD = 1  -o $NM_FRD = 1 -o $NM_ADC = 1 ]
			then
				read -er -p ">>> Enter existing tree administrator's typed FDN [cn=admin,o=foo]: " ADMINNAME
			else
				read -er -p ">>> Enter forest root domain administrator's typed FDN [cn=administrator,cn=users,dc=example,dc=com]: " ADMINNAME
			fi
		fi
		
		if [ -z "$ADMINNAME" ]
		then
			writeScreenAndLog ">>> Existing administrator name must be specified."
			exit 3
		fi

		if [ -z "$ADMINPASSWD" ]
		then
			if [ $NM_CHILD = 1  -o $NM_FRD = 1 -o $NM_ADC = 1 ]
			then
 		       		read -ers -p ">>> Enter existing tree administrator password: " ADMINPASSWD
				echo
			else
				read -ers -p ">>> Enter forest root domain administrator's password: " ADMINPASSWD
				echo
			fi
		fi
		
		if [ -z "$ADMINPASSWD" ]
		then
			writeScreenAndLog ">>> Existing administrator password must be specified."
			exit 3
		fi

		if [ -z "$PREFERRED_DNS" ]
		then
			read -er -p ">>> Enter the IP address of the preferred DNS server: " PREFERRED_DNS
		fi

		if [ -z "$PREFERRED_DNS" ]
		then
			writeScreenAndLog ">>>IP address of preferred DNS server must be specified."
			exit 3
		fi

	ADMINNAMENDS=`echo $ADMINNAME |sed 's/,/\./g'`
	ADMINNAME=`echo $ADMINNAMENDS |sed 's/\./,/g'`
	
	LD_LIBRARY_PATH=/opt/novell/eDirectory/lib:/opt/novell/eDirectory/lib/nds-modules:$LD_LIBRARY_PATH "$GETCERT_COMMAND" -a $IPADDRESS -t $TREENAME -u "$ADMINNAMENDS" -x "$ADMINPASSWD" >>$LOG 2>&1
	if [ ! -f "$SERVER_CERT" ]
	then
		writeScreenAndLog ">>> Unable to retrieve CA certificate. Exiting." 
		exit -1
	fi
	
}
validateIP()
{
	writeLog "Inside validateIP"
	ret=`echo $TREEROOT_IP | egrep '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'`
	if [ "$ret" = "" ]
	then
		writeScreenAndLog ">>> IP address %TREEROOT_IP% is not valid. Exiting."
		exit 3
	fi
	i=1
	while [ "$i" -le 4 ]
	do
		ip_part=`echo $TREEROOT_IP |cut -d "." -f$i`
		if [ "$ip_part" -ge "256" ]
		then
			writeScreenAndLog ">>> IP address %TREEROOT_IP% is not valid. Exiting."
			exit 3
		fi
		i=`expr $i + 1`		
	done
}
validateInputs()
{
	writeLog "Inside validateInputs"
	# Doing ndslogin in FRD to validate the credentials 
	ndslogin_output=`/bin/mktemp`
	$NDSLOGIN -h $TREEROOT_IP $ADMINNAMENDS -p $ADMINPASSWD > $ndslogin_output 2>&1
	ndslogin_ret=$?
	if [ $ndslogin_ret = 1 -a $FRD = 1 -a $PARTIAL = 1 ]
	then
		TMP_ADMIN=`echo "cn=xad_provisioning_user,"$DOMAINNC""|sed 's/,/\./g'`
		ADMINNAMENDS=`echo "$TMP_ADMIN"`
		ADMINNAME=`echo "$TMP_ADMIN"|sed 's/\./,/g'`
		$NDSLOGIN -h $TREEROOT_IP $TMP_ADMIN -p $ADMINPASSWD > $ndslogin_output 2>&1
		ndslogin_ret=$?
	else
		count=`$LDAPSEARCH -D $ADMINNAME -w $ADMINPASSWD -b "" -s base -e $SERVER_CERT 2>&1 | grep -ic "Invalid DN syntax"`
		if [ $count != 0 ]
                then
                        writeScreenAndLog ">>> Invalid Administrator FQDN. Exiting."
                        exit 3
                fi
	fi
	
	if [ $ndslogin_ret = 1 ]	
	then
		# Invalid Password or User Name
		cat $ndslogin_output |grep "669" > /dev/null
		ret1=$?
		cat $ndslogin_output |grep "601" > /dev/null
		ret2=$?
		
		if [ $ret1 = 0 -o $ret2 = 0 ]
		then
			writeScreenAndLog ">>> Invalid credentials. Exiting."
			exit 3
		fi 
		# eDiretory is down	
		cat $ndslogin_output |grep "login cannot be done" > /dev/null
		
		if [ $? = 0 ]
		then
			writeScreenAndLog ">>> Cannot log in to eDirectory. Check whether Novell eDirectory server is running on the machine %TREEROOT_IP%. Exiting."
			exit 3
		fi
	fi
	rm $ndslogin_output
}	
dcrmCheck()
{
	writeLog "Inside dcrmCheck"
	# Checking for other Domain Controllers in the Domain
	$LDAPSEARCH -D $ADMINNAME -w $ADMINPASSWD -b "$DCFULLNAME" -s one cn  -e $SERVER_CERT 2>/dev/null | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | grep -i "cn: " | awk -F ": " '{print $2}' | grep -v -x -i "$SERVERNAME" >/dev/null 
	if [ "$?" = 0 ]
	then
		if [ $PARTIAL != 1 ]
		then
			# More than one Domain Controller exists in the Domain
			ADPHMaster=`$LDAPSEARCH -D $ADMINNAME -w $ADMINPASSWD -e $SERVER_CERT  -b "$RIDMANAGERFULLNAME" 2>/dev/null | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | grep -i "fSMORoleOwner: " | awk -F ": " '{print $2}' | awk -F "," '{print $2}' | awk -F "cn=" '{print $2}' | tr "[:upper:]" "[:lower:]"`
			if [ "$DEBUG_INFO" = 1 ]
			then
				echo "ADPHMaster=$ADPHMaster"
				echo "SERVERNAME=$SERVERNAME"
			fi

			if [ "$ADPHMaster" = "$SERVERNAME" ]
			then
				# This server plays the role of ADPH master. This Domain Controller should not be removed
				writeScreenAndLog ">>> The server '%SERVERNAME%' has the ADPH master role. Transfer the ADPH master role to any other domain controller in the domain before removing the server."
				exit -1
			fi
		
			# This Domain Controller is not playing ADPH Master role
			# Checking for Configuration/Schema partition's replica 
			dclist=`/bin/mktemp`
			config_nc=0	
			$LDAPSEARCH -D $ADMINNAME -w $ADMINPASSWD -e $SERVER_CERT -s one -b "ou=Domain Controllers,$DEFAULTROOTDOMAIN" dn -LLL | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' >$dclist
			while read dcObject
			do
			        echo "$dcObject" |grep "dn:" > /dev/null
			        if [ $? = 0 ]
				then
					dcName=`echo $dcObject |cut -d ":" -f2| cut -d "," -f1|sed 's/^[ \t]*//;s/[ \t]*$//'|cut -d "=" -f2|tr "[:upper:]" "[:lower:]"`
					if [ $dcName != $SERVERNAME ]
					then
						$NDSSTAT -n -p ".$CONFIGURATIONNDSNAME.T=$TREENAME."  --config-file /etc/opt/novell/eDirectory/conf/nds.conf |grep -i "\.CN=$dcName\." > /dev/null 2>&1 
						if [ $? = 0 ]
						then	
							replicaType=`ndsstat -p ".$CONFIGURATIONNDSNAME.T=$TREENAME." | grep -i "\.CN=$dcName\." | awk '{print $2}'`
					                if [ $replicaType = "Subordinate" ]
					                then
					                        continue
						        fi
							config_nc=1
						fi
					fi
				fi
			done < $dclist
				
			if [ $config_nc = 0 ]
	 		then
				writeScreenAndLog ">>> The server '%SERVERNAME%' holds the only replica of configuration partition. Relocate the replica to any other domain controller before removing the server."
				exit -1
			fi
			schema_nc=0
			while read dcObject
			do
				echo "$dcObject" |grep "dn:"  > /dev/null
				if [ $? = 0 ]
				then
					dcName=`echo $dcObject |cut -d ":" -f2| cut -d "," -f1|sed 's/^[ \t]*//;s/[ \t]*$//'|cut -d "=" -f2|tr "[:upper:]" "[:lower:]"`
					if [ $dcName != $SERVERNAME ]
					then
						$NDSSTAT -n -p ".$SCHEMANDSNAME.T=$TREENAME."  --config-file /etc/opt/novell/eDirectory/conf/nds.conf |grep -i "\.CN=$dcName\." > /dev/null 2>&1
						if [ $? = 0 ]
						then
							replicaType=`ndsstat -p ".$SCHEMANDSNAME.T=$TREENAME." | grep -i "\.CN=$dcName\." | awk '{print $2}'`
					                if [ $replicaType = "Subordinate" ]
					                then
					                        continue
						        fi
							schema_nc=1
						fi
					fi
				fi
			done < $dclist
			rm $dclist
	
			if [ $schema_nc = 0 ]
			then
				writeScreenAndLog ">>> The server '%SERVERNAME%' holds the only replica of schema partition. Relocate the replica to any other domain controller before removing the server."
				exit -1
			fi
			
			writeScreenAndLog ">>> The server '%SERVERNAME%' is a domain controller hosting '%DOMAINFULLNAME%'. Are you sure you want to remove it? [y/n] "
			read user_confirmation
	
			if [ "X$user_confirmation" = "Xy" -o "X$user_confirmation" = "XY" ]
			then
				removeADC
			elif [ "X$user_confirmation" = "Xn" -o "X$user_confirmation" = "XN" ]
			then
				# Aborting on user input
				exit -1
			else
				writeScreenAndLog ">>> Invalid user input. Exiting."
				exit -1
			fi
		else	
			removeADC		
		fi
	
	else
		# This is the last Domain Controller in the domain, so lets check the trust existence, if any.
		# Ignoring the trust to the parent domain in search.
		TDO_OBJ_DN_LIST=`$LDAPSEARCH -D $ADMINNAME -w $ADMINPASSWD -e $SERVER_CERT -b "$DEFAULTROOTDOMAIN" '(&(objectClass=trustedDomain)(!(trustAttributes:1.2.840.113556.1.4.803:=4194304)))' dn 2>/dev/null | sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | grep  "dn: " | cut -d " " -f2`  
		if [ "$?" = 0 ]
		then
			if [ `echo "$TDO_OBJ_DN_LIST" | grep -ic "$DOMAINFULLNAME"` != 0 ]
			then
				# List down the Trust Partners of following trust types 
				# Parent-Child Trust with Child Domains.
				writeScreenAndLog ">>> The domain has following Child Domain/s. Remove them before removing this server."
				writeScreenAndLog "`echo "$TDO_OBJ_DN_LIST" | grep -i "$DOMAINFULLNAME"`"
				exit -1
			fi	
			# List down the Trust Partners of following trust types 
			# Cross Forest Trust OR External Trust OR Shortcut Trust.
			if [ "$TDO_OBJ_DN_LIST" != "" ]
			then
				writeScreenAndLog ">>> The domain has a trust relationship with following domain/s. Remove the trust/s before removing this server."
				writeScreenAndLog "`echo "$TDO_OBJ_DN_LIST"`"
				writeScreenAndLog ">>> Do you still wish to continue? [y/n] "
				read user_confirmation
				if [ "X$user_confirmation" = "Xy" -o "X$user_confirmation" = "XY" ]
				then
					echo
					writeScreenAndLog ">>> WARNING: This domain is trusted by one or more domains. To avoid inconsistency, the administrator of those domains must remove all trusts with this domain, using the Microsoft Management Console (MMC)."
					echo
					promptForDomainRemoval
				# Aborting on user input
				elif [ "X$user_confirmation" = "Xn" -o  "X$user_confirmation" = "XN" ]
				then
					exit -1
				# Invalid User Input. Exiting.
				else
					writeScreenAndLog ">>> Invalid user input. Exiting."
					exit -1
				fi
			fi
			# Warn for the Trust Partners of following trust types 
			# Parent-Child Trust with Parent Domain.
			if [ $FRD != 1 -o $NM_FRD != 1 ]
			then
				writeScreenAndLog ">>> WARNING: The domain has parent-child trust with its parent domain. The administrator of parent domain must remove this trust using the Microsoft Management Console (MMC)."
			fi
			echo
			promptForDomainRemoval
		fi
	fi
}
promptForDomainRemoval()
{
	# Child Domains do not exist 
	writeScreenAndLog ">>> The server '%SERVERNAME%' is the only domain controller residing in '%DOMAINFULLNAME%'. Removing this server will remove the domain '%DOMAINFULLNAME%'. Are you sure you want to remove it? [y/n] "
	read user_confirmation

	if [ "X$user_confirmation" = "Xy" -o "X$user_confirmation" = "XY" ]
	then
		removeDomain
	elif [ "X$user_confirmation" = "Xn" -o  "X$user_confirmation" = "XN" ]
	then
		# Aborting on user input
		exit -1
	else
		writeScreenAndLog ">>> Invalid user input. Exiting."
		exit -1
	fi
}
removeDNSObjects()
{
	writeLog "Inside removeDNSObjects"
	# Check if the preferred DNS server passed is a DSfW server or not
	# if not, then fall back on /etc/resolv.conf method
	/usr/bin/ldapsearch -h "$PREFERRED_DNS" -b "" -s base supportedCapabilities -x -LLL | grep '^supportedCapabilities: ' | grep '2.16.840.1.113719.1.513.7.1' >/dev/null 2>&1
	if [ $? -eq 0 ]
	then
		# this is the DSfW server to talk to for DNS related transations
		DNS_SERVER_IP="$PREFERRED_DNS"
	else
		# the server passed as the preferred DNS server is not a DSfW server
		# hence we must look for DNS servers from /etc/resolv.conf, query for
		# the domain name, check if it contains domain name as $FOREST_NAME
		# if so, that $IP_address would point to the correct DSfW server hosting
		# the DNS server.

		# calculate the number of nameserver entries
		NS_Entries=`cat /etc/resolv.conf | grep 'nameserver' | awk -F "nameserver " '{print $2}' | wc -l`
		if [ $NS_Entries -ge 1 ]
		then
			# get each NS entry's IP address and do a nslookp. Look
			# for the FOREST_NAME in the output, if found this is our
			# designated server, keep the hostname and the domain name,
			# and the IP address as well
			MATCH_FOUND=0
			for IP_address in `cat /etc/resolv.conf | grep 'nameserver' | awk -F "nameserver " '{print $2}'`
			do
				if [ "$MATCH_FOUND" -eq 1 ]
				then
					# match found for the FOREST_NAME, break the loop
					break;

				fi
				VALUE=`nslookup "$IP_address" | grep "$FOREST_NAME"`
				if [ -n "$VALUE" ]
				then
					# set the MATCH_FOUND flag
					MATCH_FOUND=1
					# set the IP as the DNS server IP
					DNS_SERVER_IP="$IP_address"
					#match found, so break the loop
					break;
				fi
			done
		fi
	fi
	# Get the NCP server context of the designated DNS server
	NCPServerFDN=`ndsstat -h $DNS_SERVER_IP | grep '^Server Name:' | awk -F "Server Name: ." '{print $2}' | awk -F ".T=" '{print $1}'`
	if [ $? -ne 0 ]
	then
		writeScreenAndLog ">>> Error enocuntered while computing the NCP server context for the DNS server $DNS_SERVER_IP. exiting.."
		exit 1
	fi

	# Get the NDSTEMPCONTAINER or the location of the DNS zone objects
	DNSServerHostname=` nslookup $DNS_SERVER_IP | grep 'name =' | awk -F "name = " '{print $2}' | awk -F "." '{print $1}'`
	NDSTEMPCONTAINER=`echo $NCPServerFDN | tr [:upper:] [:lower:] | awk -F "cn=$DNSServerHostname." '{print $2}'`
	LDAPTEMPCONTAINER=`echo $NDSTEMPCONTAINER | sed 's/\./,/g'`
	Hostname=`/bin/hostname | tr [:upper:] [:lower:]`

	# Compute the DNS Forward zone name and FDN
	DNSHOSTNAME=`/opt/novell/xad/share/dcinit/printConfigKey.pl 'DNS Host Name'`
	DNSForwardZoneRDN=`echo "$DNSHOSTNAME" | awk -F "$Hostname." '{print $2}' | sed 's/\./_/g'`
	DNSForwardZoneFDN=`echo "cn=$DNSForwardZoneRDN,$LDAPTEMPCONTAINER"`

	# Compute the DNS reverse zone name and FDN
	IP_ADDRESS_UNDERSCORE_FORM=`/opt/novell/xad/share/dcinit/printConfigKey.pl 'IP_ADDRESS_UNDERSCORE_FORM'`
	DNSReverseZoneRDN=`echo "cn=$IP_ADDRESS_UNDERSCORE_FORM"`
	DNSReverseZoneFDN=`echo "$DNSReverseZoneRDN,$LDAPTEMPCONTAINER"`

	# log the variables computed
	writeLog "DNSForwardZoneFDN : $DNSForwardZoneFDN"
	writeLog "DNSReverseZoneFDN : $DNSReverseZoneFDN"
	writeLog "LDAPTEMPCONTAINER : $LDAPTEMPCONTAINER"

	# In case its a child domain, Remove both the forward and reverse
	# DNS zones and the objects beneath them, talk to the preferred DNS
	# server as Tree admin (as the parent might not be configured as the
	# preferred DNS server, do a check for the two IPs entered), using tree
	# certs
	if [ $NM_FRD = 1 -o $CHILD = 1 -o $NM_CHILD = 1 ]
	then
		# delete the forward and reverse zone objects along with all 
		# subordinate objects
		deleteIfObjectPresent $DNS_SERVER_IP "$DNSForwardZoneFDN"
		deleteIfObjectPresent $DNS_SERVER_IP "$DNSReverseZoneFDN"
	fi

	# In case its an ADC, we need to delete the reverse DNS zone and objects
	# beneath it but in case of forward DNS zone, only the entries specific
	# to ADC are to be reomved (as they occur as Multi valued atribute DNIPRR,
	# in SRV records).The DNS forward zone object, tough remains intact.
	
	if [ $ADC = 1 -o $NM_ADC = 1 ] 
	then
		# generate the ldif to delete the Forward zone records
		# check if the forward zone file for ADC is present or not, if not create it
		DNSROOT=`/opt/novell/xad/share/dcinit/printConfigKey.pl "DNS Root"`
		if [ ! -f "/var/opt/novell/xad/ds/dns/RR/ADC_$DNSROOT.zone" ]
		then
			# create the file
			rc=`/opt/novell/xad/share/dcinit/regSubstitute.pl < /opt/novell/xad/share/dcinit/templates/additional-dc.zone > /var/opt/novell/xad/ds/dns/RR/ADC_$DNSROOT.zone`
		fi
		# delete the already existing files
		rm -f /var/opt/novell/xad/ds/dns/RR/Delete_*.ldif

		# Create the ldif files for deleting the individual record
		rc=`/opt/novell/xad/share/dcinit/GenerateRRLdifs.pl /var/opt/novell/xad/ds/dns/RR/ADC_$DNSROOT.zone $LDAPTEMPCONTAINER TRUE delete`
		if [ $? -ne 0 ]
		then
			writeScreenAndLog ">>> Failed while generating the ADC DNS record removal ldifs. Exiting.."
			exit -1
		fi
		rm -f /var/opt/novell/xad/ds/dns/final_dns_records_delete.ldif
		touch /var/opt/novell/xad/ds/dns/final_dns_records_delete.ldif
		for i in `ls /var/opt/novell/xad/ds/dns/RR/Delete_*.ldif`
		do
			cat $i >> /var/opt/novell/xad/ds/dns/final_dns_records_delete.ldif;
			echo "" >> /var/opt/novell/xad/ds/dns/final_dns_records_delete.ldif;
		done
			# Check for cert
		if [ ! -f "/etc/opt/novell/certs/SSCert.der" ]
		then
			LD_LIBRARY_PATH=/opt/novell/eDirectory/lib:/opt/novell/eDirectory/lib/nds-modules:$LD_LIBRARY_PATH "$GETCERT_COMMAND" -a $IPADDRESS -t $TREENAME -u "$ADMINNAMENDS" -x "$ADMINPASSWD" >>$LOG 2>&1
		fi
		if [ ! -f "/etc/opt/novell/certs/SSCert.der" ]
		then
			writeScreenAndLog ">>> Unable to retrieve CA certificates. Exiting.."
			exit -1
		fi
		# Delete the DNS forward zone records for ADC
		checkIfObjectPresent "$DNS_SERVER_IP" "$DNSForwardZoneFDN"
		if [ $? -eq 0 ]
		then
			/opt/novell/eDirectory/bin/ldapmodify -h $DNS_SERVER_IP -x -D $ADMINNAME -e $SERVER_CERT -p 636 -w $ADMINPASSWD -f /var/opt/novell/xad/ds/dns/final_dns_records_delete.ldif >>$LOG 2>&1
			if [ $? -ne 0 ]
			then
				object_removal_passed=false;
			fi
		writeLog "Removal of RR records under $DNSForwardZoneFDN passed=$object_removal_passed"
		fi
		# Delete the DNS reverse zone along with the subordinate objects
		deleteIfObjectPresent $DNS_SERVER_IP "$DNSReverseZoneFDN"
	fi
	
}

validateReplica()
{
	writeLog "Inside validateReplica"
	ndscheck_log="/tmp/ndscheck.log"
	ndsrepair_log="/tmp/ndsrepair.log"
	para=""
	`> $ndscheck_log`
	`> $ndsrepair_log`
	/opt/novell/eDirectory/bin/ndscheck -q -a $ADMINNAMENDS -w $ADM_PASSWD -F $ndscheck_log
	/opt/novell/eDirectory/bin/ndsrepair -T | grep -A 1 "Processing server" > $ndsrepair_log
	grep "^.CN=" $ndscheck_log | awk -F " " '{print $2}' | grep -vq "UP" && para="STATUS/"
	grep "^.CN=" $ndscheck_log | awk -F " " '{print $7}' | grep -vq "ON" && para=$para"REPLICA STATE/"
	grep -v "Processing server" $ndsrepair_log | awk -F " " '{print $5}' | grep -vq "Yes" && para=$para"TIME SYNCH"

	if [ "$para" != "" ]
	then
		writeScreenAndLog ">>> One or more replicas are unstable in terms of $para. Please remove this inconsistency by using ndsrepair tool or/and synchronizing the server's time."	
		writeLog ">>> Partition Status & Replica State Information of all Servers"
		grep -E "(Status of partition|Server Name|^.CN=)" $ndscheck_log >> $LOG
		writeLog ">>> Time Synchronization Information of all Servers"
		cat $ndsrepair_log >> $LOG
		rm $ndscheck_log
		rm $ndsrepair_log
		writeScreenAndLog ">>> Exiting here."	
		exit 4
	else
		rm $ndscheck_log
		rm $ndsrepair_log
	fi
}

removeeDirectory()
{
	rm /var/opt/novell/eDirectory/data/ndsconfig.err
	writeScreenAndLog ">>> Executing ndsconfig rm"
	$NDSCONFIG rm -a $ADMINNAMENDS -c
	ndsconfig_ret_val=$?
	if [ $ndsconfig_ret_val = 0 ] ; then
		writeLog "ndsconfig rm passed."
		return 0
	fi

	ndsconfigRetryAttempt=1
	if [ $ndsconfig_ret_val != 0 ] ; then
		writeLog "ndsconfig rm failed with return value $ndsconfig_ret_val."
		while true ; do
			ndsconfig_ret_code=`cat /var/opt/novell/eDirectory/data/ndsconfig.err`
			writeLog "ndsconfig return code from ndsconfig.err=$ndsconfig_ret_code."
			if [ "$ndsconfig_ret_code" = "-658" -a $ndsconfigRetryAttempt -lt 6 ] ; then
				ndsconfigRetryAttempt=`expr $ndsconfigRetryAttempt + 1`
				writeLog "ndsconfig retry attempt=$ndsconfigRetryAttempt."
				sleep 20
				$NDSCONFIG rm -a $ADMINNAMENDS -c
				ndsconfig_ret_val=$?
				if [ $ndsconfig_ret_val = 0 ] ; then
					writeLog "ndsconfig rm passed."
					return 0
				fi
			else 
				if [ "$ndsconfig_ret_code" = "-658" ] ; then
					writeScreenAndLog ">>> ndsconfig rm failed. Could not proceed with the removal of the domain controller."
					exit 2
				else
					return 2
				fi
			fi	
		done
	fi
}

removeADC()
{
	writeLog "Inside removeADC"
	removeDCObjects
	removeDNSObjects
	cleanSecurityObjects
	export ADM_PASSWD=$ADMINPASSWD
	StopServices
	ndsconfig_passed="true" # Default value
	# Check the replica ring for its consistency before removing the eDirectory
	validateReplica
	removeeDirectory
	if [ $? != 0 ]
	then
		ndsconfig_passed="false"
		promptUser
	fi
	unset ADM_PASSWD
	revertConfigFiles	
}
removeDomain()
{
	writeLog "Inside removeDomain"
	# check if the domain being removed is a non-name mapped FRD
	if [ $FRD = 1 ]
	then
		# warn the users that all the containers/objects under domain would be deleted
		writeScreenAndLog ">>> WARNING: All objects present in the domain will be deleted. Do you wish to continue?[y/n]: "
	else
		# warn user about the deletion of all users under cn=User container
		 writeScreenAndLog ">>> WARNING: All objects present in the cn=Users,%DOMAINNC% (cn=Users,%MAPPEDDOMAINNC%) container will be deleted. Do you wish to continue? [y/n]: "
	fi
	read user_confirmation

	if [ "X$user_confirmation" = "Xn" -o  "X$user_confirmation" = "XN" ]
	then
		# Aborting on user input
		exit -1
	elif [ "X$user_confirmation" = "Xy" -o "X$user_confirmation" = "XY" ]
	then
		continue;
	else
		# Invalid user input
		writeScreenAndLog ">>> Invalid user input. Exiting."
		exit -1
	fi
	
	if [ $NM_FRD = 1 -o $NM_CHILD = 1 ]
	then
		cleanDomainContainerAttributes
	fi
	if [ $FRD != 1 ]
	then
		if [ $NM_CHILD != 1 ]	
		then
			mergePartitions
		fi
		if [ $NM_CHILD = 1 -o $CHILD = 1 ]
		then
			removeTDO
			removeChildObjects	
		fi
		removeDNSObjects
	fi
	if [ $PARTIAL = 1 ]
	then
		cleanSecurityObjects
	fi
	export ADM_PASSWD=$ADMINPASSWD
	StopServices
	ndsconfig_passed="true" # Default value
	# Check the replica ring for its consistency before removing the eDirectory
	validateReplica
	removeeDirectory
	if [ $? != 0 ]
	then
		ndsconfig_passed="false"
		promptUser	
	fi
	unset ADM_PASSWD
	revertConfigFiles
	# wait for 60 seconds before removing the left-over DSfW specific objects
	sleep 60
	if [ $FRD != 1 ]
	then
		deleteADObjects
	fi
	
	if [ $NM_FRD = 1 -o $NM_CHILD = 1 ]
	then
		removeDomainDnsEntry	
	fi
}
promptUser()
{
	writeScreenAndLog ">>> ndsconfig failed to remove the eDirectory server properly. Do you want to continue? [y/n] "
	read user_confirmation

	if [ "X$user_confirmation" = "Xy" -o "X$user_confirmation" = "XY" ]
	then
		echo
		writeScreenAndLog "ERROR: eDirectory server is not properly removed. Use iManager to clean the tree."
		echo
		writeScreenAndLog ">>> ndsconfig failed. This failure can cause inconsistency in the tree. Do you really want to continue[y/n] "
		read user_strong_confirmation
		if [ "X$user_strong_confirmation" = "Xy" -o "X$user_strong_confirmation" = "XY" ]
		then
			echo
		elif [ "X$user_strong_confirmation" = "Xn" -o "X$user_strong_confirmation" = "XN" ]
		then
			writeScreenAndLog "ERROR: Use 'ndsconfig rm' to remove the eDirectory server. After removing the eDirectory server, use ndsdcrm to remove Domain Services for Windows server. "
		# Aborting on user input
			exit -1
		else
			writeScreenAndLog ">>> Invalid user input. Exiting."
			exit -1
		fi
	elif [ "X$user_confirmation" = "Xn" -o "X$user_confirmation" = "XN" ]
	then
		echo 
		writeScreenAndLog "ERROR: Use 'ndsconfig rm' to remove the eDirectory server. After removing the eDirectory server, use ndsdcrm to remove Domain Services for Windows server."
		# Aborting on user input
		exit -1
	else
		writeScreenAndLog ">>> Invalid user input. Exiting."
		exit -1
	fi

}
removeTDO()
{
	writeLog "Inside removeTDO"
	writeScreenAndLog ">>> Cleaning Trusted Domain Objects"
	$LDAPSEARCH  -D $ADMINNAME -w $ADMINPASSWD -e $SERVER_CERT -CC -b $FORESTNC -s sub  objectclass=trustedDomain dn 2> /dev/null |sed ' /^ / {; H; d; }; /^ /! {; x; s/\n //; }; ' | while read TDOOBJECT 
	do
		echo $TDOOBJECT |grep -i "dn: "
		if [ $? = 0 ]
		then
			RDN_TDOOBJECT=`echo $TDOOBJECT |cut -d " " -f2 |cut -d "," -f1 |cut -d "=" -f2`
			DN_TDOOBJECT=`echo $TDOOBJECT |cut -d " " -f2`
			DOMAIN_TDO_OBJ=`echo $DN_TDOOBJECT|awk -F "System," '{print $2}'|sed 's/dc=//g'|sed s/,/\./g`
			DC_TDO_OBJ_TMP=`provision -l 10 --locate-dc $DOMAIN_TDO_OBJ 2>/dev/null |grep DC: |sed 's/^[ \t]*//;s/[ \t]*$//'`	
			DC_TDO_OBJ=`echo $DC_TDO_OBJ_TMP |awk -F "\\\\" '{print $3}'`
			if [ $DOMAINFULLNAME = $RDN_TDOOBJECT ]
			then
				deleteIfObjectPresent $DC_TDO_OBJ "$DN_TDOOBJECT"
			fi
		fi
	done
}

deleteADObjects()
{
	writeLog "Inside deleteADObjects"
	writeScreenAndLog ">>> Cleaning Domain Services objects"
	if [ $CHILD = 1 ]
	then
		writeScreenAndLog ">>> Refreshing LDAP server"
		$LDAPCONFIG -R -p $TREEROOT_IP --config-file /etc/opt/novell/eDirectory/nds.conf -t "$TREENAME" -a "$ADMINNAMENDS" -w "$ADMINPASSWD" 2>>$LOG 2>&1 
		sleep 30
		deleteIfObjectPresent "$TREEROOT_IP" "$DOMAINNC"
	else
		ad_objects=`/bin/mktemp`	
		echo -e "cn=Builtin\ncn=Computers\ncn=Users\nou=Domain Controllers\ncn=DefaultMigrationContainer\ncn=Deleted Objects\ncn=ForeignSecurityPrincipals\ncn=Infrastructure\ncn=LostAndFound\ncn=Program Data\ncn=NTDS Quotas\ncn=Configuration\ncn=System\nou=novell" > $ad_objects
		while read ADContainer
		do
			ADContainerDN=$ADContainer",$MAPPEDDOMAINNC"
			deleteIfObjectPresent "$TREEROOT_IP" "$ADContainerDN"
		done < $ad_objects	
		rm $ad_objects
	fi
}

cleanDomainContainerAttributes()
{
	writeLog "Inside cleanDomainContainerAttributes"
	writeScreenAndLog ">>> Removing Domain Services specific attributes from the domain container"
	
	/opt/novell/xad/share/dcinit/genLdif.pl /opt/novell/xad/share/dcinit/templates/domain-object-modify-delete-attributes.ini --defaultrootdomainobject > /tmp/temp.ldif
	sed -e "s/^-/\ndn: $MAPPEDDOMAINNC\nchangetype: modify/g" /tmp/temp.ldif > /tmp/domain-object-modify-delete-attributes.ldif
	/usr/bin/ldapmodify -H ldapi://%2fvar%2fopt%2fnovell%2fxad%2frun%2fldapi -Y EXTERNAL -c -f /tmp/domain-object-modify-delete-attributes.ldif >> $LOG 2>&1
	rm -f /tmp/temp.ldif
	rm -f /tmp/domain-object-modify-delete-attributes.ldif
}

deleteConfigurationObjects()
{
	writeLog "Inside deleteConfigurationObjects"
	writeScreenAndLog ">>> Cleaning Domain Services objects under configuration partition"
	if [ $CHILD != 1 ]
	then
		conf_objects=`/bin/mktemp`
		echo -e "cn=Sites\ncn=Services\ncn=Deleted Objects\ncn=DisplaySpecifiers\ncn=Extended-Rights\ncn=ForestUpdates\ncn=LostAndFoundConfig\ncn=NTDS Quotas\ncn=Partitions\ncn=Physical Locations\ncn=WellKnown Security Principals\ncn=Schema" > $conf_objects
		while read ConfContainer
		do
			ConfContainerDN=$ConfContainer",$CONFIGURATIONLDAPNAME"
			deleteIfObjectPresent localhost "$ConfContainerDN"
		done < $conf_objects
		rm $conf_objects
	fi
}

mergePartitions()
{
	writeLog "Inside mergePartitions"
	$LDAPCONFIG set "Require TLS for Simple Binds with Password=no" --config-file /etc/opt/novell/eDirectory/nds.conf -t "$TREENAME" -a "$ADMINNAMENDS" -w "$ADMINPASSWD" >>$LOG 2>&1
	sleep 10 
	export ADM_PASSWD=$ADMINPASSWD	
	NCPSERVEROBJ="cn="$SERVERNAME","$DEFAULTCONTAINER","$MAPPEDDOMAINNC
	if [ $CHILD = 1 ]
	then
		# Deleting a domain Administrator before merging the partition
		deleteIfObjectPresent localhost "cn=Administrator,cn=Users,"$MAPPEDDOMAINNC

		# merging domain partition
		writeScreenAndLog ">>> Merging domain partition"
		checkIfObjectPresent localhost "$MAPPEDDOMAINNC"
		if [ $? -eq 0 ] ; then
			checkIfObjectIsPartitionRoot localhost "$MAPPEDDOMAINNC"
			if [ $? -eq 0 ] ; then
				/opt/novell/xad/sbin/replops -p 389  -s $NCPSERVEROBJ -n "$MAPPEDDOMAINNC" -D "$ADMINNAME" -w "env:ADM_PASSWD" --merge-partition >>$LOG 2>&1
				sleep 10
			fi
		fi
	elif [ $NM_FRD = 1 ] 
	then	
		# merging schema partition
		# recursively delete the objects under schema partition
		SchemaContainerDN="$SCHEMALDAPNAME"
		# wait for 60 seconds before merging the schema partition
		sleep 60
		writeScreenAndLog ">>> Merging schema partition"
		checkIfObjectPresent localhost "$SCHEMALDAPNAME"
		if [ $? -eq 0 ] ; then
			checkIfObjectIsPartitionRoot localhost "$SCHEMALDAPNAME"
			if [ $? -eq 0 ] ; then
				/opt/novell/xad/sbin/replops -p 389 -s $NCPSERVEROBJ  -n "$SCHEMALDAPNAME" -D "$ADMINNAME" -w "env:ADM_PASSWD" --merge-partition>>$LOG 2>&1
				sleep 60
			fi
		fi
		
		# merging configuration partition
		# delete all the objects in the Configuration partition prior to merging
		deleteConfigurationObjects

		# wait ofr 60 seconds before merging configuration partition
		sleep 60
		writeScreenAndLog ">>> Merging configuration partition"
		checkIfObjectPresent localhost "$CONFIGURATIONLDAPNAME"
		if [ $? -eq 0 ] ; then
			checkIfObjectIsPartitionRoot localhost "$CONFIGURATIONLDAPNAME"
			if [ $? -eq 0 ] ; then
				/opt/novell/xad/sbin/replops -p 389  -s $NCPSERVEROBJ -n "$CONFIGURATIONLDAPNAME" -D "$ADMINNAME" -w "env:ADM_PASSWD" --merge-partition >>$LOG 2>&1
				sleep 10
			fi
		fi
	fi
	unset ADM_PASSWD
}

StopServices()
{
	writeLog "Inside StopServices"
	writeScreenAndLog ">>> Stopping Services"
	if [ -f /etc/init.d/xadsd ]
	then
		writeScreenAndLog ">>> Stopping xadsd"
		/etc/init.d/xadsd stop
	fi
	if [ -f /etc/init.d/xad-kpasswdd ]
	then
		writeScreenAndLog ">>> Stopping xad-kpasswdd"
		/etc/init.d/xad-kpasswdd stop
	fi
	if [ -f /etc/init.d/xad-krb5kdc ]
	then
		writeScreenAndLog ">>> Stopping xad-krb5kdc"
		/etc/init.d/xad-krb5kdc stop
	fi
	if [ -f /etc/init.d/rpcd ]
	then
		writeScreenAndLog ">>> Stopping rpcd"
		/etc/init.d/rpcd stop
	fi
	if [ -f /etc/init.d/nmb ]
	then
		writeScreenAndLog ">>> Stopping nmb"
		/etc/init.d/nmb stop
	fi
	if [ -f /etc/init.d/winbind ]
	then
		writeScreenAndLog ">>> Stopping winbind"
		/etc/init.d/winbind stop
	fi
	if [ -f /etc/init.d/smb ]
	then
		writeScreenAndLog ">>> Stopping smb"
		/etc/init.d/smb stop
	fi
	writeScreenAndLog ">>> Stopping novell-named"
		rcnovell-named stop
}

revertConfigFiles()
{
	writeLog "Inside revertConfigFiles"
	writeScreenAndLog ">>> Backing up configuration files"
	modules_conf_tmp=`/bin/mktemp`
	cat /etc/opt/novell/eDirectory/conf/ndsmodules.conf |grep -v samspm > $modules_conf_tmp
	cat $modules_conf_tmp > /etc/opt/novell/eDirectory/conf/ndsmodules.conf
	rm $modules_conf_tmp
	if [ -f /etc/opt/novell/xad/xad.ini ]
	then 
		if [ "$ndsconfig_passed" = "true" ]
		then
			mv /etc/opt/novell/xad/xad.ini /etc/opt/novell/xad/xad.ini.old
		fi
	fi
	cp $SMBCONF_BKP $SMBCONF
	rm -f $KEYTAB_FILE
	/opt/novell/xad/bin/kdestroy
	unlink $KRB5_FILE_DEFAULT
	rm -f $KRB5_FILE
	rm -f /etc/opt/novell/xad/provisioning.xml

	echo  "[libdefaults]
	default_realm = EXAMPLE.COM

[realms]
	EXAMPLE.COM = {
                kdc = kerberos.example.com
		admin_server = kerberos.example.com
	}

[logging]
    kdc = FILE:/var/log/krb5/krb5kdc.log
    admin_server = FILE:/var/log/krb5/kadmind.log
    default = SYSLOG:NOTICE:DAEMON">$KRB5_FILE

}

removeDCObjects()
{
	writeLog "Inside removeDCObjects"
	deleteIfObjectPresent localhost "CN=$INSTALLMACHINENAME,cn=Servers,cn=Default-First-Site-Name,cn=Sites,$CONFIGURATIONLDAPNAME"
	deleteIfObjectPresent localhost "CN=$INSTALLMACHINENAME,OU=Domain Controllers,$MAPPEDDOMAINNC"
}

removeChildObjects()
{
	writeLog "Inside removeChildObjects"	
	FOREST_NC_DOMAIN=`echo $FORESTNC|sed 's/dc=//g'|sed s/,/\./g`
	FORESTNC_DC_TMP=`provision -l 10 --locate-dc $FOREST_NC_DOMAIN 2>/dev/null |grep DC: |sed 's/^[ \t]*//;s/[ \t]*$//'`	
	FORESTNC_DC=`echo $FORESTNC_DC_TMP |awk -F "\\\\" '{print $3}'`
	
	deleteIfObjectPresent "$FORESTNC_DC" "cn=$NETBIOS,cn=Partitions,$CONFIGURATIONLDAPNAME"
	deleteIfObjectPresent "$FORESTNC_DC" "CN=$INSTALLMACHINENAME,cn=Servers,cn=Default-First-Site-Name,cn=Sites,$CONFIGURATIONLDAPNAME"
}

removeDomainDnsEntry()
{
	writeLog "Inside removeDomainDnsEntry"
	echo -e "dn: $MAPPEDDOMAINNC \nchangetype: modify\ndelete: objectClass\nobjectClass: domainDNS" > /tmp/nds-domain-del.ldif
	$LDAPMODIFY -h $TREEROOT_IP -D $ADMINNAME -w $ADMINPASSWD -e $SERVER_CERT -f /tmp/nds-domain-del.ldif  >>$LOG 2>&1	
	rm /tmp/nds-domain-del.ldif 
}

cleanSecurityObjects()
{
	writeLog "Inside cleanSecurityObjects"
	deleteIfObjectPresent localhost "cn=SAS Service - "$SERVEROBJLOCATION
	deleteIfObjectPresent localhost "cn=SSL CertificateDNS - "$SERVEROBJLOCATION
	deleteIfObjectPresent localhost "cn=SSL CertificateIP - "$SERVEROBJLOCATION
	deleteIfObjectPresent localhost "cn=IP AG "$IPADDRESS" - "$SERVEROBJLOCATION
	deleteIfObjectPresent localhost "cn=DNS AG "$SERVERNAME"."$DOMAINFULLNAME" - "$SERVEROBJLOCATION

}

stopXAD()
{
	writeLog "Inside stopXAD"
	/etc/init.d/xadsd stop
	/etc/init.d/xad-krb5kdc stop
	/etc/init.d/xad-kpasswdd stop
	/etc/init.d/rpcd stop
}

main()
{
	id=`id | awk '{print $1}'|awk -F"=" '{print $2}'|awk -F"(" '{print $1}'`

        if [ $id != 0 ]
        then
                echo ""
                writeScreenAndLog "You must have root permissions to deconfigure Domain Services for Windows."
                echo ""
                exit 1
        fi

	if test "$IS_REPLICA" != "TRUE" 
	then
		analyzeScenario
	fi
	promptForAdminCredentials
	ComputeVariables
	validateInputs
	dcrmCheck
	# Cleaning up files 
	if [ -f "/var/opt/novell/xad/run/rpcdep.dat" ]
	then
		rm /var/opt/novell/xad/run/rpcdep.dat
	fi
	if [ -f "/opt/novell/oes-install/xad_provisioned" ]
	then
		rm /opt/novell/oes-install/xad_provisioned
	fi	
	if [ -f "/etc/xdg/autostart/start-xad-provisioning.desktop" ]
	then
		rm /etc/xdg/autostart/start-xad-provisioning.desktop
	fi	
	if [ -f "/etc/opt/novell/xad/gss/mech" ]
	then
		rm /etc/opt/novell/xad/gss/mech
	fi
	if [ -f "/etc/sysconfig/novell/xad2_sp2" ]
	then
		sed -e 's/^SERVICE_CONFIGURED="yes"/SERVICE_CONFIGURED="no"/g' /etc/sysconfig/novell/xad2_sp2 > /tmp/temp;mv -f /tmp/temp /etc/sysconfig/novell/xad2_sp2
	fi
	if [ -f "/etc/sysconfig/novell/NvlDns2_sp2" ]
	then
		sed -e 's/^SERVICE_CONFIGURED="yes"/SERVICE_CONFIGURED="no"/g' /etc/sysconfig/novell/NvlDns2_sp2 > /tmp/temp;mv -f /tmp/temp /etc/sysconfig/novell/NvlDns2_sp2
	fi
	if [ -f "/etc/sysconfig/novell/oes-ldap" ]
	then
		sed 's/^CONFIG_LDAP_ADMIN_CONTEXT=.*/CONFIG_LDAP_ADMIN_CONTEXT=\"\"/g' /etc/sysconfig/novell/oes-ldap > /tmp/temp
		sed 's/^XAD_TREE_ADMIN_CONTEXT=.*/XAD_TREE_ADMIN_CONTEXT=\"\"/g' /tmp/temp > /etc/sysconfig/novell/oes-ldap
	fi
	#May be possible that partial install did not cleanup the staging dirs
	if [ -e $STAGEDIR ]
	then
	    rm -rf $STAGEDIR
	fi
	if [ -e $LIVE_LOCALSTATEDIR ]
	then
	    rm -rf $LIVE_LOCALSTATEDIR
	fi
	if [ -e $KRB_TEMP ]
	then
	    rm -rf $KRB_TEMP
	fi

	if [ "$ndsconfig_passed" = "true" -a "$all_objects_removal_passed" = "true" ]
	then
		if [ -f "/etc/sysconfig/novell/edir2_sp2" ]
		then
			sed -e 's/^SERVICE_CONFIGURED="yes"/SERVICE_CONFIGURED="no"/g' /etc/sysconfig/novell/edir2_sp2 > /tmp/temp;mv -f /tmp/temp /etc/sysconfig/novell/edir2_sp2
		fi
		writeScreenAndLog ">>> Domain Services for Windows server removed successfully"
	else
		writeScreenAndLog ">>> Domain Services for Windows server removal failed"
		exit 1
	fi
}
main $@
