Release new version 0.105.0
[grml-terminalserver.git] / grml-terminalserver
index 3303df4..1314205 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 # Filename:      terminalserver
 # Purpose:       Program to do something
 # Authors:       grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
@@ -38,8 +38,8 @@ function printUsage
   cat <<EOT
 Usage: "$PROG_NAME__" [OPTIONS] <command>
 
-$PROG_NAME__ is the config program for the terminalserver
-comming with grml.
+$PROG_NAME__ is the configuration program for the terminalserver
+provided by Grml.
 
 COMMANDS:
    help             This help text
@@ -52,6 +52,7 @@ COMMANDS:
 SERVICES:
   tftp        Tftp daemon
   dhcp        Dhcp daemon
+  ipt         Iptables setup (snat for clients)
   nfs         All necessary nfs daemons
   <>          ALL services
 
@@ -65,8 +66,13 @@ EOT
 
 function killPortmapper
 {
+  if [ -f /etc/init.d/portmap ] ; then
     /etc/init.d/portmap stop >/dev/null &>/dev/null
-    killall -9 portmap &>/dev/null
+  elif [ -f /etc/init.d/rpcbind ] ; then
+    /etc/init.d/rpcbind stop >/dev/null &>/dev/null
+  fi
+  killall -9 portmap &>/dev/null
+  killall -9 rpcbind &>/dev/null
 }
 
 # DHCP SERVICE {{{
@@ -109,8 +115,12 @@ function stopDhcp
 {
   start-stop-daemon --stop --quiet --pidfile "$DHCPD_PID_"
   rm -f $DHCPD_PID_
-  rm -f /var/lib/dhcp3/dhcpd.leases* 2>/dev/null    #FIXME
-  touch /var/lib/dhcp3/dhcpd.leases
+  # ugly but necessary :-/
+  find  /var/lib/dhcp* -type f -name dhcpd.leases -delete
+  local dhcpdir
+  for dhcpdir in /var/lib/dhcp* ; do
+    touch ${dhcpdir}/dhcpd.leases
+  done
 }
 
 function startDhcp
@@ -131,35 +141,21 @@ function runDhcp
   sleep 1
   startDhcp
 }
+# }}}
 
-# make sure tcp/113 is rejected
+# IPTABLES {{{
 function runIptables
 {
- if [ -x /sbin/iptables ] ; then
-    # something keeps answering all tftp requests with auth requests (SYN
-    # packets to the client tcp/113). Since the PXE client doesn't answer with
-    # RST, the auth query has to wait until it times out. Forbidding the
-    # terminalserver to send out packets to tcp/113 via iptables _greatly_
-    # speeds up the process. But of course the real fix would be to have grml
-    # stop sending out auth queries to tftp clients. according to netstat, it
-    # is in.tftpd itself sending out the auth queries.
-    # Thanks to Marc Haber and Wolfgang Karall for noticing and current fix.
-    if iptables -L | grep -q '^REJECT.*tcp dpt:auth reject-with tcp-reset' ; then
-       echo "Rule for tcp/113 already present, nothing to be done."
-    else
-       echo "Rejecting tcp/113 via iptables to speed up booting via PXE, running:"
-       echo -n '* iptables -A OUTPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset ... '
-       iptables -A OUTPUT -p tcp --dport 113 -j REJECT --reject-with tcp-reset && echo done || echo failed
-    fi
-    # deactivate Multicast-DNS
-    if iptables -L | grep -q '^REJECT.*dpt:mdns reject-with icmp-port-unreachable' ; then
-       echo "Rule for udp/5353 already present, nothing to be done."
-    else
-       echo "Rejecting udp/5353 via iptables for deactivating Multicast-DNS, running:"
-       echo -n '* iptables -A OUTPUT -p udp -d 224.0.0.0/8 --dport 5353 -j REJECT ... '
-       iptables -A OUTPUT -p udp -d 224.0.0.0/8 --dport 5353 -j REJECT && echo done || echo failed
-    fi
-    if [ "$NAT_INTERFACE_" != "none" ]; then
+  if [[ $IPTABLES_SNAT_ != "true" ]]; then
+    return
+  fi
+  startIptables
+}
+
+function startIptables
+{
+  if [ -x $(command -v iptables) ] ; then
+    if [[ $NAT_INTERFACE_ != "" ]]; then
        local nat_source_ip_=`netGetIp "$NAT_INTERFACE_" warn`
 
        if iptables -t nat -vnL POSTROUTING | grep -q "SNAT.*${NAT_INTERFACE_}.*to:${nat_source_ip_}" ; then
@@ -179,9 +175,27 @@ function runIptables
           echo 1 > /proc/sys/net/ipv4/ip_forward && echo done || echo failed
        fi
     fi
- else
-    warn "iptables executable not avilable"
- fi
+  else
+    warn "iptables executable not available"
+  fi
+}
+
+function stopIptables
+{
+  if [[ $IPTABLES_SNAT_ != "true" ]]; then
+    return
+  fi
+  if [ -x $(command -v iptables) ] ; then
+    if [[ $NAT_INTERFACE_ != "" ]]; then
+       local nat_source_ip_=`netGetIp "$NAT_INTERFACE_" warn`
+
+       if iptables -t nat -vnL POSTROUTING | grep -q "SNAT.*${NAT_INTERFACE_}.*to:${nat_source_ip_}" ; then
+         iptables -t nat -F POSTROUTING &>/dev/null && \
+           iptables -t nat -D POSTROUTING -o "$NAT_INTERFACE_" -j SNAT --to-source "$nat_source_ip_"
+       fi
+       echo 0 > /proc/sys/net/ipv4/ip_forward
+    fi
+  fi
 }
 # }}}
 
@@ -194,20 +208,29 @@ function createTftpConf
 {
   removeTftpConf
 
-  execute "mkdir $TFTPD_DATA_DIR_/pxelinux.cfg" die
-  execute "install -m 644 /usr/lib/syslinux/pxelinux.0 $TFTPD_DATA_DIR_" die
-  execute "install -m 644 $PATH_/minirt26.gz $TFTPD_DATA_DIR_" die
-  execute "install -m 644 $KERNEL_IMAGE_ $TFTPD_DATA_DIR_/linux26" die
-  execute "install -m 644 $MEMTEST_IMAGE_ $TFTPD_DATA_DIR_/memtest" die
+  execute "mkdir -p $TFTPD_DATA_DIR_/pxelinux.cfg" die
+  if [ -r /usr/lib/PXELINUX/pxelinux.0 ] ; then
+    execute "install -m 644 /usr/lib/PXELINUX/pxelinux.0 $TFTPD_DATA_DIR_" die
+  else # older versions of syslinux-common (<= 2:4.05+dfsg-6+deb7u1):
+    execute "install -m 644 /usr/lib/syslinux/pxelinux.0 $TFTPD_DATA_DIR_" die
+  fi
+  if [ -d "$MOUNT_POINT_"/boot/release ] ; then
+    cp -r "$MOUNT_POINT_"/boot/release "$TFTPD_DATA_DIR_"
+  fi
+  [ -f "$MEMTEST_IMAGE" ] && execute "install -m 644 $MEMTEST_IMAGE_ $TFTPD_DATA_DIR_/memtest" die
   execute "install -m 644 $PXE_BOOT_MSG_ $TFTPD_DATA_DIR_" die
-  execute "install -m 644 $PXE_BOOT_LOGO_ $TFTPD_DATA_DIR_" die
+  [ -f "$PXE_BOOT_LOGO_" ] && execute "install -m 644 $PXE_BOOT_LOGO_ $TFTPD_DATA_DIR_" die
 
+  # PXE / BIOS boot (pxelinux)
   execute "source $TEMPLATE_CONFIG_DIR_/grub-pxelinux_config" die
+
+  # PXE / EFI boot (GRUB)
+  execute "source $TEMPLATE_CONFIG_DIR_/grub-shim_config" die
 }
 
 function stopTftp
 {
-  start-stop-daemon --stop --quiet -p "$TFTPD_PID_"
+  start-stop-daemon --stop --quiet -p "$TFTPD_PID_" --user nobody
 }
 function startTftp
 {
@@ -227,20 +250,27 @@ function runTftp
 # NFS  {{{
 function createNfsConfig
 {
-  execute "exportfs -o ro,no_root_squash,async,nohide $NETWORK_/$NETMASK_:$MOUNT_POINT_" warn
+  execute "exportfs -o ro,no_root_squash,async,nohide,fsid=42 $NETWORK_/$NETMASK_:$MOUNT_POINT_" warn
 }
 
 function removeNfsConfig
 {
-  execute "exportfs -u -o ro,no_root_squash,async,nohide $NETWORK_/$NETMASK_:$MOUNT_POINT_" warn
+  execute "exportfs -u -o ro,no_root_squash,async,nohide,fsid=42 $NETWORK_/$NETMASK_:$MOUNT_POINT_" warn
 }
 
 function startNfs
 {
-  /etc/init.d/portmap start
+  if [ -f /etc/init.d/portmap ] ; then
+    /etc/init.d/portmap start
+  elif [ -f /etc/init.d/rpcbind ] ; then
+    /etc/init.d/rpcbind start
+  else
+    echo "Warning: Could not start portmapper/rpcbind" >&2
+  fi
   /etc/init.d/nfs-common start
   # FIXME /etc/init.d/nfs-kernel-server start
   $USR_SHARE_/nfs-kernel-server start
+  echo
 
   createNfsConfig
 }
@@ -278,16 +308,17 @@ function actionStart
   echo -n "Starting dhcpd: "
   runDhcp && echo done || echo failed
 
-  #runIptables
+  runIptables
 
   echo "Finally starting nfs services..."
-  startNfs && echo "Sucessfully finished startup of grml-terminalserver." || echo 'Startup of grml-terminalserver-config failed!'
+  startNfs && echo "Successfully finished startup of grml-terminalserver." || echo 'Startup of grml-terminalserver failed!'
 }
 
 function actionStop
 {
   stopTftp
   stopDhcp
+  stopIptables
   stopNfs
   notice "Terminal-server stopped"
 }
@@ -322,6 +353,7 @@ function serviceStart
     "") actionStart ;;
     tftp) runTftp ;;
     dhcp) runDhcp ;;
+    ipt) startIptables ;;
     nfs) startNfs ;;
     *) warn "Service $service_ not available" ;;
   esac
@@ -335,6 +367,7 @@ function serviceStop
     "") actionStop ;;
     tftp) stopTftp ;;
     dhcp) stopDhcp ;;
+    ipt) stopIptables ;;
     nfs) stopNfs ;;
     *) warn "Service $service_ not available" ;;
   esac
@@ -368,14 +401,12 @@ isExistent $DEFAULT_CONFIG_ die
 . $CONFIG_
 # used config vars:
 # MOUNT_POINT_
-# KERNEL_IMAGE_
 # MEMTEST_IMAGE_
 # PXE_BOOT_MSG_
 # PXE_BOOT_LOGO_
-if [[ $MOUNT_POINT_ == "" || $KERNEL_IMAGE_ == "" || $MEMTEST_IMAGE_ == "" || \
+if [[ $MOUNT_POINT_ == "" || $MEMTEST_IMAGE_ == "" || \
   $PXE_BOOT_MSG_ == "" || $PXE_BOOT_MSG_ == "" ]]; then
   warn "MOUNT_POINT_=\"$MOUNT_POINT_\" \
-KERNEL_IMAGE_=\"$KERNEL_IMAGE_\" \
 MEMTEST_IMAGE_=\"$MEMTEST_IMAGE_\"
 PXE_BOOT_MSG_=\"$PXE_BOOT_MSG_\"
 PXE_BOOT_LOGO_=\"$PXE_BOOT_LOGO_\""
@@ -407,9 +438,9 @@ if [ "$1" == 'start' ]; then
   esac
 fi
 if [ $check_necessary_files_ == 'yes' ]; then
-  # test for files absolutly necessary for grml-terminalserver and created from -config
+  # test for files absolutely necessary for grml-terminalserver and created from -config
   problem_=0
-  for i in $PATH_/minirt26.gz; do
+  for i in $PATH_/initrd.img; do
     isExistent $i warn || problem_=1
   done
   if [ $problem_ -eq 1 ]; then