xref: /titanic_41/usr/src/cmd/tsol/misc/txzonemgr.sh (revision 5cd376e8b7030707d78315f63adb4bb2b4d9963e)
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		if [ $NSCD_PER_LABEL = 0 ] ; then
441			sharePasswd
442		else
443			unsharePasswd
444		fi
445	fi
446
447	print "security_policy=NONE" >> ${SYSIDCFG}
448	locale=$(locale|grep LANG | cut -d "=" -f2)
449	if [[ -z $locale ]] ; then
450		locale="C"
451	fi
452	print "system_locale=$locale" >> ${SYSIDCFG}
453	timezone=$(grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2)
454	print "timezone=$timezone" >> ${SYSIDCFG}
455	print "terminal=vt100" >> ${SYSIDCFG}
456	rootpwd=$(grep "^root:" /etc/shadow|cut -d : -f2)
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 [ ! -f /var/ldap/ldap_client_file ] ; then
541			if [ $NSCD_PER_LABEL = 0 ] ; then
542				sharePasswd
543			else
544				unsharePasswd
545			fi
546		fi
547		ipType=$(zonecfg -z $zonename info ip-type|cut -d" " -f2)
548		if [ $ipType = exclusive ] ; then
549			zoneadm -z $zonename ready
550			zonepath=$(zoneadm -z $zonename list -p|cut -d : -f4)
551			sys-unconfig -R $zonepath/root 2>/dev/null
552			initialize
553			zoneadm -z $zonename halt
554		fi
555	fi
556}
557
558install() {
559	removeZoneBEs
560	if [ $DISP -eq 0 ] ; then
561		gettext "installing zone $zonename ...\n"
562		zoneadm -z $zonename install
563	else
564		# sleep is needed here to avoid occasional timing
565		# problem with gnome-terminal display...
566		sleep 2
567		gnome-terminal \
568		    --title="$title: Installing $zonename zone" \
569		    --command "zoneadm -z $zonename install" \
570		    --disable-factory \
571		    --hide-menubar
572	fi
573
574	zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
575	if [ $zonestate != installed ] ; then
576		gettext "error installing zone $zonename.\n"
577		return 1
578	fi
579
580	zoneadm -z $zonename ready
581	zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
582	if [ $zonestate != ready ] ; then
583		gettext "error making zone $zonename ready.\n"
584		return 1
585	fi
586
587	initialize
588	zoneadm -z $zonename halt
589}
590
591delete() {
592	delopt=$*
593
594	# if there is an entry for this zone in tnzonecfg, remove it
595	# before deleting the zone.
596
597	tnzone=$(grep "^$zonename:" $TNZONECFG 2>/dev/null)
598	if [ -n "${tnzone}" ] ; then
599		sed -e "/^$zonename:/d" $TNZONECFG > \
600		    $TXTMP/tnzonefg.$$ 2>/dev/null
601		mv $TXTMP/tnzonefg.$$ $TNZONECFG
602	fi
603
604	for tnzone in $(grep ":${zonename}_unlab" $TNRHDB 2>/dev/null) ; do
605		tnctl -dh "$tnzone"
606		sed -e "/:${zonename}_unlab/d" $TNRHDB > \
607		    $TXTMP/tnrhdb.$$ 2>/dev/null
608		mv $TXTMP/tnrhdb.$$ $TNRHDB
609	done
610
611	for tnzone in $(grep "^${zonename}_unlab:" $TNRHTP 2>/dev/null) ; do
612		tnctl -dt ${zonename}_unlab
613		sed -e "/^${zonename}_unlab:/d" $TNRHTP > \
614		    $TXTMP/tnrhtp.$$ 2>/dev/null
615		mv $TXTMP/tnrhtp.$$ $TNRHTP
616	done
617
618	for tnzone in $(grep ":${zonename}_cipso" $TNRHDB 2>/dev/null) ; do
619		tnctl -dh "$tnzone"
620		sed -e "/:${zonename}_cipso/d" $TNRHDB > \
621		    $TXTMP/tnrhdb.$$ 2>/dev/null
622		mv $TXTMP/tnrhdb.$$ $TNRHDB
623	done
624
625	for tnzone in $(grep "^${zonename}_cipso:" $TNRHTP 2>/dev/null) ; do
626		tnctl -dt ${zonename}_cipso
627		sed -e "/^${zonename}_cipso:/d" $TNRHTP > \
628		    $TXTMP/tnrhtp.$$ 2>/dev/null
629		mv $TXTMP/tnrhtp.$$ $TNRHTP
630	done
631
632	zonecfg -z $zonename delete -F
633
634	removeZoneBEs $delopt
635	for snap in $(zfs list -Ho name -t snapshot|grep "\@${zonename}_snap") ; do
636		zfs destroy -R $snap
637	done
638}
639
640validateIPaddr () {
641	OLDIFS=$IFS
642	IFS=.
643	integer octet_cnt=0
644	integer dummy
645	set -A octets $ipaddr
646	IFS=$OLDIFS
647	if [ ${#octets[*]} == 4 ] ; then
648		while (( octet_cnt < ${#octets[*]} )); do
649			dummy=${octets[octet_cnt]}
650			if [ $dummy = ${octets[octet_cnt]} ] ; then
651				if (( dummy >= 0 && \
652				    dummy < 256 )) ; then
653					octet_cnt+=1
654					continue
655				fi
656			fi
657			x=$(zenity --error \
658			    --title="$title" \
659			    --text="$ipaddr $msg_badip")
660			ipaddr=
661			return
662		done
663	else
664		x=$(zenity --error \
665		    --title="$title" \
666		    --text="$ipaddr $msg_badip")
667		ipaddr=
668	fi
669}
670
671getAllZoneNICs(){
672	integer count=0
673	for i in $(ifconfig -a4|grep  "^[a-z].*:")
674	do
675		print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
676		[ $? -eq 1 ] && continue
677
678		i=${i%:} # Remove colon after interface name
679		for j in $(ifconfig $i)
680		do
681			case $j in
682				all-zones)
683					aznics[count]=$i
684					count+=1
685					;;
686			esac
687		done
688        done
689}
690
691getNetmask() {
692	cidr=
693	nm=$(zenity --entry \
694	    --title="$title" \
695	    --width=330 \
696	    --text="$ipaddr: Enter netmask: " \
697	    --entry-text 255.255.255.0)
698	[ $? != 0 ] && return;
699
700	cidr=$(perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm)
701}
702
703addNet() {
704	getIPaddr
705	if [[ -z $ipaddr ]] ; then
706		return;
707	fi
708	getNetmask
709	if [[ -z $cidr ]] ; then
710		return;
711	fi
712	zonecfg -z $zonename "add net; \
713	    set address=${ipaddr}/${cidr}; \
714	    set physical=$nic; \
715	    end"
716	template=${zonename}_cipso
717	cidr=32
718	updateTnrhdb
719}
720
721getAttrs() {
722	zone=global
723	type=ignore
724	for j in $(ifconfig $nic)
725	do
726		case $j in
727			inet) type=$j;;
728			zone) type=$j;;
729			all-zones) zone=all-zones;;
730			flags*) flags=$j;;
731			*) case $type in
732				inet) ipaddr=$j ;;
733				zone) zone=$j ;;
734				*) continue ;;
735			   esac;
736			   type=ignore;;
737		esac
738	done
739	if [[ $flags == ~(E).UP, ]] ; then
740		updown=Up
741	else
742		updown=Down
743	fi
744	if [[ $nic == ~(E).: ]] ; then
745		linktype=logical
746	else
747		vnic=$(dladm show-vnic -po link $nic 2>/dev/null)
748		if [[ -n $vnic ]] ; then
749			linktype=virtual
750		else
751			linktype=physical
752		fi
753	fi
754	if [ $ipaddr != 0.0.0.0 ] ; then
755		x=$(grep "^${ipaddr}[^0-9]" $TNRHDB)
756		if [ $? = 1 ] ; then
757			template=cipso
758			cidr=32
759			updateTnrhdb
760		else
761			template=$(print "$x"|cut -d : -f2)
762		fi
763	else
764		template="..."
765		ipaddr="..."
766	fi
767}
768deleteTnrhdbEntry() {
769	remote=$(grep "^${ipaddr}[^0-9]" $TNRHDB)
770	if [ $? = 0 ] ; then
771		ip=$(print $remote|cut -d "/" -f1)
772			if [[ $remote == ~(E)./ ]] ; then
773				pr=$(print $remote|cut -d "/" -f2)
774				remote="$ip\\/$pr"
775			fi
776		sed -e "/^${remote}/d" $TNRHDB > /tmp/tnrhdb.$$ 2>/dev/null
777		mv /tmp/tnrhdb.$$ $TNRHDB
778	fi
779}
780
781updateTnrhdb() {
782	deleteTnrhdbEntry
783	if [[ -n $cidr ]] ; then
784		print "${ipaddr}/$cidr:$template" >> $TNRHDB
785		tnctl -h ${ipaddr}/$cidr:$template
786	else
787		print "${ipaddr}:$template" >> $TNRHDB
788		tnctl -h ${ipaddr}:$template
789	fi
790}
791
792getIPaddr() {
793        hostname=$(zenity --entry \
794            --title="$title" \
795	    --width=330 \
796            --text="$nic: Enter Hostname: ")
797
798        [ $? != 0 ] && return
799
800	ipaddr=$(getent hosts $hostname|cut -f1)
801        if [[ -z $ipaddr ]] ; then
802		ipaddr=$(zenity --entry \
803		    --title="$title" \
804		    --text="$nic: Enter IP address: " \
805		    --entry-text a.b.c.d)
806		[ $? != 0 ] && return
807		validateIPaddr
808	fi
809
810}
811
812addHost() {
813	# Update hosts
814        if [[ -z $ipaddr ]] ; then
815               return;
816	fi
817	grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null
818	if [ $? -eq 1 ] ; then
819		print "$ipaddr\t$hostname" >> /etc/inet/hosts
820	fi
821
822	template=cipso
823	cidr=32
824	updateTnrhdb
825
826	ifconfig $nic $ipaddr netmask + broadcast +
827	#
828	# TODO: better integration with nwam
829	# TODO: get/set netmask for IP address
830	#
831	print $hostname > /etc/hostname.$nic
832}
833
834createInterface() {
835	msg=$(ifconfig $nic addif 0.0.0.0)
836	$(zenity --info \
837	    --title="$title" \
838	    --text="$msg" )
839	nic=$(print "$msg"|cut -d" " -f5)
840
841}
842
843createVNIC() {
844	if [ $zonename != global ] ; then
845		vnicname=${zonename}0
846	else
847		vnicname=$(zenity --entry \
848		    --title="$title" \
849		    --width=330 \
850		    --entry-text="" \
851		    --text="Enter VNIC Name: ")
852
853		if [[ ! -n $vnicname ]] ; then
854			return
855		fi
856	fi
857	x=$(dladm show-vnic|grep "^$vnicname " )
858	if [[ ! -n $x ]] ; then
859		dladm create-vnic -l $nic $vnicname
860	fi
861	if [ $zonename = global ] ; then
862		ifconfig $vnicname plumb
863	else
864		zonecfg -z $zonename "add net; \
865		    set physical=$vnicname; \
866		    end"
867	fi
868	nic=$vnicname
869}
870
871shareInterface() {
872	#
873	# TODO: better integration with nwam
874	#
875	ifconfig $nic all-zones;\
876	if_file=/etc/hostname.$nic
877	sed q | sed -e "s/$/ all-zones/" < $if_file >$TXTMP/txnetmgr.$$
878	mv $TXTMP/txnetmgr.$$ $if_file
879}
880
881addTnrhdb() {
882	ipaddr=$(zenity --entry \
883	    --title="$title" \
884	    --width=330 \
885	    --text="Zone:$zonename. Enter IP address of remote host or network: " \
886	    --entry-text a.b.c.d)
887	[ $? != 0 ] && return
888	validateIPaddr
889	if [[ -z $ipaddr ]] ; then
890		return;
891	fi
892	if [ ${octets[3]} = 0 ] ; then
893		nic="$ipaddr"
894		getNetmask
895		if [[ -z $cidr ]] ; then
896			return;
897		fi
898	else
899		cidr=32
900	fi
901	print "${ipaddr}/$cidr:$template" > $TXTMP/tnrhdb_new.$$
902	x=$(tnchkdb -h $TXTMP/tnrhdb_new.$$ 2>$TXTMP/syntax_error.$$)
903	if [ $? = 0 ] ; then
904		updateTnrhdb
905	else
906		syntax=$(cat $TXTMP/syntax_error.$$)
907		x=$(zenity --error \
908		    --title="$title" \
909		    --text="$syntax")
910	fi
911	rm $TXTMP/tnrhdb_new.$$
912	rm $TXTMP/syntax_error.$$
913}
914
915removeTnrhdb() {
916	while (( 1 )) do
917		remotes=$(grep "^[^#][0-9.]" $TNRHDB|grep ":$template"|cut -d : -f1-2|tr : " ")
918		if [ $template = cipso ] ; then
919			templateHeading="from All Zones":
920		else
921			templateHeading="from this Zone":
922		fi
923		if [[ -n $remotes ]] ; then
924			ipaddr=$(zenity --list \
925			    --title="$title" \
926			    --text="$msg_getremote" \
927			    --height=250 \
928			    --width=300 \
929			    --column="Remove Access to:" \
930			    --column="$templateHeading" \
931			    $remotes)
932
933			if [[ -n $ipaddr ]] ; then
934				deleteTnrhdbEntry
935				tnctl -dh ${ip}:$template
936			else
937				return
938			fi
939		else
940			return
941		fi
942	done
943}
944
945setMLPs() {
946	tnzone=$(grep "^$zonename:" $TNZONECFG 2>/dev/null)
947	zoneMLPs=:$(print "$tnzone"|cut -d : -f4)
948	sharedMLPs=:$(print "$tnzone"|cut -d : -f5)
949	attrs="Private Interfaces$zoneMLPs\nShared Interfaces$sharedMLPs"
950	ports=$(print "$attrs"|zenity --list \
951	    --title="$title" \
952	    --height=200 \
953	    --width=450 \
954	    --text="Zone: $zonename\nClick once to select, twice to edit.\nShift-click to select both rows." \
955	    --column="Multilevel Ports (example: 80-81/tcp;111/udp;)" \
956	    --editable \
957	    --multiple
958	    )
959
960	if [[ -z $ports ]] ; then
961		return
962	fi
963
964	# getopts needs another a blank and another dash
965	ports=--$(print "$ports"|sed 's/ //g'|sed 's/|/ --/g'|sed 's/Interfaces:/ :/g')
966
967	OPTIND=1
968	while getopts "z:(Private)s:(Shared)" opt $ports ; do
969		case $opt in
970			z) zoneMLPs=$OPTARG ;;
971			s) sharedMLPs=$OPTARG ;;
972		esac
973	done
974
975	sed -e "/^$zonename:*/d" $TNZONECFG > $TXTMP/tnzonecfg.$$ 2>/dev/null
976	tnzone=$(print "$tnzone"|cut -d : -f1-3)
977	echo "${tnzone}${zoneMLPs}${sharedMLPs}" >> $TXTMP/tnzonecfg.$$
978
979	x=$(tnchkdb -z $TXTMP/tnzonecfg.$$ 2>$TXTMP/syntax_error.$$)
980
981	if [ $? = 0 ] ; then
982		mv $TXTMP/tnzonecfg.$$ $TNZONECFG
983		zenity --info \
984		    --title="$title" \
985		    --text="Multilevel ports for the $zonename zone\nwill be interpreted on next reboot."
986		if [ $zonename != global ] ; then
987			getLabelRange
988		fi
989	else
990		syntax=$(cat $TXTMP/syntax_error.$$)
991		x=$(zenity --error \
992		    --title="$title" \
993		    --text="$syntax")
994		rm $TXTMP/tnzonecfg.$$
995	fi
996	rm $TXTMP/syntax_error.$$
997}
998
999unsharePasswd() {
1000	for i in $(zoneadm list -i | grep -v global) ; do
1001		zonecfg -z $i remove fs dir=/etc/passwd 2>&1 | grep -v such
1002		zonecfg -z $i remove fs dir=/etc/shadow 2>&1 | grep -v such
1003	done
1004}
1005
1006sharePasswd() {
1007	if [ $NSCD_PER_LABEL -ne 0 ] ; then
1008		return
1009	fi
1010	passwd=$(zonecfg -z $zonename info|grep /etc/passwd)
1011	if [ $? -eq 1 ] ; then
1012		zonecfg -z $zonename "add fs; \
1013		    set special=/etc/passwd; \
1014		    set dir=/etc/passwd; \
1015		    set type=lofs; \
1016		    add options ro; \
1017		    end; \
1018		    add fs; \
1019		    set special=/etc/shadow; \
1020		    set dir=/etc/shadow; \
1021		    set type=lofs; \
1022		    add options ro; \
1023		    end"
1024	fi
1025}
1026
1027# This routine is a toggle -- if we find it configured for global nscd,
1028# change to nscd-per-label and vice-versa.
1029#
1030# The user was presented with only the choice to CHANGE the existing
1031# configuration.
1032
1033manageNscd() {
1034	if [ $NSCD_PER_LABEL -eq 0 ] ; then
1035		# this MUST be a regular file for svc-nscd to detect
1036		touch $NSCD_INDICATOR
1037		NSCD_OPT="Unconfigure per-zone name service"
1038		NSCD_PER_LABEL=1
1039		unsharePasswd
1040	else
1041		rm -f $NSCD_INDICATOR
1042		NSCD_OPT="Configure per-zone name service"
1043		NSCD_PER_LABEL=0
1044		for i in $(zoneadm list -i | grep -v global) ; do
1045			zonename=$i
1046			sharePasswd
1047		done
1048		zonename=global
1049	fi
1050}
1051
1052manageZoneNets () {
1053	ncmds[0]="Only use all-zones interfaces"
1054	ncmds[1]="Add a logical interface"
1055	ncmds[2]="Add a virtual interface (VNIC)"
1056
1057	stacks[0]="Shared Stack"
1058	stacks[1]="Exclusive Stack"
1059
1060	getAllZoneNICs
1061	netOps[0]="1\n${ncmds[0]}\nShared Stack\n${aznics[*]}"
1062
1063	integer nic_cnt=0
1064	integer netOp_cnt=2
1065
1066	set -A nics $(dladm show-phys|grep -v LINK|cut -f1 -d " ")
1067
1068	while (( nic_cnt < ${#nics[*]} )); do
1069		netOps[netOp_cnt - 1]="\n$netOp_cnt\n${ncmds[1]}\n${stacks[0]}\n${nics[nic_cnt]}"
1070		netOp_cnt+=1
1071		netOps[netOp_cnt - 1]="\n$netOp_cnt\n${ncmds[2]}\n${stacks[1]}\n${nics[nic_cnt]}"
1072		netOp_cnt+=1
1073		nic_cnt+=1
1074	done
1075
1076	netOp=$(print "${netOps[*]}"|zenity --list \
1077	    --title="$title" \
1078	    --text="$msg_getnet $zonename zone:" \
1079	    --height=300 \
1080	    --width=500 \
1081	    --column="#" \
1082	    --column="Network Configuration " \
1083	    --column="IP Type" \
1084	    --column="Available Interfaces" \
1085	    --hide-column=1
1086	)
1087
1088	# User picked cancel or no selection
1089	if [[ -z $netOp ]] ; then
1090		return
1091	fi
1092
1093	# All-zones is the default, so just return
1094	if [ $netOp = 1 ] ; then
1095		return
1096	fi
1097
1098	cmd=$(print "${netOps[$netOp - 1]}"|tr '\n' ';' |cut -d';' -f 3)
1099	nic=$(print "${netOps[$netOp - 1]}"|tr '\n' ';' |cut -d';' -f 5)
1100	case $cmd in
1101	    ${ncmds[1]} )
1102		addNet;
1103		;;
1104	    ${ncmds[2]} )
1105		zonecfg -z $zonename set ip-type=exclusive
1106		createVNIC
1107		;;
1108	esac
1109}
1110
1111manageInterface () {
1112	while (( 1 )) do
1113		getAttrs
1114
1115		# Clear list of commands
1116
1117		share=
1118		setipaddr=
1119		newlogical=
1120		newvnic=
1121		unplumb=
1122		bringup=
1123		bringdown=
1124
1125		if [ $updown = Down ] ; then
1126			bringup="Bring Up\n"
1127		else
1128			bringdown="Bring Down\n"
1129		fi
1130
1131		case $linktype in
1132		physical )
1133			newlogical="Create Logical Interface...\n";
1134			newvnic="Create Virtual Interface (VNIC)...\n";
1135			;;
1136		logical )
1137			unplumb="Remove Logical Interface\n"
1138			;;
1139		virtual )
1140			newlogical="Create Logical Interface...\n";
1141			unplumb="Remove Virtual Interface\n" ;
1142			;;
1143		esac
1144
1145		if [ $ipaddr = "..." ] ; then
1146			setipaddr="Set IP address...\n"
1147		elif [ $zone != all-zones ] ; then
1148			share="Share with Shared-IP Zones\n"
1149		fi
1150
1151		command=$(print ""\
1152		    $share \
1153		    $setipaddr \
1154		    $newlogical \
1155		    $newvnic \
1156		    $unplumb \
1157		    $bringup \
1158		    $bringdown \
1159		    | zenity --list \
1160		    --title="$title" \
1161		    --text="Select a command from the list below:" \
1162		    --height=300 \
1163		    --column "Interface: $nic" )
1164
1165		case $command in
1166		    " Create Logical Interface...")
1167			createInterface;;
1168		    " Create Virtual Interface (VNIC)...")
1169			createVNIC ;;
1170		    " Set IP address...")
1171			getIPaddr
1172			addHost;;
1173		    " Share with Shared-IP Zones")
1174			shareInterface;;
1175		    " Remove Logical Interface")
1176			ifconfig $nic unplumb
1177			rm -f /etc/hostname.$nic
1178			return;;
1179		    " Remove Virtual Interface")
1180			ifconfig $nic unplumb
1181			dladm delete-vnic $nic
1182			rm -f /etc/hostname.$nic
1183			return;;
1184		    " Bring Up")
1185			ifconfig $nic up;;
1186		    " Bring Down")
1187			ifconfig $nic down;;
1188		    *) return;;
1189		esac
1190	done
1191}
1192
1193sharePrimaryNic() {
1194	set -A ip $(getent hosts $(cat /etc/nodename))
1195	for i in $(ifconfig -au4|grep  "^[a-z].*:" |grep -v LOOPBACK)
1196	do
1197		print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
1198		[ $? -eq 1 ] && continue
1199
1200		nic=${i%:} # Remove colon after interface name
1201		getAttrs
1202		if [ ${ip[0]} = $ipaddr ]; then
1203			shareInterface
1204			break
1205		fi
1206	done
1207}
1208
1209manageNets() {
1210	while (( 1 )) do
1211		attrs=
1212		for i in $(ifconfig -a4|grep  "^[a-z].*:" |grep -v LOOPBACK)
1213		do
1214			print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
1215			[ $? -eq 1 ] && continue
1216
1217			nic=${i%:} # Remove colon after interface name
1218			getAttrs
1219			attrs="$nic $linktype $zone $ipaddr $template $updown $attrs"
1220		done
1221
1222		nic=$(zenity --list \
1223		    --title="$title" \
1224		    --text="Select an interface from the list below:" \
1225		    --height=300 \
1226		    --width=500 \
1227		    --column="Interface" \
1228		    --column="Type" \
1229		    --column="Zone Name" \
1230		    --column="IP Address" \
1231		    --column="Template" \
1232		    --column="State" \
1233		    $attrs)
1234
1235		if [[ -z $nic ]] ; then
1236			return
1237		fi
1238		manageInterface
1239	done
1240}
1241
1242createLDAPclient() {
1243	ldaptitle="$title: Create LDAP Client"
1244	ldapdomain=$(zenity --entry \
1245	    --width=400 \
1246	    --title="$ldaptitle" \
1247	    --text="Enter Domain Name: ")
1248	if [[ -n $ldapdomain ]] ; then
1249	ldapserver=$(zenity --entry \
1250	    --width=400 \
1251	    --title="$ldaptitle" \
1252	    --text="Enter Hostname of LDAP Server: ")
1253	else
1254		return
1255	fi
1256	if [[ -n $ldapserver ]] ; then
1257	ldapserveraddr=$(zenity --entry \
1258	    --width=400 \
1259	    --title="$ldaptitle" \
1260	    --text="Enter IP adddress of LDAP Server $ldapserver: ")
1261	else
1262		return
1263	fi
1264	ldappassword=""
1265	while [[ -z ${ldappassword} || "x$ldappassword" != "x$ldappasswordconfirm" ]] ; do
1266	    ldappassword=$(zenity --entry \
1267		--width=400 \
1268		--title="$ldaptitle" \
1269		--hide-text \
1270		--text="Enter LDAP Proxy Password:")
1271	    ldappasswordconfirm=$(zenity --entry \
1272		--width=400 \
1273		--title="$ldaptitle" \
1274		--hide-text \
1275		--text="Confirm LDAP Proxy Password:")
1276	done
1277	ldapprofile=$(zenity --entry \
1278	    --width=400 \
1279	    --title="$ldaptitle" \
1280	    --text="Enter LDAP Profile Name: ")
1281	whatnext=$(zenity --list \
1282	    --width=400 \
1283	    --height=250 \
1284	    --title="$ldaptitle" \
1285	    --text="Proceed to create LDAP Client?" \
1286	    --column=Parameter --column=Value \
1287	    "Domain Name" "$ldapdomain" \
1288	    "Hostname" "$ldapserver" \
1289	    "IP Address" "$ldapserveraddr" \
1290	    "Password" "$(print "$ldappassword" | sed 's/./*/g')" \
1291	    "Profile" "$ldapprofile")
1292	[ $? != 0 ] && return
1293
1294	grep "^${ldapserveraddr}[^0-9]" /etc/hosts > /dev/null
1295	if [ $? -eq 1 ] ; then
1296		print "$ldapserveraddr $ldapserver" >> /etc/hosts
1297	fi
1298
1299	grep "${ldapserver}:" $TNRHDB > /dev/null
1300	if [ $? -eq 1 ] ; then
1301		print "# ${ldapserver} - ldap server" \
1302		    >> $TNRHDB
1303		print "${ldapserveraddr}:cipso" \
1304		    >> $TNRHDB
1305		tnctl -h "${ldapserveraddr}:cipso"
1306	fi
1307
1308	proxyDN=$(print $ldapdomain|awk -F"." \
1309	    "{ ORS = \"\" } { for (i = 1; i < NF; i++) print \"dc=\"\\\$i\",\" }{ print \"dc=\"\\\$NF }")
1310
1311	zenity --info \
1312	    --title="$ldaptitle" \
1313	    --width=500 \
1314	    --text="global zone will be LDAP client of $ldapserver"
1315
1316	ldapout=$TXTMP/ldapclient.$$
1317
1318	ldapclient init -a profileName="$ldapprofile" \
1319	    -a domainName="$ldapdomain" \
1320	    -a proxyDN"=cn=proxyagent,ou=profile,$proxyDN" \
1321	    -a proxyPassword="$ldappassword" \
1322	    "$ldapserveraddr" >$ldapout 2>&1
1323
1324	if [ $? -eq 0 ] ; then
1325	    ldapstatus=Success
1326	else
1327	    ldapstatus=Error
1328	fi
1329
1330	zenity --text-info \
1331	    --width=700 \
1332	    --height=300 \
1333	    --title="$ldaptitle: $ldapstatus" \
1334	    --filename=$ldapout
1335
1336	rm -f $ldapout
1337
1338
1339}
1340
1341tearDownZones() {
1342	if [ $DISP -eq 0 ] ; then
1343		if [ $FORCE -eq 0 ] ; then
1344			gettext "OK to destroy all zones [y|N]? "
1345			read ans
1346			printf "%s\n" "$ans" \
1347			    | /usr/xpg4/bin/grep -Eq "$(locale yesexpr)"
1348			if [ $? -ne 0 ] ; then
1349				gettext "canceled.\n"
1350				return 1
1351			fi
1352		fi
1353		gettext "destroying all zones ...\n"
1354	else
1355		killall=$(zenity --question \
1356		    --title="$title" \
1357		    --width=330 \
1358		    --text="$msg_confirmkill")
1359		if [[ $? != 0 ]]; then
1360			return
1361		fi
1362	fi
1363
1364	for p in $(zoneadm list -cp|grep -v global:) ; do
1365		zonename=$(echo "$p"|cut -d : -f2)
1366		if [ $DISP -eq 0 ] ; then
1367			gettext "destroying zone $zonename ...\n"
1368		fi
1369		zoneadm -z $zonename halt 1>/dev/null 2>&1
1370		zoneadm -z $zonename uninstall -F 1>/dev/null 2>&1
1371		delete -rRf
1372	done
1373	zonename=global
1374}
1375
1376createDefaultZones() {
1377	# If GUI display is not used, skip the dialog
1378	if [ $DISP -eq 0 ] ; then
1379		createDefaultPublic
1380		if [ $? -ne 0 ] ; then
1381			return 1
1382		fi
1383		createDefaultInternal
1384		return
1385	fi
1386
1387	msg_choose1=$(gettext "Choose one:")
1388	defpub=$(gettext "$PUBZONE zone only")
1389	defboth=$(gettext "$PUBZONE and $INTZONE zones")
1390	defskip=$(gettext "Main Menu...")
1391	command=$(echo ""\
1392	    "$defpub\n" \
1393	    "$defboth\n" \
1394	    "$defskip\n" \
1395	    | zenity --list \
1396	    --title="$title" \
1397	    --text="$msg_defzones" \
1398	    --column="$msg_choose1" \
1399	    --height=400 \
1400	    --width=330 )
1401
1402	case $command in
1403	    " $defpub")
1404		createDefaultPublic ;;
1405
1406	    " $defboth")
1407		createDefaultPublic
1408		if [ $? -ne 0 ] ; then
1409			return 1
1410		fi
1411		createDefaultInternal ;;
1412
1413	    *)
1414		return;;
1415	esac
1416}
1417
1418createDefaultPublic() {
1419	zonename=$PUBZONE
1420	if [ $DISP -eq 0 ] ; then
1421		gettext "creating default $zonename zone ...\n"
1422	fi
1423	newZone
1424	zone_cnt+=1
1425	hexlabel=$DEFAULTLABEL
1426	setTNdata
1427	sharePrimaryNic
1428
1429	install
1430	if [ $? -ne 0 ] ; then
1431		return 1
1432	fi
1433
1434	if [ $DISP -eq 0 ] ; then
1435		gettext "booting zone $zonename ...\n"
1436		zoneadm -z $zonename boot
1437	else
1438		zoneadm -z $zonename boot &
1439		gnome-terminal \
1440		    --disable-factory \
1441		    --title="Zone Console: $zonename $msg_continue" \
1442		    --command "zlogin -C $zonename"
1443	fi
1444}
1445
1446createDefaultInternal() {
1447	zoneadm -z $PUBZONE halt
1448
1449	zonename=snapshot
1450	newZone
1451	zone_cnt+=1
1452	zonecfg -z $zonename set autoboot=false
1453
1454	clone $PUBZONE
1455	zoneadm -z $PUBZONE boot &
1456
1457	zonename=$INTZONE
1458	if [ $DISP -eq 0 ] ; then
1459		gettext "creating default $zonename zone ...\n"
1460	fi
1461	newZone
1462	zone_cnt+=1
1463
1464	hexlabel=$INTLABEL
1465	x=$(grep -i :{$hexlabel}: $TNZONECFG)
1466	if [ $? = 0 ] ; then
1467		z=$(print $x|cut -d : -f1)
1468		echo "$msg_inuse $z zone."
1469	else
1470		setTNdata
1471	fi
1472
1473	clone snapshot
1474	if [ $DISP -eq 0 ] ; then
1475		gettext "booting zone $zonename ...\n"
1476	else
1477		gnome-terminal \
1478		    --title="Zone Console: $zonename" \
1479		    --command "zlogin -C $zonename" &
1480	fi
1481	zoneadm -z $zonename boot &
1482}
1483
1484selectZone() {
1485	set -A zonelist "global\nrunning\nADMIN_HIGH"
1486	integer zone_cnt=1
1487
1488	for p in $(zoneadm list -cp|grep -v global:) ; do
1489		zone_cnt+=1
1490	done
1491	if [ $zone_cnt == 1 ] ; then
1492		createDefaultZones
1493	fi
1494	if [ $zone_cnt == 1 ] ; then
1495		zonename=global
1496		singleZone
1497		return
1498	fi
1499
1500	zone_cnt=1
1501	for p in $(zoneadm list -cp|grep -v global:) ; do
1502		zonename=$(echo "$p"|cut -d : -f2)
1503		state=$(echo "$p"|cut -d : -f3)
1504		hexlabel=$(grep "^$zonename:" $TNZONECFG|cut -d : -f2)
1505		if [[ $hexlabel ]] ; then
1506			curlabel=$(hextoalabel $hexlabel)
1507		else
1508			curlabel=...
1509		fi
1510		zonelist[zone_cnt]="\n$zonename\n$state\n$curlabel"
1511		zone_cnt+=1
1512	done
1513	zonename=$(print "${zonelist[*]}"|zenity --list \
1514	    --title="$title" \
1515	    --text="$msg_getzone" \
1516	    --height=300 \
1517	    --width=500 \
1518	    --column="Zone Name" \
1519	    --column="Status" \
1520	    --column="Sensitivity Label" \
1521	)
1522
1523	# if the menu choice was a zonename, pop up zone menu
1524	if [[ -n $zonename ]] ; then
1525		singleZone
1526	else
1527		exit
1528	fi
1529}
1530
1531# Loop for single-zone menu
1532singleZone() {
1533
1534	while (( 1 )) do
1535		# Clear list of commands
1536
1537		console=
1538		label=
1539		start=
1540		reboot=
1541		stop=
1542		clone=
1543		install=
1544		ready=
1545		uninstall=
1546		autoboot=
1547		delete=
1548		deletenet=
1549		permitrelabel=
1550
1551		if [ $zone_cnt -gt 1 ] ; then
1552			killZones="Destroy all zones...\n"
1553			xit="Select another zone..."
1554		else
1555			killZones=
1556			xit="Exit"
1557		fi
1558		if [ $zonename = global ] ; then
1559			ldapClient="Create LDAP Client...\n"
1560			nscdOpt="$NSCD_OPT\n"
1561			createZone="Create a new zone...\n"
1562			addnet="Configure Network Interfaces...\n"
1563		else
1564			ldapClient=
1565			nscdOpt=
1566			createZone=
1567			addnet=
1568			killZones=
1569		fi
1570
1571		zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
1572
1573		consoleCheck;
1574		labelCheck;
1575		delay=0
1576
1577		if [ $zonename != global ] ; then
1578			case $zonestate in
1579				running)
1580					ready="Ready\n"
1581					reboot="Reboot\n"
1582					stop="Halt\n"
1583					;;
1584				ready)
1585					start="Boot\n"
1586					stop="Halt\n"
1587					;;
1588				installed)
1589					if [[ -z $label ]] ; then
1590						ready="Ready\n"
1591						start="Boot\n"
1592					fi
1593					uninstall="Uninstall\n"
1594					relabelCheck
1595					autobootCheck
1596					;;
1597				configured)
1598					install="Install...\n"
1599					cloneCheck
1600					delete="Delete\n"
1601					console=
1602					;;
1603				incomplete)
1604					uninstall="Uninstall\n"
1605					;;
1606				*)
1607				;;
1608			esac
1609		fi
1610
1611		command=$(echo ""\
1612		    $createZone \
1613		    $console \
1614		    $label \
1615		    $start \
1616		    $reboot \
1617		    $stop \
1618		    $clone \
1619		    $install \
1620		    $ready \
1621		    $uninstall \
1622		    $delete \
1623		    $addnet \
1624		    $deletenet \
1625		    $addremotehost \
1626		    $addcipsohost \
1627		    $removeremotehost \
1628		    $removecipsohost \
1629		    $setmlps \
1630		    $permitrelabel \
1631		    $autoboot \
1632		    $ldapClient \
1633		    $nscdOpt \
1634		    $killZones \
1635		    $xit \
1636		    | zenity --list \
1637		    --title="$title" \
1638		    --text="$msg_getcmd" \
1639		    --height=400 \
1640		    --width=330 \
1641		    --column "Zone: $zonename   Status: $zonestate" )
1642
1643		case $command in
1644		    " Create a new zone...")
1645			zonename=
1646			newZone ;;
1647
1648		    " Zone Console...")
1649			delay=2
1650			gnome-terminal \
1651			    --title="Zone Console: $zonename" \
1652			    --command "zlogin -C $zonename" & ;;
1653
1654		    " Select Label...")
1655			selectLabel;;
1656
1657		    " Ready")
1658			zoneadm -z $zonename ready ;;
1659
1660		    " Boot")
1661			zoneadm -z $zonename boot ;;
1662
1663		    " Halt")
1664			zoneadm -z $zonename halt ;;
1665
1666		    " Reboot")
1667			zoneadm -z $zonename reboot ;;
1668
1669		    " Install...")
1670			install;;
1671
1672		    " Clone...")
1673			clone ;;
1674
1675		    " Uninstall")
1676			zoneadm -z $zonename uninstall -F;;
1677
1678		    " Delete")
1679			delete
1680			return ;;
1681
1682		    " Configure Network Interfaces...")
1683			if [ $zonename = global ] ; then
1684				manageNets
1685			else
1686				manageZoneNets
1687			fi;;
1688
1689		    " Add Single-level Access to Remote Host...")
1690			addTnrhdb ;;
1691
1692		    " Add Multilevel Access to Remote Host...")
1693			template=cipso
1694			addTnrhdb ;;
1695
1696		    " Remove Single-level Access to Remote Host...")
1697			removeTnrhdb ;;
1698
1699		    " Remove Multilevel Access to Remote Host...")
1700			template=cipso
1701			removeTnrhdb ;;
1702
1703		    " Configure Multilevel Ports...")
1704			setMLPs;;
1705
1706		    " Permit Relabeling")
1707			zonecfg -z $zonename set limitpriv=default,\
1708win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,\
1709file_downgrade_sl,file_upgrade_sl,sys_trans_label ;;
1710
1711		    " Deny Relabeling")
1712			zonecfg -z $zonename set limitpriv=default ;;
1713
1714		    " Set Automatic Booting")
1715			zonecfg -z $zonename set autoboot=true ;;
1716
1717		    " Set Manual Booting")
1718			zonecfg -z $zonename set autoboot=false ;;
1719
1720		    " Create LDAP Client...")
1721			createLDAPclient ;;
1722
1723		    " Configure per-zone name service")
1724			manageNscd ;;
1725
1726		    " Unconfigure per-zone name service")
1727			manageNscd ;;
1728
1729		    " Destroy all zones...")
1730			tearDownZones
1731			return ;;
1732
1733		    *)
1734			if [ $zone_cnt == 1 ] ; then
1735				exit
1736			else
1737				return
1738			fi;;
1739		esac
1740		sleep $delay;
1741	done
1742}
1743
1744# Main loop for top-level window
1745#
1746
1747/usr/bin/plabel $$ 1>/dev/null 2>&1
1748if [ $? != 0 ] ; then
1749	gettext "$0 : Trusted Extensions must be enabled.\n"
1750	exit 1
1751fi
1752
1753myzone=$(/sbin/zonename)
1754if [ $myzone != "global" ] ; then
1755	gettext "$0 : must be in global zone to run.\n"
1756	exit 1
1757fi
1758
1759
1760process_options "$@" || exit
1761
1762mkdir $TXTMP 2>/dev/null
1763deflabel=$(chk_encodings -a|grep "Default User Sensitivity"|\
1764   sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
1765DEFAULTLABEL=$(atohexlabel ${deflabel})
1766intlabel=$(chk_encodings -a|grep "Default User Clearance"|\
1767   sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
1768INTLABEL=$(atohexlabel -c "${intlabel}")
1769
1770# are there any zfs pools?
1771ZDSET=none
1772zpool iostat 1>/dev/null 2>&1
1773if [ $? = 0 ] ; then
1774	# is there a zfs pool named "zone"?
1775	zpool list -H zone 1>/dev/null 2>&1
1776	if [ $? = 0 ] ; then
1777		# yes
1778		ZDSET=zone
1779	else
1780		# no, but is there a root pool?
1781		rootfs=$(df -n / | awk '{print $3}')
1782		if [ $rootfs = "zfs" ] ; then
1783			# yes, use it
1784			ZDSET=$(zfs list -Ho name / | cut -d/ -f 1)/zones
1785			zfs list -H $ZDSET 1>/dev/null 2>&1
1786			if [ $? = 1 ] ; then
1787				createZDSET "-o mountpoint=/zone" $ZDSET
1788			fi
1789		fi
1790	fi
1791fi
1792
1793if [ $DISP -eq 0 ] ; then
1794	gettext "non-interactive mode ...\n"
1795
1796	if [ $DESTROYZONES -eq 1 ] ; then
1797		tearDownZones
1798	fi
1799
1800	if [ $CREATEDEF -eq 1 ] ; then
1801		if [[ $(zoneadm list -c) == global ]] ; then
1802			createDefaultZones
1803		else
1804			gettext "cannot create default zones because there are existing zones.\n"
1805		fi
1806	fi
1807
1808	exit
1809fi
1810
1811if [ $NSCD_PER_LABEL -eq 0 ] ; then
1812	NSCD_OPT="Configure per-zone name service"
1813else
1814	NSCD_OPT="Unconfigure per-zone name service"
1815fi
1816
1817
1818while (( 1 )) do
1819	selectZone
1820done
1821