jvdias 0cd02aa
#!/bin/bash
jvdias 0cd02aa
# 
jvdias 0cd02aa
# Script to control the bind-chroot ISC BIND named(8) server runtime environment.
jvdias 0cd02aa
#
jvdias 0cd02aa
# Usage:
jvdias 0cd02aa
#  [ -e | --enable ] [ -d | --disable ] | [ -s --sync ]
jvdias 0cd02aa
#
jvdias 0cd02aa
#  -e | --enable:   enable the bind-chroot environment
jvdias 0cd02aa
#  -d | --disable:  disable the bind-chroot environment
jvdias 0cd02aa
#  -s | --sync:     sync files between the bind chroot and / environments,
jvdias 0cd02aa
#                   so they are correct for the current state of the bind-chroot
jvdias 0cd02aa
#                   (enabled / disabled)
jvdias 0cd02aa
# $BIND_CHROOT_PREFIX, default /var/named/chroot, is the location of the chroot.
jvdias 0cd02aa
# $BIND_DIR, default /var/named, is the default un-chrooted bind directory.
jvdias 0cd02aa
#
jvdias 0cd02aa
# Copyright(C) 2006 Jason Vas Dias <jvdias@redhat.com>, Red Hat, Inc.
jvdias 0cd02aa
#
jvdias 0cd02aa
#    This software is provided under the terms of the GNU
jvdias 0cd02aa
#    General Public License (GPL), as published at: 
jvdias 0cd02aa
#    http://www.gnu.org/licenses/gpl.html .
jvdias 0cd02aa
#
jvdias 0cd02aa
#
jvdias 0cd02aa
BIND_CHROOT_PREFIX=${BIND_CHROOT_PREFIX:-@BIND_CHROOT_PREFIX@}
jvdias 0cd02aa
BIND_DIR=${BIND_DIR:-@BIND_DIR@}
jvdias 0cd02aa
jvdias 0cd02aa
function usage()
jvdias 0cd02aa
{
jvdias 0cd02aa
  echo 'Usage:
jvdias 0cd02aa
  -e | --enable:   enable the bind-chroot environment
jvdias 0cd02aa
  -d | --disable:  disable the bind-chroot environment
jvdias 0cd02aa
  -s | --sync:     sync files between the bind chroot and / environments,
jvdias 0cd02aa
                   so they are correct for the current state of the bind-chroot
jvdias 0cd02aa
                   (enabled / disabled)
jvdias 0cd02aa
  $BIND_CHROOT_PREFIX, default /var/named/chroot, is the location of the chroot.
jvdias 0cd02aa
  $BIND_DIR, default /var/named, is the default un-chrooted bind directory.
jvdias 0cd02aa
';
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
function rootdir()
jvdias 0cd02aa
{
jvdias 0cd02aa
    . /etc/sysconfig/named
jvdias 0cd02aa
    if [ -n "$ROOTDIR" ]; then
jvdias 0cd02aa
	BIND_CHROOT_PREFIX="$ROOTDIR";
jvdias 0cd02aa
	BIND_CHROOT_PREFIX=`echo $BIND_CHROOT_PREFIX | sed 's#//*#/#g;s#/$##'`;
jvdias 0cd02aa
	if [ -L "$BIND_CHROOT_PREFIX" ]; then
jvdias 0cd02aa
	    BIND_CHROOT_PREFIX=`/usr/bin/readlink "$BIND_CHROOT_PREFIX"`;
jvdias 0cd02aa
	fi
jvdias 0cd02aa
	return 0;
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    return 1;
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
function check_dirs()
jvdias 0cd02aa
{
jvdias 0cd02aa
    if [ -z "$BIND_CHROOT_PREFIX" ]; then
jvdias 0cd02aa
	rootdir;
jvdias 0cd02aa
	if [ -z "$BIND_CHROOT_PREFIX" ]; then
jvdias 0cd02aa
	    usage;
jvdias 0cd02aa
	    exit 1;
jvdias 0cd02aa
	fi;
jvdias 0cd02aa
    fi
jvdias 0cd02aa
    BIND_DIR=`echo $BIND_DIR | sed 's#//*#/#g;s#/$##'`;
jvdias 0cd02aa
    if [ -L "$BIND_DIR" ]; then
jvdias 0cd02aa
	BIND_DIR=`/usr/bin/readlink "$BIND_DIR"`;
jvdias 0cd02aa
    fi
jvdias 0cd02aa
    BIND_CHROOT_PREFIX=`echo $BIND_CHROOT_PREFIX | sed 's#//*#/#g;s#/$##'`;
jvdias 0cd02aa
    if [ -L "$BIND_CHROOT_PREFIX" ]; then
jvdias 0cd02aa
	BIND_CHROOT_PREFIX=`/usr/bin/readlink "$BIND_CHROOT_PREFIX"`;
jvdias 0cd02aa
    fi
jvdias 0cd02aa
jvdias 0cd02aa
    /bin/mkdir -p ${BIND_DIR}/{slaves,data};
jvdias 0cd02aa
    /bin/chown root:named ${BIND_DIR};
jvdias 0cd02aa
    /bin/chown named:named ${BIND_DIR}/{slaves,data};
jvdias 0cd02aa
    /bin/chmod 750 ${BIND_DIR}
jvdias 0cd02aa
    /bin/chmod 770 ${BIND_DIR}/{slaves,data};
jvdias 0cd02aa
        
jvdias 0cd02aa
    mkdir -p ${BIND_CHROOT_PREFIX}/{etc,proc,dev,var/{run/dbus,run/named,named/{slaves,data}}};
jvdias 0cd02aa
    /bin/chown root:named ${BIND_CHROOT_PREFIX}/{etc,proc,dev,var/{run,run/dbus,named/}};
jvdias 0cd02aa
    /bin/chmod 750 ${BIND_CHROOT_PREFIX}/{,etc,proc,dev,var,var/{run,run/dbus,named/}};
jvdias 0cd02aa
    /bin/chown named:named ${BIND_CHROOT_PREFIX}/var/{run/named,named/{data,slaves}};
jvdias 0cd02aa
    /bin/chmod 770 ${BIND_CHROOT_PREFIX}/var/{run/named,named/{slaves,data}};
jvdias 0cd02aa
    [ ! -e "${BIND_CHROOT_PREFIX}/dev/random" ] && /bin/mknod "${BIND_CHROOT_PREFIX}/dev/random" c 1 8
jvdias 0cd02aa
    [ ! -e "${BIND_CHROOT_PREFIX}/dev/zero" ] && /bin/mknod "${BIND_CHROOT_PREFIX}/dev/zero" c 1 5
jvdias 0cd02aa
    [ ! -e "${BIND_CHROOT_PREFIX}/dev/null" ] && /bin/mknod "${BIND_CHROOT_PREFIX}/dev/null" c 1 3
jvdias 0cd02aa
    [ ! -e "${BIND_CHROOT_PREFIX}/etc/localtime" ] &&  [ -e /etc/localtime ] && /bin/cp -fp /etc/localtime "${BIND_CHROOT_PREFIX}/etc/localtime";
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
check_dirs;
jvdias 0cd02aa
jvdias 0cd02aa
function replace_with_link()
jvdias 0cd02aa
{ # replaces $dst second arg file  with link to $src first arg file
jvdias 0cd02aa
    if [ $# -lt 2 ]; then
jvdias 0cd02aa
	return 1;
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    src=$1
jvdias 0cd02aa
    dst=$2    
jvdias 0cd02aa
    if [ -z "$src" ] || [ -z "$dst" ] || [ "$src" = "$dst" ]; then
jvdias 0cd02aa
       return 1;
jvdias 0cd02aa
    fi
jvdias 0cd02aa
    if [ ! -e "$src" ]; then
jvdias 0cd02aa
       if [ ! -e "$dst" ]; then
jvdias 0cd02aa
	   return 1;
jvdias 0cd02aa
       else
jvdias 0cd02aa
	   if [ -L "$dst" ]; then
jvdias 0cd02aa
	       dstlnk=`/usr/bin/readlink "$dst"`;
jvdias 0cd02aa
	       if [ ! -e "$dstlnk" ] ; then
jvdias 0cd02aa
		   return 1;
jvdias 0cd02aa
	       fi	       
jvdias 0cd02aa
	       rm -f "$dst";
jvdias 0cd02aa
	       /bin/cp -fp "$dstlnk" "$dst";
jvdias 0cd02aa
	   fi;
jvdias 0cd02aa
	   /bin/mv "$dst" "$src";
jvdias 0cd02aa
       fi
jvdias 0cd02aa
    fi
jvdias 0cd02aa
    if [ -e "$dst" ]; then
jvdias 0cd02aa
       if [ ! -L "$dst" ]; then
jvdias 0cd02aa
	  if [ ! -s "$dst" ]; then
jvdias 0cd02aa
	     /bin/rm -f "$dst";
jvdias 0cd02aa
	  else	     
jvdias 0cd02aa
	     if [ "$src" -nt "$dst" ] || [ ! "$dst" -nt "$src" ] ; then
jvdias 0cd02aa
	        /bin/mv "$dst" "$dst".`/bin/date +'%Y-%m-%d_%H-%M-%S.%N'`;
jvdias 0cd02aa
	     else # [ "$dst" -nt "$src" ]
jvdias 0cd02aa
	        /bin/mv "$src" "$src".`/bin/date +'%Y-%m-%d_%H-%M-%S.%N'`;
jvdias 0cd02aa
	        /bin/mv "$dst" "$src";
jvdias 0cd02aa
	     fi;
jvdias 0cd02aa
	  fi;
jvdias 0cd02aa
       else
jvdias 0cd02aa
          dstlnk=`/usr/bin/readlink "$dst"`
jvdias 0cd02aa
	  if [ "$dstlnk" != $src ]; then
jvdias 0cd02aa
	     /bin/rm -f $dst;
jvdias 0cd02aa
	     if [ "$dstlnk" != "$dst" ] && [ -s $dstlnk ]; then
jvdias 0cd02aa
		 if [ "$dstlnk" -nt "$src" ] || [ ! "$dstlnk" -nt "$src" ] ; then		     
jvdias 0cd02aa
		     /bin/cp -fp "$dstlnk" "$dst".`/bin/date +'%Y-%m-%d_%H-%M-%S.%N'`;
jvdias 0cd02aa
		 else
jvdias 0cd02aa
		     /bin/mv "$src" "$src".`/bin/date +'%Y-%m-%d_%H-%M-%S.%N'`;
jvdias 0cd02aa
		     /bin/cp -fp "$dstlnk" "$src";
jvdias 0cd02aa
		 fi;
jvdias 0cd02aa
	     fi;
jvdias 0cd02aa
	  else
jvdias 0cd02aa
	     return 0;
jvdias 0cd02aa
	  fi;
jvdias 0cd02aa
       fi;
jvdias 0cd02aa
    fi; 
jvdias 0cd02aa
    /bin/ln -sf "$src" "$dst";
jvdias 0cd02aa
    return $?;
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
function replace_with_file()
jvdias 0cd02aa
{
jvdias 0cd02aa
    if [ $# -lt 2 ]; then
jvdias 0cd02aa
	return 1;
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    src=$1;
jvdias 0cd02aa
    dst=$2;
jvdias 0cd02aa
    if [ -z "$src" ] || [ -z "$dst" ] || [ "$src" = "$dst" ]; then
jvdias 0cd02aa
       return 1;
jvdias 0cd02aa
    fi
jvdias 0cd02aa
    if [ ! -e "$src" ]; then
jvdias 0cd02aa
       if [ -e "$dst" ]; then
jvdias 0cd02aa
	  /bin/rm -f $dst;
jvdias 0cd02aa
       fi;
jvdias 0cd02aa
       return 1;
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    if [ -e "$dst" ]; then
jvdias 0cd02aa
       if [ ! -L "$dst" ]; then
jvdias 0cd02aa
	   /bin/mv "$dst" "$dst".`/bin/date +'%Y-%m-%d_%H-%M-%S.%N'`;
jvdias 0cd02aa
       else
jvdias 0cd02aa
	   /bin/rm -f "$dst";
jvdias 0cd02aa
       fi;
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    /bin/mv -f "$src" "$dst";
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
function enable_bind_chroot()
jvdias 0cd02aa
{
jvdias 0cd02aa
    if /bin/egrep '^ROOTDIR=' /etc/sysconfig/named; then
jvdias 0cd02aa
	/bin/sed -i -e 's#^ROOTDIR=.*$#ROOTDIR='${BIND_CHROOT_PREFIX}'#' /etc/sysconfig/named ;
jvdias 0cd02aa
    else
jvdias 0cd02aa
	echo 'ROOTDIR='${BIND_CHROOT_PREFIX} >> /etc/sysconfig/named;
jvdias 0cd02aa
    fi
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
function disable_bind_chroot()
jvdias 0cd02aa
{
jvdias 0cd02aa
    /bin/sed -i -e '/^ROOTDIR=/d' /etc/sysconfig/named;    
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
function sync_files()
jvdias 0cd02aa
{
jvdias 0cd02aa
    shopt -q nullglob;
jvdias 0cd02aa
    ng=$?
jvdias 0cd02aa
    shopt -s nullglob;
jvdias 0cd02aa
    pfx=''
jvdias 0cd02aa
    if rootdir ; then # chroot is enabled
jvdias 0cd02aa
	/usr/bin/find /{etc/{named.*,rndc.*},${BIND_DIR#/}{/*,/data/*,/slaves/*}}  -maxdepth 0 -type f |
jvdias 0cd02aa
	while read f;
jvdias 0cd02aa
        do
jvdias 0cd02aa
	    replace_with_link ${BIND_CHROOT_PREFIX}/$f $f;
jvdias 0cd02aa
	done;
jvdias 0cd02aa
	pfx=${BIND_CHROOT_PREFIX}
jvdias 0cd02aa
    else              # chroot is disabled	
jvdias 0cd02aa
	/usr/bin/find /var/named/chroot/{etc/{named.*,rndc.*},var/named{/*,/data/*,/slaves/*}} -maxdepth 0 |
jvdias 0cd02aa
	while read f; 
jvdias 0cd02aa
	do
jvdias 0cd02aa
	    if [ ! -d "$f" ]; then
jvdias 0cd02aa
		replace_with_file $f ${f#$BIND_CHROOT_PREFIX};
jvdias 0cd02aa
	    fi;
jvdias 0cd02aa
	done
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    if [ $ng -eq 1 ]; then
jvdias 0cd02aa
	shopt -u nullglob;
jvdias 0cd02aa
    fi;
jvdias 0cd02aa
    chown root:named ${pfx}/var/named/* >/dev/null 2>&1;
jvdias 0cd02aa
    chmod 750 ${pfx}/var/named  >/dev/null 2>&1;
jvdias 0cd02aa
    chmod 640 ${pfx}/var/named/* >/dev/null 2>&1;
jvdias 0cd02aa
    chown named:named ${pfx}/var/named/{data{,/*},slaves{,*/}} >/dev/null 2>&1;
jvdias 0cd02aa
    chmod 770 ${pfx}/var/named/{data,slaves} >/dev/null 2>&1;
jvdias 0cd02aa
    chmod 640 ${pfx}/var/named/{data/*,slaves/*} >/dev/null 2>&1; 
jvdias 0cd02aa
#    [ -x /sbin/restorecon ] && /sbin/restorecon -R $pfx{/var/named,/etc/{named,rndc}.*}  -e ${BIND_CHROOT_PREFIX}/proc -e ${BIND_CHROOT_PREFIX}/var/run/dbus -e ${BIND_CHROOT_PREFIX}/dev >/dev/null 2>&1;
jvdias 0cd02aa
}
jvdias 0cd02aa
jvdias 0cd02aa
case $1 in 
jvdias 0cd02aa
    -e|--enable)
jvdias 0cd02aa
	enable_bind_chroot;
jvdias 0cd02aa
	sync_files;
jvdias 0cd02aa
	/sbin/service named condrestart
jvdias 0cd02aa
	exit $?;
jvdias 0cd02aa
	;;
jvdias 0cd02aa
    -d|--disable)
jvdias 0cd02aa
	disable_bind_chroot;
jvdias 0cd02aa
	sync_files;
jvdias 0cd02aa
	/sbin/service named condrestart
jvdias 0cd02aa
	exit $?;
jvdias 0cd02aa
	;;
jvdias 0cd02aa
    -s|--sync)
jvdias 0cd02aa
        sync_files;
jvdias 0cd02aa
	exit $?;
jvdias 0cd02aa
	;;
jvdias 0cd02aa
    -q)
jvdias 0cd02aa
	;;
jvdias 0cd02aa
    *)
jvdias 0cd02aa
	usage;
jvdias 0cd02aa
	exit 1;
jvdias 0cd02aa
esac