xref: /illumos-gate/usr/src/cmd/tsol/misc/txzonemgr.sh (revision a8449b6b)
1#!/bin/ksh
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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23#
24#
25
26# This script provides a simple GUI for managing labeled zones.
27# It provides contextual menus which provide appropriate choices.
28# It must be run in the global zone as root.
29
30# These arguments are accepted, and will result in non-interactive
31# (text-only) mode:
32#
33#	txzonemgr [-c | -d[f]]
34#
35#	-c	create default zones
36#	-d	destroy all zones; prompts for confirmation unless
37#		the -f flag is also specified
38#	-f	force
39#
40
41# DISP - use GUI (otherwise use non-interactive mode)
42DISP=1
43# CREATEDEF - make default zones (non-interactive)
44CREATEDEF=0
45# DESTROYZONES - tear down all zones (non-interactive)
46DESTROYZONES=0
47# FORCE - force
48FORCE=0
49
50NSCD_PER_LABEL=0
51NSCD_INDICATOR=/var/tsol/doors/nscd_per_label
52if [ -f $NSCD_INDICATOR ] ; then
53	NSCD_PER_LABEL=1
54fi
55
56myname=$(basename $0)
57
58TXTMP=/tmp/txzonemgr
59TNRHTP=/etc/security/tsol/tnrhtp
60TNRHDB=/etc/security/tsol/tnrhdb
61TNZONECFG=/etc/security/tsol/tnzonecfg
62PUBZONE=public
63INTZONE=internal
64
65PATH=/usr/bin:/usr/sbin:/usr/lib export PATH
66title="Labeled Zone Manager 2.1"
67
68msg_defzones=$(gettext "Create default zones using default settings?")
69msg_confirmkill=$(gettext "OK to destroy all zones?")
70msg_continue=$(gettext "(exit to resume $(basename $0) when ready)")
71msg_getlabel=$(gettext "Select a label for the")
72msg_getremote=$(gettext "Select a remote host or network from the list below:")
73msg_getnet=$(gettext "Select a network configuration for the")
74msg_getzone=$(gettext "Select a zone from the list below:
75(select global for zone creation and shared settings)")
76msg_getcmd=$(gettext "Select a command from the list below:")
77msg_inuse=$(gettext "That label is already assigned\nto the")
78msg_getmin=$(gettext "Select the minimum network label for the")
79msg_getmax=$(gettext "Select the maximum network label for the")
80msg_badip=$(gettext " is not a valid IP address")
81
82
83process_options()
84{
85	typeset opt optlist
86
87	optlist='cdf'
88
89	while getopts ":$optlist" opt
90	do
91		case $opt in
92		c)	CREATEDEF=1
93			DISP=0
94			;;
95		d)	DESTROYZONES=1
96			DISP=0
97			;;
98		f)	FORCE=1
99			;;
100		*)	gettext "invalid option -$OPTARG\n"
101			usage
102			return 2
103			;;
104		esac
105	done
106
107	if [ $CREATEDEF -eq 1 -a $DESTROYZONES -eq 1 ] ; then
108		gettext "cannot combine options -c and -d\n"
109		usage
110		return 2
111	fi
112	if [ $CREATEDEF -eq 1 -a $FORCE -eq 1 ] ; then
113		gettext "option -f not allowed with -c\n"
114		usage
115		return 2
116	fi
117	if [ $FORCE -eq 1 -a $CREATEDEF -eq 0 -a $DESTROYZONES -eq 0 ] ; then
118		gettext "option -f specified without any other options\n"
119		usage
120		return 2
121	fi
122
123	shift $((OPTIND - 1))
124	if [ "x$1" != "x" ] ; then
125		usage
126		return 2
127	fi
128
129	return 0
130}
131
132usage() {
133	gettext "usage: $myname [-c | -d[f]]\n"
134}
135
136consoleCheck() {
137	if [ $zonename != global ] ; then
138		zconsole=$(pgrep -f "zlogin -C $zonename")
139		if [ $? != 0 ] ; then
140			console="Zone Console...\n"
141		fi
142	fi
143}
144
145labelCheck() {
146	hexlabel=$(grep "^$zonename:" $TNZONECFG|cut -d : -f2);
147	if [[ $hexlabel ]] ; then
148		label=
149		if [ $zonename = global ] ; then
150			template="admin_low"
151			addcipsohost="Add Multilevel Access to Remote Host...\n"
152			removecipsohost="Remove Multilevel Access to Remote Host...\n"
153			setmlps="Configure Multilevel Ports...\n"
154		else
155			template=${zonename}_unlab
156			addcipsohost=
157			removecipsohost=
158			setmlps=
159
160			net=$(zonecfg -z $zonename info net)
161			if [[ -n $net ]] ; then
162				setmlps="Configure Multilevel Ports...\n"
163			elif [ $zonestate = configured ] ; then
164				addnet="Configure Network Interfaces...\n"
165			fi
166		fi
167		addremotehost="Add Single-level Access to Remote Host...\n"
168		remotes=$(grep -v "^#" $TNRHDB|grep $template)
169		if [ $? = 0 ] ; then
170			removeremotehost="Remove Single-level Access to Remote Host...\n"
171		else
172			removeremotehost=
173		fi
174	else
175		label="Select Label...\n"
176		addremotehost=
177		removeremotehost=
178		addcipsohost=
179		removecipsohost=
180		setmlps=
181	fi
182}
183
184cloneCheck() {
185	set -A zonelist
186	integer clone_cnt=0
187	for p in $(zoneadm list -ip) ; do
188		z=$(echo "$p"|cut -d : -f2)
189		s=$(echo "$p"|cut -d : -f3)
190		if [ $z = $zonename ] ; then
191			continue
192		elif [ $s = "installed" ] ; then
193			zonelist[clone_cnt]=$z
194			clone_cnt+=1
195		fi
196	done
197	if [ $clone_cnt -gt 0 ] ; then
198		clone="Clone...\n"; \
199	fi
200}
201
202relabelCheck() {
203	macstate=$(zonecfg -z $zonename info|grep win_mac_write)
204	if [[ -n $macstate ]] ; then
205		permitrelabel="Deny Relabeling\n"
206	else
207		permitrelabel="Permit Relabeling\n"
208	fi
209}
210
211autobootCheck() {
212	bootmode=$(zonecfg -z $zonename info autoboot)
213	if [[ $bootmode == 'autoboot: true' ]] ; then
214		autoboot="Set Manual Booting\n"
215	else
216		autoboot="Set Automatic Booting\n"
217	fi
218}
219
220newZone() {
221		if [[ ! -n $zonename ]] ; then
222			zonename=$(zenity --entry \
223			    --title="$title" \
224			    --width=330 \
225			    --entry-text="" \
226			    --text="Enter Zone Name: ")
227
228			if [[ ! -n $zonename ]] ; then
229				zonename=global
230				return
231			fi
232		fi
233		zonecfg -z $zonename "create -t SUNWtsoldef;\
234		     set zonepath=/zone/$zonename"
235}
236
237removeZoneBEs() {
238	delopt=$*
239
240	zfs list -H $ZDSET/$zonename 1>/dev/null 2>&1
241	if [ $? = 0 ] ; then
242		for zbe in $(zfs list -rHo name $ZDSET/$zonename|grep ROOT/zbe) ; do
243			zfs destroy $delopt $zbe
244		done
245	fi
246}
247
248updateTemplate () {
249	if [ $hostType = cipso ] ; then
250		template=${zonename}_cipso
251		deflabel=
252	else
253		template=${zonename}_unlab
254		deflabel="def_label=${hexlabel};"
255	fi
256
257	tnzone=$(grep "^${template}:" $TNRHTP 2>/dev/null)
258	if [ $? -eq 0 ] ; then
259		sed -e "/^${template}/d" $TNRHTP > $TXTMP/tnrhtp.$$ 2>/dev/null
260		mv $TXTMP/tnrhtp.$$ $TNRHTP
261	fi
262	print "${template}:host_type=${hostType};doi=1;min_sl=${minlabel};max_sl=${maxlabel};$deflabel" >> $TNRHTP
263	tnctl -t $template
264}
265
266setTNdata () {
267	tnzline="$zonename:${hexlabel}:0::"
268	grep "^$tnzline" $TNZONECFG 1>/dev/null 2>&1
269	if [ $? -eq 1 ] ; then
270		print "$tnzline" >> $TNZONECFG
271	fi
272
273	#
274	# Add matching entries in tnrhtp if necessary
275	#
276	minlabel=admin_low
277	maxlabel=admin_high
278	hostType=cipso
279	updateTemplate
280
281	hostType=unlabeled
282	updateTemplate
283}
284
285selectLabel() {
286	hexlabel=$(tgnome-selectlabel \
287		--title="$title" \
288		--text="$msg_getlabel $zonename zone:" \
289		--min="${DEFAULTLABEL}"  \
290		--default="${DEFAULTLABEL}"  \
291		--max=$(chk_encodings -X) \
292		--accredcheck=yes \
293		--mode=sensitivity \
294		--format=internal)
295	if [ $? = 0 ] ; then
296		x=$(grep -i :{$hexlabel}: $TNZONECFG)
297		if [ $? = 0 ] ; then
298			z=$(print $x|cut -d : -f1)
299			x=$(zenity --error \
300			    --title="$title" \
301			    --text="$msg_inuse $z zone.")
302		else
303			setTNdata
304		fi
305	fi
306}
307
308getLabelRange() {
309	deflabel=$(hextoalabel $hexlabel)
310	minlabel=$(tgnome-selectlabel \
311		--title="$title" \
312		--text="$msg_getmin $zonename zone:" \
313		--min="${DEFAULTLABEL}"  \
314		--max="$deflabel" \
315		--default="$hexlabel" \
316		--accredcheck=no \
317		--mode=sensitivity \
318		--format=internal)
319	[ $? != 0 ] && return
320
321	maxlabel=$(tgnome-selectlabel \
322		--title="$title" \
323		--text="$msg_getmax $zonename zone:" \
324		--min="$deflabel"  \
325		--max=$(chk_encodings -X) \
326		--default="$hexlabel" \
327		--accredcheck=no \
328		--mode=sensitivity \
329		--format=internal)
330	[ $? != 0 ] && return
331
332	hostType=cipso
333	updateTemplate
334}
335
336
337encryptionValues() {
338	echo $(zfs get 2>&1 | grep encryption | sed -e s/^.*YES// -e s/\|//g)
339}
340
341getPassphrase() {
342	pass1=$(zenity --entry --title="$title" --text="Enter passphrase:" \
343	    --width=330 --hide-text)
344	pass2=$(zenity --entry --title="$title" --text="Re-enter passphrase:" \
345	    --width=330 --hide-text)
346	if [[ "$pass1" != "$pass2" ]]; then
347		zenity --error --title="$title" \
348			--text="Passphrases do not match"
349		return ""
350	fi
351	file=$(mktemp)
352	echo "$pass1" > $file
353	echo "$file"
354}
355
356createZDSET() {
357	options=$1
358	pool=${2%%/*}
359
360	# First check if ZFS encrytption support is available
361	pversion=$(zpool list -H -o version $pool)
362	cversion=$(zpool upgrade -v | grep Crypto | awk '{ print $1 }')
363	if (( cversion == 0 || pversion < cversion )); then
364		zfs create $options $ZDSET
365		return
366	fi
367
368	encryption=$(zenity --list --title="$title" --height=320 \
369		--text="Select cipher for encryption of all labels:" \
370		--column="encryption" $(encryptionValues))
371
372	if [[ $? != 0 || $encryption == "off" ]]; then
373		zfs create $options $ZDSET
374		return
375	fi
376
377	format=$(zenity --list --title="$title" \
378		--text "Select encryption key source:" \
379		--column="Key format and location" \
380		"Passphrase" "Generate Key in file")
381	[ $? != 0 ] && exit
382
383	if [[ $format == "Passphrase" ]]; then
384		file=$(getPassphrase)
385		if [[ $file == "" ]]; then
386			exit
387		fi
388		keysource="passphrase,file://$file"
389		removefile=1;
390	elif [[ $format == "Generate Key in file" ]]; then
391		file=$(zenity --file-selection \
392			--title="$title: Location of key file" \
393			--save --confirm-overwrite)
394		[ $? != 0 ] && exit
395		if [[ $encryption == "on" ]]; then
396			keylen=128
397		else
398			t=${encryption#aes-} && keylen=${t%%-*}
399		fi
400		pktool genkey keystore=file keytype=aes \
401		    keylen=$keylen outkey=$file
402		keysource="raw,file:///$file"
403	fi
404
405	options="$options -o encryption=$encryption -o keysource=$keysource"
406	zfs create $options $ZDSET
407	if (( removefile == 1 )); then
408		zfs set keysource=passphrase,prompt $ZDSET
409		rm $file
410	fi
411}
412
413
414initialize() {
415	zonepath=$(zoneadm -z $zonename list -p|cut -d : -f4)
416	ZONE_ETC_DIR=$zonepath/root/etc
417	SYSIDCFG=${ZONE_ETC_DIR}/sysidcfg
418
419	if [ -f /var/ldap/ldap_client_file ] ; then
420		ldapaddress=$(ldapclient list | \
421		    grep "^NS_LDAP_SERVERS" | cut -d " " -f2)
422		print "name_service=LDAP {" > ${SYSIDCFG}
423		domain=$(domainname)
424		print "domain_name=$domain" >> ${SYSIDCFG}
425		profName=$(ldapclient list | \
426		    grep "^NS_LDAP_PROFILE" | cut -d " " -f2)
427		proxyPwd=$(ldapclient list | \
428		    grep "^NS_LDAP_BINDPASSWD" | cut -d " " -f2)
429		proxyDN=$(ldapclient list | \
430		    grep "^NS_LDAP_BINDDN" | cut -d " " -f 2)
431		if [ "$proxyDN" ] ; then
432			print "proxy_dn=\"$proxyDN\"" >> ${SYSIDCFG}
433			print "proxy_password=\"$proxyPwd\"" >> ${SYSIDCFG}
434		fi
435		print "profile=$profName" >> ${SYSIDCFG}
436		print "profile_server=$ldapaddress }" >> ${SYSIDCFG}
437		cp /etc/nsswitch.conf $ZONE_ETC_DIR/nsswitch.ldap
438	else
439		print "name_service=NONE" > ${SYSIDCFG}
440		fi
441	print "security_policy=NONE" >> ${SYSIDCFG}
442	locale=$(locale|grep LANG | cut -d "=" -f2)
443	if [[ -z $locale ]] ; then
444		locale="C"
445	fi
446	print "system_locale=$locale" >> ${SYSIDCFG}
447	timezone=$(grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2)
448	print "timezone=$timezone" >> ${SYSIDCFG}
449	print "terminal=vt100" >> ${SYSIDCFG}
450	rootpwd=$(grep "^root:" /etc/shadow|cut -d : -f2)
451
452#	There are two problems with setting the root password:
453#		The zone's shadow file may be read-only
454#		The password contains unparsable characters
455#	so the following line is commented out until this is resolved.
456
457	#print "root_password=$rootpwd" >> ${SYSIDCFG}
458	print "nfs4_domain=dynamic" >> ${SYSIDCFG}
459	print "network_interface=PRIMARY {" >> ${SYSIDCFG}
460
461	net=$(zonecfg -z $zonename info net)
462	ipType=$(zonecfg -z $zonename info ip-type|cut -d" " -f2)
463	if [ $ipType = exclusive ] ; then
464		hostname=$(zenity --entry \
465		    --title="$title" \
466		    --width=330 \
467		    --text="${zonename}0: Enter Hostname or dhcp: ")
468		[ $? != 0 ] && return
469
470		if [ $hostname = dhcp ] ; then
471			print "dhcp" >> ${SYSIDCFG}
472		else
473			print "hostname=$hostname" >> ${SYSIDCFG}
474			ipaddr=$(getent hosts $hostname|cut -f1)
475			if [ $? != 0 ] ; then
476				ipaddr=$(zenity --entry \
477				    --title="$title" \
478				    --text="$nic: Enter IP address: " \
479				    --entry-text a.b.c.d)
480				[ $? != 0 ] && return
481
482				validateIPaddr
483				if [[ -z $ipaddr ]] ; then
484					return
485				fi
486			fi
487			print "ip_address=$ipaddr" >> ${SYSIDCFG}
488			getNetmask
489			print "netmask=$nm" >> ${SYSIDCFG}
490			print "default_route=none" >> ${SYSIDCFG}
491			template=${zonename}_cipso
492			cidr=32
493			updateTnrhdb
494		fi
495	elif [[ -n $net ]] ; then
496		hostname=$(hostname)
497		hostname=$(zenity --entry \
498		    --title="$title" \
499		    --width=330 \
500		    --text="Enter Hostname: " \
501		    --entry-text $hostname)
502		[ $? != 0 ] && return
503
504		print "hostname=$hostname" >> ${SYSIDCFG}
505		ipaddr=$(getent hosts $hostname|cut -f1)
506		if [ $? = 0 ] ; then
507			print "ip_address=$ipaddr" >> ${SYSIDCFG}
508		fi
509	else
510		getAllZoneNICs
511		for i in ${aznics[*]} ; do
512			ipaddr=$(ifconfig $i|grep inet|cut -d " " -f2)
513		done
514		print "hostname=$(hostname)" >> ${SYSIDCFG}
515		print "ip_address=$ipaddr" >> ${SYSIDCFG}
516	fi
517
518	print "protocol_ipv6=no }" >> ${SYSIDCFG}
519	cp /etc/default/nfs ${ZONE_ETC_DIR}/default/nfs
520	touch ${ZONE_ETC_DIR}/.NFS4inst_state.domain
521}
522
523clone() {
524	image=$1
525	if [[ -z $image ]] ; then
526		msg_clone=$(gettext "Clone the $zonename zone using a
527snapshot of one of the following halted zones:")
528		image=$(zenity --list \
529		    --title="$title" \
530		    --text="$msg_clone" \
531		    --height=300 \
532		    --width=330 \
533		    --column="Installed Zones" ${zonelist[*]})
534	fi
535
536	if [[ -n $image ]] ; then
537		removeZoneBEs
538		zoneadm -z $zonename clone $image
539
540		if [ $NSCD_PER_LABEL = 0 ] ; then
541			sharePasswd $zonename
542		else
543			unsharePasswd $zonename
544		fi
545
546		ipType=$(zonecfg -z $zonename info ip-type|cut -d" " -f2)
547		if [ $ipType = exclusive ] ; then
548			zoneadm -z $zonename ready
549			zonepath=$(zoneadm -z $zonename list -p|cut -d : -f4)
550			sys-unconfig -R $zonepath/root 2>/dev/null
551			initialize
552			zoneadm -z $zonename halt
553		fi
554	fi
555}
556
557install() {
558	removeZoneBEs
559	if [ $DISP -eq 0 ] ; then
560		gettext "installing zone $zonename ...\n"
561		zoneadm -z $zonename install
562	else
563		# sleep is needed here to avoid occasional timing
564		# problem with gnome-terminal display...
565		sleep 2
566		gnome-terminal \
567		    --title="$title: Installing $zonename zone" \
568		    --command "zoneadm -z $zonename install" \
569		    --disable-factory \
570		    --hide-menubar
571	fi
572
573	zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
574	if [ $zonestate != installed ] ; then
575		gettext "error installing zone $zonename.\n"
576		return 1
577	fi
578
579	zoneadm -z $zonename ready
580	zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
581	if [ $zonestate != ready ] ; then
582		gettext "error making zone $zonename ready.\n"
583		return 1
584	fi
585
586	if [ $NSCD_PER_LABEL = 0 ] ; then
587		sharePasswd $zonename
588	else
589		unsharePasswd $zonename
590	fi
591
592	initialize
593	zoneadm -z $zonename halt
594}
595
596delete() {
597	delopt=$*
598
599	# if there is an entry for this zone in tnzonecfg, remove it
600	# before deleting the zone.
601
602	tnzone=$(grep "^$zonename:" $TNZONECFG 2>/dev/null)
603	if [ -n "${tnzone}" ] ; then
604		sed -e "/^$zonename:/d" $TNZONECFG > \
605		    $TXTMP/tnzonefg.$$ 2>/dev/null
606		mv $TXTMP/tnzonefg.$$ $TNZONECFG
607	fi
608
609	for tnzone in $(grep ":${zonename}_unlab" $TNRHDB 2>/dev/null) ; do
610		tnctl -dh "$tnzone"
611		sed -e "/:${zonename}_unlab/d" $TNRHDB > \
612		    $TXTMP/tnrhdb.$$ 2>/dev/null
613		mv $TXTMP/tnrhdb.$$ $TNRHDB
614	done
615
616	for tnzone in $(grep "^${zonename}_unlab:" $TNRHTP 2>/dev/null) ; do
617		tnctl -dt ${zonename}_unlab
618		sed -e "/^${zonename}_unlab:/d" $TNRHTP > \
619		    $TXTMP/tnrhtp.$$ 2>/dev/null
620		mv $TXTMP/tnrhtp.$$ $TNRHTP
621	done
622
623	for tnzone in $(grep ":${zonename}_cipso" $TNRHDB 2>/dev/null) ; do
624		tnctl -dh "$tnzone"
625		sed -e "/:${zonename}_cipso/d" $TNRHDB > \
626		    $TXTMP/tnrhdb.$$ 2>/dev/null
627		mv $TXTMP/tnrhdb.$$ $TNRHDB
628	done
629
630	for tnzone in $(grep "^${zonename}_cipso:" $TNRHTP 2>/dev/null) ; do
631		tnctl -dt ${zonename}_cipso
632		sed -e "/^${zonename}_cipso:/d" $TNRHTP > \
633		    $TXTMP/tnrhtp.$$ 2>/dev/null
634		mv $TXTMP/tnrhtp.$$ $TNRHTP
635	done
636
637	zonecfg -z $zonename delete -F
638
639	removeZoneBEs $delopt
640	for snap in $(zfs list -Ho name -t snapshot|grep "\@${zonename}_snap") ; do
641		zfs destroy -R $snap
642	done
643}
644
645validateIPaddr () {
646	OLDIFS=$IFS
647	IFS=.
648	integer octet_cnt=0
649	integer dummy
650	set -A octets $ipaddr
651	IFS=$OLDIFS
652	if [ ${#octets[*]} == 4 ] ; then
653		while (( octet_cnt < ${#octets[*]} )); do
654			dummy=${octets[octet_cnt]}
655			if [ $dummy = ${octets[octet_cnt]} ] ; then
656				if (( dummy >= 0 && \
657				    dummy < 256 )) ; then
658					octet_cnt+=1
659					continue
660				fi
661			else
662			x=$(zenity --error \
663			    --title="$title" \
664			    --text="$ipaddr $msg_badip")
665			ipaddr=
666			return
667			fi
668		done
669	else
670		x=$(zenity --error \
671		    --title="$title" \
672		    --text="$ipaddr $msg_badip")
673		ipaddr=
674	fi
675}
676
677getAllZoneNICs(){
678	integer count=0
679	for i in $(ifconfig -a4|grep  "^[a-z].*:")
680	do
681		print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
682		[ $? -eq 1 ] && continue
683
684		i=${i%:} # Remove colon after interface name
685		for j in $(ifconfig $i)
686		do
687			case $j in
688				all-zones)
689					aznics[count]=$i
690					count+=1
691					;;
692			esac
693		done
694        done
695}
696
697getNetmask() {
698	cidr=
699	nm=$(zenity --entry \
700	    --title="$title" \
701	    --width=330 \
702	    --text="$ipaddr: Enter netmask: " \
703	    --entry-text 255.255.255.0)
704	[ $? != 0 ] && return;
705
706	cidr=$(perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm)
707}
708
709addNet() {
710	getIPaddr
711	if [[ -z $ipaddr ]] ; then
712		return;
713	fi
714	getNetmask
715	if [[ -z $cidr ]] ; then
716		return;
717	fi
718	zonecfg -z $zonename "add net; \
719	    set address=${ipaddr}/${cidr}; \
720	    set physical=$nic; \
721	    end"
722	template=${zonename}_cipso
723	cidr=32
724	updateTnrhdb
725}
726
727getAttrs() {
728	zone=global
729	type=ignore
730	for j in $(ifconfig $nic)
731	do
732		case $j in
733			inet) type=$j;;
734			zone) type=$j;;
735			all-zones) zone=all-zones;;
736			flags*) flags=$j;;
737			*) case $type in
738				inet) ipaddr=$j ;;
739				zone) zone=$j ;;
740				*) continue ;;
741			   esac;
742			   type=ignore;;
743		esac
744	done
745	if [[ $flags == ~(E).UP, ]] ; then
746		updown=Up
747	else
748		updown=Down
749	fi
750	if [[ $nic == ~(E).: ]] ; then
751		linktype=logical
752	else
753		vnic=$(dladm show-vnic -po link $nic 2>/dev/null)
754		if [[ -n $vnic ]] ; then
755			linktype=virtual
756		else
757			linktype=physical
758		fi
759	fi
760	if [ $ipaddr != 0.0.0.0 ] ; then
761		x=$(grep "^${ipaddr}[^0-9]" $TNRHDB)
762		if [ $? = 1 ] ; then
763			template=cipso
764			cidr=32
765			updateTnrhdb
766		else
767			template=$(print "$x"|cut -d : -f2)
768		fi
769	else
770		template="..."
771		ipaddr="..."
772	fi
773}
774deleteTnrhdbEntry() {
775	remote=$(grep "^${ipaddr}[^0-9]" $TNRHDB)
776	if [ $? = 0 ] ; then
777		ip=$(print $remote|cut -d "/" -f1)
778			if [[ $remote == ~(E)./ ]] ; then
779				pr=$(print $remote|cut -d "/" -f2)
780				remote="$ip\\/$pr"
781			fi
782		sed -e "/^${remote}/d" $TNRHDB > /tmp/tnrhdb.$$ 2>/dev/null
783		mv /tmp/tnrhdb.$$ $TNRHDB
784	fi
785}
786
787updateTnrhdb() {
788	deleteTnrhdbEntry
789	if [[ -n $cidr ]] ; then
790		print "${ipaddr}/$cidr:$template" >> $TNRHDB
791		tnctl -h ${ipaddr}/$cidr:$template
792	else
793		print "${ipaddr}:$template" >> $TNRHDB
794		tnctl -h ${ipaddr}:$template
795	fi
796}
797
798getIPaddr() {
799        hostname=$(zenity --entry \
800            --title="$title" \
801	    --width=330 \
802            --text="$nic: Enter Hostname: ")
803
804        [ $? != 0 ] && return
805
806	ipaddr=$(getent hosts $hostname|cut -f1)
807        if [[ -z $ipaddr ]] ; then
808		ipaddr=$(zenity --entry \
809		    --title="$title" \
810		    --text="$nic: Enter IP address: " \
811		    --entry-text a.b.c.d)
812		[ $? != 0 ] && return
813		validateIPaddr
814	fi
815
816}
817
818addHost() {
819	# Update hosts
820        if [[ -z $ipaddr ]] ; then
821               return;
822	fi
823	grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null
824	if [ $? -eq 1 ] ; then
825		print "$ipaddr\t$hostname" >> /etc/inet/hosts
826	fi
827
828	template=cipso
829	cidr=32
830	updateTnrhdb
831
832	ifconfig $nic $ipaddr netmask + broadcast +
833	#
834	# TODO: better integration with nwam
835	# TODO: get/set netmask for IP address
836	#
837	print $hostname > /etc/hostname.$nic
838}
839
840createInterface() {
841	msg=$(ifconfig $nic addif 0.0.0.0)
842	$(zenity --info \
843	    --title="$title" \
844	    --text="$msg" )
845	nic=$(print "$msg"|cut -d" " -f5)
846
847}
848
849createVNIC() {
850	if [ $zonename != global ] ; then
851		vnicname=${zonename}0
852	else
853		vnicname=$(zenity --entry \
854		    --title="$title" \
855		    --width=330 \
856		    --entry-text="" \
857		    --text="Enter VNIC Name: ")
858
859		if [[ ! -n $vnicname ]] ; then
860			return
861		fi
862	fi
863	x=$(dladm show-vnic|grep "^$vnicname " )
864	if [[ ! -n $x ]] ; then
865		dladm create-vnic -l $nic $vnicname
866	fi
867	if [ $zonename = global ] ; then
868		ifconfig $vnicname plumb
869	else
870		zonecfg -z $zonename "add net; \
871		    set physical=$vnicname; \
872		    end"
873	fi
874	nic=$vnicname
875}
876
877shareInterface() {
878	#
879	# TODO: better integration with nwam
880	#
881	ifconfig $nic all-zones;\
882	if_file=/etc/hostname.$nic
883	sed q | sed -e "s/$/ all-zones/" < $if_file >$TXTMP/txnetmgr.$$
884	mv $TXTMP/txnetmgr.$$ $if_file
885}
886
887unshareInterface() {
888	#
889	# TODO: better integration with nwam
890	#
891	ifconfig $nic -zone;\
892	if_file=/etc/hostname.$nic
893	sed q | sed -e "s/all-zones/ /" < $if_file >$TXTMP/txnetmgr.$$
894	mv $TXTMP/txnetmgr.$$ $if_file
895}
896
897addTnrhdb() {
898	ipaddr=$(zenity --entry \
899	    --title="$title" \
900	    --width=330 \
901	    --text="Zone:$zonename. Enter IP address of remote host or network: " \
902	    --entry-text a.b.c.d)
903	[ $? != 0 ] && return
904	validateIPaddr
905	if [[ -z $ipaddr ]] ; then
906		return;
907	fi
908	if [ ${octets[3]} = 0 ] ; then
909		nic="$ipaddr"
910		getNetmask
911		if [[ -z $cidr ]] ; then
912			return;
913		fi
914	else
915		cidr=32
916	fi
917	print "${ipaddr}/$cidr:$template" > $TXTMP/tnrhdb_new.$$
918	x=$(tnchkdb -h $TXTMP/tnrhdb_new.$$ 2>$TXTMP/syntax_error.$$)
919	if [ $? = 0 ] ; then
920		updateTnrhdb
921	else
922		syntax=$(cat $TXTMP/syntax_error.$$)
923		x=$(zenity --error \
924		    --title="$title" \
925		    --text="$syntax")
926	fi
927	rm $TXTMP/tnrhdb_new.$$
928	rm $TXTMP/syntax_error.$$
929}
930
931removeTnrhdb() {
932	while (( 1 )) do
933		remotes=$(grep "^[^#][0-9.]" $TNRHDB|grep ":$template"|cut -d : -f1-2|tr : " ")
934		if [ $template = cipso ] ; then
935			templateHeading="from All Zones":
936		else
937			templateHeading="from this Zone":
938		fi
939		if [[ -n $remotes ]] ; then
940			ipaddr=$(zenity --list \
941			    --title="$title" \
942			    --text="$msg_getremote" \
943			    --height=250 \
944			    --width=300 \
945			    --column="Remove Access to:" \
946			    --column="$templateHeading" \
947			    $remotes)
948
949			if [[ -n $ipaddr ]] ; then
950				deleteTnrhdbEntry
951				tnctl -dh ${ip}:$template
952			else
953				return
954			fi
955		else
956			return
957		fi
958	done
959}
960
961setMLPs() {
962	tnzone=$(grep "^$zonename:" $TNZONECFG 2>/dev/null)
963	zoneMLPs=:$(print "$tnzone"|cut -d : -f4)
964	sharedMLPs=:$(print "$tnzone"|cut -d : -f5)
965	attrs="Private Interfaces$zoneMLPs\nShared Interfaces$sharedMLPs"
966	ports=$(print "$attrs"|zenity --list \
967	    --title="$title" \
968	    --height=200 \
969	    --width=450 \
970	    --text="Zone: $zonename\nClick once to select, twice to edit.\nShift-click to select both rows." \
971	    --column="Multilevel Ports (example: 80-81/tcp;111/udp;)" \
972	    --editable \
973	    --multiple
974	    )
975
976	if [[ -z $ports ]] ; then
977		return
978	fi
979
980	# getopts needs another a blank and another dash
981	ports=--$(print "$ports"|sed 's/ //g'|sed 's/|/ --/g'|sed 's/Interfaces:/ :/g')
982
983	OPTIND=1
984	while getopts "z:(Private)s:(Shared)" opt $ports ; do
985		case $opt in
986			z) zoneMLPs=$OPTARG ;;
987			s) sharedMLPs=$OPTARG ;;
988		esac
989	done
990
991	sed -e "/^$zonename:*/d" $TNZONECFG > $TXTMP/tnzonecfg.$$ 2>/dev/null
992	tnzone=$(print "$tnzone"|cut -d : -f1-3)
993	echo "${tnzone}${zoneMLPs}${sharedMLPs}" >> $TXTMP/tnzonecfg.$$
994
995	x=$(tnchkdb -z $TXTMP/tnzonecfg.$$ 2>$TXTMP/syntax_error.$$)
996
997	if [ $? = 0 ] ; then
998		mv $TXTMP/tnzonecfg.$$ $TNZONECFG
999		zenity --info \
1000		    --title="$title" \
1001		    --text="Multilevel ports for the $zonename zone\nwill be interpreted on next reboot."
1002		if [ $zonename != global ] ; then
1003			getLabelRange
1004		fi
1005	else
1006		syntax=$(cat $TXTMP/syntax_error.$$)
1007		x=$(zenity --error \
1008		    --title="$title" \
1009		    --text="$syntax")
1010		rm $TXTMP/tnzonecfg.$$
1011	fi
1012	rm $TXTMP/syntax_error.$$
1013}
1014
1015enableAuthentication() {
1016	integer file_cnt=0
1017
1018	zonepath=$(zoneadm -z $1 list -p|cut -d : -f4)
1019	ZONE_ETC_DIR=$zonepath/root/etc
1020
1021	# If the zone's shadow file was previously read-only
1022	# there may be no root password entry for this zone.
1023	# If so, replace the root password entry with the global zone's.
1024
1025	entry=$(grep ^root:: $ZONE_ETC_DIR/shadow)
1026	if [ $? -eq 0 ] ; then
1027		grep ^root: /etc/shadow > $TXTMP/shadow.$$
1028		sed -e "/^root::/d" $ZONE_ETC_DIR/shadow >> \
1029		    $TXTMP/shadow.$$ 2>/dev/null
1030		mv $TXTMP/shadow.$$ $ZONE_ETC_DIR/shadow
1031		chmod 400 $ZONE_ETC_DIR/shadow
1032	fi
1033
1034	if [ $LOGNAME = "root" ]; then
1035		return
1036	fi
1037
1038	file[0]="passwd"
1039	file[1]="shadow"
1040	file[2]="user_attr"
1041	#
1042	# Add the user who assumed the root role to each installed zone
1043	#
1044	while (( file_cnt < ${#file[*]} )); do
1045		exists=$(grep "^${LOGNAME}:" \
1046		    $ZONE_ETC_DIR/${file[file_cnt]} >/dev/null)
1047		if [ $? -ne 0 ] ; then
1048			entry=$(grep "^${LOGNAME}:" \
1049			    /etc/${file[file_cnt]})
1050			if [ $? -eq 0 ] ; then
1051				print "$entry" >> \
1052				    $ZONE_ETC_DIR/${file[file_cnt]}
1053			fi
1054		fi
1055		file_cnt+=1
1056	done
1057	chmod 400 $ZONE_ETC_DIR/shadow
1058}
1059
1060unsharePasswd() {
1061	zonecfg -z $1 remove fs dir=/etc/passwd >/dev/null 2>&1 | grep -v such
1062	zonecfg -z $1 remove fs dir=/etc/shadow >/dev/null 2>&1 | grep -v such
1063	zoneadm -z $1 ready >/dev/null 2>&1
1064	if [ $? -eq 0 ] ; then
1065		enableAuthentication $1
1066		zoneadm -z $1 halt >/dev/null 2>&1
1067	else
1068		echo Skipping $1
1069	fi
1070}
1071
1072sharePasswd() {
1073	passwd=$(zonecfg -z $1 info|grep /etc/passwd)
1074	if [ $? -eq 1 ] ; then
1075		zonecfg -z $1 "add fs; \
1076		    set special=/etc/passwd; \
1077		    set dir=/etc/passwd; \
1078		    set type=lofs; \
1079		    add options ro; \
1080		    end; \
1081		    add fs; \
1082		    set special=/etc/shadow; \
1083		    set dir=/etc/shadow; \
1084		    set type=lofs; \
1085		    add options ro; \
1086		    end"
1087	fi
1088	zoneadm -z $1 ready >/dev/null 2>&1
1089	if [ $? -eq 0 ] ; then
1090		zoneadm -z $1 halt >/dev/null 2>&1
1091	else
1092		echo Skipping $1
1093	fi
1094}
1095
1096# This routine is a toggle -- if we find it configured for global nscd,
1097# change to nscd-per-label and vice-versa.
1098#
1099# The user was presented with only the choice to CHANGE the existing
1100# configuration.
1101
1102manageNscd() {
1103	if [ $NSCD_PER_LABEL -eq 0 ] ; then
1104		# this MUST be a regular file for svc-nscd to detect
1105		touch $NSCD_INDICATOR
1106		NSCD_OPT="Unconfigure per-zone name service"
1107		NSCD_PER_LABEL=1
1108		for i in $(zoneadm list -i | grep -v global) ; do
1109			zoneadm -z $i halt >/dev/null 2>&1
1110			unsharePasswd $i
1111		done
1112	else
1113		rm -f $NSCD_INDICATOR
1114		NSCD_OPT="Configure per-zone name service"
1115		NSCD_PER_LABEL=0
1116		for i in $(zoneadm list -i | grep -v global) ; do
1117			zoneadm -z $i halt >/dev/null 2>&1
1118			sharePasswd $i
1119		done
1120	fi
1121}
1122
1123manageZoneNets () {
1124	ncmds[0]="Only use all-zones interfaces"
1125	ncmds[1]="Add a logical interface"
1126	ncmds[2]="Add a virtual interface (VNIC)"
1127
1128	stacks[0]="Shared Stack"
1129	stacks[1]="Exclusive Stack"
1130
1131	getAllZoneNICs
1132	netOps[0]="1\n${ncmds[0]}\nShared Stack\n${aznics[*]}"
1133
1134	integer nic_cnt=0
1135	integer netOp_cnt=2
1136
1137	set -A nics $(dladm show-phys|grep -v LINK|cut -f1 -d " ")
1138
1139	while (( nic_cnt < ${#nics[*]} )); do
1140		netOps[netOp_cnt - 1]="\n$netOp_cnt\n${ncmds[1]}\n${stacks[0]}\n${nics[nic_cnt]}"
1141		netOp_cnt+=1
1142		netOps[netOp_cnt - 1]="\n$netOp_cnt\n${ncmds[2]}\n${stacks[1]}\n${nics[nic_cnt]}"
1143		netOp_cnt+=1
1144		nic_cnt+=1
1145	done
1146
1147	netOp=$(print "${netOps[*]}"|zenity --list \
1148	    --title="$title" \
1149	    --text="$msg_getnet $zonename zone:" \
1150	    --height=300 \
1151	    --width=500 \
1152	    --column="#" \
1153	    --column="Network Configuration " \
1154	    --column="IP Type" \
1155	    --column="Available Interfaces" \
1156	    --hide-column=1
1157	)
1158
1159	# User picked cancel or no selection
1160	if [[ -z $netOp ]] ; then
1161		return
1162	fi
1163
1164	# All-zones is the default, so just return
1165	if [ $netOp = 1 ] ; then
1166		return
1167	fi
1168
1169	cmd=$(print "${netOps[$netOp - 1]}"|tr '\n' ';' |cut -d';' -f 3)
1170	nic=$(print "${netOps[$netOp - 1]}"|tr '\n' ';' |cut -d';' -f 5)
1171	case $cmd in
1172	    ${ncmds[1]} )
1173		addNet;
1174		;;
1175	    ${ncmds[2]} )
1176		zonecfg -z $zonename set ip-type=exclusive
1177		createVNIC
1178		;;
1179	esac
1180}
1181
1182manageInterface () {
1183	while (( 1 )) do
1184		getAttrs
1185
1186		# Clear list of commands
1187
1188		share=
1189		setipaddr=
1190		newlogical=
1191		newvnic=
1192		unplumb=
1193		bringup=
1194		bringdown=
1195
1196		if [ $updown = Down ] ; then
1197			bringup="Bring Up\n"
1198		else
1199			bringdown="Bring Down\n"
1200		fi
1201
1202		case $linktype in
1203		physical )
1204			newlogical="Create Logical Interface...\n";
1205			newvnic="Create Virtual Interface (VNIC)...\n";
1206			;;
1207		logical )
1208			unplumb="Remove Logical Interface\n"
1209			;;
1210		virtual )
1211			newlogical="Create Logical Interface...\n";
1212			unplumb="Remove Virtual Interface\n" ;
1213			;;
1214		esac
1215
1216		if [ $ipaddr = "..." ] ; then
1217			setipaddr="Set IP address...\n"
1218		elif [ $zone != all-zones ] ; then
1219			share="Share with Shared-IP Zones\n"
1220		else
1221			share="Remove from Shared-IP Zones\n"
1222		fi
1223
1224		command=$(print ""\
1225		    $share \
1226		    $setipaddr \
1227		    $newlogical \
1228		    $newvnic \
1229		    $unplumb \
1230		    $bringup \
1231		    $bringdown \
1232		    | zenity --list \
1233		    --title="$title" \
1234		    --text="Select a command from the list below:" \
1235		    --height=300 \
1236		    --column "Interface: $nic" )
1237
1238		case $command in
1239		    " Create Logical Interface...")
1240			createInterface;;
1241		    " Create Virtual Interface (VNIC)...")
1242			createVNIC ;;
1243		    " Set IP address...")
1244			getIPaddr
1245			addHost;;
1246		    " Share with Shared-IP Zones")
1247			shareInterface;;
1248		    " Remove from Shared-IP Zones")
1249			unshareInterface;;
1250		    " Remove Logical Interface")
1251			ifconfig $nic unplumb
1252			rm -f /etc/hostname.$nic
1253			return;;
1254		    " Remove Virtual Interface")
1255			ifconfig $nic unplumb
1256			dladm delete-vnic $nic
1257			rm -f /etc/hostname.$nic
1258			return;;
1259		    " Bring Up")
1260			ifconfig $nic up;;
1261		    " Bring Down")
1262			ifconfig $nic down;;
1263		    *) return;;
1264		esac
1265	done
1266}
1267
1268sharePrimaryNic() {
1269	set -A ip $(getent hosts $(cat /etc/nodename))
1270	for i in $(ifconfig -au4|grep  "^[a-z].*:" |grep -v LOOPBACK)
1271	do
1272		print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
1273		[ $? -eq 1 ] && continue
1274
1275		nic=${i%:} # Remove colon after interface name
1276		getAttrs
1277		if [ ${ip[0]} = $ipaddr ]; then
1278			shareInterface
1279			break
1280		fi
1281	done
1282}
1283
1284manageNets() {
1285	while (( 1 )) do
1286		attrs=
1287		for i in $(ifconfig -a4|grep  "^[a-z].*:" |grep -v LOOPBACK)
1288		do
1289			print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
1290			[ $? -eq 1 ] && continue
1291
1292			nic=${i%:} # Remove colon after interface name
1293			getAttrs
1294			attrs="$nic $linktype $zone $ipaddr $template $updown $attrs"
1295		done
1296
1297		nic=$(zenity --list \
1298		    --title="$title" \
1299		    --text="Select an interface from the list below:" \
1300		    --height=300 \
1301		    --width=500 \
1302		    --column="Interface" \
1303		    --column="Type" \
1304		    --column="Zone Name" \
1305		    --column="IP Address" \
1306		    --column="Template" \
1307		    --column="State" \
1308		    $attrs)
1309
1310		if [[ -z $nic ]] ; then
1311			return
1312		fi
1313		manageInterface
1314	done
1315}
1316
1317createLDAPclient() {
1318	ldaptitle="$title: Create LDAP Client"
1319	ldapdomain=$(zenity --entry \
1320	    --width=400 \
1321	    --title="$ldaptitle" \
1322	    --text="Enter Domain Name: ")
1323	if [[ -n $ldapdomain ]] ; then
1324	ldapserver=$(zenity --entry \
1325	    --width=400 \
1326	    --title="$ldaptitle" \
1327	    --text="Enter Hostname of LDAP Server: ")
1328	else
1329		return
1330	fi
1331	if [[ -n $ldapserver ]] ; then
1332	ldapserveraddr=$(zenity --entry \
1333	    --width=400 \
1334	    --title="$ldaptitle" \
1335	    --text="Enter IP adddress of LDAP Server $ldapserver: ")
1336	else
1337		return
1338	fi
1339	ldappassword=""
1340	while [[ -z ${ldappassword} || "x$ldappassword" != "x$ldappasswordconfirm" ]] ; do
1341	    ldappassword=$(zenity --entry \
1342		--width=400 \
1343		--title="$ldaptitle" \
1344		--hide-text \
1345		--text="Enter LDAP Proxy Password:")
1346	    ldappasswordconfirm=$(zenity --entry \
1347		--width=400 \
1348		--title="$ldaptitle" \
1349		--hide-text \
1350		--text="Confirm LDAP Proxy Password:")
1351	done
1352	ldapprofile=$(zenity --entry \
1353	    --width=400 \
1354	    --title="$ldaptitle" \
1355	    --text="Enter LDAP Profile Name: ")
1356	whatnext=$(zenity --list \
1357	    --width=400 \
1358	    --height=250 \
1359	    --title="$ldaptitle" \
1360	    --text="Proceed to create LDAP Client?" \
1361	    --column=Parameter --column=Value \
1362	    "Domain Name" "$ldapdomain" \
1363	    "Hostname" "$ldapserver" \
1364	    "IP Address" "$ldapserveraddr" \
1365	    "Password" "$(print "$ldappassword" | sed 's/./*/g')" \
1366	    "Profile" "$ldapprofile")
1367	[ $? != 0 ] && return
1368
1369	grep "^${ldapserveraddr}[^0-9]" /etc/hosts > /dev/null
1370	if [ $? -eq 1 ] ; then
1371		print "$ldapserveraddr $ldapserver" >> /etc/hosts
1372	fi
1373
1374	grep "${ldapserver}:" $TNRHDB > /dev/null
1375	if [ $? -eq 1 ] ; then
1376		print "# ${ldapserver} - ldap server" \
1377		    >> $TNRHDB
1378		print "${ldapserveraddr}:cipso" \
1379		    >> $TNRHDB
1380		tnctl -h "${ldapserveraddr}:cipso"
1381	fi
1382
1383	proxyDN=$(print $ldapdomain|awk -F"." \
1384	    "{ ORS = \"\" } { for (i = 1; i < NF; i++) print \"dc=\"\\\$i\",\" }{ print \"dc=\"\\\$NF }")
1385
1386	zenity --info \
1387	    --title="$ldaptitle" \
1388	    --width=500 \
1389	    --text="global zone will be LDAP client of $ldapserver"
1390
1391	ldapout=$TXTMP/ldapclient.$$
1392
1393	ldapclient init -a profileName="$ldapprofile" \
1394	    -a domainName="$ldapdomain" \
1395	    -a proxyDN"=cn=proxyagent,ou=profile,$proxyDN" \
1396	    -a proxyPassword="$ldappassword" \
1397	    "$ldapserveraddr" >$ldapout 2>&1
1398
1399	if [ $? -eq 0 ] ; then
1400	    ldapstatus=Success
1401	else
1402	    ldapstatus=Error
1403	fi
1404
1405	zenity --text-info \
1406	    --width=700 \
1407	    --height=300 \
1408	    --title="$ldaptitle: $ldapstatus" \
1409	    --filename=$ldapout
1410
1411	rm -f $ldapout
1412
1413
1414}
1415
1416tearDownZones() {
1417	if [ $DISP -eq 0 ] ; then
1418		if [ $FORCE -eq 0 ] ; then
1419			gettext "OK to destroy all zones [y|N]? "
1420			read ans
1421			printf "%s\n" "$ans" \
1422			    | /usr/xpg4/bin/grep -Eq "$(locale yesexpr)"
1423			if [ $? -ne 0 ] ; then
1424				gettext "canceled.\n"
1425				return 1
1426			fi
1427		fi
1428		gettext "destroying all zones ...\n"
1429	else
1430		killall=$(zenity --question \
1431		    --title="$title" \
1432		    --width=330 \
1433		    --text="$msg_confirmkill")
1434		if [[ $? != 0 ]]; then
1435			return
1436		fi
1437	fi
1438
1439	for p in $(zoneadm list -cp|grep -v global:) ; do
1440		zonename=$(echo "$p"|cut -d : -f2)
1441		if [ $DISP -eq 0 ] ; then
1442			gettext "destroying zone $zonename ...\n"
1443		fi
1444		zoneadm -z $zonename halt 1>/dev/null 2>&1
1445		zoneadm -z $zonename uninstall -F 1>/dev/null 2>&1
1446		delete -rRf
1447	done
1448	zonename=global
1449}
1450
1451createDefaultZones() {
1452	# If GUI display is not used, skip the dialog
1453	if [ $DISP -eq 0 ] ; then
1454		createDefaultPublic
1455		if [ $? -ne 0 ] ; then
1456			return 1
1457		fi
1458		createDefaultInternal
1459		return
1460	fi
1461
1462	msg_choose1=$(gettext "Choose one:")
1463	defpub=$(gettext "$PUBZONE zone only")
1464	defboth=$(gettext "$PUBZONE and $INTZONE zones")
1465	defskip=$(gettext "Main Menu...")
1466	command=$(echo ""\
1467	    "$defpub\n" \
1468	    "$defboth\n" \
1469	    "$defskip\n" \
1470	    | zenity --list \
1471	    --title="$title" \
1472	    --text="$msg_defzones" \
1473	    --column="$msg_choose1" \
1474	    --height=400 \
1475	    --width=330 )
1476
1477	case $command in
1478	    " $defpub")
1479		createDefaultPublic ;;
1480
1481	    " $defboth")
1482		createDefaultPublic
1483		if [ $? -ne 0 ] ; then
1484			return 1
1485		fi
1486		createDefaultInternal ;;
1487
1488	    *)
1489		return;;
1490	esac
1491}
1492
1493createDefaultPublic() {
1494	zonename=$PUBZONE
1495	if [ $DISP -eq 0 ] ; then
1496		gettext "creating default $zonename zone ...\n"
1497	fi
1498	newZone
1499	zone_cnt+=1
1500	hexlabel=$DEFAULTLABEL
1501	setTNdata
1502	sharePrimaryNic
1503
1504	install
1505	if [ $? -ne 0 ] ; then
1506		return 1
1507	fi
1508
1509	if [ $DISP -eq 0 ] ; then
1510		gettext "booting zone $zonename ...\n"
1511		zoneadm -z $zonename boot
1512	else
1513		zoneadm -z $zonename boot &
1514		gnome-terminal \
1515		    --disable-factory \
1516		    --title="Zone Console: $zonename $msg_continue" \
1517		    --command "zlogin -C $zonename"
1518	fi
1519}
1520
1521createDefaultInternal() {
1522	zoneadm -z $PUBZONE halt
1523
1524	zonename=snapshot
1525	newZone
1526	zone_cnt+=1
1527	zonecfg -z $zonename set autoboot=false
1528
1529	clone $PUBZONE
1530	zoneadm -z $PUBZONE boot &
1531
1532	zonename=$INTZONE
1533	if [ $DISP -eq 0 ] ; then
1534		gettext "creating default $zonename zone ...\n"
1535	fi
1536	newZone
1537	zone_cnt+=1
1538
1539	hexlabel=$INTLABEL
1540	x=$(grep -i :{$hexlabel}: $TNZONECFG)
1541	if [ $? = 0 ] ; then
1542		z=$(print $x|cut -d : -f1)
1543		echo "$msg_inuse $z zone."
1544	else
1545		setTNdata
1546	fi
1547
1548	clone snapshot
1549	if [ $DISP -eq 0 ] ; then
1550		gettext "booting zone $zonename ...\n"
1551	else
1552		gnome-terminal \
1553		    --title="Zone Console: $zonename" \
1554		    --command "zlogin -C $zonename" &
1555	fi
1556	zoneadm -z $zonename boot &
1557}
1558
1559selectZone() {
1560	set -A zonelist "global\nrunning\nADMIN_HIGH"
1561	integer zone_cnt=1
1562
1563	for p in $(zoneadm list -cp|grep -v global:) ; do
1564		zone_cnt+=1
1565	done
1566	if [ $zone_cnt == 1 ] ; then
1567		createDefaultZones
1568	fi
1569	if [ $zone_cnt == 1 ] ; then
1570		zonename=global
1571		singleZone
1572		return
1573	fi
1574
1575	zone_cnt=1
1576	for p in $(zoneadm list -cp|grep -v global:) ; do
1577		zonename=$(echo "$p"|cut -d : -f2)
1578		state=$(echo "$p"|cut -d : -f3)
1579		hexlabel=$(grep "^$zonename:" $TNZONECFG|cut -d : -f2)
1580		if [[ $hexlabel ]] ; then
1581			curlabel=$(hextoalabel $hexlabel)
1582		else
1583			curlabel=...
1584		fi
1585		zonelist[zone_cnt]="\n$zonename\n$state\n$curlabel"
1586		zone_cnt+=1
1587	done
1588	zonename=$(print "${zonelist[*]}"|zenity --list \
1589	    --title="$title" \
1590	    --text="$msg_getzone" \
1591	    --height=300 \
1592	    --width=500 \
1593	    --column="Zone Name" \
1594	    --column="Status" \
1595	    --column="Sensitivity Label" \
1596	)
1597
1598	# if the menu choice was a zonename, pop up zone menu
1599	if [[ -n $zonename ]] ; then
1600		singleZone
1601	else
1602		exit
1603	fi
1604}
1605
1606# Loop for single-zone menu
1607singleZone() {
1608
1609	while (( 1 )) do
1610		# Clear list of commands
1611
1612		console=
1613		label=
1614		start=
1615		reboot=
1616		stop=
1617		clone=
1618		install=
1619		ready=
1620		uninstall=
1621		autoboot=
1622		delete=
1623		deletenet=
1624		permitrelabel=
1625
1626		if [ $zone_cnt -gt 1 ] ; then
1627			killZones="Destroy all zones...\n"
1628			xit="Select another zone..."
1629		else
1630			killZones=
1631			xit="Exit"
1632		fi
1633		if [ $zonename = global ] ; then
1634			ldapClient="Create LDAP Client...\n"
1635			nscdOpt="$NSCD_OPT\n"
1636			createZone="Create a new zone...\n"
1637			addnet="Configure Network Interfaces...\n"
1638		else
1639			ldapClient=
1640			nscdOpt=
1641			createZone=
1642			addnet=
1643			killZones=
1644		fi
1645
1646		zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
1647
1648		consoleCheck;
1649		labelCheck;
1650		delay=0
1651
1652		if [ $zonename != global ] ; then
1653			case $zonestate in
1654				running)
1655					ready="Ready\n"
1656					reboot="Reboot\n"
1657					stop="Halt\n"
1658					;;
1659				ready)
1660					start="Boot\n"
1661					stop="Halt\n"
1662					;;
1663				installed)
1664					if [[ -z $label ]] ; then
1665						ready="Ready\n"
1666						start="Boot\n"
1667					fi
1668					uninstall="Uninstall\n"
1669					relabelCheck
1670					autobootCheck
1671					;;
1672				configured)
1673					install="Install...\n"
1674					cloneCheck
1675					delete="Delete\n"
1676					console=
1677					;;
1678				incomplete)
1679					uninstall="Uninstall\n"
1680					;;
1681				*)
1682				;;
1683			esac
1684		fi
1685
1686		command=$(echo ""\
1687		    $createZone \
1688		    $console \
1689		    $label \
1690		    $start \
1691		    $reboot \
1692		    $stop \
1693		    $clone \
1694		    $install \
1695		    $ready \
1696		    $uninstall \
1697		    $delete \
1698		    $addnet \
1699		    $deletenet \
1700		    $addremotehost \
1701		    $addcipsohost \
1702		    $removeremotehost \
1703		    $removecipsohost \
1704		    $setmlps \
1705		    $permitrelabel \
1706		    $autoboot \
1707		    $ldapClient \
1708		    $nscdOpt \
1709		    $killZones \
1710		    $xit \
1711		    | zenity --list \
1712		    --title="$title" \
1713		    --text="$msg_getcmd" \
1714		    --height=400 \
1715		    --width=330 \
1716		    --column "Zone: $zonename   Status: $zonestate" )
1717
1718		case $command in
1719		    " Create a new zone...")
1720			zonename=
1721			newZone ;;
1722
1723		    " Zone Console...")
1724			delay=2
1725			gnome-terminal \
1726			    --title="Zone Console: $zonename" \
1727			    --command "zlogin -C $zonename" & ;;
1728
1729		    " Select Label...")
1730			selectLabel;;
1731
1732		    " Ready")
1733			zoneadm -z $zonename ready ;;
1734
1735		    " Boot")
1736			zoneadm -z $zonename boot ;;
1737
1738		    " Halt")
1739			zoneadm -z $zonename halt ;;
1740
1741		    " Reboot")
1742			zoneadm -z $zonename reboot ;;
1743
1744		    " Install...")
1745			install;;
1746
1747		    " Clone...")
1748			clone ;;
1749
1750		    " Uninstall")
1751			zoneadm -z $zonename uninstall -F;;
1752
1753		    " Delete")
1754			delete
1755			return ;;
1756
1757		    " Configure Network Interfaces...")
1758			if [ $zonename = global ] ; then
1759				manageNets
1760			else
1761				manageZoneNets
1762			fi;;
1763
1764		    " Add Single-level Access to Remote Host...")
1765			addTnrhdb ;;
1766
1767		    " Add Multilevel Access to Remote Host...")
1768			template=cipso
1769			addTnrhdb ;;
1770
1771		    " Remove Single-level Access to Remote Host...")
1772			removeTnrhdb ;;
1773
1774		    " Remove Multilevel Access to Remote Host...")
1775			template=cipso
1776			removeTnrhdb ;;
1777
1778		    " Configure Multilevel Ports...")
1779			setMLPs;;
1780
1781		    " Permit Relabeling")
1782			zonecfg -z $zonename set limitpriv=default,\
1783win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,\
1784file_downgrade_sl,file_upgrade_sl,sys_trans_label ;;
1785
1786		    " Deny Relabeling")
1787			zonecfg -z $zonename set limitpriv=default ;;
1788
1789		    " Set Automatic Booting")
1790			zonecfg -z $zonename set autoboot=true ;;
1791
1792		    " Set Manual Booting")
1793			zonecfg -z $zonename set autoboot=false ;;
1794
1795		    " Create LDAP Client...")
1796			createLDAPclient ;;
1797
1798		    " Configure per-zone name service")
1799			manageNscd ;;
1800
1801		    " Unconfigure per-zone name service")
1802			manageNscd ;;
1803
1804		    " Destroy all zones...")
1805			tearDownZones
1806			return ;;
1807
1808		    *)
1809			if [ $zone_cnt == 1 ] ; then
1810				exit
1811			else
1812				return
1813			fi;;
1814		esac
1815		sleep $delay;
1816	done
1817}
1818
1819# Main loop for top-level window
1820#
1821
1822/usr/bin/plabel $$ 1>/dev/null 2>&1
1823if [ $? != 0 ] ; then
1824	gettext "$0 : Trusted Extensions must be enabled.\n"
1825	exit 1
1826fi
1827
1828myzone=$(/sbin/zonename)
1829if [ $myzone != "global" ] ; then
1830	gettext "$0 : must be in global zone to run.\n"
1831	exit 1
1832fi
1833
1834
1835process_options "$@" || exit
1836
1837mkdir $TXTMP 2>/dev/null
1838deflabel=$(chk_encodings -a|grep "Default User Sensitivity"|\
1839   sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
1840DEFAULTLABEL=$(atohexlabel ${deflabel})
1841intlabel=$(chk_encodings -a|grep "Default User Clearance"|\
1842   sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
1843INTLABEL=$(atohexlabel -c "${intlabel}")
1844
1845# are there any zfs pools?
1846ZDSET=none
1847zpool iostat 1>/dev/null 2>&1
1848if [ $? = 0 ] ; then
1849	# is there a zfs pool named "zone"?
1850	zpool list -H zone 1>/dev/null 2>&1
1851	if [ $? = 0 ] ; then
1852		# yes
1853		ZDSET=zone
1854	else
1855		# no, but is there a root pool?
1856		rootfs=$(df -n / | awk '{print $3}')
1857		if [ $rootfs = "zfs" ] ; then
1858			# yes, use it
1859			ZDSET=$(zfs list -Ho name / | cut -d/ -f 1)/zones
1860			zfs list -H $ZDSET 1>/dev/null 2>&1
1861			if [ $? = 1 ] ; then
1862				createZDSET "-o mountpoint=/zone" $ZDSET
1863			fi
1864		fi
1865	fi
1866fi
1867
1868if [ $DISP -eq 0 ] ; then
1869	gettext "non-interactive mode ...\n"
1870
1871	if [ $DESTROYZONES -eq 1 ] ; then
1872		tearDownZones
1873	fi
1874
1875	if [ $CREATEDEF -eq 1 ] ; then
1876		if [[ $(zoneadm list -c) == global ]] ; then
1877			createDefaultZones
1878		else
1879			gettext "cannot create default zones because there are existing zones.\n"
1880		fi
1881	fi
1882
1883	exit
1884fi
1885
1886if [ $NSCD_PER_LABEL -eq 0 ] ; then
1887	NSCD_OPT="Configure per-zone name service"
1888else
1889	NSCD_OPT="Unconfigure per-zone name service"
1890fi
1891
1892
1893while (( 1 )) do
1894	selectZone
1895done
1896