xref: /illumos-gate/usr/src/cmd/ypcmd/ypinit.sh (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
1#!/sbin/sh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22# Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
23#
24# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26
27#	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
28#	  All Rights Reserved
29
30# Portions of this source code were derived from Berkeley 4.3 BSD
31# under license from the Regents of the University of California.
32
33# set -xv
34YPXFR=/usr/lib/netsvc/yp/ypxfr
35MAKEPATH=/usr/ccs/bin
36maps="publickey publickey.byname"
37yproot_dir=/var/yp
38yproot_exe=/usr/sbin/yp
39hf=/var/run/ypservers.$$
40XFR=${YPXFR}
41
42hosts_file=/etc/hosts
43hosts6_file=/etc/inet/ipnodes
44clientp=F
45masterp=F
46slavep=F
47host=""
48def_dom=""
49master=""
50got_host_list=F
51first_time=T
52non_interactive=F
53exit_on_error=F
54errors_in_setup=F
55
56enable_next_boot () {
57	/usr/sbin/svcadm disable -t $1
58	[ $? = 0 ] || echo "ypinit: unable to temporarily disable $1"
59	/usr/sbin/svccfg -s $1 \
60	    setprop general/enabled = true
61	[ $? = 0 ] || echo "ypinit: unable to enable $1 for next boot"
62}
63
64enable_this_boot () {
65	/usr/sbin/svcadm enable $1
66	[ $? = 0 ] || echo "ypinit: unable to enable $1"
67}
68
69is_valid_ipaddr () {
70	test -n "`echo $1 | awk 'NF != 1 {exit} \
71	    $1 !~ /[0-9]/ || /[;-~]/ || /!--/ || /\// {exit} \
72	    $1 !~ /\./ {exit} {print}'`" || \
73	test -n "`echo $1 | awk 'NF != 1 {exit} \
74	    ($1 !~ /[0-9]/ && $1 !~ /[A-F]/ && \
75	    $1 !~ /[a-f]/) || \
76	    /[;-@]/ || /[G-\`]/ || /[g-~]/ || /!--/ || \
77	    /\// {exit} \
78	    $1 !~ /:/ {exit} {print}'`"
79}
80
81PATH=/bin:/usr/bin:/usr/etc:/usr/sbin:$yproot_exe:$MAKEPATH:$PATH
82export PATH
83
84# To do cleanup
85trap '/usr/bin/rm -f $hf' 0 1 2 3 15
86
87# Check out total number of arguments
88case $# in
891)	case $1 in
90	-c)	clientp=T;;
91	-m)	masterp=T;;
92	*)	echo 'usage:'
93		echo '	ypinit -c [server_name...]'
94		echo '	ypinit -m'
95		echo '	ypinit -s master_server'
96		echo ""
97		echo "\
98where -c is used to set up a yp client, -m is used to build a master "
99                echo "\
100yp server data base, and -s is used for a slave data base."
101		echo "\
102master_server must be an existing reachable yp server."
103		exit 1;;
104	esac;;
105
1062)	case $1 in
107	-s)	slavep=T; master=$2;
108		if ( grep $master $hosts_file $hosts6_file > /dev/null )
109		then
110			echo ""
111		else
112			echo "server not found in $hosts_file or $hosts6_file"
113			exit 1
114		fi;;
115
116	# the case with more than one argument with the '-c' option
117	# is a subject to enter non-interactive mode
118	-c)	clientp=T; non_interactive=T;
119		;;
120	*)	echo 'usage:'
121		echo '	ypinit -c [server_name...]'
122		echo '	ypinit -m'
123		echo '	ypinit -s master_server'
124		echo ""
125		echo "\
126where -c is used to set up a yp client, -m is used to build a master "
127                echo "\
128yp server data base, and -s is used for a slave data base."
129		echo "\
130master_server must be an existing reachable yp server."
131		exit 1;;
132	esac;;
133*)	case $1 in
134
135	# the case with more than one argument with the '-c' option
136	# is a subject to enter non-interactive mode
137	-c)	clientp=T; non_interactive=T;
138		;;
139	*)	echo 'usage:'
140		echo '	ypinit -c [server_name...]'
141		echo '	ypinit -m'
142		echo '	ypinit -s master_server'
143		echo ""
144		echo "\
145where -c is used to set up a yp client, -m is used to build a master "
146                echo "\
147yp server data base, and -s is used for a slave data base."
148		echo "\
149master_server must be an existing reachable yp server."
150		exit 1;;
151	esac;;
152esac
153
154if [ $? -ne 0 ]
155then
156	echo "\
157You have to be the superuser to run this.  Please log in as root."
158	exit 1
159fi
160
161host=`uname -n`
162
163if [ $? -ne 0 ]
164then
165	echo "Can't get local host's name.  Please check your path."
166	exit 1
167fi
168
169if [ -z "$host" ]
170then
171	echo "The local host's name hasn't been set.  Please set it."
172	exit 1
173fi
174
175def_dom=`domainname`
176
177if [ $? -ne 0 ]
178then
179	echo "Can't get local host's domain name.  Please check your path."
180	exit 1
181fi
182
183if [ -z "$def_dom" ]
184then
185	echo "The local host's domain name hasn't been set.  Please set it."
186	exit 1
187fi
188
189domainname $def_dom
190real_def_dom=$def_dom
191#def_dom=`ypalias -d $def_dom`
192ypservers_map=`ypalias ypservers`
193domain_dir="$yproot_dir""/""$def_dom"
194binding_dir="$yproot_dir""/binding/""$def_dom"
195binding_file="$yproot_dir""/binding/""$def_dom""/ypservers"
196
197if [ ! -d $yproot_dir -o -f $yproot_dir ]
198then
199    echo "\
200The directory $yproot_dir doesn't exist.  Restore it from the distribution."
201	exit 1
202fi
203
204# add domainname and ypservers aliases to aliases file
205echo ypservers $ypservers_map >> $yproot_dir/aliases
206echo $real_def_dom $def_dom >> $yproot_dir/aliases
207sort $yproot_dir/aliases | uniq > /var/run/.ypaliases; mv /var/run/.ypaliases $yproot_dir/aliases
208
209if [ ! -d "$yproot_dir"/binding ]
210then
211	mkdir "$yproot_dir"/binding
212fi
213
214if [ ! -d  $binding_dir ]
215then
216	mkdir  "$binding_dir"
217fi
218
219if [ $slavep = F ]
220then
221	if [ $non_interactive = F ]
222	then
223		while [ $got_host_list = F ]; do
224			touch $hf    # make sure file exists
225			echo ""
226			echo "\
227In order for NIS to operate sucessfully, we have to construct a list of the "
228			echo "\
229NIS servers.  Please continue to add the names for YP servers in order of"
230			echo "\
231preference, one per line.  When you are done with the list, type a <control D>"
232			echo "\
233or a return on a line by itself."
234			if [ $masterp = T ]
235			then
236				echo $host > $hf
237				echo "\tnext host to add:  $host"
238			elif [ -f $binding_file ]
239			then
240				if [ $first_time = T ]
241				then
242					for h in `cat $binding_file`
243					do
244						echo $h >> $hf
245						echo "\tnext host to add:  $h"
246					done
247				fi
248			fi
249
250			echo  "\tnext host to add:  \c"
251
252			while read h ; test -n "$h"
253			do
254				#
255				# Host should be in the v4 or v6 hosts file or
256				# reasonably resemble an IP address.  We'll do a
257				# sanity check that a v4 addr is one word consisting
258				# of only numbers and the "." character,
259				# which should guard against fully qualified
260				# hostnames and most malformed entries.  IPv6
261				# addresses can be numbers, hex letters, and have
262				# at least one ":" character and possibly one or
263				# more "." characters for embedded v4 addresses
264				#
265				if ( grep $h $hosts_file $hosts6_file > /dev/null ) || \
266				    ( test $clientp = T && `is_valid_ipaddr $h` )
267				then
268					echo $h >> $hf
269					echo  "\tnext host to add:  \c"
270				else
271					echo "host $h not found in $hosts_file or" \
272					    "$hosts6_file.\nNot added to the list."
273					echo ""
274					echo  "Do you wish to abort [y/n: y]  \c"
275					read cont_ok
276
277					case $cont_ok in
278					n*)	echo "\tnext host to add:  \c";;
279					N*)	echo "\tnext host to add:  \c";;
280					*)	exit 1;;
281					esac
282				fi
283			done
284
285			echo ""
286			if [ -s $hf ]
287			then
288				echo "The current list of yp servers looks like this:"
289				echo ""
290				cat $hf
291				echo ""
292				echo "Is this correct?  [y/n: y]  \c"
293			else
294				echo "You have not added any server information."
295				echo ""
296				echo "Do you still wish to exit? [y/n: y]  \c"
297			fi
298
299			read hlist_ok
300
301			case $hlist_ok in
302			n*)	got_host_list=F
303				first_time=F
304				rm $hf
305				echo "Let's try the whole thing again...";;
306			N*)	got_host_list=F
307				first_time=F
308				rm $hf
309				echo "Let's try the whole thing again...";;
310			*)	got_host_list=T;;
311			esac
312		done
313	else
314		shift
315		> $hf
316		while [[ $# > 0 ]]; do
317			if ( grep $1 $hosts_file $hosts6_file > /dev/null ) || \
318			    ( `is_valid_ipaddr $1` )
319			then
320				echo $1 >> $hf
321			else
322				echo "host $1 not found in $hosts_file or" \
323				    "$hosts6_file.\nNot added to the list."
324				echo ""
325			fi
326			shift
327		done
328	fi
329
330	if [ -s $hf ]
331	then
332		cp  $hf $binding_file
333	fi
334fi
335
336#
337# Start client service on next boot, unless we're establishing a slave
338# server, in which case the binding is needed now (or should be
339# preserved).
340#
341if [ $slavep = T ]
342then
343	enable_this_boot network/nis/client:default
344else
345	enable_next_boot network/nis/client:default
346fi
347
348#
349# As a client, our configuration is correct once a binding file is
350# established, and so we can exit (making sure we're no longer a server,
351# of course).
352#
353if [ $clientp = T ]
354then
355	rm $hf
356	/usr/sbin/svcadm disable network/nis/server:default
357	/usr/sbin/svcadm disable network/nis/xfr:default
358	/usr/sbin/svcadm disable network/nis/passwd:default
359	/usr/sbin/svcadm disable network/nis/update:default
360	exit 0
361fi
362
363if [ $slavep = T ]
364then
365	if [ $host = $master ]
366	then
367		echo "\
368The host specified should be a running master yp server, not this machine."
369		exit 1
370	fi
371
372	maps=`ypwhich -m | egrep $master$| awk '{ printf("%s ",$1) }' -`
373	if [ -z "$maps" ]
374	then
375		echo "Can't enumerate maps from $master. Please check that it is running."
376		exit 1
377	fi
378fi
379
380echo ""
381
382echo "Installing the YP database will require that you answer a few questions."
383echo "Questions will all be asked at the beginning of the procedure."
384echo ""
385echo "Do you want this procedure to quit on non-fatal errors? [y/n: n]  \c"
386read doexit
387
388case $doexit in
389y*)	exit_on_error=T;;
390Y*)	exit_on_error=T;;
391*)	echo "\
392OK, please remember to go back and redo manually whatever fails.  If you"
393	echo "\
394don't, some part of the system (perhaps the yp itself) won't work.";;
395esac
396
397echo "The yp domain directory is $yproot_dir""/""$def_dom"
398
399for dir in $yproot_dir/$def_dom
400do
401
402	if [ -d $dir ]; then
403		echo  "Can we destroy the existing $dir and its contents? [y/n: n]  \c"
404		read kill_old_dir
405
406		case $kill_old_dir in
407		y*)	rm -r -f $dir
408
409			if [ $?  -ne 0 ]
410			then
411			echo "Can't clean up old directory $dir.  Fatal error."
412				exit 1
413			fi;;
414
415		Y*)	rm -r -f $dir
416
417			if [ $?  -ne 0 ]
418			then
419			echo "Can't clean up old directory $dir.  Fatal error."
420				exit 1
421			fi;;
422
423		*)    echo "OK, please clean it up by hand and start again.  Bye"
424			exit 0;;
425		esac
426	fi
427
428	mkdir $dir
429
430	if [ $?  -ne 0 ]
431	then
432		echo "Can't make new directory $dir.  Fatal error."
433		exit 1
434	fi
435
436done
437
438if [ $slavep = T ]
439then
440	echo "\
441There will be no further questions. The remainder of the procedure should take"
442	echo "a few minutes, to copy the data bases from $master."
443
444	for dom in  $real_def_dom
445	do
446		for map in $maps
447		do
448			echo "Transferring $map..."
449			$XFR -h $master -c -d $dom $map
450
451			if [ $?  -ne 0 ]
452			then
453				errors_in_setup=T
454
455				if [ $exit_on_error = T ]
456				then
457					exit 1
458				fi
459			fi
460		done
461	done
462
463	echo ""
464	echo  "${host}'s nis data base has been set up\n"
465
466	if [ $errors_in_setup = T ]
467	then
468		echo " with errors.  Please remember"
469		echo "to figure out what went wrong, and fix it."
470	else
471		echo " without any errors."
472	fi
473
474	# enable slave services
475	enable_this_boot network/nis/server:default
476
477	enable_this_boot network/nis/client:default
478
479	exit 0
480else
481
482	rm -f $yproot_dir/*.time
483
484	echo "\
485There will be no further questions. The remainder of the procedure should take"
486	echo "5 to 10 minutes."
487
488	echo "Building $yproot_dir/$def_dom/ypservers..."
489	makedbm $hf $yproot_dir/$def_dom/$ypservers_map
490
491	if [ $?  -ne 0 ]
492	then
493		echo "\
494Couldn't build yp data base $yproot_dir/$def_dom/$ypservers_map."
495		errors_in_setup=T
496
497		if [ $exit_on_error = T ]
498		then
499			exit 1
500		fi
501	fi
502
503	rm $hf
504
505	in_pwd=`pwd`
506	cd $yproot_dir
507	echo  "Running \c"
508	echo  $yproot_dir "\c"
509	echo "/Makefile..."
510	make NOPUSH=1
511
512	if [ $?  -ne 0 ]
513	then
514		echo "\
515Error running Makefile."
516		errors_in_setup=T
517
518		if [ $exit_on_error = T ]
519		then
520			exit 1
521		fi
522	fi
523
524	cd $in_pwd
525	echo ""
526	echo  "\
527$host has been set up as a yp master server\c"
528
529	if [ $errors_in_setup = T ]
530	then
531		echo " with errors.  Please remember"
532		echo "to figure out what went wrong, and fix it."
533	else
534		echo " without any errors."
535	fi
536
537	echo ""
538	echo "\
539If there are running slave yp servers, run yppush now for any data bases"
540	echo "\
541which have been changed.  If there are no running slaves, run ypinit on"
542	echo "\
543those hosts which are to be slave servers."
544
545	# enable master services
546	enable_this_boot network/nis/server:default
547	enable_this_boot network/nis/xfr:default
548	enable_this_boot network/nis/passwd:default
549	enable_this_boot network/nis/update:default
550
551	enable_this_boot network/nis/client:default
552fi
553