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)
  42 DISP=1
  43 # CREATEDEF - make default zones (non-interactive)
  44 CREATEDEF=0
  45 # DESTROYZONES - tear down all zones (non-interactive)
  46 DESTROYZONES=0
  47 # FORCE - force
  48 FORCE=0
  49 
  50 NSCD_PER_LABEL=0
  51 NSCD_INDICATOR=/var/tsol/doors/nscd_per_label
  52 if [ -f $NSCD_INDICATOR ] ; then
  53         NSCD_PER_LABEL=1
  54 fi
  55 
  56 myname=$(basename $0)
  57 
  58 TXTMP=/tmp/txzonemgr
  59 TNRHTP=/etc/security/tsol/tnrhtp
  60 TNRHDB=/etc/security/tsol/tnrhdb
  61 TNZONECFG=/etc/security/tsol/tnzonecfg
  62 PUBZONE=public
  63 INTZONE=internal
  64 
  65 PATH=/usr/bin:/usr/sbin:/usr/lib export PATH
  66 title="Labeled Zone Manager 2.1"
  67 
  68 msg_defzones=$(gettext "Create default zones using default settings?")
  69 msg_confirmkill=$(gettext "OK to destroy all zones?")
  70 msg_continue=$(gettext "(exit to resume $(basename $0) when ready)")
  71 msg_getlabel=$(gettext "Select a label for the")
  72 msg_getremote=$(gettext "Select a remote host or network from the list below:")
  73 msg_getnet=$(gettext "Select a network configuration for the")
  74 msg_getzone=$(gettext "Select a zone from the list below:
  75 (select global for zone creation and shared settings)")
  76 msg_getcmd=$(gettext "Select a command from the list below:")
  77 msg_inuse=$(gettext "That label is already assigned\nto the")
  78 msg_getmin=$(gettext "Select the minimum network label for the")
  79 msg_getmax=$(gettext "Select the maximum network label for the")
  80 msg_badip=$(gettext " is not a valid IP address")
  81 
  82 
  83 process_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 
 132 usage() {
 133         gettext "usage: $myname [-c | -d[f]]\n"
 134 }
 135 
 136 consoleCheck() {
 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 
 145 labelCheck() {
 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 
 184 cloneCheck() {
 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 
 202 relabelCheck() {
 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 
 211 autobootCheck() {
 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 
 220 newZone() { 
 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 
 237 removeZoneBEs() {
 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 
 248 updateTemplate () {
 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                 
 266 setTNdata () {
 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 
 285 selectLabel() {
 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 
 308 getLabelRange() {
 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 
 337 encryptionValues() {
 338         echo $(zfs get 2>&1 | grep encryption | sed -e s/^.*YES// -e s/\|//g)
 339 }
 340 
 341 getPassphrase() {
 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 
 356 createZDSET() {
 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 
 414 initialize() {
 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 
 523 clone() {
 524         image=$1
 525         if [[ -z $image ]] ; then
 526                 msg_clone=$(gettext "Clone the $zonename zone using a
 527 snapshot 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 
 557 install() {
 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 
 596 delete() {
 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 
 645 validateIPaddr () {
 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 
 677 getAllZoneNICs(){
 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 
 697 getNetmask() {
 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 
 709 addNet() {
 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 
 727 getAttrs() {
 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 }
 774 deleteTnrhdbEntry() {
 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 
 787 updateTnrhdb() {
 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 
 798 getIPaddr() {
 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 
 818 addHost() {
 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 
 840 createInterface() {
 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                     
 849 createVNIC() {
 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 
 877 shareInterface() {
 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 
 887 unshareInterface() {
 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 
 897 addTnrhdb() {
 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 
 931 removeTnrhdb() {
 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 
 961 setMLPs() {
 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 
1015 enableAuthentication() {
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 
1060 unsharePasswd() {
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 
1072 sharePasswd() {
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 
1097 manageNscd() {
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 
1118 manageZoneNets () {
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 
1177 manageInterface () {
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 
1263 sharePrimaryNic() {
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 
1279 manageNets() {
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 
1312 createLDAPclient() {
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 
1411 tearDownZones() {
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 
1446 createDefaultZones() {
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 
1488 createDefaultPublic() {
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 
1516 createDefaultInternal() {
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 
1554 selectZone() {
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
1602 singleZone() {
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,\
1778 win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,\
1779 file_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
1818 if [ $? != 0 ] ; then
1819         gettext "$0 : Trusted Extensions must be enabled.\n"
1820         exit 1
1821 fi
1822 
1823 myzone=$(/sbin/zonename)
1824 if [ $myzone != "global" ] ; then
1825         gettext "$0 : must be in global zone to run.\n"
1826         exit 1
1827 fi
1828 
1829 
1830 process_options "$@" || exit
1831 
1832 mkdir $TXTMP 2>/dev/null
1833 deflabel=$(chk_encodings -a|grep "Default User Sensitivity"|\
1834    sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
1835 DEFAULTLABEL=$(atohexlabel ${deflabel})
1836 intlabel=$(chk_encodings -a|grep "Default User Clearance"|\
1837    sed 's/= /=/'|sed 's/"/'''/g|cut -d"=" -f2)
1838 INTLABEL=$(atohexlabel -c "${intlabel}")
1839 
1840 # are there any zfs pools?
1841 ZDSET=none
1842 zpool iostat 1>/dev/null 2>&1
1843 if [ $? = 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
1861 fi
1862 
1863 if [ $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
1879 fi
1880 
1881 if [ $NSCD_PER_LABEL -eq 0 ] ; then
1882         NSCD_OPT="Configure per-zone name service"
1883 else
1884         NSCD_OPT="Unconfigure per-zone name service"
1885 fi
1886 
1887 
1888 while (( 1 )) do
1889         selectZone
1890 done