1#!/bin/pfksh 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22# Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23# Use is subject to license terms. 24# 25#ident "%Z%%M% %I% %E% SMI" 26# 27 28# This script provides a simple GUI for managing labeled zones. 29# It takes no arguments, but provides contextual menus which 30# provide appropriate choices. It must be run in the global 31# zone as root. 32 33PATH=/usr/bin:/usr/sbin:/usr/lib export PATH 34title="Labeled Zone Manager" 35maxlabel=`chk_encodings -X 2>/dev/null` 36if [[ ! -n $maxlabel ]]; then 37 maxlabel=0x000a-08-f8 38fi 39config=/tmp/zfg.$$ ; 40 41consoleCheck() { 42 zconsole=`pgrep -f "zlogin -C $zonename"` 43 if [ $? != 0 ]; then 44 console="Zone Console...\n" 45 fi 46} 47 48labelCheck() { 49 hexlabel=`/bin/grep "^$zonename:" \ 50 /etc/security/tsol/tnzonecfg|cut -d ":" -f2`; 51 if [ $hexlabel ] ; then 52 label= 53 curlabel=`hextoalabel $hexlabel` 54 else 55 label="Select Label...\n" 56 curlabel=... 57 fi 58} 59 60snapshotCheck() { 61 filesystem=`zfs list |grep zone/$zonename |cut -d " " -f1` 62 if [[ -n $filesystem ]]; then 63 snapshot="Create Snapshot\n" 64 fi 65} 66 67copyCheck() { 68 zonelist="" 69 for p in `zoneadm list -ip`; do 70 q=`echo $p|cut -d ":" -f2` 71 if [ $q != $zonename ]; then 72 zonelist="$zonelist $q" 73 fi 74 done 75 if [[ -n $zonelist ]]; then 76 copy="Copy...\n"; \ 77 clone="Clone\n"; \ 78 fi 79} 80 81relabelCheck() { 82 macstate=`zonecfg -z $zonename info|grep win_mac_write` 83 if [[ -n $macstate ]]; then 84 permitrelabel="Deny Relabeling\n" 85 else 86 permitrelabel="Permit Relabeling\n" 87 fi 88} 89 90selectLabel() { 91 labelList="" 92 for p in `lslabels -h $maxlabel`; do 93 hexlabel=`/bin/grep :$p: /etc/security/tsol/tnzonecfg` 94 if [ $? != 0 ]; then 95 newlabel=`hextoalabel $p` 96 labelList="$labelList $newlabel\n" 97 fi 98 done 99 alabel=$(echo $labelList|zenity --list \ 100 --title="$title" \ 101 --height=300 \ 102 --width=400 \ 103 --column="Available Sensitivity Labels") 104 105 if [[ -n $alabel ]]; then 106 newlabel=`atohexlabel "$alabel" 2>null` 107 if [[ -n $newlabel ]]; then 108 echo $zonename:$newlabel:0:: >> /etc/security/tsol/tnzonecfg 109 else 110 x=$(zenity --error \ 111 --title="$title" \ 112 --text="$alabel is not valid") 113 fi 114 fi 115} 116 117clone() { 118 image=`zfs list |grep snapshot|cut -d " " -f1| \ 119 zenity --list \ 120 --title="$title" \ 121 --height=300 \ 122 --column="ZFS Zone Snapshots"` 123 if [[ -n $image ]]; then 124 dataset=`zfs list |grep zone/$zonename |cut -d " " -f1` 125 if [[ -n $dataset ]]; then 126 /usr/sbin/zfs destroy zone/$zonename 127 fi 128 /usr/sbin/zfs clone $image zone/$zonename 129 /usr/sbin/zoneadm -z $zonename attach -F 130 if [ ! -f /var/ldap/ldap_client_file ]; then 131 sharePasswd 132 fi 133 fi 134} 135 136copy() { 137 138 image=`zenity --list \ 139 --title="$title: Copy From" \ 140 --height=300 \ 141 --column="Installed Zones" $zonelist` 142 143 /usr/bin/gnome-terminal \ 144 --title="$title: Copying $image to $zonename zone" \ 145 --command "zoneadm -z $zonename clone -m copy $image" 146 --hide-menubar 147 148 if [ ! -f /var/ldap/ldap_client_file ]; then 149 sharePasswd 150 fi 151} 152 153initialize() { 154 hostname=`hostname` 155 hostname=$(zenity --entry \ 156 --title="$title" \ 157 --text="Enter Host Name: " \ 158 --entry-text $hostname) 159 if [ $? != 0 ]; then 160 exit 1 161 fi 162 163 ZONE_PATH=`zoneadm list -cp|grep ":${zonename}:"|cut -d ":" -f4` 164 ZONE_ETC_DIR=$ZONE_PATH/root/etc 165 ipaddress=`getent hosts $hostname|cut -f1` 166 SYSIDCFG=${ZONE_ETC_DIR}/sysidcfg 167 168 if [ -f /var/ldap/ldap_client_file ]; then 169 ldapaddress=`ldapclient list | \ 170 /bin/grep "^NS_LDAP_SERVERS" | cut -d " " -f2` 171 echo "name_service=LDAP {" > ${SYSIDCFG} 172 domain=`domainname` 173 echo "domain_name=$domain" >> ${SYSIDCFG} 174 profName=`ldapclient list | \ 175 /bin/grep "^NS_LDAP_PROFILE" | cut -d " " -f2` 176 proxyPwd=`ldapclient list | \ 177 /bin/grep "^NS_LDAP_BINDPASSWD" | cut -d " " -f2` 178 proxyDN=`ldapclient list | \ 179 /bin/grep "^NS_LDAP_BINDDN" | cut -d " " -f 2` 180 if [ "$proxyDN" ]; then 181 echo "proxy_dn=\"$proxyDN\"" >> ${SYSIDCFG} 182 echo "proxy_password=\"$proxyPwd\"" >> ${SYSIDCFG} 183 fi 184 echo "profile=$profName" >> ${SYSIDCFG} 185 echo "profile_server=$ldapaddress }" >> ${SYSIDCFG} 186 cp /etc/nsswitch.conf $ZONE_ETC_DIR/nsswitch.ldap 187 else 188 echo "name_service=NONE" > ${SYSIDCFG} 189 sharePasswd 190 fi 191 192 echo "security_policy=NONE" >> ${SYSIDCFG} 193 locale=`locale|grep LANG | cut -d "=" -f2` 194 if [[ -z $locale ]]; then 195 locale="C" 196 fi 197 echo "system_locale=$locale" >> ${SYSIDCFG} 198 timezone=`/bin/grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2` 199 echo "timezone=$timezone" >> ${SYSIDCFG} 200 echo "terminal=vt100" >> ${SYSIDCFG} 201 rootpwd=`/bin/grep "^root:" /etc/shadow|cut -d ":" -f2` 202 echo "root_password=$rootpwd" >> ${SYSIDCFG} 203 echo "network_interface=PRIMARY {" >> ${SYSIDCFG} 204 echo "protocol_ipv6=no" >> ${SYSIDCFG} 205 echo "hostname=$hostname" >> ${SYSIDCFG} 206 echo "ip_address=$ipaddress }" >> ${SYSIDCFG} 207 cp /etc/default/nfs ${ZONE_ETC_DIR}/default/nfs 208 touch ${ZONE_ETC_DIR}/.NFS4inst_state.domain 209} 210 211install() { 212 # if there is a zfs pool for zone 213 # create a new dataset for the zone 214 # This step is done automatically by zonecfg 215 # in Solaris Express 8/06 or newer 216 217 zp=`zpool list -H zone 2>/dev/null` 218 if [ $? = 0 ]; then 219 zfs create zone/$zonename 220 chmod 700 /zone/$zonename 221 fi 222 223 /usr/bin/gnome-terminal \ 224 --title="$title: Installing $zonename zone" \ 225 --command "zoneadm -z $zonename install" \ 226 --hide-menubar 227 228 initialize 229} 230 231delete() { 232 # if there is an entry for this zone in tnzonecfg, remove it 233 # before deleting the zone. 234 235 tnzone=`egrep "^$zonename:" /etc/security/tsol/tnzonecfg 2>/dev/null` 236 if [ -n "${tnzone}" ]; then 237 sed -e "/^$tnzone:*/d" /etc/security/tsol/tnzonecfg > \ 238 /tmp/tnzonefg.$$ 2>/dev/null 239 mv /tmp/tnzonefg.$$ /etc/security/tsol/tnzonecfg 240 fi 241 zonecfg -z $zonename delete -F 242 zonename= 243} 244 245getNIC(){ 246 247 nics= 248 for i in `ifconfig -a4|grep "^[a-z].*:" |grep -v LOOPBACK` 249 do 250 echo $i |grep "^[a-z].*:" >/dev/null 2>&1 251 if [ $? -eq 1 ]; then 252 continue 253 fi 254 i=${i%:} # Remove colon after interface name 255 echo $i |grep ":" >/dev/null 2>&1 256 if [ $? -eq 0 ]; then 257 continue 258 fi 259 nics="$nics $i" 260 done 261 262 nic=$(zenity --list \ 263 --title="$title" \ 264 --column="Interface" \ 265 $nics) 266} 267 268getNetmask() { 269 270 cidr= 271 nm=$(zenity --entry \ 272 --title="$title" \ 273 --text="$ipaddr: Enter netmask: " \ 274 --entry-text 255.255.255.0) 275 if [ $? != 0 ]; then 276 return; 277 fi 278 279 cidr=`perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm` 280} 281 282addNet() { 283 getNIC 284 if [[ -z $nic ]]; then 285 return; 286 fi 287 getIPaddr 288 if [[ -z $ipaddr ]]; then 289 return; 290 fi 291 getNetmask 292 if [[ -z $cidr ]]; then 293 return; 294 fi 295 zcfg=" 296add net 297set address=${ipaddr}/${cidr} 298set physical=$nic 299end 300commit 301" 302 echo "$zcfg" > $config ; 303 zonecfg -z $zonename -f $config ; 304 rm $config 305} 306 307getAttrs() { 308 zone=global 309 type=ignore 310 for j in `ifconfig $nic` 311 do 312 case $j in 313 inet) type=$j;; 314 zone) type=$j;; 315 all-zones) zone=all-zones;; 316 flags*) flags=$j;; 317 *) case $type in 318 inet) ipaddr=$j ;; 319 zone) zone=$j ;; 320 *) continue ;; 321 esac;\ 322 type=ignore;; 323 esac 324 done 325 if [ $ipaddr != 0.0.0.0 ]; then 326 template=`tninfo -h $ipaddr|grep Template| cut -d" " -f3` 327 else 328 template="..." 329 ipaddr="..." 330 fi 331} 332 333updateTnrhdb() { 334 tnctl -h ${ipaddr}:$template 335 x=`grep "^${ipaddr}[^0-9]" /etc/security/tsol/tnrhdb` 336 if [ $? = 0 ]; then 337 sed s/$x/${ipaddr}:$template/g /etc/security/tsol/tnrhdb \ 338 > /tmp/txnetmgr.$$ 339 mv /tmp/txnetmgr.$$ /etc/security/tsol/tnrhdb 340 else 341 echo ${ipaddr}:$template >> /etc/security/tsol/tnrhdb 342 fi 343} 344 345getIPaddr() { 346 hostname=$(zenity --entry \ 347 --title="$title" \ 348 --text="$nic: Enter hostname: ") 349 350 if [ $? != 0 ]; then 351 return; 352 fi 353 354 ipaddr=`getent hosts $hostname|cut -f1` 355 if [[ -z $ipaddr ]]; then 356 357 ipaddr=$(zenity --entry \ 358 --title="$title" \ 359 --text="$nic: Enter IP address: " \ 360 --entry-text a.b.c.d) 361 if [ $? != 0 ]; then 362 return; 363 fi 364 fi 365 366} 367 368addHost() { 369 # Update hosts and ipnodes 370 if [[ -z $ipaddr ]]; then 371 return; 372 fi 373 grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null 374 if [ $? -eq 1 ]; then 375 echo "$ipaddr\t$hostname" >> /etc/inet/hosts 376 fi 377 378 grep "^${ipaddr}[^0-9]" /etc/inet/ipnodes >/dev/null 379 if [ $? -eq 1 ]; then 380 echo "$ipaddr\t$hostname" >> /etc/inet/ipnodes 381 fi 382 383 template=cipso 384 updateTnrhdb 385 386 ifconfig $nic $ipaddr netmask + broadcast + 387 echo $hostname > /etc/hostname.$nic 388} 389 390getTemplate() { 391 templates=$(cat /etc/security/tsol/tnrhtp|\ 392 grep "^[A-z]"|grep "type=cipso"|cut -f1 -d":") 393 394 while [ 1 -gt 0 ]; do 395 t_cmd=$(zenity --list \ 396 --title="$title" \ 397 --height=300 \ 398 --column="Network Templates" \ 399 $templates) 400 401 if [ $? != 0 ]; then 402 break; 403 fi 404 405 t_label=$(tninfo -t $t_cmd | grep sl|zenity --list \ 406 --title="$title" \ 407 --height=300 \ 408 --width=450 \ 409 --column="Click OK to associate $t_cmd template with $ipaddr" ) 410 411 if [ $? != 0 ]; then 412 continue 413 fi 414 template=$t_cmd 415 updateTnrhdb 416 break 417 done 418} 419 420createInterface() { 421 msg=`ifconfig $nic addif 0.0.0.0` 422 $(zenity --info \ 423 --title="$title" \ 424 --text="$msg" ) 425} 426 427shareInterface() { 428 ifconfig $nic all-zones;\ 429 if_file=/etc/hostname.$nic 430 sed q | sed -e "s/$/ all-zones/" < $if_file >/tmp/txnetmgr.$$ 431 mv /tmp/txnetmgr.$$ $if_file 432} 433 434setMacPrivs() { 435 zcfg=" 436set limitpriv=default,win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,file_downgrade_sl,file_upgrade_sl,sys_trans_label 437commit 438" 439 echo "$zcfg" > $config ; 440 zonecfg -z $zonename -f $config ; 441 rm $config 442} 443 444resetMacPrivs() { 445 zcfg=" 446set limitpriv=default 447commit 448" 449 echo "$zcfg" > $config ; 450 zonecfg -z $zonename -f $config ; 451 rm $config 452} 453 454sharePasswd() { 455 passwd=`zonecfg -z $zonename info|grep /etc/passwd` 456 if [[ $? -eq 1 ]]; then 457 zcfg=" 458add fs 459set special=/etc/passwd 460set dir=/etc/passwd 461set type=lofs 462end 463add fs 464set special=/etc/shadow 465set dir=/etc/shadow 466set type=lofs 467end 468commit 469" 470 echo "$zcfg" > $config ; 471 zonecfg -z $zonename -f $config ; 472 rm $config 473 fi 474} 475 476manageNets() { 477 while [ 1 -gt 0 ]; do 478 attrs= 479 for i in `ifconfig -au4|grep "^[a-z].*:" |grep -v LOOPBACK` 480 do 481 echo $i |grep "^[a-z].*:" >/dev/null 2>&1 482 if [ $? -eq 1 ]; then 483 continue 484 fi 485 nic=${i%:} # Remove colon after interface name 486 getAttrs 487 attrs="$nic $zone $ipaddr $template Up $attrs" 488 done 489 490 for i in `ifconfig -ad4 |grep "^[a-z].*:" |grep -v LOOPBACK` 491 do 492 echo $i |grep "^[a-z].*:" >/dev/null 2>&1 493 if [ $? -eq 1 ]; then 494 continue 495 fi 496 nic=${i%:} # Remove colon after interface name 497 getAttrs 498 attrs="$nic $zone $ipaddr $template Down $attrs" 499 done 500 501 nic=$(zenity --list \ 502 --title="$title" \ 503 --height=300 \ 504 --width=450 \ 505 --column="Interface" \ 506 --column="Zone Name" \ 507 --column="IP Address" \ 508 --column="Template" \ 509 --column="State" \ 510 $attrs) 511 512 if [[ -z $nic ]]; then 513 return 514 fi 515 516 getAttrs 517 518 # Clear list of commands 519 520 share= 521 setipaddr= 522 settemplate= 523 newlogical= 524 unplumb= 525 bringup= 526 bringdown= 527 528 # Check for physical interface 529 530 hascolon=`echo $nic |grep :` 531 if [ $? != 0 ]; then 532 newlogical="Create Logical Interface\n"; 533 else 534 up=`echo $flags|grep "UP,"` 535 if [ $? != 0 ]; then 536 unplumb="Remove Logical Interface\n" 537 if [ $ipaddr != "..." ]; then 538 bringup="Bring Up\n" 539 fi 540 else 541 bringdown="Bring Down\n" 542 fi 543 fi 544 545 if [ $ipaddr = "..." ]; then 546 setipaddr="Set IP address...\n"; 547 else 548 settemplate="View Templates...\n" 549 if [ $zone = global ]; then 550 share="Share\n" 551 fi 552 fi 553 554 command=$(echo ""\ 555 $share \ 556 $setipaddr \ 557 $settemplate \ 558 $newlogical \ 559 $unplumb \ 560 $bringup \ 561 $bringdown \ 562 | zenity --list \ 563 --title="$title" \ 564 --height=300 \ 565 --column "Interface: $nic" ) 566 567 case $command in 568 " Create Logical Interface")\ 569 createInterface;; 570 " Set IP address...")\ 571 getIPaddr 572 addHost;; 573 " Share")\ 574 shareInterface;; 575 " View Templates...")\ 576 getTemplate;; 577 " Remove Logical Interface")\ 578 ifconfig $nic unplumb;\ 579 rm -f /etc/hostname.$nic;; 580 " Bring Up")\ 581 ifconfig $nic up;; 582 " Bring Down")\ 583 ifconfig $nic down;; 584 *) continue;; 585 esac 586 done 587} 588 589# Main loop for top-level window 590# 591# Always display vni0 since it is useful for cross-zone networking 592# 593ifconfig vni0 > /dev/null 2>&1 594if [ $? != 0 ]; then 595 ifconfig vni0 plumb >/dev/null 2>&1 596fi 597while [ "${command}" != Exit ]; do 598 if [[ ! -n $zonename ]]; then 599 zonelist="" 600 for p in `zoneadm list -cp|grep -v global:`; do 601 zonename=`echo $p|cut -d : -f2` 602 state=`echo $p|cut -d : -f3` 603 labelCheck 604 zonelist="$zonelist$zonename\n$state\n$curlabel\n" 605 done 606 607 zonelist="${zonelist}Create a new zone...\n\n\nManage Network Interfaces...\n\n" 608 zonename=$(echo $zonelist|zenity --list \ 609 --title="$title" \ 610 --height=300 \ 611 --width=500 \ 612 --column="Zone Name" \ 613 --column="Status" \ 614 --column="Sensitivity Label" \ 615 ) 616 617 if [[ ! -n $zonename ]]; then 618 exit 619 fi 620 621 if [ "$zonename" = "Manage Network Interfaces..." ]; then 622 zonename= 623 manageNets 624 continue 625 elif [ "$zonename" = "Create a new zone..." ]; then 626 zonename=$(zenity --entry \ 627 --title="$title" \ 628 --entry-text="" \ 629 --text="Enter Zone Name: ") 630 631 if [[ ! -n $zonename ]]; then 632 continue 633 fi 634 635 zcfg=" 636create -t SUNWtsoldef 637set zonepath=/zone/$zonename 638commit 639" 640 echo "$zcfg" > $config ; 641 zonecfg -z $zonename -f $config ; 642 rm $config 643 fi 644 fi 645 646 # Clear list of commands 647 648 console= 649 label= 650 start= 651 reboot= 652 stop= 653 clone= 654 copy= 655 install= 656 ready= 657 uninstall= 658 delete= 659 snapshot= 660 addnet= 661 deletenet= 662 permitrelabel= 663 664 zonestate=`zoneadm -z $zonename list -p | cut -d ":" -f 3` 665 666 consoleCheck; 667 labelCheck; 668 delay=0 669 670 case $zonestate in 671 running) ready="Ready\n"; \ 672 reboot="Reboot\n"; \ 673 stop="Halt\n"; \ 674 ;; 675 ready) start="Boot\n"; \ 676 stop="Halt\n" \ 677 ;; 678 installed) 679 if [[ -z $label ]]; then \ 680 ready="Ready\n"; \ 681 start="Boot\n"; \ 682 fi; \ 683 uninstall="Uninstall\n"; \ 684 snapshotCheck; \ 685 relabelCheck; 686 addnet="Add Network...\n" 687 ;; 688 configured) install="Install...\n"; \ 689 copyCheck; \ 690 delete="Delete\n"; \ 691 console=; \ 692 ;; 693 incomplete) delete="Delete\n"; \ 694 ;; 695 *) 696 ;; 697 esac 698 699 command=$(echo ""\ 700 $console \ 701 $label \ 702 $start \ 703 $reboot \ 704 $stop \ 705 $clone \ 706 $copy \ 707 $install \ 708 $ready \ 709 $uninstall \ 710 $delete \ 711 $snapshot \ 712 $addnet \ 713 $deletenet \ 714 $permitrelabel \ 715 "Select another zone...\n" \ 716 "Exit" \ 717 | zenity --list \ 718 --title="$title" \ 719 --height=300 \ 720 --column "$zonename: $zonestate" ) 721 722 case $command in 723 " Zone Console...") 724 delay=2; \ 725 /usr/bin/gnome-terminal \ 726 --title="Zone Terminal Console: $zonename" \ 727 --command "/usr/sbin/zlogin -C $zonename" &;; 728 729 " Select Label...") 730 selectLabel;; 731 732 " Ready") 733 zoneadm -z $zonename ready ;; 734 735 " Boot") 736 zoneadm -z $zonename boot ;; 737 738 " Halt") 739 zoneadm -z $zonename halt ;; 740 741 " Reboot") 742 zoneadm -z $zonename reboot ;; 743 744 " Install...") 745 install;; 746 747 " Clone") 748 clone ;; 749 750 " Copy...") 751 copy ;; 752 753 " Uninstall") 754 zoneadm -z $zonename uninstall -F;; 755 756 " Delete") 757 delete ;; 758 759 " Create Snapshot") 760 zfs snapshot zone/${zonename}@snapshot;; 761 762 " Add Network...") 763 addNet ;; 764 765 " Permit Relabeling") 766 setMacPrivs ;; 767 768 " Deny Relabeling") 769 resetMacPrivs ;; 770 771 " Select another zone...") 772 zonename= ;; 773 774 *) 775 exit ;; 776 esac 777 sleep $delay; 778done 779