12848 add txzonemgr options for creating and destroying zones
authorRic Aleshire <Ric.Aleshire@Sun.COM>
Fri, 18 Dec 2009 08:33:09 -0800
changeset 1613 ad53f6457e8a
parent 1612 5494c7899186
child 1614 4dc7080bddff
12848 add txzonemgr options for creating and destroying zones
src/util/distro-import/130/txzonemgr
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/util/distro-import/130/txzonemgr	Fri Dec 18 08:33:09 2009 -0800
@@ -0,0 +1,1633 @@
+#!/bin/ksh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#
+
+# This script provides a simple GUI for managing labeled zones.
+# It takes no arguments, but provides contextual menus which
+# provide appropriate choices. It must be run in the global
+# zone as root.
+
+NSCD_PER_LABEL=0
+NSCD_INDICATOR=/var/tsol/doors/nscd_per_label
+if [ -f $NSCD_INDICATOR ] ; then
+	NSCD_PER_LABEL=1
+fi
+
+TXTMP=/tmp/txzonemgr
+TNRHTP=/etc/security/tsol/tnrhtp
+TNRHDB=/etc/security/tsol/tnrhdb
+TNZONECFG=/etc/security/tsol/tnzonecfg
+PUBZONE=public
+INTZONE=internal
+
+PATH=/usr/bin:/usr/sbin:/usr/lib export PATH
+title="Labeled Zone Manager 2.1"
+
+msg_defzones=$(gettext "Create default zones using default settings?")
+msg_confirmkill=$(gettext "OK to destroy all zones?")
+msg_continue=$(gettext "(exit to resume $(basename $0) when ready)")
+msg_getlabel=$(gettext "Select a label for the")
+msg_getremote=$(gettext "Select a remote host or network from the list below:")
+msg_getnet=$(gettext "Select a network configuration for the")
+msg_getzone=$(gettext "Select a zone from the list below:
+(select global for zone creation and shared settings)")
+msg_getcmd=$(gettext "Select a command from the list below:")
+msg_inuse=$(gettext "That label is already assigned\nto the")
+msg_getmin=$(gettext "Select the minimum network label for the")
+msg_getmax=$(gettext "Select the maximum network label for the")
+msg_badip=$(gettext " is not a valid IP address")
+
+
+consoleCheck() {
+	if [ $zonename != global ] ; then
+		zconsole=$(pgrep -f "zlogin -C $zonename")
+		if [ $? != 0 ] ; then
+			console="Zone Console...\n"
+		fi
+	fi
+}
+
+labelCheck() {
+	hexlabel=$(grep "^$zonename:" $TNZONECFG|cut -d : -f2);
+	if [[ $hexlabel ]] ; then
+		label=
+		if [ $zonename = global ] ; then
+			template="admin_low"
+			addcipsohost="Add Multilevel Access to Remote Host...\n"
+			removecipsohost="Remove Multilevel Access to Remote Host...\n"
+			setmlps="Configure Multilevel Ports...\n"
+		else
+			template=${zonename}_unlab
+			addcipsohost=
+			removecipsohost=
+			setmlps=
+
+			net=$(zonecfg -z $zonename info net)
+			if [[ -n $net ]] ; then
+				setmlps="Configure Multilevel Ports...\n"
+			elif [ $zonestate = configured ] ; then
+				addnet="Configure Network Interfaces...\n"
+			fi
+		fi
+		addremotehost="Add Single-level Access to Remote Host...\n"
+		remotes=$(grep -v "^#" $TNRHDB|grep $template)
+		if [ $? = 0 ] ; then
+			removeremotehost="Remove Single-level Access to Remote Host...\n"
+		else
+			removeremotehost=
+		fi
+	else
+		label="Select Label...\n"
+		addremotehost=
+		removeremotehost=
+		addcipsohost=
+		removecipsohost=
+		setmlps=
+	fi
+}
+
+cloneCheck() {
+	set -A zonelist
+	integer clone_cnt=0
+	for p in $(zoneadm list -ip) ; do
+		z=$(echo "$p"|cut -d : -f2)
+		s=$(echo "$p"|cut -d : -f3)
+		if [ $z = $zonename ] ; then
+			continue
+		elif [ $s = "installed" ] ; then
+			zonelist[clone_cnt]=$z
+			clone_cnt+=1
+		fi
+	done
+	if [ $clone_cnt -gt 0 ] ; then
+		clone="Clone...\n"; \
+	fi
+}
+
+relabelCheck() {
+	macstate=$(zonecfg -z $zonename info|grep win_mac_write)
+	if [[ -n $macstate ]] ; then
+		permitrelabel="Deny Relabeling\n"
+	else
+		permitrelabel="Permit Relabeling\n"
+	fi
+}
+
+autobootCheck() {
+	bootmode=$(zonecfg -z $zonename info autoboot)
+	if [[ $bootmode == 'autoboot: true' ]] ; then
+		autoboot="Set Manual Booting\n"
+	else
+		autoboot="Set Automatic Booting\n"
+	fi
+}
+
+newZone() { 
+		if [[ ! -n $zonename ]] ; then
+			zonename=$(zenity --entry \
+			    --title="$title" \
+			    --width=330 \
+			    --entry-text="" \
+			    --text="Enter Zone Name: ")
+
+			if [[ ! -n $zonename ]] ; then
+				zonename=global
+				return
+			fi
+		fi
+		zonecfg -z $zonename "create -t SUNWtsoldef;\
+		     set zonepath=/zone/$zonename"
+}
+
+removeZoneBEs() {
+	delopt=$*
+
+	zfs list -H $ZDSET/$zonename 1>/dev/null 2>&1
+	if [ $? = 0 ] ; then
+		for zbe in $(zfs list -rHo name $ZDSET/$zonename|grep ROOT/zbe) ; do
+			zfs destroy $delopt $zbe
+		done
+	fi
+}
+
+updateTemplate () {
+	if [ $hostType = cipso ] ; then
+		template=${zonename}_cipso
+		deflabel=
+	else
+		template=${zonename}_unlab
+		deflabel="def_label=${hexlabel};"
+	fi
+
+	tnzone=$(grep "^${template}:" $TNRHTP 2>/dev/null)
+	if [ $? -eq 0 ] ; then
+		sed -e "/^${template}/d" $TNRHTP > $TXTMP/tnrhtp.$$ 2>/dev/null
+		mv $TXTMP/tnrhtp.$$ $TNRHTP
+	fi
+	print "${template}:host_type=${hostType};doi=1;min_sl=${minlabel};max_sl=${maxlabel};$deflabel" >> $TNRHTP
+	tnctl -t $template
+}
+		
+setTNdata () {
+	tnzline="$zonename:${hexlabel}:0::"
+	grep "^$tnzline" $TNZONECFG 1>/dev/null 2>&1
+	if [ $? -eq 1 ] ; then
+		print "$tnzline" >> $TNZONECFG
+	fi
+
+	#
+	# Add matching entries in tnrhtp if necessary
+	#
+	minlabel=admin_low
+	maxlabel=admin_high
+	hostType=cipso
+	updateTemplate
+
+	hostType=unlabeled
+	updateTemplate
+}
+
+selectLabel() {
+	hexlabel=$(tgnome-selectlabel \
+		--title="$title" \
+		--text="$msg_getlabel $zonename zone:" \
+		--min="${DEFAULTLABEL}"  \
+		--default="${DEFAULTLABEL}"  \
+		--max=$(chk_encodings -X) \
+		--accredcheck=yes \
+		--mode=sensitivity \
+		--format=internal)
+	if [ $? = 0 ] ; then
+		x=$(grep -i :{$hexlabel}: $TNZONECFG)
+		if [ $? = 0 ] ; then
+			z=$(print $x|cut -d : -f1)
+			x=$(zenity --error \
+			    --title="$title" \
+			    --text="$msg_inuse $z zone.")
+		else
+			setTNdata
+		fi
+	fi	
+}
+
+getLabelRange() {
+	deflabel=$(hextoalabel $hexlabel)
+	minlabel=$(tgnome-selectlabel \
+		--title="$title" \
+		--text="$msg_getmin $zonename zone:" \
+		--min="${DEFAULTLABEL}"  \
+		--max="$deflabel" \
+		--default="$hexlabel" \
+		--accredcheck=no \
+		--mode=sensitivity \
+		--format=internal)
+	[ $? != 0 ] && return
+	
+	maxlabel=$(tgnome-selectlabel \
+		--title="$title" \
+		--text="$msg_getmax $zonename zone:" \
+		--min="$deflabel"  \
+		--max=$(chk_encodings -X) \
+		--default="$hexlabel" \
+		--accredcheck=no \
+		--mode=sensitivity \
+		--format=internal)
+	[ $? != 0 ] && return
+
+	hostType=cipso
+	updateTemplate
+}
+
+
+encryptionValues() {
+	echo $(zfs get 2>&1 | grep encryption | sed -e s/^.*YES// -e s/\|//g)
+}
+
+getPassphrase() {
+	pass1=$(zenity --entry --title="$title" --text="Enter passphrase:" \
+	    --width=330 --hide-text)
+	pass2=$(zenity --entry --title="$title" --text="Re-enter passphrase:" \
+	    --width=330 --hide-text)
+	if [[ "$pass1" != "$pass2" ]]; then
+		zenity --error --title="$title" \
+			--text="Passphrases do not match"
+		return ""
+	fi
+	file=$(mktemp)
+	echo "$pass1" > $file
+	echo "$file"
+}
+
+createZDSET() {
+	options=$1
+	pool=${2%%/*}
+
+	# First check if ZFS encrytption support is available
+	pversion=$(zpool list -H -o version $pool)
+	cversion=$(zpool upgrade -v | grep Crypto | awk '{ print $1 }')
+
+	if [[ $cversion == "" || $pversion -lt $cversion ]]; then
+		zfs create $options $ZDSET
+		return
+	fi
+
+	encryption=$(zenity --list --title="$title" --height=320 \
+		--text="Select cipher for encryption of all labels:" \
+		--column="encryption" $(encryptionValues))
+
+	if [[ $? != 0 || $encryption == "off" ]]; then
+		zfs create $options $ZDSET
+		return
+	fi
+
+	format=$(zenity --list --title="$title" \
+		--text "Select encryption key source:" \
+		--column="Key format and location" \
+		"Passphrase" "Generate Key in file")
+	[ $? != 0 ] && exit 
+
+	if [[ $format == "Passphrase" ]]; then
+		file=$(getPassphrase)
+		if [[ $file == "" ]]; then
+			exit
+		fi
+		keysource="passphrase,file://$file"
+		removefile=1;
+	elif [[ $format == "Generate Key in file" ]]; then
+		file=$(zenity --file-selection \
+			--title="$title: Location of key file" \
+			--save --confirm-overwrite)
+		[ $? != 0 ] && exit 
+		if [[ $encryption == "on" ]]; then
+			keylen=128
+		else
+			t=${encryption#aes-} && keylen=${t%%-*}
+		fi
+		pktool genkey keystore=file keytype=aes \
+		    keylen=$keylen outkey=$file
+		keysource="raw,file:///$file"
+	fi
+
+	options="$options -o encryption=$encryption -o keysource=$keysource"
+	zfs create $options $ZDSET
+	if [[ $removefile -eq 1 ]]; then
+		zfs set keysource=passphrase,prompt $ZDSET
+		rm $file
+	fi
+}
+
+
+initialize() {
+	zonepath=$(zoneadm -z $zonename list -p|cut -d : -f4)
+	ZONE_ETC_DIR=$zonepath/root/etc
+	SYSIDCFG=${ZONE_ETC_DIR}/sysidcfg
+
+	if [ -f /var/ldap/ldap_client_file ] ; then
+		ldapaddress=$(ldapclient list | \
+		    grep "^NS_LDAP_SERVERS" | cut -d " " -f2)
+		print "name_service=LDAP {" > ${SYSIDCFG}
+		domain=$(domainname)
+		print "domain_name=$domain" >> ${SYSIDCFG}
+		profName=$(ldapclient list | \
+		    grep "^NS_LDAP_PROFILE" | cut -d " " -f2)
+		proxyPwd=$(ldapclient list | \
+		    grep "^NS_LDAP_BINDPASSWD" | cut -d " " -f2)
+		proxyDN=$(ldapclient list | \
+		    grep "^NS_LDAP_BINDDN" | cut -d " " -f 2)
+		if [ "$proxyDN" ] ; then
+			print "proxy_dn=\"$proxyDN\"" >> ${SYSIDCFG}
+			print "proxy_password=\"$proxyPwd\"" >> ${SYSIDCFG}
+		fi
+		print "profile=$profName" >> ${SYSIDCFG}
+		print "profile_server=$ldapaddress }" >> ${SYSIDCFG}
+		cp /etc/nsswitch.conf $ZONE_ETC_DIR/nsswitch.ldap
+	else
+		print "name_service=NONE" > ${SYSIDCFG}
+		if [ $NSCD_PER_LABEL = 0 ] ; then
+			sharePasswd
+		else
+			unsharePasswd
+		fi
+	fi
+
+	print "security_policy=NONE" >> ${SYSIDCFG}
+	locale=$(locale|grep LANG | cut -d "=" -f2)
+	if [[ -z $locale ]] ; then
+		locale="C"
+	fi
+	print "system_locale=$locale" >> ${SYSIDCFG}
+	timezone=$(grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2)
+	print "timezone=$timezone" >> ${SYSIDCFG}
+	print "terminal=vt100" >> ${SYSIDCFG}
+	rootpwd=$(grep "^root:" /etc/shadow|cut -d : -f2)
+	#print "root_password=$rootpwd" >> ${SYSIDCFG}
+	print "nfs4_domain=dynamic" >> ${SYSIDCFG}
+	print "network_interface=PRIMARY {" >> ${SYSIDCFG}
+
+	net=$(zonecfg -z $zonename info net)
+	ipType=$(zonecfg -z $zonename info ip-type|cut -d" " -f2)
+	if [ $ipType = exclusive ] ; then
+		hostname=$(zenity --entry \
+		    --title="$title" \
+		    --width=330 \
+		    --text="${zonename}0: Enter Hostname or dhcp: ")
+		[ $? != 0 ] && return
+
+		if [ $hostname = dhcp ] ; then
+			print "dhcp" >> ${SYSIDCFG}
+		else
+			print "hostname=$hostname" >> ${SYSIDCFG}
+			ipaddr=$(getent hosts $hostname|cut -f1)
+			if [ $? != 0 ] ; then
+				ipaddr=$(zenity --entry \
+				    --title="$title" \
+				    --text="$nic: Enter IP address: " \
+				    --entry-text a.b.c.d)
+				[ $? != 0 ] && return
+				
+				validateIPaddr
+				if [[ -z $ipaddr ]] ; then
+					return
+				fi
+			fi
+			print "ip_address=$ipaddr" >> ${SYSIDCFG}
+			getNetmask
+			print "netmask=$nm" >> ${SYSIDCFG}
+			print "default_route=none" >> ${SYSIDCFG}
+			template=${zonename}_cipso
+			cidr=32
+			updateTnrhdb
+		fi
+	elif [[ -n $net ]] ; then
+		hostname=$(hostname)
+		hostname=$(zenity --entry \
+		    --title="$title" \
+		    --width=330 \
+		    --text="Enter Hostname: " \
+		    --entry-text $hostname)
+		[ $? != 0 ] && return
+		
+		print "hostname=$hostname" >> ${SYSIDCFG}
+		ipaddr=$(getent hosts $hostname|cut -f1)
+		if [ $? = 0 ] ; then
+			print "ip_address=$ipaddr" >> ${SYSIDCFG}
+		fi
+	else
+		getAllZoneNICs
+		for i in ${aznics[*]} ; do
+			ipaddr=$(ifconfig $i|grep inet|cut -d " " -f2)
+		done
+		print "hostname=$(hostname)" >> ${SYSIDCFG}
+		print "ip_address=$ipaddr" >> ${SYSIDCFG}
+	fi
+		
+	print "protocol_ipv6=no }" >> ${SYSIDCFG}
+	cp /etc/default/nfs ${ZONE_ETC_DIR}/default/nfs
+	touch ${ZONE_ETC_DIR}/.NFS4inst_state.domain
+}
+
+clone() {
+	msg_clone=$(gettext "Clone the $zonename zone using a snapshot
+of one of the following halted zones:")
+	image=$(zenity --list \
+	    --title="$title" \
+	    --text="$msg_clone" \
+	    --height=300 \
+	    --width=330 \
+	    --column="Installed Zones" ${zonelist[*]})
+	if [[ -n $image ]] ; then
+		removeZoneBEs
+		zoneadm -z $zonename clone $image
+
+		if [ ! -f /var/ldap/ldap_client_file ] ; then
+			if [ $NSCD_PER_LABEL = 0 ] ; then
+				sharePasswd
+			else
+				unsharePasswd
+			fi
+		fi
+		ipType=$(zonecfg -z $zonename info ip-type|cut -d" " -f2)
+		if [ $ipType = exclusive ] ; then
+			zoneadm -z $zonename ready
+			zonepath=$(zoneadm -z $zonename list -p|cut -d : -f4)
+			sys-unconfig -R $zonepath/root 2>/dev/null
+			initialize
+			zoneadm -z $zonename halt
+		fi
+	fi
+}
+
+install() {
+	removeZoneBEs
+	gnome-terminal \
+	    --title="$title: Installing $zonename zone" \
+	    --command "zoneadm -z $zonename install" \
+	    --disable-factory \
+	    --hide-menubar
+
+	zoneadm -z $zonename ready
+	initialize
+	zoneadm -z $zonename halt
+}
+
+delete() {
+	delopt=$*
+
+	# if there is an entry for this zone in tnzonecfg, remove it
+	# before deleting the zone.
+
+	tnzone=$(grep "^$zonename:" $TNZONECFG 2>/dev/null)
+	if [ -n "${tnzone}" ] ; then
+		sed -e "/^$zonename:/d" $TNZONECFG > \
+		    $TXTMP/tnzonefg.$$ 2>/dev/null
+		mv $TXTMP/tnzonefg.$$ $TNZONECFG
+	fi
+
+	for tnzone in $(grep ":${zonename}_unlab" $TNRHDB 2>/dev/null) ; do
+		tnctl -dh "$tnzone"
+		sed -e "/:${zonename}_unlab/d" $TNRHDB > \
+		    $TXTMP/tnrhdb.$$ 2>/dev/null
+		mv $TXTMP/tnrhdb.$$ $TNRHDB
+	done
+
+	for tnzone in $(grep "^${zonename}_unlab:" $TNRHTP 2>/dev/null) ; do
+		tnctl -dt ${zonename}_unlab
+		sed -e "/^${zonename}_unlab:/d" $TNRHTP > \
+		    $TXTMP/tnrhtp.$$ 2>/dev/null
+		mv $TXTMP/tnrhtp.$$ $TNRHTP
+	done
+
+	for tnzone in $(grep ":${zonename}_cipso" $TNRHDB 2>/dev/null) ; do
+		tnctl -dh "$tnzone"
+		sed -e "/:${zonename}_cipso/d" $TNRHDB > \
+		    $TXTMP/tnrhdb.$$ 2>/dev/null
+		mv $TXTMP/tnrhdb.$$ $TNRHDB
+	done
+
+	for tnzone in $(grep "^${zonename}_cipso:" $TNRHTP 2>/dev/null) ; do
+		tnctl -dt ${zonename}_cipso
+		sed -e "/^${zonename}_cipso:/d" $TNRHTP > \
+		    $TXTMP/tnrhtp.$$ 2>/dev/null
+		mv $TXTMP/tnrhtp.$$ $TNRHTP
+	done
+
+	zonecfg -z $zonename delete -F
+
+	removeZoneBEs $delopt
+	for snap in $(zfs list -Ho name -t snapshot|grep "\@${zonename}_snap") ; do
+		zfs destroy -R $snap
+	done
+}
+
+validateIPaddr () {
+	OLDIFS=$IFS
+	IFS=.
+	integer octet_cnt=0
+	integer dummy
+	set -A octets $ipaddr
+	IFS=$OLDIFS
+	if [ ${#octets[*]} == 4 ] ; then
+		while (( octet_cnt < ${#octets[*]} )); do
+			dummy=${octets[octet_cnt]}
+			if [ $dummy = ${octets[octet_cnt]} ] ; then
+				if (( $dummy >= 0 && \
+				    $dummy < 256 )) ; then
+					octet_cnt+=1
+					continue
+				fi
+			else
+				x=$(zenity --error \
+				    --title="$title" \
+				    --text="$ipaddr $msg_badip")
+				ipaddr=
+				return
+			fi
+		done
+	else
+		x=$(zenity --error \
+		    --title="$title" \
+		    --text="$ipaddr $msg_badip")
+		ipaddr=
+	fi
+}
+
+getAllZoneNICs(){
+	integer count=0
+	for i in $(ifconfig -a4|grep  "^[a-z].*:")
+	do
+		print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
+		[ $? -eq 1 ] && continue
+		
+		i=${i%:} # Remove colon after interface name
+		for j in $(ifconfig $i)
+		do
+			case $j in
+				all-zones)
+					aznics[count]=$i
+					count+=1
+					;;
+			esac
+		done
+        done
+}
+
+getNetmask() {
+	cidr=
+	nm=$(zenity --entry \
+	    --title="$title" \
+	    --width=330 \
+	    --text="$ipaddr: Enter netmask: " \
+	    --entry-text 255.255.255.0)
+	[ $? != 0 ] && return;
+
+	cidr=$(perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm)
+}
+
+addNet() {
+	getIPaddr
+	if [[ -z $ipaddr ]] ; then
+		return;
+	fi
+	getNetmask
+	if [[ -z $cidr ]] ; then
+		return;
+	fi
+	zonecfg -z $zonename "add net; \
+	    set address=${ipaddr}/${cidr}; \
+	    set physical=$nic; \
+	    end"
+	template=${zonename}_cipso
+	cidr=32
+	updateTnrhdb
+}
+
+getAttrs() {
+	zone=global
+	type=ignore
+	for j in $(ifconfig $nic)
+	do
+		case $j in
+			inet) type=$j;;
+			zone) type=$j;;
+			all-zones) zone=all-zones;;
+			flags*) flags=$j;;
+			*) case $type in
+				inet) ipaddr=$j ;;
+				zone) zone=$j ;;
+				*) continue ;;
+			   esac;
+			   type=ignore;;
+		esac
+	done
+	if [[ $flags == ~(E).UP, ]] ; then
+		updown=Up
+	else
+		updown=Down
+	fi
+	if [[ $nic == ~(E).: ]] ; then
+		linktype=logical
+	else
+		vnic=$(dladm show-vnic -po link $nic 2>/dev/null)
+		if [[ -n $vnic ]] ; then
+			linktype=virtual
+		else
+			linktype=physical
+		fi
+	fi
+	if [ $ipaddr != 0.0.0.0 ] ; then
+		x=$(grep "^${ipaddr}[^0-9]" $TNRHDB)
+		if [ $? = 1 ] ; then
+			template=cipso
+			cidr=32
+			updateTnrhdb
+		else
+			template=$(print "$x"|cut -d : -f2)
+		fi
+	else
+		template="..."
+		ipaddr="..."
+	fi
+}
+deleteTnrhdbEntry() {
+	remote=$(grep "^${ipaddr}[^0-9]" $TNRHDB)
+	if [ $? = 0 ] ; then
+		ip=$(print $remote|cut -d "/" -f1)
+			if [[ $remote == ~(E)./ ]] ; then
+				pr=$(print $remote|cut -d "/" -f2)
+				remote="$ip\\/$pr"
+			fi
+		sed -e "/^${remote}/d" $TNRHDB > /tmp/tnrhdb.$$ 2>/dev/null
+		mv /tmp/tnrhdb.$$ $TNRHDB
+	fi
+}
+
+updateTnrhdb() {
+	deleteTnrhdbEntry
+	if [[ -n $cidr ]] ; then
+		print "${ipaddr}/$cidr:$template" >> $TNRHDB
+		tnctl -h ${ipaddr}/$cidr:$template
+	else
+		print "${ipaddr}:$template" >> $TNRHDB
+		tnctl -h ${ipaddr}:$template
+	fi
+}
+
+getIPaddr() {
+        hostname=$(zenity --entry \
+            --title="$title" \
+	    --width=330 \
+            --text="$nic: Enter Hostname: ")
+
+        [ $? != 0 ] && return
+
+	ipaddr=$(getent hosts $hostname|cut -f1)
+        if [[ -z $ipaddr ]] ; then
+		ipaddr=$(zenity --entry \
+		    --title="$title" \
+		    --text="$nic: Enter IP address: " \
+		    --entry-text a.b.c.d)
+		[ $? != 0 ] && return
+		validateIPaddr
+	fi
+
+}
+
+addHost() {
+	# Update hosts
+        if [[ -z $ipaddr ]] ; then
+               return;
+	fi
+	grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null
+	if [ $? -eq 1 ] ; then
+		print "$ipaddr\t$hostname" >> /etc/inet/hosts
+	fi
+
+	template=cipso
+	cidr=32
+	updateTnrhdb
+
+	ifconfig $nic $ipaddr netmask + broadcast +
+	#
+	# TODO: better integration with nwam
+	# TODO: get/set netmask for IP address
+	#
+	print $hostname > /etc/hostname.$nic
+}
+
+createInterface() {
+	msg=$(ifconfig $nic addif 0.0.0.0)
+	$(zenity --info \
+	    --title="$title" \
+	    --text="$msg" )
+	nic=$(print "$msg"|cut -d" " -f5)
+
+}
+		    
+createVNIC() {
+	if [ $zonename != global ] ; then
+		vnicname=${zonename}0
+	else
+		vnicname=$(zenity --entry \
+		    --title="$title" \
+		    --width=330 \
+		    --entry-text="" \
+		    --text="Enter VNIC Name: ")
+
+		if [[ ! -n $vnicname ]] ; then
+			return
+		fi
+	fi
+	x=$(dladm show-vnic|grep "^$vnicname " )
+	if [[ ! -n $x ]] ; then
+		dladm create-vnic -l $nic $vnicname
+	fi
+	if [ $zonename = global ] ; then
+		ifconfig $vnicname plumb
+	else
+		zonecfg -z $zonename "add net; \
+		    set physical=$vnicname; \
+		    end"
+	fi
+	nic=$vnicname
+}
+
+shareInterface() {
+	#
+	# TODO: better integration with nwam
+	#
+	ifconfig $nic all-zones;\
+	if_file=/etc/hostname.$nic
+	sed q | sed -e "s/$/ all-zones/" < $if_file >$TXTMP/txnetmgr.$$
+	mv $TXTMP/txnetmgr.$$ $if_file
+}
+
+addTnrhdb() {
+	ipaddr=$(zenity --entry \
+	    --title="$title" \
+	    --width=330 \
+	    --text="Zone:$zonename. Enter IP address of remote host or network: " \
+	    --entry-text a.b.c.d)
+	[ $? != 0 ] && return
+	validateIPaddr
+	if [[ -z $ipaddr ]] ; then
+		return;
+	fi
+	if [ ${octets[3]} = 0 ] ; then
+		nic="$ipaddr"
+		getNetmask
+		if [[ -z $cidr ]] ; then
+			return;
+		fi
+	else
+		cidr=32
+	fi
+	print "${ipaddr}/$cidr:$template" > $TXTMP/tnrhdb_new.$$
+	x=$(tnchkdb -h $TXTMP/tnrhdb_new.$$ 2>$TXTMP/syntax_error.$$)
+	if [ $? = 0 ] ; then
+		updateTnrhdb
+	else
+		syntax=$(cat $TXTMP/syntax_error.$$)
+		x=$(zenity --error \
+		    --title="$title" \
+		    --text="$syntax")
+	fi
+	rm $TXTMP/tnrhdb_new.$$
+	rm $TXTMP/syntax_error.$$
+}
+
+removeTnrhdb() {
+	while (( 1 )) do
+		remotes=$(grep "^[^#][0-9.]" $TNRHDB|grep ":$template"|cut -d : -f1-2|tr : " ")
+		if [ $template = cipso ] ; then
+			templateHeading="from All Zones":
+		else
+			templateHeading="from this Zone":
+		fi
+		if [[ -n $remotes ]] ; then
+			ipaddr=$(zenity --list \
+			    --title="$title" \
+			    --text="$msg_getremote" \
+			    --height=250 \
+			    --width=300 \
+			    --column="Remove Access to:" \
+			    --column="$templateHeading" \
+			    $remotes)
+
+			if [[ -n $ipaddr ]] ; then
+				deleteTnrhdbEntry
+				tnctl -dh ${ip}:$template
+			else
+				return
+			fi
+		else
+			return
+		fi
+	done
+}
+
+setMLPs() {
+	tnzone=$(grep "^$zonename:" $TNZONECFG 2>/dev/null)
+	zoneMLPs=:$(print "$tnzone"|cut -d : -f4)
+	sharedMLPs=:$(print "$tnzone"|cut -d : -f5)
+	attrs="Private Interfaces$zoneMLPs\nShared Interfaces$sharedMLPs"
+	ports=$(print "$attrs"|zenity --list \
+	    --title="$title" \
+	    --height=200 \
+	    --width=450 \
+	    --text="Zone: $zonename\nClick once to select, twice to edit.\nShift-click to select both rows." \
+	    --column="Multilevel Ports (example: 80-81/tcp;111/udp;)" \
+	    --editable \
+	    --multiple
+	    )
+
+	if [[ -z $ports ]] ; then
+		return
+	fi
+
+	# getopts needs another a blank and another dash
+	ports=--$(print "$ports"|sed 's/ //g'|sed 's/|/ --/g'|sed 's/Interfaces:/ :/g')
+
+	OPTIND=1
+	while getopts "z:(Private)s:(Shared)" opt $ports ; do
+		case $opt in
+			z) zoneMLPs=$OPTARG ;;
+			s) sharedMLPs=$OPTARG ;;
+		esac
+	done
+
+	sed -e "/^$zonename:*/d" $TNZONECFG > $TXTMP/tnzonecfg.$$ 2>/dev/null
+	tnzone=$(print "$tnzone"|cut -d : -f1-3)
+	echo "${tnzone}${zoneMLPs}${sharedMLPs}" >> $TXTMP/tnzonecfg.$$
+
+	x=$(tnchkdb -z $TXTMP/tnzonecfg.$$ 2>$TXTMP/syntax_error.$$)
+
+	if [ $? = 0 ] ; then
+		mv $TXTMP/tnzonecfg.$$ $TNZONECFG
+		zenity --info \
+		    --title="$title" \
+		    --text="Multilevel ports for the $zonename zone\nwill be interpreted on next reboot."
+		if [ $zonename != global ] ; then
+			getLabelRange
+		fi
+	else
+		syntax=$(cat $TXTMP/syntax_error.$$)
+		x=$(zenity --error \
+		    --title="$title" \
+		    --text="$syntax")
+		rm $TXTMP/tnzonecfg.$$
+	fi
+	rm $TXTMP/syntax_error.$$
+}
+
+unsharePasswd() {
+	for i in $(zoneadm list -i | grep -v global) ; do
+		zonecfg -z $i remove fs dir=/etc/passwd 2>&1 | grep -v such
+		zonecfg -z $i remove fs dir=/etc/shadow 2>&1 | grep -v such
+	done
+}
+
+sharePasswd() {
+	if [ $NSCD_PER_LABEL -ne 0 ] ; then
+		return
+	fi
+	passwd=$(zonecfg -z $zonename info|grep /etc/passwd)
+	if [ $? -eq 1 ] ; then
+		zonecfg -z $zonename "add fs; \
+		    set special=/etc/passwd; \
+		    set dir=/etc/passwd; \
+		    set type=lofs; \
+		    add options ro; \
+		    end; \
+		    add fs; \
+		    set special=/etc/shadow; \
+		    set dir=/etc/shadow; \
+		    set type=lofs; \
+		    add options ro; \
+		    end"
+	fi
+}
+
+# This routine is a toggle -- if we find it configured for global nscd,
+# change to nscd-per-label and vice-versa.
+#
+# The user was presented with only the choice to CHANGE the existing
+# configuration.
+
+manageNscd() {
+	if [ $NSCD_PER_LABEL -eq 0 ] ; then
+		# this MUST be a regular file for svc-nscd to detect
+		touch $NSCD_INDICATOR
+		NSCD_OPT="Unconfigure per-zone name service"
+		NSCD_PER_LABEL=1
+		unsharePasswd
+	else
+		rm -f $NSCD_INDICATOR
+		NSCD_OPT="Configure per-zone name service"
+		NSCD_PER_LABEL=0
+		for i in $(zoneadm list -i | grep -v global) ; do
+			zonename=$i
+			sharePasswd
+		done
+		zonename=global
+	fi
+}
+
+manageZoneNets () {
+	ncmds[0]="Only use all-zones interfaces"
+	ncmds[1]="Add a logical interface"
+	ncmds[2]="Add a virtual interface (VNIC)"
+
+	stacks[0]="Shared Stack"
+	stacks[1]="Exclusive Stack"
+
+	getAllZoneNICs
+	netOps[0]="1\n${ncmds[0]}\nShared Stack\n${aznics[*]}"
+
+	integer nic_cnt=0
+	integer netOp_cnt=2
+
+	set -A nics $(dladm show-phys|grep -v LINK|cut -f1 -d " ")
+
+	while (( nic_cnt < ${#nics[*]} )); do
+		netOps[netOp_cnt - 1]="\n$netOp_cnt\n${ncmds[1]}\n${stacks[0]}\n${nics[nic_cnt]}"
+		netOp_cnt+=1
+		netOps[netOp_cnt - 1]="\n$netOp_cnt\n${ncmds[2]}\n${stacks[1]}\n${nics[nic_cnt]}"
+		netOp_cnt+=1
+		nic_cnt+=1
+	done
+
+	netOp=$(print "${netOps[*]}"|zenity --list \
+	    --title="$title" \
+	    --text="$msg_getnet $zonename zone:" \
+	    --height=300 \
+	    --width=500 \
+	    --column="#" \
+	    --column="Network Configuration " \
+	    --column="IP Type" \
+	    --column="Available Interfaces" \
+	    --hide-column=1
+	)
+	
+	# User picked cancel or no selection
+	if [[ -z $netOp ]] ; then
+		return
+	fi
+
+	# All-zones is the default, so just return
+	if [ $netOp = 1 ] ; then
+		return
+	fi
+
+	cmd=$(print "${netOps[$netOp - 1]}"|tr '\n' ';' |cut -d';' -f 3)
+	nic=$(print "${netOps[$netOp - 1]}"|tr '\n' ';' |cut -d';' -f 5) 
+	case $cmd in
+	    ${ncmds[1]} )
+		addNet;
+		;;	
+	    ${ncmds[2]} )
+		zonecfg -z $zonename set ip-type=exclusive
+		createVNIC
+		;;
+	esac
+}
+
+manageInterface () {
+	while (( 1 )) do
+		getAttrs
+
+		# Clear list of commands
+
+		share=
+		setipaddr=
+		newlogical=
+		newvnic=
+		unplumb=
+		bringup=
+		bringdown=
+
+		if [ $updown = Down ] ; then
+			bringup="Bring Up\n"
+		else
+			bringdown="Bring Down\n"
+		fi
+
+		case $linktype in
+		physical )
+			newlogical="Create Logical Interface...\n";
+			newvnic="Create Virtual Interface (VNIC)...\n";
+			;;
+		logical )
+			unplumb="Remove Logical Interface\n"
+			;;
+		virtual )
+			newlogical="Create Logical Interface...\n";
+			unplumb="Remove Virtual Interface\n" ;
+			;;
+		esac
+
+		if [ $ipaddr = "..." ] ; then
+			setipaddr="Set IP address...\n"
+		elif [ $zone != all-zones ] ; then
+			share="Share with Shared-IP Zones\n"
+		fi
+
+		command=$(print ""\
+		    $share \
+		    $setipaddr \
+		    $newlogical \
+		    $newvnic \
+		    $unplumb \
+		    $bringup \
+		    $bringdown \
+		    | zenity --list \
+		    --title="$title" \
+		    --text="Select a command from the list below:" \
+		    --height=300 \
+		    --column "Interface: $nic" )
+
+		case $command in
+		    " Create Logical Interface...")
+			createInterface;;
+		    " Create Virtual Interface (VNIC)...")
+			createVNIC ;;	
+		    " Set IP address...")
+			getIPaddr
+			addHost;;
+		    " Share with Shared-IP Zones")
+			shareInterface;;
+		    " Remove Logical Interface")
+			ifconfig $nic unplumb
+			rm -f /etc/hostname.$nic
+			return;;
+		    " Remove Virtual Interface")
+			ifconfig $nic unplumb
+			dladm delete-vnic $nic
+			rm -f /etc/hostname.$nic
+			return;;
+		    " Bring Up")
+			ifconfig $nic up;;
+		    " Bring Down")
+			ifconfig $nic down;;
+		    *) return;;
+		esac
+	done
+}
+
+sharePrimaryNic() {
+	set -A ip $(getent hosts $(cat /etc/nodename))
+	for i in $(ifconfig -au4|grep  "^[a-z].*:" |grep -v LOOPBACK)
+	do
+		print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
+		[ $? -eq 1 ] && continue
+		
+		nic=${i%:} # Remove colon after interface name
+		getAttrs
+		if [ ${ip[0]} = $ipaddr ]; then
+			shareInterface
+			break
+		fi
+	done
+}
+
+manageNets() {
+	while (( 1 )) do
+		attrs=
+		for i in $(ifconfig -a4|grep  "^[a-z].*:" |grep -v LOOPBACK)
+		do
+			print "$i" |grep "^[a-z].*:" >/dev/null 2>&1
+			[ $? -eq 1 ] && continue
+			
+			nic=${i%:} # Remove colon after interface name
+			getAttrs
+			attrs="$nic $linktype $zone $ipaddr $template $updown $attrs"
+		done
+
+		nic=$(zenity --list \
+		    --title="$title" \
+		    --text="Select an interface from the list below:" \
+		    --height=300 \
+		    --width=500 \
+		    --column="Interface" \
+		    --column="Type" \
+		    --column="Zone Name" \
+		    --column="IP Address" \
+		    --column="Template" \
+		    --column="State" \
+		    $attrs)
+
+		if [[ -z $nic ]] ; then
+			return
+		fi
+		manageInterface
+	done
+}
+
+createLDAPclient() {
+	ldaptitle="$title: Create LDAP Client"
+	ldapdomain=$(zenity --entry \
+	    --width=400 \
+	    --title="$ldaptitle" \
+	    --text="Enter Domain Name: ")
+	if [[ -n $ldapdomain ]] ; then
+	ldapserver=$(zenity --entry \
+	    --width=400 \
+	    --title="$ldaptitle" \
+	    --text="Enter Hostname of LDAP Server: ")
+	else
+		return
+	fi
+	if [[ -n $ldapserver ]] ; then
+	ldapserveraddr=$(zenity --entry \
+	    --width=400 \
+	    --title="$ldaptitle" \
+	    --text="Enter IP adddress of LDAP Server $ldapserver: ")
+	else
+		return
+	fi
+	ldappassword=""
+	while [[ -z ${ldappassword} || "x$ldappassword" != "x$ldappasswordconfirm" ]] ; do
+	    ldappassword=$(zenity --entry \
+		--width=400 \
+		--title="$ldaptitle" \
+		--hide-text \
+		--text="Enter LDAP Proxy Password:")
+	    ldappasswordconfirm=$(zenity --entry \
+		--width=400 \
+		--title="$ldaptitle" \
+		--hide-text \
+		--text="Confirm LDAP Proxy Password:")
+	done
+	ldapprofile=$(zenity --entry \
+	    --width=400 \
+	    --title="$ldaptitle" \
+	    --text="Enter LDAP Profile Name: ")
+	whatnext=$(zenity --list \
+	    --width=400 \
+	    --height=250 \
+	    --title="$ldaptitle" \
+	    --text="Proceed to create LDAP Client?" \
+	    --column=Parameter --column=Value \
+	    "Domain Name" "$ldapdomain" \
+	    "Hostname" "$ldapserver" \
+	    "IP Address" "$ldapserveraddr" \
+	    "Password" "$(print "$ldappassword" | sed 's/./*/g')" \
+	    "Profile" "$ldapprofile")
+	[ $? != 0 ] && return
+
+	grep "^${ldapserveraddr}[^0-9]" /etc/hosts > /dev/null
+	if [ $? -eq 1 ] ; then
+		print "$ldapserveraddr $ldapserver" >> /etc/hosts
+	fi
+
+	grep "${ldapserver}:" $TNRHDB > /dev/null
+	if [ $? -eq 1 ] ; then
+		print "# ${ldapserver} - ldap server" \
+		    >> $TNRHDB
+		print "${ldapserveraddr}:cipso" \
+		    >> $TNRHDB
+		tnctl -h "${ldapserveraddr}:cipso"
+	fi
+
+	proxyDN=$(print $ldapdomain|awk -F"." \
+	    "{ ORS = \"\" } { for (i = 1; i < NF; i++) print \"dc=\"\\\$i\",\" }{ print \"dc=\"\\\$NF }")
+
+	zenity --info \
+	    --title="$ldaptitle" \
+	    --width=500 \
+	    --text="global zone will be LDAP client of $ldapserver"
+
+	ldapout=$TXTMP/ldapclient.$$
+
+	ldapclient init -a profileName="$ldapprofile" \
+	    -a domainName="$ldapdomain" \
+	    -a proxyDN"=cn=proxyagent,ou=profile,$proxyDN" \
+	    -a proxyPassword="$ldappassword" \
+	    "$ldapserveraddr" >$ldapout 2>&1
+
+	if [ $? -eq 0 ] ; then
+	    ldapstatus=Success
+	else
+	    ldapstatus=Error
+	fi
+
+	zenity --text-info \
+	    --width=700 \
+	    --height=300 \
+	    --title="$ldaptitle: $ldapstatus" \
+	    --filename=$ldapout
+
+	rm -f $ldapout
+
+
+}
+
+tearDownZones() {
+	killall=$(zenity --question \
+	    --title="$title" \
+	    --width=330 \
+	    --text="$msg_confirmkill")
+	if [[ $? != 0 ]]; then
+		return
+	fi
+
+	for p in $(zoneadm list -cp|grep -v global:) ; do
+		zonename=$(echo "$p"|cut -d : -f2)
+		zoneadm -z $zonename halt 1>/dev/null 2>&1
+		zoneadm -z $zonename uninstall -F 1>/dev/null 2>&1
+		delete -rRf
+	done
+	zonename=global
+}
+
+createDefaultZones() {
+	msg_choose1=$(gettext "Choose one:")
+	defpub=$(gettext "$PUBZONE zone only")
+	defboth=$(gettext "$PUBZONE and $INTZONE zones")
+	defskip=$(gettext "Main Menu...")
+	command=$(echo ""\
+	    "$defpub\n" \
+	    "$defboth\n" \
+	    "$defskip\n" \
+	    | zenity --list \
+	    --title="$title" \
+	    --text="$msg_defzones" \
+	    --column="$msg_choose1" \
+	    --height=400 \
+	    --width=330 )
+
+	case $command in
+	    " $defpub")
+		createDefaultPublic ;;
+
+	    " $defboth")
+		createDefaultPublic
+		createDefaultInternal ;;
+
+	    *)
+		return;;
+	esac
+}
+
+createDefaultPublic() {
+	zonename=$PUBZONE
+	newZone	
+	zone_cnt+=1 
+	hexlabel=$DEFAULTLABEL
+	setTNdata
+	sharePrimaryNic
+	install
+	zoneadm -z $zonename boot &
+	gnome-terminal \
+	    --disable-factory \
+	    --title="Zone Console: $zonename $msg_continue" \
+	    --command "zlogin -C $zonename"
+}
+
+createDefaultInternal() {
+	zoneadm -z $PUBZONE halt
+
+	zonename=snapshot
+	newZone	
+	zone_cnt+=1 
+	zonecfg -z $zonename set autoboot=false
+
+	removeZoneBEs
+	zoneadm -z $zonename clone $PUBZONE
+	zoneadm -z $PUBZONE boot &
+
+	zonename=$INTZONE
+	newZone	
+	zone_cnt+=1 
+	selectLabel
+
+	removeZoneBEs
+	zoneadm -z $zonename clone snapshot
+	gnome-terminal \
+	    --title="Zone Console: $zonename" \
+	    --command "zlogin -C $zonename" &
+	zoneadm -z $zonename boot &
+}
+
+selectZone() {
+	set -A zonelist "global\nrunning\nADMIN_HIGH"
+	integer zone_cnt=1
+
+	for p in $(zoneadm list -cp|grep -v global:) ; do
+		zone_cnt+=1
+	done
+	if [ $zone_cnt == 1 ] ; then
+		createDefaultZones
+	fi
+	if [ $zone_cnt == 1 ] ; then
+		zonename=global
+		singleZone
+		return
+	fi
+
+	zone_cnt=1
+	for p in $(zoneadm list -cp|grep -v global:) ; do
+		zonename=$(echo "$p"|cut -d : -f2)
+		state=$(echo "$p"|cut -d : -f3)
+		hexlabel=$(grep "^$zonename:" $TNZONECFG|cut -d : -f2)
+		if [[ $hexlabel ]] ; then
+			curlabel=$(hextoalabel $hexlabel)
+		else
+			curlabel=...
+		fi
+		zonelist[zone_cnt]="\n$zonename\n$state\n$curlabel"
+		zone_cnt+=1
+	done
+	zonename=$(print "${zonelist[*]}"|zenity --list \
+	    --title="$title" \
+	    --text="$msg_getzone" \
+	    --height=300 \
+	    --width=500 \
+	    --column="Zone Name" \
+	    --column="Status" \
+	    --column="Sensitivity Label" \
+	)
+
+	# if the menu choice was a zonename, pop up zone menu
+	if [[ -n $zonename ]] ; then
+		singleZone
+	else
+		exit
+	fi
+}
+
+# Loop for single-zone menu
+singleZone() {
+
+	while (( 1 )) do
+		# Clear list of commands
+
+		console=
+		label=
+		start=
+		reboot=
+		stop=
+		clone=
+		install=
+		ready=
+		uninstall=
+		autoboot=
+		delete=
+		deletenet=
+		permitrelabel=
+
+		if [ $zone_cnt -gt 1 ] ; then
+			killZones="Destroy all zones...\n"
+			xit="Select another zone..."
+		else
+			killZones=
+			xit="Exit"
+		fi
+		if [ $zonename = global ] ; then
+			ldapClient="Create LDAP Client...\n"
+			nscdOpt="$NSCD_OPT\n"
+			createZone="Create a new zone...\n"
+			addnet="Configure Network Interfaces...\n"
+		else
+			ldapClient=
+			nscdOpt=
+			createZone=
+			addnet=
+			killZones=
+		fi
+
+		zonestate=$(zoneadm -z $zonename list -p | cut -d : -f 3)
+
+		consoleCheck;
+		labelCheck;
+		delay=0
+
+		if [ $zonename != global ] ; then
+			case $zonestate in
+				running)
+					ready="Ready\n"
+					reboot="Reboot\n"
+					stop="Halt\n"
+					;;
+				ready)
+					start="Boot\n"
+					stop="Halt\n"
+					;;
+				installed)
+					if [[ -z $label ]] ; then
+						ready="Ready\n"
+						start="Boot\n"
+					fi
+					uninstall="Uninstall\n"
+					relabelCheck
+					autobootCheck
+					;;
+				configured) 
+					install="Install...\n"
+					cloneCheck
+					delete="Delete\n"
+					console=
+					;;
+				incomplete)
+					uninstall="Uninstall\n"
+					;;
+				*)
+				;;
+			esac
+		fi
+
+		command=$(echo ""\
+		    $createZone \
+		    $console \
+		    $label \
+		    $start \
+		    $reboot \
+		    $stop \
+		    $clone \
+		    $install \
+		    $ready \
+		    $uninstall \
+		    $delete \
+		    $addnet \
+		    $deletenet \
+		    $addremotehost \
+		    $addcipsohost \
+		    $removeremotehost \
+		    $removecipsohost \
+		    $setmlps \
+		    $permitrelabel \
+		    $autoboot \
+		    $ldapClient \
+		    $nscdOpt \
+		    $killZones \
+		    $xit \
+		    | zenity --list \
+		    --title="$title" \
+		    --text="$msg_getcmd" \
+		    --height=400 \
+		    --width=330 \
+		    --column "Zone: $zonename   Status: $zonestate" )
+
+		case $command in
+		    " Create a new zone...")
+			zonename=
+			newZone ;;
+
+		    " Zone Console...")
+			delay=2
+			gnome-terminal \
+			    --title="Zone Console: $zonename" \
+			    --command "zlogin -C $zonename" & ;;
+
+		    " Select Label...")
+			selectLabel;;
+
+		    " Ready")
+			zoneadm -z $zonename ready ;;
+
+		    " Boot")
+			zoneadm -z $zonename boot ;;
+
+		    " Halt")
+			zoneadm -z $zonename halt ;;
+
+		    " Reboot")
+			zoneadm -z $zonename reboot ;;
+
+		    " Install...")
+			install;;
+
+		    " Clone...")
+			clone ;;
+
+		    " Uninstall")
+			zoneadm -z $zonename uninstall -F;;
+
+		    " Delete")
+			delete
+			return ;;
+
+		    " Configure Network Interfaces...")
+			if [ $zonename = global ] ; then
+				manageNets
+			else
+				manageZoneNets
+			fi;;	
+
+		    " Add Single-level Access to Remote Host...")
+			addTnrhdb ;;
+
+		    " Add Multilevel Access to Remote Host...")
+			template=cipso
+			addTnrhdb ;;
+
+		    " Remove Single-level Access to Remote Host...")
+			removeTnrhdb ;;
+
+		    " Remove Multilevel Access to Remote Host...")
+			template=cipso
+			removeTnrhdb ;;
+
+		    " Configure Multilevel Ports...")
+			setMLPs;;
+
+		    " Permit Relabeling")
+			zonecfg -z $zonename set 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 ;;
+
+		    " Deny Relabeling")
+			zonecfg -z $zonename set limitpriv=default ;;
+
+		    " Set Automatic Booting")
+			zonecfg -z $zonename set autoboot=true ;;
+
+		    " Set Manual Booting")
+			zonecfg -z $zonename set autoboot=false ;;
+
+		    " Create LDAP Client...")
+			createLDAPclient ;;
+
+		    " Configure per-zone name service")
+			manageNscd ;;
+
+		    " Unconfigure per-zone name service")
+			manageNscd ;;
+
+		    " Destroy all zones...")
+			tearDownZones
+			return ;;
+
+		    *)
+			if [ $zone_cnt == 1 ] ; then
+				exit
+			else
+				return
+			fi;;
+		esac
+		sleep $delay;
+	done
+}
+
+# Main loop for top-level window
+#
+
+mkdir $TXTMP 2>/dev/null
+deflabel=$(chk_encodings -a|grep "Default User Sensitivity"|\
+   sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
+DEFAULTLABEL=$(atohexlabel ${deflabel})
+
+# are there any zfs pools?
+ZDSET=none
+zpool iostat 1>/dev/null 2>&1
+if [ $? = 0 ] ; then
+	# is there a zfs pool named "zone"?
+	zpool list -H zone 1>/dev/null 2>&1
+	if [ $? = 0 ] ; then
+		# yes
+		ZDSET=zone
+	else
+		# no, but is there a root pool?
+		rootfs=$(df -n / | awk '{print $3}')
+		if [ $rootfs = "zfs" ] ; then
+			# yes, use it
+			ZDSET=$(zfs list -Ho name / | cut -d/ -f 1)/zones
+			zfs list -H $ZDSET 1>/dev/null 2>&1
+			if [ $? = 1 ] ; then
+				createZDSET "-o mountpoint=/zone" $ZDSET
+			fi
+		fi
+	fi
+fi
+
+if [ $NSCD_PER_LABEL -eq 0 ]  ; then
+	NSCD_OPT="Configure per-zone name service"
+else
+	NSCD_OPT="Unconfigure per-zone name service"
+fi
+
+
+while (( 1 )) do
+	selectZone
+done