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