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