Adam Tkac d218af
#!/bin/bash
Adam Tkac d218af
Petr Menšík 3fdc82
ROOTDIR="$1"
Petr Menšík 3fdc82
CONFIG_FILES="${3:-/etc/named-chroot.files}"
Adam Tkac d218af
Adam Tkac d218af
usage()
Adam Tkac d218af
{
Adam Tkac d218af
  echo
Adam Tkac d218af
  echo 'This script setups chroot environment for BIND'
Petr Menšík 3fdc82
  echo 'Usage: setup-named-chroot.sh ROOTDIR <on|off> [chroot.files]'
Adam Tkac d218af
}
Adam Tkac d218af
Petr Menšík 3fdc82
if ! [ "$#" -ge 2 -a "$#" -le 3 ]; then
Adam Tkac d218af
  echo 'Wrong number of arguments'
Adam Tkac d218af
  usage
Adam Tkac d218af
  exit 1
Adam Tkac d218af
fi
Adam Tkac d218af
Adam Tkac d218af
# Exit if ROOTDIR doesn't exist
Adam Tkac d218af
if ! [ -d "$ROOTDIR" ]; then
Adam Tkac d218af
  echo "Root directory $ROOTDIR doesn't exist"
Adam Tkac d218af
  usage
Adam Tkac d218af
  exit 1
Adam Tkac d218af
fi
Adam Tkac d218af
Petr Menšík 3fdc82
if ! [ -r "$CONFIG_FILES" ]; then
Petr Menšík 3fdc82
  echo "Files list $CONFIG_FILES doesn't exist" 2>&1
Petr Menšík 3fdc82
  usage
Petr Menšík 3fdc82
  exit 1
Petr Menšík 3fdc82
fi
Petr Menšík 3fdc82
Petr Menšík 41d690
dev_create()
Petr Menšík 41d690
{
Petr Menšík 41d690
  DEVNAME="$ROOTDIR/dev/$1"
Petr Menšík 572c58
  shift
Petr Menšík 41d690
  if ! [ -e "$DEVNAME" ]; then
Petr Menšík 572c58
    /bin/mknod -m 0664 "$DEVNAME" $@
Petr Menšík 572c58
    /bin/chgrp named "$DEVNAME"
Petr Menšík 572c58
    if [ -x /usr/sbin/selinuxenabled -a -x /sbin/restorecon ]; then
Petr Menšík 572c58
      /usr/sbin/selinuxenabled && /sbin/restorecon "$DEVNAME" > /dev/null || :
Petr Menšík 572c58
    fi
Petr Menšík 41d690
  fi
Petr Menšík 41d690
}
Petr Menšík 41d690
Petr Menšík 41d690
dev_chroot_prep()
Petr Menšík 41d690
{
Petr Menšík 572c58
  dev_create random c 1 8
Petr Menšík 572c58
  dev_create zero   c 1 5
Petr Menšík 572c58
  dev_create null   c 1 3
Petr Menšík 41d690
}
Petr Menšík 41d690
Petr Menšík 41d690
files_comment_filter()
Petr Menšík 41d690
{
Petr Menšík 41d690
  if [ -d "$1" ]; then
Petr Menšík 41d690
    grep -v '^[[:space:]]*#' "$1"/*.files
Petr Menšík 41d690
  else
Petr Menšík 41d690
    grep -v '^[[:space:]]*#' "$1"
Petr Menšík 41d690
  fi
Petr Menšík 41d690
}
Petr Menšík 41d690
Adam Tkac d218af
mount_chroot_conf()
Adam Tkac d218af
{
Adam Tkac d218af
  if [ -n "$ROOTDIR" ]; then
Petr Menšík 41d690
    # Check devices are prepared
Petr Menšík 41d690
    dev_chroot_prep
Petr Menšík 41d690
    files_comment_filter "$CONFIG_FILES" | while read -r all; do
Adam Tkac d218af
      # Skip nonexistant files
Adam Tkac d218af
      [ -e "$all" ] || continue
Adam Tkac d218af
Adam Tkac d218af
      # If mount source is a file
Adam Tkac d218af
      if ! [ -d "$all" ]; then
Adam Tkac d218af
        # mount it only if it is not present in chroot or it is empty
Adam Tkac d218af
        if ! [ -e "$ROOTDIR$all" ] || [ `stat -c'%s' "$ROOTDIR$all"` -eq 0 ]; then
Adam Tkac d218af
          touch "$ROOTDIR$all"
Adam Tkac d218af
          mount --bind "$all" "$ROOTDIR$all"
Adam Tkac d218af
        fi
Adam Tkac d218af
      else
Adam Tkac d218af
        # Mount source is a directory. Mount it only if directory in chroot is
Adam Tkac d218af
        # empty.
Adam Tkac d218af
        if [ -e "$all" ] && [ `ls -1A $ROOTDIR$all | wc -l` -eq 0 ]; then
Tomas Hozza 7eb562
          mount --bind --make-private "$all" "$ROOTDIR$all"
Adam Tkac d218af
        fi
Adam Tkac d218af
      fi
Adam Tkac d218af
    done
Adam Tkac d218af
  fi
Adam Tkac d218af
}
Adam Tkac d218af
Adam Tkac d218af
umount_chroot_conf()
Adam Tkac d218af
{
Adam Tkac 773ac2
  if [ -n "$ROOTDIR" ]; then
Petr Menšík 41d690
    files_comment_filter "$CONFIG_FILES" | while read -r all; do
Adam Tkac 773ac2
      # Check if file is mount target. Do not use /proc/mounts because detecting
Adam Tkac 773ac2
      # of modified mounted files can fail.
Adam Tkac 773ac2
      if mount | grep -q '.* on '"$ROOTDIR$all"' .*'; then
Adam Tkac 773ac2
        umount "$ROOTDIR$all"
Adam Tkac 773ac2
        # Remove temporary created files
Adam Tkac 773ac2
        [ -f "$all" ] && rm -f "$ROOTDIR$all"
Adam Tkac 773ac2
      fi
Adam Tkac 773ac2
    done
Adam Tkac 773ac2
  fi
Adam Tkac d218af
}
Adam Tkac d218af
Adam Tkac d218af
case "$2" in
Adam Tkac d218af
  on)
Adam Tkac d218af
    mount_chroot_conf
Adam Tkac d218af
    ;;
Adam Tkac d218af
  off)
Adam Tkac d218af
    umount_chroot_conf
Adam Tkac d218af
    ;;
Adam Tkac d218af
  *)
Adam Tkac d218af
    echo 'Second argument has to be "on" or "off"'
Adam Tkac d218af
    usage
Adam Tkac d218af
    exit 1
Adam Tkac d218af
esac
Adam Tkac d218af
Adam Tkac d218af
exit 0