#!/bin/pfksh # # CDDL HEADER START # # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License"). # You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. # See the License for the specific language governing permissions # and limitations under the License. # # When distributing Covered Code, include this CDDL HEADER in each # file and include the License file at usr/src/OPENSOLARIS.LICENSE. # If applicable, add the following below this CDDL HEADER, with the # fields enclosed by brackets "[]" replaced with your own identifying # information: Portions Copyright [yyyy] [name of copyright owner] # # CDDL HEADER END # # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" # # This script provides a simple GUI for managing labeled zones. # It takes no arguments, but provides contextual menus which # provide appropriate choices. It must be run in the global # zone as root. PATH=/usr/bin:/usr/sbin:/usr/lib export PATH title="Labeled Zone Manager" maxlabel=`chk_encodings -X 2>/dev/null` if [[ ! -n $maxlabel ]]; then maxlabel=0x000a-08-f8 fi config=/tmp/zfg.$$ ; consoleCheck() { zconsole=`pgrep -f "zlogin -C $zonename"` if [ $? != 0 ]; then console="Zone Console...\n" fi } labelCheck() { hexlabel=`/bin/grep "^$zonename:" \ /etc/security/tsol/tnzonecfg|cut -d ":" -f2`; if [ $hexlabel ] ; then label= curlabel=`hextoalabel $hexlabel` else label="Select Label...\n" curlabel=... fi } snapshotCheck() { filesystem=`zfs list |grep zone/$zonename |cut -d " " -f1` if [[ -n $filesystem ]]; then snapshot="Create Snapshot\n" fi } copyCheck() { zonelist="" for p in `zoneadm list -ip`; do q=`echo $p|cut -d ":" -f2` if [ $q != $zonename ]; then zonelist="$zonelist $q" fi done if [[ -n $zonelist ]]; then copy="Copy...\n"; \ clone="Clone\n"; \ fi } relabelCheck() { macstate=`zonecfg -z $zonename info|grep win_mac_write` if [[ -n $macstate ]]; then permitrelabel="Deny Relabeling\n" else permitrelabel="Permit Relabeling\n" fi } selectLabel() { labelList="" for p in `lslabels -h $maxlabel`; do hexlabel=`/bin/grep :$p: /etc/security/tsol/tnzonecfg` if [ $? != 0 ]; then newlabel=`hextoalabel $p` labelList="$labelList $newlabel\n" fi done alabel=$(echo $labelList|zenity --list \ --title="$title" \ --height=300 \ --width=400 \ --column="Available Sensitivity Labels") if [[ -n $alabel ]]; then newlabel=`atohexlabel "$alabel" 2>null` if [[ -n $newlabel ]]; then echo $zonename:$newlabel:0:: >> /etc/security/tsol/tnzonecfg else x=$(zenity --error \ --title="$title" \ --text="$alabel is not valid") fi fi } clone() { image=`zfs list |grep snapshot|cut -d " " -f1| \ zenity --list \ --title="$title" \ --height=300 \ --column="ZFS Zone Snapshots"` if [[ -n $image ]]; then dataset=`zfs list |grep zone/$zonename |cut -d " " -f1` if [[ -n $dataset ]]; then /usr/sbin/zfs destroy zone/$zonename fi /usr/sbin/zfs clone $image zone/$zonename /usr/sbin/zoneadm -z $zonename attach -F if [ ! -f /var/ldap/ldap_client_file ]; then sharePasswd fi fi } copy() { image=`zenity --list \ --title="$title: Copy From" \ --height=300 \ --column="Installed Zones" $zonelist` /usr/bin/gnome-terminal \ --title="$title: Copying $image to $zonename zone" \ --command "zoneadm -z $zonename clone -m copy $image" --hide-menubar if [ ! -f /var/ldap/ldap_client_file ]; then sharePasswd fi } initialize() { hostname=`hostname` hostname=$(zenity --entry \ --title="$title" \ --text="Enter Host Name: " \ --entry-text $hostname) if [ $? != 0 ]; then exit 1 fi ZONE_PATH=`zoneadm list -cp|grep ":${zonename}:"|cut -d ":" -f4` ZONE_ETC_DIR=$ZONE_PATH/root/etc ipaddress=`getent hosts $hostname|cut -f1` SYSIDCFG=${ZONE_ETC_DIR}/sysidcfg if [ -f /var/ldap/ldap_client_file ]; then ldapaddress=`ldapclient list | \ /bin/grep "^NS_LDAP_SERVERS" | cut -d " " -f2` echo "name_service=LDAP {" > ${SYSIDCFG} domain=`domainname` echo "domain_name=$domain" >> ${SYSIDCFG} profName=`ldapclient list | \ /bin/grep "^NS_LDAP_PROFILE" | cut -d " " -f2` proxyPwd=`ldapclient list | \ /bin/grep "^NS_LDAP_BINDPASSWD" | cut -d " " -f2` proxyDN=`ldapclient list | \ /bin/grep "^NS_LDAP_BINDDN" | cut -d " " -f 2` if [ "$proxyDN" ]; then echo "proxy_dn=\"$proxyDN\"" >> ${SYSIDCFG} echo "proxy_password=\"$proxyPwd\"" >> ${SYSIDCFG} fi echo "profile=$profName" >> ${SYSIDCFG} echo "profile_server=$ldapaddress }" >> ${SYSIDCFG} cp /etc/nsswitch.conf $ZONE_ETC_DIR/nsswitch.ldap else echo "name_service=NONE" > ${SYSIDCFG} sharePasswd fi echo "security_policy=NONE" >> ${SYSIDCFG} locale=`locale|grep LANG | cut -d "=" -f2` if [[ -z $locale ]]; then locale="C" fi echo "system_locale=$locale" >> ${SYSIDCFG} timezone=`/bin/grep "^TZ" /etc/TIMEZONE|cut -d "=" -f2` echo "timezone=$timezone" >> ${SYSIDCFG} echo "terminal=vt100" >> ${SYSIDCFG} rootpwd=`/bin/grep "^root:" /etc/shadow|cut -d ":" -f2` echo "root_password=$rootpwd" >> ${SYSIDCFG} echo "network_interface=PRIMARY {" >> ${SYSIDCFG} echo "protocol_ipv6=no" >> ${SYSIDCFG} echo "hostname=$hostname" >> ${SYSIDCFG} echo "ip_address=$ipaddress }" >> ${SYSIDCFG} cp /etc/default/nfs ${ZONE_ETC_DIR}/default/nfs touch ${ZONE_ETC_DIR}/.NFS4inst_state.domain } install() { # if there is a zfs pool for zone # create a new dataset for the zone # This step is done automatically by zonecfg # in Solaris Express 8/06 or newer zp=`zpool list -H zone 2>/dev/null` if [ $? = 0 ]; then zfs create zone/$zonename chmod 700 /zone/$zonename fi /usr/bin/gnome-terminal \ --title="$title: Installing $zonename zone" \ --command "zoneadm -z $zonename install" \ --hide-menubar initialize } delete() { # if there is an entry for this zone in tnzonecfg, remove it # before deleting the zone. tnzone=`egrep "^$zonename:" /etc/security/tsol/tnzonecfg 2>/dev/null` if [ -n "${tnzone}" ]; then sed -e "/^$tnzone:*/d" /etc/security/tsol/tnzonecfg > \ /tmp/tnzonefg.$$ 2>/dev/null mv /tmp/tnzonefg.$$ /etc/security/tsol/tnzonecfg fi zonecfg -z $zonename delete -F zonename= } getNIC(){ nics= for i in `ifconfig -a4|grep "^[a-z].*:" |grep -v LOOPBACK` do echo $i |grep "^[a-z].*:" >/dev/null 2>&1 if [ $? -eq 1 ]; then continue fi i=${i%:} # Remove colon after interface name echo $i |grep ":" >/dev/null 2>&1 if [ $? -eq 0 ]; then continue fi nics="$nics $i" done nic=$(zenity --list \ --title="$title" \ --column="Interface" \ $nics) } getNetmask() { cidr= nm=$(zenity --entry \ --title="$title" \ --text="$ipaddr: Enter netmask: " \ --entry-text 255.255.255.0) if [ $? != 0 ]; then return; fi cidr=`perl -e 'use Socket; print unpack("%32b*",inet_aton($ARGV[0])), "\n";' $nm` } addNet() { getNIC if [[ -z $nic ]]; then return; fi getIPaddr if [[ -z $ipaddr ]]; then return; fi getNetmask if [[ -z $cidr ]]; then return; fi zcfg=" add net set address=${ipaddr}/${cidr} set physical=$nic end commit " echo "$zcfg" > $config ; zonecfg -z $zonename -f $config ; rm $config } getAttrs() { zone=global type=ignore for j in `ifconfig $nic` do case $j in inet) type=$j;; zone) type=$j;; all-zones) zone=all-zones;; flags*) flags=$j;; *) case $type in inet) ipaddr=$j ;; zone) zone=$j ;; *) continue ;; esac;\ type=ignore;; esac done if [ $ipaddr != 0.0.0.0 ]; then template=`tninfo -h $ipaddr|grep Template| cut -d" " -f3` else template="..." ipaddr="..." fi } updateTnrhdb() { tnctl -h ${ipaddr}:$template x=`grep "^${ipaddr}[^0-9]" /etc/security/tsol/tnrhdb` if [ $? = 0 ]; then sed s/$x/${ipaddr}:$template/g /etc/security/tsol/tnrhdb \ > /tmp/txnetmgr.$$ mv /tmp/txnetmgr.$$ /etc/security/tsol/tnrhdb else echo ${ipaddr}:$template >> /etc/security/tsol/tnrhdb fi } getIPaddr() { hostname=$(zenity --entry \ --title="$title" \ --text="$nic: Enter hostname: ") if [ $? != 0 ]; then return; fi ipaddr=`getent hosts $hostname|cut -f1` if [[ -z $ipaddr ]]; then ipaddr=$(zenity --entry \ --title="$title" \ --text="$nic: Enter IP address: " \ --entry-text a.b.c.d) if [ $? != 0 ]; then return; fi fi } addHost() { # Update hosts and ipnodes if [[ -z $ipaddr ]]; then return; fi grep "^${ipaddr}[^0-9]" /etc/inet/hosts >/dev/null if [ $? -eq 1 ]; then echo "$ipaddr\t$hostname" >> /etc/inet/hosts fi grep "^${ipaddr}[^0-9]" /etc/inet/ipnodes >/dev/null if [ $? -eq 1 ]; then echo "$ipaddr\t$hostname" >> /etc/inet/ipnodes fi template=cipso updateTnrhdb ifconfig $nic $ipaddr netmask + broadcast + echo $hostname > /etc/hostname.$nic } getTemplate() { templates=$(cat /etc/security/tsol/tnrhtp|\ grep "^[A-z]"|grep "type=cipso"|cut -f1 -d":") while [ 1 -gt 0 ]; do t_cmd=$(zenity --list \ --title="$title" \ --height=300 \ --column="Network Templates" \ $templates) if [ $? != 0 ]; then break; fi t_label=$(tninfo -t $t_cmd | grep sl|zenity --list \ --title="$title" \ --height=300 \ --width=450 \ --column="Click OK to associate $t_cmd template with $ipaddr" ) if [ $? != 0 ]; then continue fi template=$t_cmd updateTnrhdb break done } createInterface() { msg=`ifconfig $nic addif 0.0.0.0` $(zenity --info \ --title="$title" \ --text="$msg" ) } shareInterface() { ifconfig $nic all-zones;\ if_file=/etc/hostname.$nic sed q | sed -e "s/$/ all-zones/" < $if_file >/tmp/txnetmgr.$$ mv /tmp/txnetmgr.$$ $if_file } setMacPrivs() { zcfg=" set limitpriv=default,win_mac_read,win_mac_write,win_selection,win_dac_read,win_dac_write,file_downgrade_sl,file_upgrade_sl,sys_trans_label commit " echo "$zcfg" > $config ; zonecfg -z $zonename -f $config ; rm $config } resetMacPrivs() { zcfg=" set limitpriv=default commit " echo "$zcfg" > $config ; zonecfg -z $zonename -f $config ; rm $config } sharePasswd() { passwd=`zonecfg -z $zonename info|grep /etc/passwd` if [[ $? -eq 1 ]]; then zcfg=" add fs set special=/etc/passwd set dir=/etc/passwd set type=lofs end add fs set special=/etc/shadow set dir=/etc/shadow set type=lofs end commit " echo "$zcfg" > $config ; zonecfg -z $zonename -f $config ; rm $config fi } manageNets() { while [ 1 -gt 0 ]; do attrs= for i in `ifconfig -au4|grep "^[a-z].*:" |grep -v LOOPBACK` do echo $i |grep "^[a-z].*:" >/dev/null 2>&1 if [ $? -eq 1 ]; then continue fi nic=${i%:} # Remove colon after interface name getAttrs attrs="$nic $zone $ipaddr $template Up $attrs" done for i in `ifconfig -ad4 |grep "^[a-z].*:" |grep -v LOOPBACK` do echo $i |grep "^[a-z].*:" >/dev/null 2>&1 if [ $? -eq 1 ]; then continue fi nic=${i%:} # Remove colon after interface name getAttrs attrs="$nic $zone $ipaddr $template Down $attrs" done nic=$(zenity --list \ --title="$title" \ --height=300 \ --width=450 \ --column="Interface" \ --column="Zone Name" \ --column="IP Address" \ --column="Template" \ --column="State" \ $attrs) if [[ -z $nic ]]; then return fi getAttrs # Clear list of commands share= setipaddr= settemplate= newlogical= unplumb= bringup= bringdown= # Check for physical interface hascolon=`echo $nic |grep :` if [ $? != 0 ]; then newlogical="Create Logical Interface\n"; else up=`echo $flags|grep "UP,"` if [ $? != 0 ]; then unplumb="Remove Logical Interface\n" if [ $ipaddr != "..." ]; then bringup="Bring Up\n" fi else bringdown="Bring Down\n" fi fi if [ $ipaddr = "..." ]; then setipaddr="Set IP address...\n"; else settemplate="View Templates...\n" if [ $zone = global ]; then share="Share\n" fi fi command=$(echo ""\ $share \ $setipaddr \ $settemplate \ $newlogical \ $unplumb \ $bringup \ $bringdown \ | zenity --list \ --title="$title" \ --height=300 \ --column "Interface: $nic" ) case $command in " Create Logical Interface")\ createInterface;; " Set IP address...")\ getIPaddr addHost;; " Share")\ shareInterface;; " View Templates...")\ getTemplate;; " Remove Logical Interface")\ ifconfig $nic unplumb;\ rm -f /etc/hostname.$nic;; " Bring Up")\ ifconfig $nic up;; " Bring Down")\ ifconfig $nic down;; *) continue;; esac done } # Main loop for top-level window # # Always display vni0 since it is useful for cross-zone networking # ifconfig vni0 > /dev/null 2>&1 if [ $? != 0 ]; then ifconfig vni0 plumb >/dev/null 2>&1 fi while [ "${command}" != Exit ]; do if [[ ! -n $zonename ]]; then zonelist="" for p in `zoneadm list -cp|grep -v global:`; do zonename=`echo $p|cut -d : -f2` state=`echo $p|cut -d : -f3` labelCheck zonelist="$zonelist$zonename\n$state\n$curlabel\n" done zonelist="${zonelist}Create a new zone...\n\n\nManage Network Interfaces...\n\n" zonename=$(echo $zonelist|zenity --list \ --title="$title" \ --height=300 \ --width=500 \ --column="Zone Name" \ --column="Status" \ --column="Sensitivity Label" \ ) if [[ ! -n $zonename ]]; then exit fi if [ "$zonename" = "Manage Network Interfaces..." ]; then zonename= manageNets continue elif [ "$zonename" = "Create a new zone..." ]; then zonename=$(zenity --entry \ --title="$title" \ --entry-text="" \ --text="Enter Zone Name: ") if [[ ! -n $zonename ]]; then continue fi zcfg=" create -t SUNWtsoldef set zonepath=/zone/$zonename commit " echo "$zcfg" > $config ; zonecfg -z $zonename -f $config ; rm $config fi fi # Clear list of commands console= label= start= reboot= stop= clone= copy= install= ready= uninstall= delete= snapshot= addnet= deletenet= permitrelabel= zonestate=`zoneadm -z $zonename list -p | cut -d ":" -f 3` consoleCheck; labelCheck; delay=0 case $zonestate in running) ready="Ready\n"; \ reboot="Reboot\n"; \ stop="Halt\n"; \ ;; ready) start="Boot\n"; \ stop="Halt\n" \ ;; installed) if [[ -z $label ]]; then \ ready="Ready\n"; \ start="Boot\n"; \ fi; \ uninstall="Uninstall\n"; \ snapshotCheck; \ relabelCheck; addnet="Add Network...\n" ;; configured) install="Install...\n"; \ copyCheck; \ delete="Delete\n"; \ console=; \ ;; incomplete) delete="Delete\n"; \ ;; *) ;; esac command=$(echo ""\ $console \ $label \ $start \ $reboot \ $stop \ $clone \ $copy \ $install \ $ready \ $uninstall \ $delete \ $snapshot \ $addnet \ $deletenet \ $permitrelabel \ "Select another zone...\n" \ "Exit" \ | zenity --list \ --title="$title" \ --height=300 \ --column "$zonename: $zonestate" ) case $command in " Zone Console...") delay=2; \ /usr/bin/gnome-terminal \ --title="Zone Terminal Console: $zonename" \ --command "/usr/sbin/zlogin -C $zonename" &;; " Select Label...") selectLabel;; " Ready") zoneadm -z $zonename ready ;; " Boot") zoneadm -z $zonename boot ;; " Halt") zoneadm -z $zonename halt ;; " Reboot") zoneadm -z $zonename reboot ;; " Install...") install;; " Clone") clone ;; " Copy...") copy ;; " Uninstall") zoneadm -z $zonename uninstall -F;; " Delete") delete ;; " Create Snapshot") zfs snapshot zone/${zonename}@snapshot;; " Add Network...") addNet ;; " Permit Relabeling") setMacPrivs ;; " Deny Relabeling") resetMacPrivs ;; " Select another zone...") zonename= ;; *) exit ;; esac sleep $delay; done