232b6c98b4
systems are fully "ready to go". 'FILESYSTEMS' states: "This is a dummy dependency, for services which require file systems to be mounted before starting." However, we have 'var' which is was run after 'FILESYSTEMS' and can mount /var if it already isn't mounted. Furthermore, several scripts cannot use /var until 'cleanvar' has done its thing. Thus "FILESYSTEMS" hasn't really meant all critical file systems are fully usable.
302 lines
7.3 KiB
Bash
Executable File
302 lines
7.3 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
|
|
# PROVIDE: named
|
|
# REQUIRE: SERVERS FILESYSTEMS
|
|
# KEYWORD: shutdown
|
|
|
|
. /etc/rc.subr
|
|
|
|
name="named"
|
|
rcvar=named_enable
|
|
|
|
extra_commands="reload"
|
|
|
|
start_precmd="named_prestart"
|
|
start_postcmd="named_poststart"
|
|
reload_cmd="named_reload"
|
|
stop_cmd="named_stop"
|
|
stop_postcmd="named_poststop"
|
|
|
|
# If running in a chroot cage, ensure that the appropriate files
|
|
# exist inside the cage, as well as helper symlinks into the cage
|
|
# from outside.
|
|
#
|
|
# As this is called after the is_running and required_dir checks
|
|
# are made in run_rc_command(), we can safely assume ${named_chrootdir}
|
|
# exists and named isn't running at this point (unless forcestart
|
|
# is used).
|
|
#
|
|
chroot_autoupdate()
|
|
{
|
|
local file
|
|
|
|
# Create (or update) the chroot directory structure
|
|
#
|
|
if [ -r /etc/mtree/BIND.chroot.dist ]; then
|
|
mtree -deU -f /etc/mtree/BIND.chroot.dist \
|
|
-p ${named_chrootdir}
|
|
else
|
|
warn "/etc/mtree/BIND.chroot.dist missing,"
|
|
warn "chroot directory structure not updated"
|
|
fi
|
|
|
|
# Create (or update) the configuration directory symlink
|
|
#
|
|
if [ ! -L "${named_conf%/*}" ]; then
|
|
if [ -d "${named_conf%/*}" ]; then
|
|
warn "named chroot: ${named_conf%/*} is a directory!"
|
|
elif [ -e "${named_conf%/*}" ]; then
|
|
warn "named chroot: ${named_conf%/*} exists!"
|
|
else
|
|
ln -s ${named_confdir} ${named_conf%/*}
|
|
fi
|
|
else
|
|
# Make sure it points to the right place.
|
|
ln -shf ${named_confdir} ${named_conf%/*}
|
|
fi
|
|
|
|
# Mount a devfs in the chroot directory if needed
|
|
#
|
|
if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then
|
|
umount ${named_chrootdir}/dev 2>/dev/null
|
|
devfs_domount ${named_chrootdir}/dev devfsrules_hide_all
|
|
devfs -m ${named_chrootdir}/dev rule apply path null unhide
|
|
devfs -m ${named_chrootdir}/dev rule apply path random unhide
|
|
else
|
|
if [ -c ${named_chrootdir}/dev/null -a \
|
|
-c ${named_chrootdir}/dev/random ]; then
|
|
info "named chroot: using pre-mounted devfs."
|
|
else
|
|
err 1 "named chroot: devfs cannot be mounted from" \
|
|
"within a jail. Thus a chrooted named cannot" \
|
|
"be run from within a jail." \
|
|
"To run named without chrooting it, set" \
|
|
"named_chrootdir=\"\" in /etc/rc.conf."
|
|
fi
|
|
fi
|
|
|
|
# Copy and/or update key files to the chroot /etc
|
|
#
|
|
for file in localtime protocols services; do
|
|
if [ -r /etc/$file ]; then
|
|
cmp -s /etc/$file "${named_chrootdir}/etc/$file" ||
|
|
cp -p /etc/$file "${named_chrootdir}/etc/$file"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Make symlinks to the correct pid file
|
|
#
|
|
make_symlinks()
|
|
{
|
|
checkyesno named_symlink_enable &&
|
|
ln -fs "${named_chrootdir}${pidfile}" ${pidfile}
|
|
}
|
|
|
|
named_poststart() {
|
|
make_symlinks
|
|
|
|
if checkyesno named_wait; then
|
|
until ${command%/sbin/named}/bin/host $named_wait_host >/dev/null 2>&1; do
|
|
echo " Waiting for nameserver to resolve $named_wait_host"
|
|
sleep 1
|
|
done
|
|
fi
|
|
}
|
|
|
|
named_reload()
|
|
{
|
|
${command%/named}/rndc reload
|
|
}
|
|
|
|
find_pidfile()
|
|
{
|
|
if get_pidfile_from_conf pid-file $named_conf; then
|
|
pidfile="$_pidfile_from_conf"
|
|
else
|
|
pidfile="/var/run/named/pid"
|
|
fi
|
|
}
|
|
|
|
named_stop()
|
|
{
|
|
find_pidfile
|
|
|
|
# This duplicates an undesirably large amount of code from the stop
|
|
# routine in rc.subr in order to use rndc to shut down the process,
|
|
# and to give it a second chance in case rndc fails.
|
|
rc_pid=$(check_pidfile $pidfile $command)
|
|
if [ -z "$rc_pid" ]; then
|
|
[ -n "$rc_fast" ] && return 0
|
|
_run_rc_notrunning
|
|
return 1
|
|
fi
|
|
echo 'Stopping named.'
|
|
if ${command%/named}/rndc stop 2>/dev/null; then
|
|
wait_for_pids $rc_pid
|
|
else
|
|
echo -n 'rndc failed, trying kill: '
|
|
kill -TERM $rc_pid
|
|
wait_for_pids $rc_pid
|
|
fi
|
|
}
|
|
|
|
named_poststop()
|
|
{
|
|
if [ -n "${named_chrootdir}" -a -c ${named_chrootdir}/dev/null ]; then
|
|
if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then
|
|
umount ${named_chrootdir}/dev 2>/dev/null || true
|
|
else
|
|
warn "named chroot:" \
|
|
"cannot unmount devfs from inside jail!"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
create_file() {
|
|
if [ -e "$1" ]; then
|
|
unlink $1
|
|
fi
|
|
> $1
|
|
chown root:wheel $1
|
|
chmod 644 $1
|
|
}
|
|
|
|
named_prestart()
|
|
{
|
|
find_pidfile
|
|
|
|
if [ -n "$named_pidfile" ]; then
|
|
warn 'named_pidfile: now determined from the conf file'
|
|
fi
|
|
|
|
command_args="-u ${named_uid:=root}"
|
|
|
|
if [ ! "$named_conf" = '/etc/namedb/named.conf' ]; then
|
|
case "$named_flags" in
|
|
-c*|*' -c'*) ;; # No need to add it
|
|
*) command_args="-c $named_conf $command_args" ;;
|
|
esac
|
|
fi
|
|
|
|
local line nsip firstns
|
|
|
|
# Is the user using a sandbox?
|
|
#
|
|
if [ -n "$named_chrootdir" ]; then
|
|
rc_flags="$rc_flags -t $named_chrootdir"
|
|
checkyesno named_chroot_autoupdate && chroot_autoupdate
|
|
else
|
|
named_symlink_enable=NO
|
|
fi
|
|
|
|
# Create an rndc.key file for the user if none exists
|
|
#
|
|
confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \
|
|
-c ${named_confdir}/rndc.key"
|
|
if [ -s "${named_confdir}/rndc.conf" ]; then
|
|
unset confgen_command
|
|
fi
|
|
if [ -s "${named_confdir}/rndc.key" ]; then
|
|
case `stat -f%Su ${named_confdir}/rndc.key` in
|
|
root|$named_uid) ;;
|
|
*) $confgen_command ;;
|
|
esac
|
|
else
|
|
$confgen_command
|
|
fi
|
|
|
|
local checkconf
|
|
|
|
checkconf="${command%/named}/named-checkconf"
|
|
if ! checkyesno named_chroot_autoupdate && [ -n "$named_chrootdir" ]; then
|
|
checkconf="$checkconf -t $named_chrootdir"
|
|
fi
|
|
|
|
# Create a forwarder configuration based on /etc/resolv.conf
|
|
if checkyesno named_auto_forward; then
|
|
if [ ! -s /etc/resolv.conf ]; then
|
|
warn "named_auto_forward enabled, but no /etc/resolv.conf"
|
|
|
|
# Empty the file in case it is included in named.conf
|
|
[ -s "${named_confdir}/auto_forward.conf" ] &&
|
|
create_file ${named_confdir}/auto_forward.conf
|
|
|
|
$checkconf $named_conf ||
|
|
err 3 'named-checkconf for $named_conf failed'
|
|
return
|
|
fi
|
|
|
|
create_file /var/run/naf-resolv.conf
|
|
create_file /var/run/auto_forward.conf
|
|
|
|
echo ' forwarders {' > /var/run/auto_forward.conf
|
|
|
|
while read line; do
|
|
case "$line" in
|
|
'nameserver '*|'nameserver '*)
|
|
nsip=${line##nameserver[ ]}
|
|
|
|
if [ -z "$firstns" ]; then
|
|
if [ ! "$nsip" = '127.0.0.1' ]; then
|
|
echo 'nameserver 127.0.0.1'
|
|
echo " ${nsip};" >> /var/run/auto_forward.conf
|
|
fi
|
|
|
|
firstns=1
|
|
else
|
|
[ "$nsip" = '127.0.0.1' ] && continue
|
|
echo " ${nsip};" >> /var/run/auto_forward.conf
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
echo $line
|
|
done < /etc/resolv.conf > /var/run/naf-resolv.conf
|
|
|
|
echo ' };' >> /var/run/auto_forward.conf
|
|
echo '' >> /var/run/auto_forward.conf
|
|
if checkyesno named_auto_forward_only; then
|
|
echo " forward only;" >> /var/run/auto_forward.conf
|
|
else
|
|
echo " forward first;" >> /var/run/auto_forward.conf
|
|
fi
|
|
|
|
if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then
|
|
unlink /var/run/naf-resolv.conf
|
|
else
|
|
[ -e /etc/resolv.conf ] && unlink /etc/resolv.conf
|
|
mv /var/run/naf-resolv.conf /etc/resolv.conf
|
|
fi
|
|
|
|
if cmp -s ${named_confdir}/auto_forward.conf \
|
|
/var/run/auto_forward.conf; then
|
|
unlink /var/run/auto_forward.conf
|
|
else
|
|
[ -e "${named_confdir}/auto_forward.conf" ] &&
|
|
unlink ${named_confdir}/auto_forward.conf
|
|
mv /var/run/auto_forward.conf \
|
|
${named_confdir}/auto_forward.conf
|
|
fi
|
|
else
|
|
# Empty the file in case it is included in named.conf
|
|
[ -s "${named_confdir}/auto_forward.conf" ] &&
|
|
create_file ${named_confdir}/auto_forward.conf
|
|
fi
|
|
|
|
$checkconf $named_conf || err 3 'named-checkconf for $named_conf failed'
|
|
}
|
|
|
|
load_rc_config $name
|
|
|
|
# Updating the following variables requires that rc.conf be loaded first
|
|
#
|
|
required_dirs="$named_chrootdir" # if it is set, it must exist
|
|
|
|
named_confdir="${named_chrootdir}${named_conf%/*}"
|
|
|
|
run_rc_command "$1"
|