xref: /titanic_44/usr/src/cmd/tsol/misc/txzonemgr.sh (revision 8e4728571e959f3afb368407b22125278412c9d4)
1#!/bin/pfksh
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 2007 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25#ident	"%Z%%M%	%I%	%E% SMI"
26#
27
28# This script provides a simple GUI for managing labeled zones.
29# It takes no arguments, but provides contextual menus which
30# provide appropriate choices. It must be run in the global
31# zone as root.
32
33NSCD_PER_LABEL=0
34NSCD_INDICATOR="/var/tsol/doors/nscd_per_label"
35export NSCD_PER_LABEL
36export NSCD_INDICATOR
37if [ -f $NSCD_INDICATOR ] ; then
38	NSCD_PER_LABEL=1
39fi
40PATH=/usr/bin:/usr/sbin:/usr/lib export PATH
41title="Labeled Zone Manager"
42maxlabel=`chk_encodings -X 2>/dev/null`
43if [[ ! -n $maxlabel ]]; then
44	maxlabel=0x000a-08-f8
45fi
46zonename=""
47export zonename
48config=/tmp/zfg.$$ ;
49
50consoleCheck() {
51	zconsole=`pgrep -f "zlogin -C $zonename"`
52	if [ $? != 0 ]; then
53		console="Zone Console...\n"
54	fi
55}
56
57labelCheck() {
58	hexlabel=`/bin/grep "^$zonename:" \
59	    /etc/security/tsol/tnzonecfg|cut -d ":" -f2`;
60	if [ $hexlabel ] ; then
61		label=
62		curlabel=`hextoalabel $hexlabel`
63	else
64		label="Select Label...\n"
65		curlabel=...
66	fi
67}
68
69snapshotCheck() {
70	filesystem=`zfs list |grep zone/$zonename |cut -d " " -f1`
71	if [[ -n $filesystem ]]; then
72		snapshot="Create Snapshot\n"
73	fi
74}
75
76copyCheck() {
77	zonelist=""
78	for p in `zoneadm list -ip`; do
79		q=`echo $p|cut -d ":" -f2`
80		if [ $q != $zonename ]; then
81			zonelist="$zonelist $q"
82		fi
83	done
84	if [[ -n $zonelist ]]; then
85		copy="Copy...\n"; \
86		clone="Clone\n"; \
87	fi
88}
89
90relabelCheck() {
91	macstate=`zonecfg -z $zonename info|grep win_mac_write`
92	if [[ -n $macstate ]]; then
93		permitrelabel="Deny Relabeling\n"
94	else
95		permitrelabel="Permit Relabeling\n"
96	fi
97}
98
99selectLabel() {
100	labelList=""
101	for p in `lslabels -h $maxlabel`; do
102		hexlabel=`/bin/grep :$p: /etc/security/tsol/tnzonecfg`
103		if [ $? != 0 ]; then
104			newlabel=`hextoalabel $p`
105			labelList="$labelList $newlabel\n"
106		fi
107	done
108	alabel=$(echo $labelList|zenity --list \
109	    --title="$title" \
110	    --height=300 \
111	    --width=400 \
112	    --column="Available Sensitivity Labels")
113
114	if [[ -n $alabel ]]; then
115		newlabel=`atohexlabel "$alabel" 2>null`
116		if [[ -n $newlabel ]]; then
117			echo $zonename:$newlabel:0:: >> /etc/security/tsol/tnzonecfg
118		else
119			x=$(zenity --error \
120			    --title="$title" \
121			    --text="$alabel is not valid")
122		fi
123	fi
124}
125
126resolveXdisplay() {
127	export ZONE_PATH
128	export ZONE_ETC_DIR
129	export IPNODES
130	export LIST
131	ERRORLIST=""
132	export ERRORLIST
133	# if using nscd-per-label then we have to be sure the global zone's
134	# hostname resolves because it is used for DISPLAY in X
135	ghostname=`hostname`
136	export ghostname
137
138	if [[ -n "$1" ]] ; then
139		LIST=`zoneadm list -ip | grep ":$1:"`
140	else
141		LIST=`zoneadm list -ip | grep -v "global"`
142	fi
143
144	gipaddress=`getent hosts $ghostname|cut -f1`
145	for i in $LIST; do
146		ZONE_PATH=`echo "$i" |cut -d ":" -f4`
147		ZONE_ETC_DIR=$ZONE_PATH/root/etc
148		IPNODES=${ZONE_ETC_DIR}/inet/ipnodes
149
150		# Rather than toggle on and off with NSCD_PER_LABEL, put the
151		# information in there and a sysadmin can remove it if necessary
152		# $DISPLAY will not work in X without global hostname
153		ENTRY=`grep $ghostname $IPNODES`
154		case "$ENTRY" in
155			127.0.0.1* )
156				if [[ -z $ERRORLIST ]] ; then
157					ERRORLIST="$ghostname address 127.0.0.1 found in:\n"
158				fi
159				ERRORLIST="$ERRORLIST $IPNODES\n"
160				;;
161			"")
162				gipaddress=`getent hosts $ghostname|cut -f1`
163				echo "$gipaddress\t$ghostname" >>  $IPNODES
164				;;
165			*)
166				continue
167				;;
168
169		esac
170	done
171	if [[ -n "$ERRORLIST" ]] ; then
172		x=$(zenity --error \
173		    --title="$title" \
174		    --text="WARNING:\n\n\n$ERRORLIST\n\n")
175	fi
176}
177
178clone() {
179	image=`zfs list |grep snapshot|cut -d " " -f1| \
180	    zenity --list \
181		--title="$title" \
182	        --height=300 \
183		--column="ZFS Zone Snapshots"`
184	if [[ -n $image ]]; then
185		dataset=`zfs list |grep zone/$zonename |cut -d " " -f1`
186		if [[ -n $dataset ]]; then
187			/usr/sbin/zfs destroy zone/$zonename
188		fi
189		/usr/sbin/zfs clone $image zone/$zonename
190		/usr/sbin/zoneadm -z $zonename attach -F
191		if [ ! -f /var/ldap/ldap_client_file ]; then
192			if [ $NSCD_PER_LABEL = 0 ] ; then
193				sharePasswd
194			else
195				unsharePasswd
196				resolveXdisplay
197			fi
198		fi
199	fi
200}
201
202copy() {
203
204	image=`zenity --list \
205	    --title="$title: Copy From" \
206	    --height=300 \
207	    --column="Installed Zones" $zonelist`
208
209	/usr/bin/gnome-terminal \
210	    --title="$title: Copying $image to $zonename zone" \
211	    --command "zoneadm -z $zonename clone -m copy $image" \
212	    --disable-factory \
213	    --hide-menubar
214
215	if [ ! -f /var/ldap/ldap_client_file ]; then
216		if [ $NSCD_PER_LABEL = 0 ] ; then
217			sharePasswd
218		else
219			unsharePasswd
220			resolveXdisplay
221		fi
222	fi
223}
224
225initialize() {
226	hostname=`hostname`
227	hostname=$(zenity --entry \
228	    --title="$title" \
229	    --text="Enter Host Name: " \
230	    --entry-text $hostname)
231	if [ $? != 0 ]; then
232		exit 1
233	fi
234
235	ZONE_PATH=`zoneadm list -ip|grep ":${zonename}:"|cut -d ":" -f4`
236	if [ -z "$ZONE_PATH" ] ; then
237		x=$(zenity --error \
238		    --title="$title" \
239		    --text="$zonename is not an installed zone")
240		exit 1
241	fi
242	ZONE_ETC_DIR=$ZONE_PATH/root/etc
243	ipaddress=`getent hosts $hostname|cut -f1`
244	SYSIDCFG=${ZONE_ETC_DIR}/sysidcfg
245
246	if [ -f /var/ldap/ldap_client_file ]; then
247		ldapaddress=`ldapclient list | \
248		    /bin/grep "^NS_LDAP_SERVERS" | cut -d " " -f2`
249		echo "name_service=LDAP {" > ${SYSIDCFG}
250		domain=`domainname`
251		echo "domain_name=$domain" >> ${SYSIDCFG}
252		profName=`ldapclient list | \
253		    /bin/grep "^NS_LDAP_PROFILE" | cut -d " " -f2`
254		proxyPwd=`ldapclient list | \
255		    /bin/grep "^NS_LDAP_BINDPASSWD" | cut -d " " -f2`
256		proxyDN=`ldapclient list | \
257		    /bin/grep "^NS_LDAP_BINDDN" | cut -d " " -f 2`
258		if [ "$proxyDN" ]; then
259			echo "proxy_dn=\"$proxyDN\"" >> ${SYSIDCFG}
260			echo "proxy_password=\"$proxyPwd\"" >> ${SYSIDCFG}
261		fi
262		echo "profile=$profName" >> ${SYSIDCFG}
263		echo "profile_server=$ldapaddress }" >> ${SYSIDCFG}
264		cp /etc/nsswitch.conf $ZONE_ETC_DIR/nsswitch.ldap
265	else
266		echo "name_service=NONE" > ${SYSIDCFG}
267		if [ $NSCD_PER_LABEL = 0 ] ; then
268			sharePasswd
269		else
270			# had to put resolveXdisplay lower down for this case
271			unsharePasswd
272		fi
273	fi
274
275	echo "security_policy=NONE" >> ${SYSIDCFG}
276	locale=`locale|grep LANG | cut -d "=" -f2`
277	if [[ -z $locale ]]; then
278		locale="C"
279	fi
280	echo "system_locale=$locale" >> ${SYSIDCFG}
281	timezone=`/bin/grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2`
282	echo "timezone=$timezone" >> ${SYSIDCFG}
283	echo "terminal=vt100" >> ${SYSIDCFG}
284	rootpwd=`/bin/grep "^root:" /etc/shadow|cut -d ":" -f2`
285	echo "root_password=$rootpwd" >> ${SYSIDCFG}
286	echo "network_interface=PRIMARY {" >> ${SYSIDCFG}
287	echo "protocol_ipv6=no" >> ${SYSIDCFG}
288	echo "hostname=$hostname" >> ${SYSIDCFG}
289	echo "ip_address=$ipaddress }" >> ${SYSIDCFG}
290	cp /etc/default/nfs ${ZONE_ETC_DIR}/default/nfs
291	touch ${ZONE_ETC_DIR}/.NFS4inst_state.domain
292	if [ $NSCD_PER_LABEL = 1 ] ; then
293		resolveXdisplay
294	fi
295}
296
297install() {
298	# if there is a zfs pool for zone
299	# create a new dataset for the zone
300	# This step is done automatically by zonecfg
301	# in Solaris Express 8/06 or newer
302
303	zp=`zpool list -H zone 2>/dev/null`
304	if [ $? = 0 ]; then
305		zfs create zone/$zonename
306		chmod 700 /zone/$zonename
307	fi
308
309	/usr/bin/gnome-terminal \
310	    --title="$title: Installing $zonename zone" \
311	    --command "zoneadm -z $zonename install" \
312	    --disable-factory \
313	    --hide-menubar
314
315	initialize
316}
317
318delete() {
319	# if there is an entry for this zone in tnzonecfg, remove it
320	# before deleting the zone.
321
322	tnzone=`egrep "^$zonename:" /etc/security/tsol/tnzonecfg 2>/dev/null`
323	if [ -n "${tnzone}" ]; then
324		sed -e "/^$tnzone:*/d" /etc/security/tsol/tnzonecfg > \
325		    /tmp/tnzonefg.$$ 2>/dev/null
326		mv /tmp/tnzonefg.$$ /etc/security/tsol/tnzonecfg
327	fi
328	zonecfg -z $zonename delete -F
329	zonename=
330}
331
332getNIC(){
333
334	nics=
335	for i in `ifconfig -a4|grep  "^[a-z].*:" |grep -v LOOPBACK`
336	do
337		echo $i |grep "^[a-z].*:" >/dev/null 2>&1
338		if [ $? -eq 1 ]; then
339			continue
340		fi
341		i=${i%:} # Remove colon after interface name
342		echo $i |grep ":" >/dev/null 2>&1
343		if [ $? -eq 0 ]; then
344			continue
345		fi
346		nics="$nics $i"
347	done
348
349	nic=$(zenity --list \
350	    --title="$title" \
351	    --column="Interface" \
352	    $nics)
353}
354
355getNetmask() {
356
357	cidr=
358	nm=$(zenity --entry \
359	    --title="$title" \
360	    --text="$ipaddr: Enter netmask: " \
361	    --entry-text 255.255.255.0)
362	if [ $? != 0 ]; then
363	       return;
364	fi
365
366	cidr=`perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm`
367}
368
369addNet() {
370	getNIC
371	if [[ -z $nic ]]; then
372		return;
373	fi
374	getIPaddr
375	if [[ -z $ipaddr ]]; then
376		return;
377	fi
378	getNetmask
379	if [[ -z $cidr ]]; then
380		return;
381	fi
382	zcfg="
383add net
384set address=${ipaddr}/${cidr}
385set physical=$nic
386end
387commit
388"
389	echo "$zcfg" > $config ;
390	zonecfg -z $zonename -f $config ;
391	rm $config
392}
393
394getAttrs() {
395	zone=global
396	type=ignore
397	for j in `ifconfig $nic`
398	do
399		case $j in
400			inet) type=$j;;
401			zone) type=$j;;
402			all-zones) zone=all-zones;;
403			flags*) flags=$j;;
404			*) case $type in
405				inet) ipaddr=$j ;;
406				zone) zone=$j ;;
407				*) continue ;;
408			   esac;\
409			   type=ignore;;
410		esac
411	done
412	if [ $ipaddr != 0.0.0.0 ]; then
413		template=`tninfo -h $ipaddr|grep Template| cut -d" " -f3`
414	else
415		template="..."
416		ipaddr="..."
417	fi
418}
419
420updateTnrhdb() {
421	tnctl -h ${ipaddr}:$template
422	x=`grep "^${ipaddr}[^0-9]" /etc/security/tsol/tnrhdb`
423	if [ $? = 0 ]; then
424		sed s/$x/${ipaddr}:$template/g /etc/security/tsol/tnrhdb \
425		    > /tmp/txnetmgr.$$
426		mv /tmp/txnetmgr.$$ /etc/security/tsol/tnrhdb
427	else
428		echo ${ipaddr}:$template >> /etc/security/tsol/tnrhdb
429	fi
430}
431
432getIPaddr() {
433        hostname=$(zenity --entry \
434            --title="$title" \
435            --text="$nic: Enter hostname: ")
436
437        if [ $? != 0 ]; then
438               return;
439	fi
440
441	ipaddr=`getent hosts $hostname|cut -f1`
442        if [[ -z $ipaddr ]]; then
443
444		ipaddr=$(zenity --entry \
445		    --title="$title" \
446		    --text="$nic: Enter IP address: " \
447		    --entry-text a.b.c.d)
448		if [ $? != 0 ]; then
449		       return;
450		fi
451	fi
452
453}
454
455addHost() {
456	# Update hosts and ipnodes
457        if [[ -z $ipaddr ]]; then
458               return;
459	fi
460	grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null
461	if [ $? -eq 1 ]; then
462		echo "$ipaddr\t$hostname" >> /etc/inet/hosts
463	fi
464
465	grep "^${ipaddr}[^0-9]" /etc/inet/ipnodes >/dev/null
466	if [ $? -eq 1 ]; then
467		echo "$ipaddr\t$hostname" >> /etc/inet/ipnodes
468	fi
469
470	template=cipso
471	updateTnrhdb
472
473	ifconfig $nic $ipaddr netmask + broadcast +
474	echo $hostname > /etc/hostname.$nic
475}
476
477getTemplate() {
478	templates=$(cat /etc/security/tsol/tnrhtp|\
479	    grep "^[A-z]"|grep "type=cipso"|cut -f1 -d":")
480
481	while [ 1 -gt 0 ]; do
482		t_cmd=$(zenity --list \
483		    --title="$title" \
484		    --height=300 \
485		    --column="Network Templates" \
486		    $templates)
487
488		if [ $? != 0 ]; then
489		       break;
490		fi
491
492		t_label=$(tninfo -t $t_cmd | grep sl|zenity --list \
493		    --title="$title" \
494		    --height=300 \
495		    --width=450 \
496		    --column="Click OK to associate $t_cmd template with $ipaddr" )
497
498		if [ $? != 0 ]; then
499			continue
500		fi
501		template=$t_cmd
502		updateTnrhdb
503		break
504	done
505}
506
507createInterface() {
508	msg=`ifconfig $nic addif 0.0.0.0`
509	$(zenity --info \
510	    --title="$title" \
511	    --text="$msg" )
512}
513
514shareInterface() {
515	ifconfig $nic all-zones;\
516	if_file=/etc/hostname.$nic
517	sed q | sed -e "s/$/ all-zones/" < $if_file >/tmp/txnetmgr.$$
518	mv /tmp/txnetmgr.$$ $if_file
519}
520
521setMacPrivs() {
522	zcfg="
523set limitpriv=default,win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,file_downgrade_sl,file_upgrade_sl,sys_trans_label
524commit
525"
526	echo "$zcfg" > $config ;
527	zonecfg -z $zonename -f $config ;
528	rm $config
529}
530
531resetMacPrivs() {
532	zcfg="
533set limitpriv=default
534commit
535"
536	echo "$zcfg" > $config ;
537	zonecfg -z $zonename -f $config ;
538	rm $config
539}
540
541unsharePasswd() {
542	for i in `zoneadm list -i | grep -v global`; do
543		zonecfg -z $i remove fs dir=/etc/passwd 2>&1 | grep -v such
544		zonecfg -z $i remove fs dir=/etc/shadow 2>&1 | grep -v such
545	done
546}
547
548sharePasswd() {
549	if [ $NSCD_PER_LABEL -ne 0 ] ; then
550		return
551	fi
552	passwd=`zonecfg -z $zonename info|grep /etc/passwd`
553	if [[ $? -eq 1 ]]; then
554		zcfg="
555add fs
556set special=/etc/passwd
557set dir=/etc/passwd
558set type=lofs
559add options ro
560end
561add fs
562set special=/etc/shadow
563set dir=/etc/shadow
564set type=lofs
565add options ro
566end
567commit
568"
569		echo "$zcfg" > $config ;
570		zonecfg -z $zonename -f $config ;
571		rm $config
572	fi
573}
574
575# This routine is a toggle -- if we find it configured for global nscd,
576# change to nscd-per-label and vice-versa.
577#
578# The user was presented with only the choice to CHANGE the existing
579# configuration.
580
581manageNscd() {
582	if [ $NSCD_PER_LABEL -eq 0 ] ; then
583		# this MUST be a regular file for svc-nscd to detect
584		touch $NSCD_INDICATOR
585		NSCD_PER_LABEL=1
586		unsharePasswd
587		resolveXdisplay
588	else
589		export zonename
590		rm -f $NSCD_INDICATOR
591		NSCD_PER_LABEL=0
592		for i in `zoneadm list -i | grep -v global`; do
593			zonename=$i
594			sharePasswd
595		done
596		zonename=
597	fi
598}
599
600manageNets() {
601	while [ 1 -gt 0 ]; do
602		attrs=
603		for i in `ifconfig -au4|grep  "^[a-z].*:" |grep -v LOOPBACK`
604		do
605			echo $i |grep "^[a-z].*:" >/dev/null 2>&1
606			if [ $? -eq 1 ]; then
607				continue
608			fi
609			nic=${i%:} # Remove colon after interface name
610			getAttrs
611			attrs="$nic $zone $ipaddr $template Up $attrs"
612		done
613
614		for i in `ifconfig -ad4 |grep  "^[a-z].*:" |grep -v LOOPBACK`
615		do
616			echo $i |grep "^[a-z].*:" >/dev/null 2>&1
617			if [ $? -eq 1 ]; then
618				continue
619			fi
620			nic=${i%:} # Remove colon after interface name
621			getAttrs
622			attrs="$nic $zone $ipaddr $template Down $attrs"
623		done
624
625		nic=$(zenity --list \
626		    --title="$title" \
627		    --height=300 \
628		    --width=450 \
629		    --column="Interface" \
630		    --column="Zone Name" \
631		    --column="IP Address" \
632		    --column="Template" \
633		    --column="State" \
634		    $attrs)
635
636		if [[ -z $nic ]]; then
637			return
638		fi
639
640		getAttrs
641
642		# Clear list of commands
643
644		share=
645		setipaddr=
646		settemplate=
647		newlogical=
648		unplumb=
649		bringup=
650		bringdown=
651
652		# Check for physical interface
653
654		hascolon=`echo $nic |grep :`
655		if [ $? != 0 ]; then
656			newlogical="Create Logical Interface\n";
657		else
658			up=`echo $flags|grep "UP,"`
659			if [ $? != 0 ]; then
660				unplumb="Remove Logical Interface\n"
661				if [ $ipaddr != "..." ]; then
662					bringup="Bring Up\n"
663				fi
664			else
665				bringdown="Bring Down\n"
666			fi
667		fi
668
669		if [ $ipaddr = "..." ]; then
670			setipaddr="Set IP address...\n";
671		else
672			settemplate="View Templates...\n"
673			if [ $zone = global ]; then
674				share="Share\n"
675			fi
676		fi
677
678		command=$(echo ""\
679		    $share \
680		    $setipaddr \
681		    $settemplate \
682		    $newlogical \
683		    $unplumb \
684		    $bringup \
685		    $bringdown \
686		    | zenity --list \
687		    --title="$title" \
688		    --height=300 \
689		    --column "Interface: $nic" )
690
691		case $command in
692		    " Create Logical Interface")\
693			createInterface;;
694		    " Set IP address...")\
695			getIPaddr
696			addHost;;
697		    " Share")\
698			shareInterface;;
699		    " View Templates...")\
700			getTemplate;;
701		    " Remove Logical Interface")\
702			ifconfig $nic unplumb;\
703			rm -f /etc/hostname.$nic;;
704		    " Bring Up")\
705			ifconfig $nic up;;
706		    " Bring Down")\
707			ifconfig $nic down;;
708		    *) continue;;
709		esac
710	done
711}
712
713# Loop for single-zone menu
714singleZone() {
715
716	while [ "${command}" != Exit ]; do
717		if [[ ! -n $zonename ]]; then
718			x=$(zenity --error \
719			    --title="$title" \
720			    --text="zonename \"$zonename\" is not valid")
721			return
722		fi
723		# Clear list of commands
724
725		console=
726		label=
727		start=
728		reboot=
729		stop=
730		clone=
731		copy=
732		install=
733		ready=
734		uninstall=
735		delete=
736		snapshot=
737		addnet=
738		deletenet=
739		permitrelabel=
740
741		zonestate=`zoneadm -z $zonename list -p | cut -d ":" -f 3`
742
743		consoleCheck;
744		labelCheck;
745		delay=0
746
747		case $zonestate in
748			running) ready="Ready\n"; \
749			       reboot="Reboot\n"; \
750			       stop="Halt\n"; \
751			;;
752			ready) start="Boot\n"; \
753			       stop="Halt\n" \
754			;;
755			installed)
756				if [[ -z $label ]]; then \
757					ready="Ready\n"; \
758					start="Boot\n"; \
759				fi; \
760				uninstall="Uninstall\n"; \
761				snapshotCheck; \
762				relabelCheck;
763				addnet="Add Network...\n"
764			;;
765			configured) install="Install...\n"; \
766				copyCheck; \
767				delete="Delete\n"; \
768				console=; \
769			;;
770			incomplete) delete="Delete\n"; \
771			;;
772			*)
773			;;
774		esac
775
776		command=$(echo ""\
777		    $console \
778		    $label \
779		    $start \
780		    $reboot \
781		    $stop \
782		    $clone \
783		    $copy \
784		    $install \
785		    $ready \
786		    $uninstall \
787		    $delete \
788		    $snapshot \
789		    $addnet \
790		    $deletenet \
791		    $permitrelabel \
792		    "Return to Main Menu" \
793		    | zenity --list \
794		    --title="$title" \
795		    --height=300 \
796		    --column "$zonename: $zonestate" )
797
798		case $command in
799		    " Zone Console...")
800			delay=2; \
801			/usr/bin/gnome-terminal \
802			    --title="Zone Terminal Console: $zonename" \
803			    --command "/usr/sbin/zlogin -C $zonename" &;;
804
805		    " Select Label...")
806			selectLabel;;
807
808		    " Ready")
809			zoneadm -z $zonename ready ;;
810
811		    " Boot")
812			zoneadm -z $zonename boot ;;
813
814		    " Halt")
815			zoneadm -z $zonename halt ;;
816
817		    " Reboot")
818			zoneadm -z $zonename reboot ;;
819
820		    " Install...")
821			install;;
822
823		    " Clone")
824			clone ;;
825
826		    " Copy...")
827			copy ;;
828
829		    " Uninstall")
830			zoneadm -z $zonename uninstall -F;;
831
832		    " Delete")
833			delete
834			return ;;
835
836		    " Create Snapshot")
837			zfs snapshot zone/${zonename}@snapshot;;
838
839		    " Add Network...")
840			addNet ;;
841
842		    " Permit Relabeling")
843			setMacPrivs ;;
844
845		    " Deny Relabeling")
846			resetMacPrivs ;;
847
848		    *)
849			zonename=
850			return ;;
851		esac
852		sleep $delay;
853	done
854}
855
856# Main loop for top-level window
857#
858# Always display vni0 since it is useful for cross-zone networking
859#
860ifconfig vni0 > /dev/null 2>&1
861if [ $? != 0 ]; then
862	ifconfig vni0 plumb >/dev/null 2>&1
863fi
864export NSCD_OPT
865while [ "${command}" != Exit ]; do
866	zonelist=""
867	for p in `zoneadm list -cp |grep -v global:`; do
868		zonename=`echo $p|cut -d : -f2`
869		state=`echo $p|cut -d : -f3`
870		labelCheck
871		zonelist="$zonelist$zonename\n$state\n$curlabel\n"
872	done
873
874	if [ $NSCD_PER_LABEL -eq 0 ]  ; then
875		NSCD_OPT="Configure per-zone name service"
876	else
877		NSCD_OPT="Unconfigure per-zone name service"
878	fi
879	zonelist=${zonelist}"Manage Network Interfaces...\n\n\nCreate a new zone...\n\n\n${NSCD_OPT}\n\n\nExit\n\n"
880
881	zonename=""
882	topcommand=$(echo $zonelist|zenity --list \
883	    --title="$title" \
884	    --height=300 \
885	    --width=500 \
886	    --column="Zone Name" \
887	    --column="Status" \
888	    --column="Sensitivity Label" \
889	    )
890
891	if [[ ! -n $topcommand ]]; then
892		command=Exit
893		exit
894	fi
895
896	if [ "$topcommand" = "$NSCD_OPT" ]; then
897		topcommand=
898		manageNscd
899		continue
900	elif [ "$topcommand" = "Manage Network Interfaces..." ]; then
901		topcommand=
902		manageNets
903		continue
904	elif [ "$topcommand" = "Exit" ]; then
905		command=Exit
906		exit
907	elif [ "$topcommand" = "Create a new zone..." ]; then
908		zonename=$(zenity --entry \
909		    --title="$title" \
910		    --entry-text="" \
911		    --text="Enter Zone Name: ")
912
913		if [[ ! -n $zonename ]]; then
914			continue
915		fi
916
917		zcfg="
918create -t SUNWtsoldef
919set zonepath=/zone/$zonename
920commit
921"
922		echo "$zcfg" > $config ;
923		zonecfg -z $zonename -f $config ;
924		rm $config
925		# Now, go to the singleZone menu, using the global
926		# variable zonename, and continue with zone creation
927		singleZone
928		continue
929	fi
930	# if the menu choice was a zonename, pop up zone menu
931	zonename=$topcommand
932	singleZone
933done
934