#!/sbin/sh
#
# Portions Copyright 06/24/98 Sun Microsystems, Inc. All Rights Reserved

#	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
#	  All Rights Reserved

#	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
#	The copyright notice above does not evidence any
#	actual or intended publication of such source code.

#pragma ident	"@(#)dsypinit	1.32	98/06/24 SMI"         /* SVr4.0 1.2   */

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#	PROPRIETARY NOTICE (Combined)
#
# This source code is unpublished proprietary information
# constituting, or derived under license from AT&T's UNIX(r) System V.
# In addition, portions of such source code were derived from Berkeley
# 4.3 BSD under license from the Regents of the University of
# California.
#
#
#
#	Copyright Notice 
#
# Notice of copyright on this source code product does not indicate 
#  publication.
#
#	(c) 1986,1987,1988,1989,1990  Sun Microsystems, Inc
#	(c) 1983,1984,1985,1986,1987,1988,1989  AT&T.
#          All rights reserved.
#

BASEDIR=`/bin/pkgparam SUNWsds BASEDIR 2>/dev/null`
if [ -z "$BASEDIR" ]  
then
        BASEDIR=/opt   
fi

YPXFR=$BASEDIR/SUNWconn/ldap/sbin/dsypxfr
DSYPXFRD=$BASEDIR/SUNWconn/ldap/lib/dsypxfrd
DSYPPASSWDD=$BASEDIR/SUNWconn/ldap/lib/dsyppasswdd
DSYPXFRDPID=/var/opt/SUNWconn/ldap/log/dsypxfrd.pid
DECL=$BASEDIR/SUNWconn/ldap/lib/dsypdecl
DSIMPORT=$BASEDIR/SUNWconn/ldap/sbin/dsimport
DSSERVINI=/etc/opt/SUNWconn/ldap/current/dsserv.ini
MAPPING=/etc/opt/SUNWconn/ldap/current/mapping/nis.mapping

ADMINDIR=/etc/opt/SUNWconn/ldap/current
MAKEPATH=/usr/ccs/bin
maps="publickey publickey.byname"
yproot_dir=/var/yp
yproot_exe=/usr/sbin/yp
hf=/tmp/ypservers.$$
XFR=${YPXFR}
WHOAMI=/usr/ucb/whoami

NISCACHE_DIR=`cat $MAPPING | grep DBM_DIRECTORY | awk 'BEGIN {FS="="} { printf("%s",$2) }'`
if [ -z "$NISCACHE_DIR" ]
then
	NISCACHE_DIR=/var/opt/SUNWconn/ldap/nis/cache
fi

YPL_MASTER_FILE=/etc/opt/SUNWconn/ldap/current/nis.master

hosts_file=/etc/hosts
clientp=F
masterp=F
slavep=F
host=""
def_dom=""
master=""
got_host_list=F
first_time=T
exit_on_error=F
errors_in_setup=F
localhost=`uname -n`

interdomain=F
load=F
restricted=F
newdomain=""
maplist=""
keycmd=""

PATH=/bin:/usr/bin:/usr/etc:/usr/sbin:$yproot_exe:$MAKEPATH:$PATH
export PATH 

usage() {
        echo 'usage:'
        echo '  dsypinit -c'
        echo '  dsypinit -m [-r] [-b] [-l] [-k <key> <value>] [-d <domain>] [<map> *]'
        echo '  dsypinit -s master_server'
        echo '  dsypinit -u [-d <domain>] [<map> *]'
        echo ""
        echo "where -c is used to set up a yp client, -m is used to build a master "
        echo "yp server data base, and -s is used for a slave data base."
        echo "master_server must be an existing reachable yp server."
	echo ""
	echo "master options:"
	echo "  -r: Secure map(s). Accept connections from secure NIS networks only."
	echo "  -b: Insert the YP_INTERDOMAIN into the map(s)."
	echo "      This key causes the NIS server to use DNS for host name and address"
	echo "      lookups for hosts not found in the maps."
	echo "  -l: Initialize the maps with existing entries of the LDAP database."
	echo "      Potentially unsecure if invalid entries are present in LDAP."
	echo "  -k: Insert a NIS special key and value in the specified map(s). "
	echo "      Special keys usually starts with YP_ prefix and are interpreted"
	echo "      bu NIS utilities. "
	echo "  -d: Initialize maps of <domain> only. Others maps in the mapping file"
	echo "      are not initialized. By default, all domains are initialized."
	echo ""
	echo "      A map list can be used to initialize some maps only or to initialize"
	echo "      maps with different options."
	echo ""
	echo "  -u: Disable the specified NIS maps in the specified domain."
	echo ""
        exit 1
}

stop_dsyprsvd() {
        pid=`ps -fe | grep lib/dsyprsvd | grep -v grep|awk '{print $2}'`
        if [ -n "$pid" ]
        then
                echo "Stopping DNS resolver daemon (dsyprsvd)..."
                kill -TERM ${pid}
        fi
}

stop_dsyppasswd() {
        pid=`ps -fe | grep lib/dsyppasswdd | grep -v grep|awk '{print $2}'`
        if [ -n "$pid" ]
        then
                echo "Stopping NIS password daemon (dsyppasswdd)..."
                kill -TERM ${pid}
        fi
}

stop_dsypxfrd() {

        if [ -f ${DSYPXFRDPID} ]; then
                pid=`cat ${DSYPXFRDPID}`
                /bin/rm -f ${DSYPXFRDPID}
                count=`/bin/ps -e| /bin/awk '{print $1}' | grep -c ${pid}`
                if [ ${count} -eq "1" ]; then
                        echo "Stopping NIS replication daemon (dsypxfrd)..."
                        kill -TERM ${pid}
                fi
        else
                pid=`ps -fe | grep lib/dsypxfrd | grep -v grep|awk '{print $2}'`
                if [ -n "$pid" ]
                then
                        echo "Stopping NIS replication daemon (dsypxfrd)..."
                        kill -TERM ${pid}
                fi
        fi
}

start_dsypxfrd() {

        #
        # Make sure NIS replication is enabled
        #

        enabled=`cat $MAPPING|grep "DBM_XFR_REPLICATION"| awk 'BEGIN { FS="=" } {print $2} END {}'`
        if [ "$enabled" = "enabled" ]
        then
                pid=`ps -fe | grep lib/dsypxfrd | grep -v grep|awk '{print $2}'`
                if [ -n "$pid" ]
                then
                        echo "Another dsypxfrd process is already running"
                else
                        echo "Starting NIS replication daemon (dsypxfrd)..."
                        $DSYPXFRD
                fi
        else

                #
                # Stop it if it is running
                #

                pid=`ps -fe | grep lib/dsypxfrd | grep -v grep|awk '{print $2}'`
                if [ -n "$pid" ]
                then
                        echo "NIS replication disabled and dsypxfrd running!"
                        stop_dsypxfrd
                fi
        fi
}

start_dsyppasswd() {

        pid=`ps -fe | grep lib/dsyppasswdd | grep -v grep|awk '{print $2}'`
        if [ -n "$pid" ]
        then
                echo "Another dsyppasswd process is already running"
        else
                echo "Starting NIS password daemon (dsyppasswdd)..."
                $DSYPPASSWDD
        fi
}


masterp=F
partnewd=F
partkey=F
partval=F
removemode=F
keykey="" 
valval=""
kfound=F
m_operational=F
s_operational=F

case "$1" in
'-c')
	if [ ! $# = 1 ]
	then
		usage
	fi
	clientp=T;;
'-s')
	if [ ! $# = 2 ]
	then
		usage
	fi
        slavep=T; master=$2;
        if ( grep $master $hosts_file > /dev/null )
        then
                echo ""
        else
                echo "server not found in /etc/hosts file"
                exit 1
        fi;;
'-m')

	masterp=T

	if [ ! $# = 1 ]
	then
	startmap=F
	first=T
	while [ $# -ne 0 ]
	do
		if [ $first = T ]
		then
			shift
			first=F
		fi

		case "$1" in
		'-r')
			if [ $startmap = T ]
			then 
				usage
			else
				restricted=T
			fi;;
		'-b')
			if [ $startmap = T ]
			then 
				usage
			else
				interdomain=T
			fi;;
		'-l')
			if [ $startmap = T ]
			then 
				usage
			else
				load=T
			fi;;
		'-k')
			partkey=T;;
		'-d')
			partnewd=T;;
		*)
			if [ $partkey = T ]
			then
				partkey=F
				partval=T
				kfound=T
				keykey=$1
			elif [ $partval = T ]
			then
				partkey=F
				partval=F
				valval=$1
			elif [ $partnewd = T ]
			then
				newdomain=$1
				partnewd=F
			else
				maplist="$maplist $1"
				startmap=T
			fi
			;;
		esac

		shift
	done

	if [ $partnewd = T ]
	then
		if [ "$newdomain" = "" ]
		then
			usage
		fi
	fi
	fi
	;;
'-u')
	removemode=T
	if [ ! $# = 1 ]
        then
        startmap=F
        first=T
        while [ $# -ne 0 ]
        do
                if [ $first = T ]
                then
                        shift
                        first=F
                fi

                case "$1" in
                '-r')   usage;;
                '-b')   usage;;
                '-l')   usage;;
                '-k')   usage;;
	 	'-d')
                        partnewd=T;;
                *)
                        if [ $partnewd = T ]
                        then
                                newdomain=$1
                                partnewd=F
                        else
                                maplist="$maplist $1"
                                startmap=T
                        fi
                        ;;
                esac

                shift
        done

	if [ $partnewd = T ]
        then
                if [ "$newdomain" = "" ]
                then
                        usage
                fi
        fi
        fi
        ;;

*)
	usage;;
esac
	
if [ $load = T ]
then 
	load="-l"
else
	load=""
fi

if [ $restricted = T ]
then
	restricted="-r"
else
	restricted=""
fi

if [ $interdomain = T ]
then
	interdomain="-b"
else
	interdomain=""
fi

if [ $kfound = T ]
then
	if [ "$keykey" = "" ]
	then
		usage
	elif [ "$valval" = "" ]
	then
		usage
	else
		keycmd="-k $keykey $valval"
	fi
fi

if [ $partkey = T ]
then
	usage
elif [ $partval = T ]
then
	usage
fi

me=`$WHOAMI`
if [ ! $me = "root" ]
then 
	echo "\
You have to be the superuser to run this.  Please log in as root."
	exit 1
fi

host=`uname -n`

if [ $? -ne 0 ]
then 
	echo "Can't get local host's name.  Please check your path."
	exit 1
fi

if [ -z "$host" ]
then
	echo "The local host's name hasn't been set.  Please set it."
	exit 1
fi

if [ ! "$newdomain" = "" ]
then 
	 def_dom=$newdomain
	 newdomain="-d "$newdomain
else
	def_dom=`domainname`
fi

if [ $? -ne 0 ]
then 
	echo "Can't get local host's domain name.  Please check your path."
	exit 1
fi

if [ -z "$def_dom" ]
then
	echo "The local host's domain name hasn't been set.  Please set it."
	exit 1
fi

if [ $removemode = T ]
then
        $DECL -u $newdomain $maplist
	exit $?
fi

domainname $def_dom
real_def_dom=$def_dom
#def_dom=`ypalias -d $def_dom`
ypservers_map=`ypalias ypservers`
domain_dir="$yproot_dir""/""$def_dom" 
binding_dir="$yproot_dir""/binding/""$def_dom"
binding_file="$yproot_dir""/binding/""$def_dom""/ypservers"

if [ ! -d $yproot_dir -o -f $yproot_dir ]
then
    echo "\
The directory $yproot_dir doesn't exist.  Restore it from the distribution."
	exit 1
fi

# add domainname and ypservers aliases to aliases file
echo ypservers $ypservers_map >> $yproot_dir/aliases
echo $real_def_dom $def_dom >> $yproot_dir/aliases
sort $yproot_dir/aliases | uniq > /tmp/.ypaliases; mv /tmp/.ypaliases $yproot_dir/aliases

if [ ! -d "$yproot_dir"/binding ]
then
	mkdir "$yproot_dir"/binding
fi

if [ ! -d  $binding_dir ]
then
	mkdir  "$binding_dir"
fi

if [ $slavep = F ]
then
	while [ $got_host_list = F ]; do
		touch $hf    # make sure file exists
		echo ""
		echo "\
In order for NIS to operate sucessfully, we have to construct a list of the "
		echo "\
NIS servers.  Please continue to add the names for YP servers in order of"
		echo "\
preference, one per line.  When you are done with the list, type a <control D>"
		echo "\
or a return on a line by itself."
		if [ $masterp = T ]
		then
			echo $host > $hf
			echo "\tnext host to add:  $host"
		elif [ -f $binding_file ]
		then
			if [ $first_time = T ]
			then
				for h in `cat $binding_file`
				do
					echo $h >> $hf
					echo "\tnext host to add:  $h" 
				done
			fi
		fi

		echo  "\tnext host to add:  \c"

		while read h ; test -n "$h"
		do
			if ( grep $h $hosts_file > /dev/null )
			then
				echo $h >> $hf
				echo  "\tnext host to add:  \c"
			else
				echo "host $h not found in $hosts_file file. Not added to the list"
				echo ""
				echo  "Do you wish to abort [y/n: y]  \c"
				read cont_ok

				case $cont_ok in
				n*)	echo "\tnext host to add:  \c";;	
				N*)	echo "\tnext host to add:  \c";;	
				*)	exit 1;;
				esac
			fi

		done

		echo ""
		echo "The current list of yp servers looks like this:"
		echo ""

		cat $hf
		echo ""
		echo  "Is this correct?  [y/n: y]  \c"
		read hlist_ok

		case $hlist_ok in
		n*)	got_host_list=F
			first_time=F
			rm $hf
			echo "Let's try the whole thing again...";;
		N*)	got_host_list=F
			first_time=F
			rm $hf
			echo "Let's try the whole thing again...";;
		*)	got_host_list=T;;
		esac
	done
		cp  $hf $binding_file
fi

#
# If client only, we are done
# 	our purpose was just to set up the binding file
#
if [ $clientp = T ]
then
	rm $hf
	touch $ADMINDIR/nis.client
	exit 1
fi

if [ $slavep = T ]
then
	if [ $host = $master ]
	then
		echo "\
The host specified should be a running master yp server, not this machine."
		exit 1
	fi

	maps=`ypwhich -m | egrep $master$| awk '{ printf("%s ",$1) }' -`
	if [ -z "$maps" ]
	then
		echo "Can't enumerate maps from $master. Please check that it is running."
		exit 1
	fi
fi

echo ""

echo "Installing the YP database will require that you answer a few questions."
echo "Questions will all be asked at the beginning of the procedure."
echo ""
echo "Do you want this procedure to quit on non-fatal errors? [y/n: n]  \c"
read doexit

case $doexit in
y*)	exit_on_error=T;;
Y*)	exit_on_error=T;;
*)	echo "\
OK, please remember to go back and redo manually whatever fails.  If you"
	echo "\
don't, some part of the system (perhaps the yp itself) won't work.";;
esac

echo "The yp domain is $def_dom"

for dir in $yproot_dir/$def_dom
do

	if [ -d $dir ]; then
		echo  "Can we destroy the existing $dir and its contents? [y/n: n]  \c"
		read kill_old_dir

		case $kill_old_dir in
		y*)	rm -r -f $dir

			if [ $?  -ne 0 ]
			then
			echo "Can't clean up old directory $dir.  Fatal error."
				exit 1
			fi;;

		Y*)	rm -r -f $dir

			if [ $?  -ne 0 ]
			then
			echo "Can't clean up old directory $dir.  Fatal error."
				exit 1
			fi;;

		*)    echo "OK, please clean it up by hand and start again.  Bye"
			exit 0;;
		esac
	fi

#	mkdir $dir
#
#	if [ $?  -ne 0 ]
#	then
#		echo "Can't make new directory $dir.  Fatal error."
#		exit 1
#	fi

done

if [ -f $ADMINDIR/nis.slave ]
then
	s_operational=T
fi
if [ -f $ADMINDIR/nis.master ]
then
	m_operational=T
fi

if [ $slavep = T ]
then
	echo "\
There will be no further questions. The remainder of the procedure should take"
	echo "a few minutes, to copy the data bases from $master."


	for dom in  $real_def_dom
	do

		if [ ! -d $NISCACHE_DIR/$dom ]
		then
			mkdir -p $NISCACHE_DIR/$dom
		fi

		$DECL -m $master -d $dom $maps
		for map in $maps
		do
			echo "Transferring $map..."
			$XFR -f -h $master -c -d $dom $map

			if [ $?  -ne 0 ]
			then
				errors_in_setup=T

				if [ $exit_on_error = T ]
				then
					exit 1
				fi
			fi
		done
	done

	rm -rf $ADMINDIR/nis.master
	touch  $ADMINDIR/nis.server
	touch  $ADMINDIR/nis.slave

	echo ""
	echo  "${host}'s nis data base has been set up\n"

	if [ $errors_in_setup = T ]
	then
		echo " with errors.  Please remember"
		echo "to figure out what went wrong, and fix it."
	else
		echo " without any errors."
	fi

	#
	# Stop auxilliary daemons
	#

        stop_dsypxfrd
        stop_dsyppasswd
        stop_dsyprsvd

	if [ $m_operational = T ]
	then

		echo "NIS was previously configured as a master. Removing cache files..."

		/etc/init.d/dsserv stop
		
		for dom in  $real_def_dom
		do
			if [ -d $NISCACHE_DIR/$dom ]
			then
				rm -f $NISCACHE_DIR/$dom/*.dir
				rm -f $NISCACHE_DIR/$dom/*.pag
			fi
		done

		/etc/init.d/dsserv start
	fi

	exit 0
else

#
#
#
#	rm -f $yproot_dir/*.time

	echo "\
There will be no further questions. The remainder of the procedure should take"
	echo "about 1 minute."
	echo ""

	if [ ! -d $NISCACHE_DIR ]
	then
		mkdir -p $NISCACHE_DIR
	fi

	if [ -f $ADMINDIR/nis.master ]
	then
		operational=T
	fi

	touch $ADMINDIR/nis.master
	rm -rf $ADMINDIR/nis.slave

	$DECL $interdomain $restricted $load $newdomain $keycmd -m $localhost $maplist

	if [ $?  -ne 0 ]
	then
		echo "\
Error while initializing the nis maps."
		errors_in_setup=T
		if [ $exit_on_error = T ]
		then
			exit 1
		fi
	fi
	sleep 5

	echo "Building ypservers map for domain $def_dom ..."

	# Get the current LDAP port

	if [ -f $DSSERVINI ]
	then
        	. $DSSERVINI
	fi

        if [ -n "$LdapPort" ]
        then
                LdapPort="-p $LdapPort"
	fi

	#
	# Make sure the ypservers map has been declared
	#

	$DECL $newdomain -m $localhost ypservers

	if [ $?  -ne 0 ]
	then
		echo "\
Couldn't enable ypservers map for domain $def_dom."
		errors_in_setup=T

		if [ $exit_on_error = T ]
		then
			exit 1
		fi
	fi

	rm -rf $ADMINDIR/nis.slave
	touch $ADMINDIR/nis.server
	touch $ADMINDIR/nis.master

	#
	# Then update the ypservers map
	#

	$DSIMPORT $LdapPort -t ypservers $binding_file

	if [ $?  -ne 0 ]
	then
		echo "\
Couldn't build ypservers map for domain $def_dom."
		errors_in_setup=T

		if [ $exit_on_error = T ]
		then
			exit 1
		fi
	fi

	#
	# Update the other maps
	#

	rm $hf
	cd /var/yp
	
	echo "Removing \*.time files"
	rm -f *.time

	if [ "$maplist" = "" ]
	then
		echo  "Running /var/yp/Makefile\c"
		make NOPUSH=1 
	else
		for i in $maplist
		do
			echo "Running /var/yp/Makefile for map $i...\c"
			make $i NOPUSH=1
		done
	fi

	if [ $?  -ne 0 ]
	then
		echo "\
Error running Makefile."
		errors_in_setup=T
		
		if [ $exit_on_error = T ]
		then
			exit 1
		fi
	fi

	cd $in_pwd
	echo ""
	echo  "\
$host has been set up as a yp master server\c"

	if [ $errors_in_setup = T ]
	then
		echo " with errors.  Please remember"
		echo "to figure out what went wrong, and fix it."
	else
		echo " without any errors."
	fi

	echo ""
	echo "\
If there are running slave yp servers, run dsyppush now for any data bases"
	echo "\
which have been changed.  If there are no running slaves, run dsypinit on"
	echo "\
those hosts which are to be slave servers."

	#
	# Start auxilliary daemons
	#

	start_dsypxfrd
	start_dsyppasswd

	exit 0
fi
