#!/bin/sh
#
# @(#)joindomain.sh	1.58	8/23/99
#
textdomaindir=/opt/lanman/lib/locale

textdomain='joindomain'
vQuote="'"                   ## virtual quote hack for pgettext
Progname=joindomain

INSTANCE_NOT_FOUND="\nThe instance is unavailable."
INSTANCE_NOT_SPECIFIED="\nThe instance must be specified."

echoif() {
      if [ $cargs = 0 ]
      then
              echo "$@"
      fi
}

#
# Function to run gettext with TEXTDOMAINDIR set.
# TEXTDOMAINDIR is not set in the exported environment so subprocesses 
# do not inadvertently use it.
#

pgettext () {
	gttext=gettext #Trick to fool shgettext
	TEXTDOMAINDIR=${textdomaindir} ${gttext} ${textdomain} "$1"
}

usage() {
	pgettext "\nUsage: joindomain [-I <instance number | instance name>]\n"
}

get_default_ip()
{
	ifc="`head -1 /etc/opt/SUNWlznb/netbios.conf | $AWK '{print $2}'`"
        if [ "$ifc" = "" ]
        then
            defaddr=""
        else
            defaddr="`ifconfig $ifc | $AWK '{ for (i = 1; i <= NF; i++) if ($i=="inet") print $(i+1) }'`"
        fi
}

check_server_name() {
	ipaddr="`$SRVCONFIG_PATH -I $PCNL_INSTANCE -g "lmxserver,ipaddress"`"
	if [ "$ipaddr" = "" ]
	then
		get_default_ip
		ipaddr=$defaddr
	fi
	$NBBIND -i "$ipaddr" -s $1 > $DEV_NULL_PATH 2>&1
	ret=$?

	if [ "$ret" -ne "0" ]
	then
		eval echo "\"`pgettext 'The server name is already in use."
		retcode=104
		cancel_and_exit
	fi
}

check_domain_name() {
	ipaddr="`$SRVCONFIG_PATH -I $PCNL_INSTANCE -g "lmxserver,ipaddress"`"
	if [ "$ipaddr" = "" ]
	then
		get_default_ip
		ipaddr=$defaddr
	fi
	$NBBIND -i "$ipaddr" -d $1 > $DEV_NULL_PATH 2>&1
	ret=$?
	if [ "$ret" -ne "0" ]
	then
		eval echo "\"`pgettext 'The domain name is already in use."
		retcode=203
		cancel_and_exit
	fi
}

convert_instance() {

if [ $1 -lt 1 -o $1 -gt 99 ]
then
	ilist=`/opt/lanman/lib/instlist |awk -e ' { print $1 }'`	
	for i in $ilist
        do
		name=`/opt/lanman/sbin/srvconfig -I $i -g "server,listenname"`
		if [ "$name" = "$1" ]
		then
			PCNL_INSTANCE=$i
			return
		fi
        done
	echoif $INSTANCE_NOT_FOUND
	exit 4
fi
}		

read_miconfig() {

if [ $# -gt 0 ]
then
	PCNL_INSTANCE=$1
	convert_instance $PCNL_INSTANCE
	IDIR=`/opt/lanman/lib/instlist ${PCNL_INSTANCE} |awk -e ' { print $2 }'`
	if [ ${IDIR:-""} = "" ]
	then
		echoif $INSTANCE_NOT_FOUND
		exit 4
	fi
elif [ ${PCNL_INSTANCE:-""} != "" ]
then
	convert_instance $PCNL_INSTANCE
	IDIR=`/opt/lanman/lib/instlist ${PCNL_INSTANCE} |awk -e ' { print $2 }'`
	if [ ${IDIR:-""} = "" ]
	then
		echoif $INSTANCE_NOT_FOUND
		usage
		exit 4
	fi
else
	count=0
	ilist=`/opt/lanman/lib/instlist | while read inum path lhost
	do
		echo $inum
	done`
	for INS in ${ilist}
	do
		count=`expr $count + 1`
	done
	if [ $count -eq 1 ]
	then
		PCNL_INSTANCE=${ilist}
		IDIR=`/opt/lanman/lib/instlist ${PCNL_INSTANCE} |awk -e ' { print $2 }'`
	else
		echoif $INSTANCE_NOT_SPECIFIED
		usage
		exit 3
	fi
fi

if [ "$IDIR" = "/" ]
then
	IDIR=""
fi

export PCNL_INSTANCE
export IDIR

if [ ! -d ${IDIR}/var/opt/lanman/${PCNL_INSTANCE} ]
then
	echoif $INSTANCE_NOT_FOUND
	exit 4
fi
}

NBUTIL_PATH=/opt/SUNWlznb/sbin/nbutil
AWK=/usr/bin/nawk
HEAD=/usr/bin/head
NBBIND=/opt/lanman/lib/nbbind
CUT=/usr/bin/cut

FATAL_EXIT_CODE=1


COMMENT="Solaris (TM) PC NetLink Server"
progname=`basename $0`

#AllowStandAlone="YeS"

# Use this file to check whether another instance of joindomain is running
lock_file=/tmp/${Progname}.lock

# Invalid character list for server and domain names
#INVALIDCH='][/\*:+;<>,?"=	'
INVALIDCH='][/\*:+;<>,?"= 	'

# for makemach error status checks
ACCESS_DENIED=5

SAMCHECK_PRIMARY_ERROR()
{
    pgettext "ERROR:\tA new user accounts database cannot be created.\nRemove this package and any previous installations before reinstalling.\n"
}

SAMCHECK_BACKUP_ERROR()
{
    pgettext "ERROR:\tServer cannot be configured as backup controller now.\nConfirm that the domain name and primary domain controller name are correct,\nand verify that the primary domain controller is running before attempting \nto run this program.\n"
}

CHUSER_ERROR()
{
    pgettext "ERROR:\tThe administrative password cannot be set.\n"
}

MAKEMACH_BACKUP_ERROR()
{
    eval echo "\"`pgettext 'ERROR:\tAn account for this machine cannot be created\non the primary domain controller ${primary}.\n\nThe primary domain controller for this domain must be started and active\non the network before the installation of a backup domain controller is\nattempted.'`\""
}

MAKEMACH_STAND_ALONE_ERROR()
{
    eval echo "\"`pgettext 'ERROR:\tAn account for this machine cannot be created\non the primary domain controller ${vQuote}${primary}${vQuote}.\nThe primary domain controller for this domain must be started and active\non the network before the installation of a stand-alone server which is a\n domain member is attempted.'`\""
}

MAKEMACH_PASSWORD_ERROR()
{
    eval echo "\"`pgettext 'ERROR:\tThe password for this account could not be \n\
set in local database.  Make sure the existing account at primary ${vQuote}${primary}${vQuote} is \n\
a ${vQuote}${role}${vQuote} account type.'`\""
}


MAKEMACH_PRIMARY_ERROR()
{
    echo "ERROR:\tAn account for this machine cannot be created.\n"
}


FIXMEMSRV_ADD_ERROR()
{
    echo "ERROR:\tOne or more built-in global groups are not added to\n\
built-in local groups at member server." 
}


BDC_ERROR_ACCOUNT_EXIST()
{   echo "ERROR:\tA workstation account with the same server name you \n\
specified exists on primary domain controller. You can re-new this account \n\
or choose a different server name."
}

MEMBER_ERROR_ACCOUNT_EXIST()
{   echo "ERROR:\tA domain controller account with the same server name\n\
you specified exists on primary domain controller. You can re-new this account \n\
or choose a different server name."
}

#
# Ask the user a question, return true(YES) if yes, false(NO) if no
#
NO=255
YES=0
NO_DEFAULT=2
yorn ()
{
	if [ $cargs = 1 ]
	then
		return $YES
	else
		def=$1
		shift
		while [ 1 ]
		do
			if [ $def = $NO ]
			then
				echoif "$* [y/n]? n\b\c"
			elif [ $def = $YES ]
			then
				echoif "$* [y/n]? y\b\c"
			else
				echoif "$* [y/n]? \c"
			fi

			case `line` in
			y|Y|[yY][eE][sS])
				return $YES
				;;
			n|N|[nN][oO])
				return $NO
				;;
			'')
				if [ $def != $NO_DEFAULT ]
				then
					return $def
				fi
				echoif "\tPlease respond with y(es) or n(o)"
				;;
			*)
				echoif "\tPlease respond with y(es) or n(o)"
				;;
			esac
		done
	fi
}

getpw()
{

	while [ 1 ]
	do
		echo $2
		stty -echo; read pw; stty echo
		n=`echo "$pw" | wc -c`
		if [ $n -gt 15 -o $n -lt $1 ]
		then
			echo "\nPassword must be shorter than 15 characters."
			continue
		fi
		echo "\nRe-enter password: \c"
		stty -echo; read ANS2; stty echo
		if [ "$pw" != "$ANS2" ]
		then
			echo "\nPassword mismatch!"
			continue
		fi
		echo
		break
	done
}

getadmin()
{
	admindomain=""
	admin="Administrator"
	eval echoif "\"`pgettext '\nEnter the name of an administrator account\n \
or press Enter to select ${vQuote}${admin}${vQuote}: '`\c\""
	if [ $cargs = 1 ]
	then
		x=$admincli
	else
		read x
	fi
	if [ "$x" != "" ]
	then
		admindomain=`echo "$x" | $AWK '{ FS="/*|\\\\\*"} { print \$1}'`
		admin=`echo "$x" | $AWK '{ FS="/\*|\\\\\*"} { print \$2}'`

		if [ "$admin" = "" ]
		then
			admin="$admindomain"
			admindomain=""
		fi
	else
		x="$admin"
	fi

	echoif ""
	if [ $adminpwdcli = 0 ]
	then
		eval getpw 0 "\"`pgettext 'Enter the password for ${vQuote}${x}${vQuote}: '`\c\""
		domain_pw="$pw"
	fi
}

#
# get the server name
#
getserver_name ()
{
	servername=`echo ${original_servername}`

	echoif "\nThe current name of this server is ($servername).\n"
	eval yorn $NO "\"`pgettext 'Would you like to change this name now'`\""
	if [ $? = $NO ]
	then
		return
	fi

	newservername=""
	while [ "$retcode" = "0" ]
	do
		echoif "\nEnter the new servername (15 characters or less): "
		if [ $cargs = 1 ]
		then
			x=$servercli
		else
			read x
		fi

		if [ "$x" != "" ]
		then
			newservername="${x}"
		fi

		# Make sure server name is OK
		#
		if [ "$newservername" = "" ]
		then
			echo "You must select a server name.\n"
			retcode=100
			continue
		fi

		# if not allowing uname, can't be uname
		if [ "$ALLOW_UNAME_SERVER" != yes -a "$newservername" = "`uname -n | cut -d. -f1`" ]
		then
			echo "The server name cannot be the system name.\n"
			echo "You must select a unique name.\n"
			retcode=101
			continue
		fi

		# check name length
		namelen=`echo $newservername | wc -c`
		namelen=`expr $namelen - 1`
		if [ $namelen -gt 15 ]
		then
			echo "Server names must be 15 characters or less."
			newservername=""
			retcode=102
			continue
		fi

		# check for valid character set
		len=`expr "$newservername" : "[^${INVALIDCH}]*"`
		if [ "$len" -ne "$namelen" ]
		then
			eval echo "\"`pgettext 'The server name contains invalid characters.\n\
The invalid characters are: ${INVALIDCH}'`\""
			newservername=""
			retcode=103
			continue
		fi
		break
	done

	if [ $retcode != 0 ]
	then
		cancel_and_exit
	fi

	servername=$newservername

	return
}

#
# get the server's role, either primary, backup, or member
#
getserver_role ()
{
	role=${original_role} 

	#
	# removed case that took the following acion in all cases
	#
	#newrole=""

	#
	# cleanup any failed SAM stuff, if necessary
	#
	if [ $PurgeSamStuff = yes ]
	then
		rm -f $LSA_PATH $BUILTIN_PATH > $DEV_NULL_PATH 2>&1
		rm -f $CHANGELOG_PATH $SAMDIR_PATH/* > $DEV_NULL_PATH 2>&1
		PurgeSamStuff=no
	fi

	while [ 1 ]
	do
		if [ "$newrole" = "" ]
		then
		    pgettext "\nEnter role ('primary', 'backup', or 'member'): "
		    read newrole
		fi

		case "$newrole" in
		"primary"|"backup"|"member")
			;;
		"p")
			newrole=primary
			;;
		"b")
			newrole=backup
			;;
		"m")
			newrole="member"
			;;
		"")
			pgettext "\nYou must enter either 'primary' or 'backup' or 'member'.\n"
                        newrole=""
                        continue
                        ;;

		*)
			pgettext "\nYou must enter either 'primary', 'backup', or 'member'.\n"
			newrole=""
			continue
			;;
		esac
		break
	done
	role=$newrole

	if [ "$role" = member ]
	then
		eval echoif "\"`pgettext '\nThis server will become a member server.\n'`\""
	else
		eval echoif "\"`pgettext '\nThis server will become a ${role} domain controller.\n'`\""
	fi
	return
}

#
# get the domain; new role is PDC
#
getdomain_name_pdc()
{

	domain_type="domain"
	Domain_type="Domain"

	domain=${original_domain}
	if [ "$original_role" != "primary" -o "$domain" = "" ]
	then
		domain=`uname -n | cut -d. -f1 | cut -c1-11`_dom
	fi

	echoif "\nThe domain that this server will join is named ($domain)."

	eval yorn $YES "\"`pgettext '\nWould you like to change this ${domain_type} name now'`\""
	change=$?

	newdomain=""
	while [ $retcode = 0 ]
	do
		if [ "$change" = "$YES" ]
		then
			eval echoif "\"`pgettext '\nEnter new $domain_type name (15 characters or less): '`\c\""
			if [ $cargs = 1 ]
			then
				x=$domaincli
			else
				read x
			fi
			if [ "$x" != "" ]
			then
				newdomain=$x
			fi
		else
			newdomain=$domain
		fi
	
		# if change is set to no, then set to yes in case of retry
		change="$YES"

		# Make sure domain name is OK
		#
		if [ "$newdomain" = "" ]
		then
			eval echo "\"`pgettext 'You must select a $domain_type name.'`\""
			retcode=200
			continue
		fi
		domainlen=`echo $newdomain | wc -c`
		domainlen=`expr $domainlen - 1`
		if [ $domainlen -gt 15 ]
		then
			eval echo "\"`pgettext '${Domain_type} names must be 15 characters or less.'`\""
			newdomain=""
			retcode=201
			continue
		fi
		len=`expr "$newdomain" : "[^${INVALIDCH}]*"`
		if [ "$len" -ne "$domainlen" ]
		then
			eval echo "\"`pgettext 'The ${domain_type} name contains invalid characters.'`\""
			eval echo "\"`pgettext 'The invalid characters are: ${INVALIDCH}'`\""
			newdomain=""
			retcode=202
			continue
		fi
		break
	done

	if [ $retcode != 0 ]
	then
		cancel_and_exit
	fi

	domain=`echo $newdomain | tr '[a-z]' '[A-Z]'`
	return
}

#
# get the domain; new role is NOT PDC
#
getdomain_name_other()
{

	domain_type="domain"
	Domain_type="Domain"

	domain=${original_domain}
	if [ "$domain" = "" ]
	then
		domain=`uname -n | cut -d. -f1 | cut -c1-11`_dom
	fi

	echoif "\nThe domain that this server will join is named ($domain)."

	eval yorn $YES "\"`pgettext '\nWould you like to change this ${domain_type} name now'`\""
	change=$?

	newdomain=""
	while [ $retcode = 0 ]
	do
		if [ "$change" = "$YES" ]
		then
			eval echoif "\"`pgettext '\nEnter new $domain_type name (15 characters or less): '`\c\""
			if [ $cargs = 1 ]
			then
				x=$domaincli
			else
				read x
			fi
			if [ "$x" != "" ]
			then
				newdomain=$x
			fi
		else
			newdomain=$domain
		fi

		# if change is set to no, then set to yes in case of retry
		change="$YES"

		# Make sure domain name is OK
		#
		if [ "$newdomain" = "" ]
		then
			eval echo "\"`pgettext 'You must select a $domain_type name.'`\""
			retcode=200
			continue
		fi
		domainlen=`echo $newdomain | wc -c`
		domainlen=`expr $domainlen - 1`
		if [ $domainlen -gt 15 ]
		then
			eval echo "\"`pgettext '${Domain_type} names must be 15 characters or less.'`\""
			newdomain=""
			retcode=201
			continue
		fi
		len=`expr "$newdomain" : "[^${INVALIDCH}]*"`
		if [ "$len" -ne "$domainlen" ]
		then
			eval echo "\"`pgettext 'The ${domain_type} name contains invalid characters.'`\""
			eval echo "\"`pgettext 'The invalid characters are: ${INVALIDCH}'`\""
			newdomain=""
			retcode=202
			continue
		fi

		# First, make sure domain exists.
		r=`${NBUTIL_PATH} -T 0x1c -f ${newdomain}`
		ret=$?

		# make sure there are not only deregistered names returned 
		checkdereg=`echo $r | grep -v Deregistered | grep "\[1c\]"` 

		#if [ $ret -eq 255 -o "$checkdereg" = "" ]
		if [ $ret -eq 255 ]
		then
			eval echo "\"`pgettext 'The domain name ${vQuote}\"${newdomain}\"${vQuote} does not exists.'`\""
			newdomain=""
			retcode=204
			continue
		elif [ $ret -ne 0 ]
		then
			eval echo "\"`pgettext 'Cannot determine if domain name exists.'`\""
			newdomain=""
			retcode=205
			continue;
		fi

		# Next, determine the PDC
		primary=""
		plist=`${NBUTIL_PATH} -T 0x1b -n ${newdomain} | grep -v Deregistered | grep "\[20\]" | $CUT -c10-24 | sed -e "s' *$''" | grep -v "\*"`

		newdomainU=`echo $newdomain |nawk ' { s=toupper($1); print s }'`
		for srv in $plist
		do 
			tempdom=`$MAKEMACH_PATH -q -s "$srv" 2> $DEV_NULL_PATH`
			tempdomU=`echo $tempdom |nawk ' { s=toupper($1); print s }'`
			if [ "$tempdomU" = "$newdomainU" ]
			then 
			# The -r option returns "3" for a PDC and "2" for a BDC
				temprole=`$MAKEMACH_PATH -q -r -s "$srv"`
				if [ $temprole = "3" ]
				then
					primary="$srv"
					break
				fi
			fi
		done

		if [ "$primary" = "" ]
		then
			eval echo "\"`pgettext 'The primary domain controller for ${vQuote}${domain_type}${vQuote} cannot be reached.'`\""
			newdomain=""
			retcode=206
			continue
		fi
		break
	done

	if [ $retcode != 0 ]
	then
		cancel_and_exit
	fi

	tempdom=`$MAKEMACH_PATH -q -s "$primary"`
	if [ "$tempdom" != "" ]
	then
		domain=$tempdom
	else
		eval echo "\"`pgettext 'Invalid Domain Name.'`\""
		retcode=207
		cancel_and_exit
	fi
	return
}

#
# check_acct_exist()
# 
# Checks to see if machine account already exists.
#

check_acct_exist()
{
	machine_account_exist=no

	#
	# PDC exists and we got its domain name.
	# Check for existing machine account.
	#
	# Note we have already shown we can query it successfully
	# so failure other than access denied means no machine account
	#
	# Hide error message as above.

	server_type=`$MAKEMACH_PATH -C -s "$primary" -m "$servername" 2> $DEV_NULL_PATH`
	ret=$?

	# see if we got a machine acct

	if [ $ret -ne 0 ]
	then
		machine_account_exist=no
	else
		machine_account_exist=yes

		if [ "$role" = "member" ]
		then
			if [ "$server_type" != "WORKSTATION" ]
			then
				machine_account_exist=no
			fi
		else 
		#
		# role = backup
		#
			if [ "$server_type" != "DOMAIN_CONTROLLER" ]
			then
				machine_account_exist=no
			fi
		fi
        fi

	if [ "$machine_account_exist" = yes ]
	then
	    eval echoif "\"`pgettext '\nUsing existing machine account on ${vQuote}${primary}${vQuote}.\n '`\""
	fi

	if [ "$machine_account_exist" = no ]
	then
	    # admin credentials will be needed to create the new acct
	    # get and validate them if we don't already have them.
	    #
	    # we have to do this here because if we get a machine account
	    # but it's the wrong kind, and the user does not want to
	    # renew, we end up here with no machine account and
	    # maybe no user and pw.


	    eval echoif "\"`pgettext '\nNo machine account found on PDC.\nAdministrative credentials required to create new account.\n'`\""

	while [ 1 ]
	do
	    if [ "$admin" = "" ]
	    then
		getadmin
		if [ "$admindomain" = "" ]
		then
		echo "$domain_pw" | $MAKEMACH_PATH -q -g -l $domain -a "$admin" -s "$primary" > $DEV_NULL_PATH 2>&1
		ret=$?
		else
		echo "$domain_pw" | $MAKEMACH_PATH -q -g -l $admindomain -a $admin -s "$primary" > $DEV_NULL_PATH 2>&1
		ret=$?
		fi
		
		if [ "$ret" -ne 0 ]
		then
		    eval yorn $YES "\"`pgettext '\nLogin incorrect.\nDo you want to enter new information and retry'`\""
		    if [ $? = $YES -a $cargs = 0 ]
		    then
			# have any previously created SAM stuff trashed
			PurgeSamStuff=yes
			admin=""
			continue
		    else
			echo "Login incorrect."
			retcode=7
			cancel_and_exit
		    fi
		else
		    break
		fi
	    fi
	done
	fi
	
	return
}

checkipaddress()
{

# Get the default address
        ifc="`head -1 /etc/opt/SUNWlznb/netbios.conf | $AWK '{print $2}'`"
        if [ "$ifc" = "" ]
        then
	    defipaddr=""
	else
            defipaddr="`ifconfig $ifc | $AWK '{ for (i = 1; i <= NF; i++) if ($i=="inet") print $(i+1) }'`"
	fi

        ipaddr="`$SRVCONFIG_PATH -I $PCNL_INSTANCE -g "lmxserver,ipaddress"`"
        if [ "$ipaddr" = "" ]
        then
# This instance is configured to use default ip address, i.e. the first entry
# in netbios.conf.  Get the ip address corresponding to this default.
            if [ "$defipaddr" = "" ]
            then
		pgettext "\nThe default IP address can not be determined.  Please configure Netbios.\n"
		retcode=15
		cancel_and_exit
            else
            	ipaddr=$defipaddr
	    fi
        fi

# Get list of configured instances.  For each, if it is a domain controller,
# check that its IP Address is not the same as the one configured for this
# instance.
	stat=0
	ilist=`/opt/lanman/lib/instlist | awk -e ' { print $1 }'`
	for i in $ilist
	do
		if [ "$i" != "$PCNL_INSTANCE" ]
		then
		    if [ "$role" = "member" ]
		    then 
			otherrole=`/opt/lanman/sbin/getrole -I $i -r`
			if [ "$otherrole" = "member" ]
			then
				continue
			fi
		    fi
		    iptest=`$SRVCONFIG_PATH -I $i -g "lmxserver,ipaddress"`
		    if [ "$iptest" = "" ]
		    then
			iptest=$defipaddr
		    fi

		    if [ "$iptest" = "$ipaddr" ]
		    then 
		 	stat=1
			break
		    fi
		fi
	done
	return $stat
}

Prompt_For_IPAddress()
{
	pgettext "\nEnter the IP address to be assigned to this instance or  \
	\n<Return> if the IP address(es) of the physical adapter(s) should be used: "
	read answer ignore_extra_words
	case "$answer" in

	"")
	  ipaddr=""
	  break
	  ;;

	*)
	  $SRVCONFIG_PATH -I $PCNL_INSTANCE -s "lmxserver,ipaddress=$answer"
	esac
}

configureserver ()
{
while [ 1 ]
do
	getserver_name

	getserver_role

	if [ $role = primary ]
	then
		getdomain_name_pdc
	else
		getdomain_name_other
		check_acct_exist
	fi

	# server name may not be the same as the domain name
	# test must be case insensitive.  use sort since it honors locale
	#
	locale="`$SRVCONFIG_PATH -I $PCNL_INSTANCE -g lmxserver,lang`"
	count=`echo "$servername\n$domain" | LC_CTYPE="$locale" sort -fu | wc -l`
	if [ "$count" -eq 1 ]
	then
		pgettext "\nThe server name cannot be the same as the domain name.\n"

		# have the previously created SAM stuff trashed
		PurgeSamStuff=yes
		continue
	fi

	# If the IP address has been passed on the command line, set it and
	# then check it. 
	if [ $ipaddress != 0 ]
	then 
	  	$SRVCONFIG_PATH -I $PCNL_INSTANCE -s "lmxserver,ipaddress=$ipaddress"
		checkipaddress
		if [ $? != 0 ]
		then 
			retcode=15 
			cancel_and_exit
		fi
	else 
		checkipaddress
		while [ $? != 0 ]
		do
			pgettext "\nThe IP address $ipaddr is in use by other domain\ncontroller instances.  Please specify another IP address.\n"
			Prompt_For_IPAddress
			checkipaddress
		done
	fi

	check_server_name ${servername}

	if [ $role = primary ]
	then
		check_domain_name ${domain}
	fi

	# We have all the answers.  Give them one last chance to change them
	#
	eval echoif "\"`pgettext '\n\
Confirm choices:	servername   : ${servername}\n\
			role         : ${role}\n\
			domain       : ${domain}'`\""

	if [ $role = backup -o $role = member ]
	then
		eval echoif "\"`pgettext '\
			primary      : ${primary}'`\""
	fi

	eval yorn $YES "\"`pgettext 'Is this correct'`\""
	if [ $? = $NO ]
	then
		# have the previously created SAM stuff trashed
		PurgeSamStuff=yes
		admin=""
		continue
	fi

	# get the administrator password
	# if backup or member, already asked for domain password
	if [ "$role" = "primary" ]
	then
		if [ $adminpwdcli = 0 ]
		then
			echoif ""
			eval getpw 0 "\"`pgettext 'Enter the password for Administrator:'`\c\""
			domain_pw="$pw"
		fi
	fi

	if [ "$role" = "member" ]
	then
		if [ $localpwdcli = 0 ]
		then
			echoif ""
			eval getpw 0 "\"`pgettext 'Enter the password for Administrator on ${servername}:'`\c\""
			local_pw="$pw"
		fi
	fi

	# if nothing has changed, ask whether to continue or not
	if [ "$role" = "$original_role" \
		-a "$servername" = "$original_servername" \
		-a "$domain" = "$original_domain" ]
	then

echoif "You have not made any changes to the server name, server${vQuote}s role or domain.
If you continue, the user accounts database and associated files will be 
re-initialized. All data currently in those files will be replaced."

		eval yorn $NO "\"`pgettext '\nDo you want to continue'`\""
		if [ $? = $NO ]
		then
			eval echo "\"`pgettext 'No changes have been made to ${COMMENT}'`\""
			cancel_and_exit
		fi
		if [ $cargs = 1 -a $contcli = 0 ]
		then
			eval echo "\"`pgettext 'No changes have been made to ${COMMENT}'`\""
			retcode=8
			cancel_and_exit
		fi
	fi

	# update files with input provided by the user
	# set listenname only if a servername is entered and the user
	# has changed it
	if [ "$servername" != ""  -a  "$servername" != "$original_servername" ]
	then
		# update listenname.  
		# set if no unix listener or new name is not uname.serve.
		# remove if unix listener and new name is uname.serve.
		if [ "$ListenNameCheck" = no  -o \
				"$servername" != $UnameDotServe ]
		then
			$SRVCONFIG_PATH -s "server,listenname=$servername"
		else
			sed -e "/listenname=/d" -e "/listenname =/d" $LANMAN_INI_PATH > /tmp/lanman.$$
			cp /tmp/lanman.$$ $LANMAN_INI_PATH
			rm -f /tmp/lanman.$$
		fi
	fi

	# If the servername is 'uname'.serve, update UNIX listener database
	# Tell nlsadmin to install the Client Vc handoff program
	# Do it for every network protocol loaded.

	if [ "$ListenNameCheck" = yes -a "$servername" = $UnameDotServe ]
	then
		for x in `$NLSADMIN_PATH -x | cut -f1`
		do
			$NLSADMIN_PATH -q -z 2 $x > $DEV_NULL_PATH 2>&1
			if [ $? -eq 0 ]
			then
				eval echoif "\"`pgettext 'Removing old entry for the server on protocol stack: ${x}'`\""
				$NLSADMIN_PATH -r 2 $x > $DEV_NULL_PATH 2>&1
			fi
			eval echoif "\"`pgettext 'Adding the server to protocol stack: ${1x}'`\""
			$NLSADMIN_PATH -m -a 2 -c "$PASSCLI_PATH" -y \
			eval echoif "\"`pgettext 'Used by ${COMMENT}'`\"" -w root $x
		done
	fi

	# update domain
	$SRVCONFIG_PATH -s "workstation,domain=$domain"
	
	# update product type
	if [ "$role" = member ]
	then
		ProductType=ServerNT
	else
		ProductType=LanmanNT
	fi

	if [ "$ProductType" != "$original_ProductType" ]
	then
		$SRVCONFIG_PATH -s "server,ProductType=$ProductType"
	fi

	# build the databases
	eval echo "\"`pgettext '\nCreating $COMMENT accounts database.\n'`\""
	if [ $role = primary ]
	then
		$SAMCHECK_PATH -d > $DEV_NULL_PATH 2>&1
		if [ $? -ne 0 ]
		then
			SAMCHECK_PRIMARY_ERROR
			retcode=9
			cancel_and_exit
		fi

		# set the administrator password
		$CHUSER_PATH -A -p "$domain_pw" 
		if [ $? -ne 0 ]
		then
			CHUSER_ERROR
			retcode=10
			cancel_and_exit
		fi

		$MAKEMACH_PATH -P > $DEV_NULL_PATH
		if [ $? -ne 0 ]
		then
			MAKEMACH_PRIMARY_ERROR
			retcode=11
			cancel_and_exit
		fi
	elif [ $role = member ]
	then
		$SAMCHECK_PATH -m -p "$primary" > $DEV_NULL_PATH 2>&1
		if [ $? -ne 0 ]
		then
			SAMCHECK_PRIMARY_ERROR
			retcode=9
			cancel_and_exit
		fi

		# set the administrator password
		$CHUSER_PATH -A -p "$local_pw" 
		if [ $? -ne 0 ]
		then
			CHUSER_ERROR
			retcode=10
			cancel_and_exit
		fi

		if [ "$machine_account_exist" = "no" ] 
		then 
			if [ "$admindomain" = "" ]
			then
				echo "$domain_pw" | $MAKEMACH_PATH -M -a $admin -s "$primary" > $DEV_NULL_PATH 2>&1
			else
				echo "$domain_pw" | $MAKEMACH_PATH -M -l $admindomain -a $admin -s "$primary" > $DEV_NULL_PATH 2>&1
			fi
			if [ $? -ne 0 ]
			then
				MAKEMACH_STAND_ALONE_ERROR
				retcode=11
				cancel_and_exit
			fi
		else
			$MAKEMACH_PATH -M -s "$primary" -e > $DEV_NULL_PATH 2>&1
			ret=$?

			if [ $ret -ne 0 ]
			then
				MAKEMACH_PASSWORD_ERROR
				retcode=12
				cancel_and_exit
			fi
		fi

		$FIXMEMSRV_PATH > $DEV_NULL_PATH 2>&1
		if [ $? -ne 0 ]
		then
			FIXMEMSRV_ADD_ERROR
			retcode=13
                        cancel_and_exit
		fi
	else
		$SAMCHECK_PATH -d -p "$primary" > $DEV_NULL_PATH 2>&1
		if [ $? -ne 0 ]
		then
			SAMCHECK_BACKUP_ERROR
			retcode=14
			cancel_and_exit
		fi

		if [ "$machine_account_exist" = "no" ]
		then
			if [ "$admindomain" = "" ]
			then
				echo "$domain_pw" | $MAKEMACH_PATH -B -a $admin -s "$primary" > $DEV_NULL_PATH 2>&1
			else
				echo "$domain_pw" | $MAKEMACH_PATH -B -l $admindomain -a $admin -s "$primary" > $DEV_NULL_PATH 2>&1
			fi
			if [ $? -ne 0 ]
			then
				MAKEMACH_BACKUP_ERROR
				retcode=11
				cancel_and_exit
			fi
		else
			$MAKEMACH_PATH -B -s "$primary" -e > $DEV_NULL_PATH 2>&1
			ret=$?

			if [ $ret -ne 0 ]
			then
				MAKEMACH_PASSWORD_ERROR
				retcode=12
				cancel_and_exit
			fi
		fi
	fi

	break
done
return
}

grab_lock_file()
{
        pid=`lock_file_holder`

        case "$pid" in
        $$)
                ;;
        "")
                rm -f "$lock_file" > $DEV_NULL_PATH 2>&1
                echo $$ > "$lock_file" 2> $DEV_NULL_PATH
                #^-- assumes echo is an atomic write
                ;;
         *) 
                false; return
                ;;
        esac

        [ x`lock_file_holder` = x"$$" ]
}

release_lock_file()
{
        pid=`lock_file_holder`

        case "$pid.$1" in
        "".*|$$.*|*.--force)
                rm -f "$lock_file" > $DEV_NULL_PATH 2>&1
                ;;
        *)
                false; return
                ;;
        esac

        :
}

lock_file_holder()
{
        pid=`head -1 "$lock_file" 2> $DEV_NULL_PATH`

        case "$pid" in
        ""|$$) ;;  *) kill -0 "$pid" || pid="" ;;
        esac
            
        echo "$pid"

        :
}

save_tty_state()
{
        tty_state=`stty -g`
}

restore_tty_state()
{
        if [ -n "$tty_state" ]
        then
                stty "$tty_state";  sc=$?

                unset  tty_state

                (exit "$sc")
        fi
}

save_lmx_state()
{
		

        # stop server; remember whether it was running

        ps -ef -o pid,args | egrep "${LMXCTRL_NAME} -I ${PCNL_INSTANCE}$" | grep -v grep > $DEV_NULL_PATH 2>&1
        if [ $? = 0 ]
        then
		if [ $cargs = 1 ]
		then
			echo "You must stop the server before running this command."
			retcode=6
			cancel_and_exit
		fi

                lmx_was_running=1

                eval echoif "\"`pgettext '\nThe ${Progname} utility cannot continue when the server is running.\n'`\""
                eval yorn $YES "\"`pgettext '\nDo you want to stop the server and continue '`\""
                if [ $? != $YES ]
                then
                        false; return
                fi

                pgettext "\nStopping the server ... "
                $NET_PATH /I:${PCNL_INSTANCE} stop server /y > $DEV_NULL_PATH 2>&1
                if [ $? = 0 ]
                then
                        echoif "Success\n"
                else
                        pgettext "\nERROR: Unable to stop the server.\n"
                        false; return
                fi
        else
                lmx_was_running=0
        fi

        remove_saved_lmx_state
        create_saved_lmx_state
}

restore_lmx_state()
{
	echoif "\nRestoring server to its previous state ... \c"

        if load_saved_lmx_state
        then
                echoif "Success\n"
        else
                echoif "Failed\n"
                false; return
        fi

	if [ $lmx_was_running = 1 ]
	then
		eval echoif "\"`pgettext 'Restarting the ${COMMENT} ... '`\c\""
		$NET_PATH /I:${PCNL_INSTANCE} start server > $DEV_NULL_PATH 2>&1
                if [ $? -ne 0 ]
		then
			pgettext "Failed\n"
                        false; return
		else
			pgettext "Success\n"
		fi
	fi

        :
}

create_saved_lmx_state()
{
        ( find ${IDIR}/etc/opt/lanman/${PCNL_INSTANCE} ${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/datafiles ${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/domains |

          egrep -v '^${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/datafiles/(acl|share|registry.*)$' |
          #^                                   ^^^^^^^^^^^^^^^^^^^^^^
          #^-- exclude potentially large files which we do not alter

          cpio -ov -H crc > ${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/${Progname}.cpio

        ) > $DEV_NULL_PATH 2>&1

        if [ $? -ne 0 ]
        then
                lmx_state_was_saved=0
                false; return
        else
                lmx_state_was_saved=1
        fi

        :
}

remove_saved_lmx_state()
{
        rm -f ${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/${Progname}.cpio
}

load_saved_lmx_state()
{
        if [ "$lmx_state_was_saved" != 1 ]
        then
                false; return
        fi

        ( rm -rf ${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/domains &&

          cpio -idmuv < ${IDIR}/var/opt/lanman/${PCNL_INSTANCE}/${Progname}.cpio

        ) > $DEV_NULL_PATH 2>&1
}

cancel_and_exit()
{
        restore_tty_state

        trap 'ignore_interrupts_while_exiting' 1 2 3 15

	echoif "\nProgram Terminated.\n"

        restore_lmx_state

        cleanup_and_exit "$@"
}

cleanup_and_exit()
{
        trap 'ignore_interrupts_while_exiting' 1 2 3 15

        trap 0  # disable exit handling; we're there

        remove_saved_lmx_state

        release_lock_file

        exit ${1:-${retcode}}
}

ignore_interrupts_while_exiting()
{
        pgettext "\nIgnoring interrupts while exiting...\n"
}


#
# Main
#

cargs=0
retcode=0
resetlock=0
contcli=0
adminpwdcli=0
localpwdcli=0
ipaddress=0

# are there any commandline arguments?
if [ "$1" = "" ]
then
	break;
else
	while getopts pbmLcy:u:a:s:d:I:i: c
	do
		if [ "$OPTARG" != "" ]
		then
			dash=`echo $OPTARG | nawk '{ print index($1,"-") }'`
			if [ "$dash" = "1" ]
			then
				echo "Invalid argument: missing argument for -$c"
				retcode=1
				cancel_and_exit
			fi	
		fi
		case $c in
		p)      	newrole="primary"
				cargs=1;;
		b)      	newrole="backup"
				cargs=1;;
		m)      	newrole="member"
				cargs=1;;
		L)      	resetlock=1
				cargs=1;;
		c)		contcli=1
				cargs=1;;
		y)		adminpwdcli=1
				domain_pw=$OPTARG;;
		u)		localpwdcli=1
				local_pw=$OPTARG;;
		a)		admincli=$OPTARG
				cargs=1;;
		s)		servercli=$OPTARG
				cargs=1;;
		d)		domaincli=$OPTARG
				cargs=1;;
		i)		ipaddress=$OPTARG
				cargs=1;;
		I)		instancecli=$OPTARG;;
		\?)             usage
		  exit 1;;
		esac
	done
fi

read_miconfig $instancecli

LMPATHS="`/bin/dirname $0`/../lib/lmpaths"

if [ -f ${LMPATHS} ]
then
    . ${LMPATHS}
else
    . lmpaths
fi

# cannot run if not root
id | grep root > $DEV_NULL_PATH 2>&1
if [ $? != 0 ]
then
	echo "\nYou must be root to run this command.\n"
	exit 2
fi

ulimit 1000000	 # Never run out of ulimit space

save_tty_state

# -L means run even if already locked; used after
# the machine crashed while joindomain was running
[ $resetlock = 1 ] && release_lock_file --force

trap 'cleanup_and_exit' 0
trap  'cancel_and_exit' 1 2 3 15


grab_lock_file || {

	eval echoif "\"`pgettext 'The ${COMMENT} configuration utility, ${Progname},\n\
appears to be running. This instance of ${Progname} will exit.\n\
Check all running processes and try again.\n\
If you are sure that another copy of $Progname is not currently\n\
running, rerun $Progname with the -L option to reset the lock file.'`\"" 

	exit
}


eval echoif "\"`pgettext 'The ${COMMENT} configuration utility (${Progname}) \n\
allows you to specify the server name, the domain name, and the server${vQuote}s\n\
role within that domain. Each time you run this utility, the server\n\
will be stopped and the user accounts database and associated files will\n\
be re-initialized. All data currently in those files will be replaced.'`\""

eval yorn $NO "\"`pgettext '\nDo you want to continue'`\""
if [ $cargs = 0 -a $? = $NO ]
then
	exit
fi

eval echoif "\"`pgettext '${COMMENT} provides a NETLOGON service which\n\
simplifies the administration of multiple servers. A single user\n\
accounts database can be shared by multiple servers grouped together\n\
into an administrative collection called a domain. Within a domain, each\n\
server has a designated role. A single server, called the primary domain\n\
controller, manages all changes to the user accounts database and\n\
automatically distributes those changes to other servers, called backup\n\
domain controllers, within the same domain. You must now supply a server\n\
name (the name which this server will be known on the network), the role\n\
that this server will perform in that domain (primary, backup, or\n\
member), and a domain name.'`\""


save_lmx_state || exit


role=""
domain=""
primary=""
servername=""
PurgeSamStuff=no

original_ProductType=`$SRVCONFIG_PATH -g "server,ProductType"`
original_domain=`$SRVCONFIG_PATH -g "workstation,domain"`
original_listenname=`$SRVCONFIG_PATH -g "server,listenname"`
ListenNameCheck=`$SRVCONFIG_PATH -g "lmxserver,listennamechk"`
ListenExtension=`$SRVCONFIG_PATH -g "lmxserver,listenextension" | \
						tr '[A-Z]' '[a-z]'`
if [ -z "$ListenExtension" ]
then
	ListenExtension=".serve"
fi
len=`echo $ListenExtension | wc -c`
len=`expr 16 - $len`
UnameDotServe="`uname -n | cut -c1-${len}`${ListenExtension}"

if [ "$original_listenname" = '' ]
then
	original_servername=$UnameDotServe
else
	original_servername=$original_listenname
fi

original_role=`${GETROLE_PATH} -r | tr -d "\012"` 

configureserver

if [ -z "${JoinDomainDoNotRestartServer}" -a $cargs = 0 ]
then
	# Prompt to start the server
	eval yorn $YES "\"`pgettext '\nDo you want to start the server now'`\""
	if [ $? = $YES ]
	then
		eval echoif "\"`pgettext 'Starting the $COMMENT ... '`\c\""
		$NET_PATH /I:${PCNL_INSTANCE} start server > $DEV_NULL_PATH 2>&1
		if [ $? -ne 0 ]
		then
			pgettext "Failed\n"
			cancel_and_exit
		else
			echo " Success \n\nNote: If this server was previously a backup controller in another domain,\nyou should use the Server Manager to contact the primary controller of the old domain and remove this server from that domain.  If the replicator service is running on this server, it may have to be reconfigured. Use the Properties function of Server Manager to check the replication configuration.\n"
		fi
	fi
fi

if [ $cargs = 1 ]
then
	echo "Successfully added ${vQuote}$servername${vQuote} to domain ${vQuote}$domain${vQuote} as type ${vQuote}$role${vQuote}."
	echo
fi

cleanup_and_exit 0
