178344Sobrien#!/bin/sh 278344Sobrien# 398184Sgordon# $FreeBSD$ 478344Sobrien# 578344Sobrien 678344Sobrien# PROVIDE: named 7242153Sobrien# REQUIRE: SERVERS FILESYSTEMS 8139075Speadar# KEYWORD: shutdown 978344Sobrien 1078344Sobrien. /etc/rc.subr 1178344Sobrien 1278344Sobrienname="named" 13155595Sdougbrcvar=named_enable 14155595Sdougb 15155595Sdougbextra_commands="reload" 16155595Sdougb 17200448Sdougbstart_precmd="named_prestart" 18192215Sdougbstart_postcmd="named_poststart" 19155595Sdougbreload_cmd="named_reload" 20155595Sdougbstop_cmd="named_stop" 21139066Speadarstop_postcmd="named_poststop" 2278344Sobrien 2398184Sgordon# If running in a chroot cage, ensure that the appropriate files 2498184Sgordon# exist inside the cage, as well as helper symlinks into the cage 2598184Sgordon# from outside. 2698184Sgordon# 2798184Sgordon# As this is called after the is_running and required_dir checks 2898184Sgordon# are made in run_rc_command(), we can safely assume ${named_chrootdir} 2998184Sgordon# exists and named isn't running at this point (unless forcestart 3098184Sgordon# is used). 3198184Sgordon# 3298184Sgordonchroot_autoupdate() 3398184Sgordon{ 34181114Sdougb local file 35181114Sdougb 36135875Sdougb # Create (or update) the chroot directory structure 37104980Sschweikh # 38155595Sdougb if [ -r /etc/mtree/BIND.chroot.dist ]; then 39135875Sdougb mtree -deU -f /etc/mtree/BIND.chroot.dist \ 40135875Sdougb -p ${named_chrootdir} 41135875Sdougb else 42135875Sdougb warn "/etc/mtree/BIND.chroot.dist missing," 43135875Sdougb warn "chroot directory structure not updated" 44104980Sschweikh fi 45135875Sdougb 46201367Sdougb # Create (or update) the configuration directory symlink 47135875Sdougb # 48201367Sdougb if [ ! -L "${named_conf%/*}" ]; then 49201367Sdougb if [ -d "${named_conf%/*}" ]; then 50201367Sdougb warn "named chroot: ${named_conf%/*} is a directory!" 51201367Sdougb elif [ -e "${named_conf%/*}" ]; then 52201367Sdougb warn "named chroot: ${named_conf%/*} exists!" 53135875Sdougb else 54201367Sdougb ln -s ${named_confdir} ${named_conf%/*} 55135875Sdougb fi 56139015Sphk else 57139015Sphk # Make sure it points to the right place. 58201367Sdougb ln -shf ${named_confdir} ${named_conf%/*} 59135703Sdougb fi 6098184Sgordon 61135875Sdougb # Mount a devfs in the chroot directory if needed 62104980Sschweikh # 63188293Sbz if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then 64188293Sbz umount ${named_chrootdir}/dev 2>/dev/null 65188293Sbz devfs_domount ${named_chrootdir}/dev devfsrules_hide_all 66188293Sbz devfs -m ${named_chrootdir}/dev rule apply path null unhide 67188293Sbz devfs -m ${named_chrootdir}/dev rule apply path random unhide 68188293Sbz else 69188293Sbz if [ -c ${named_chrootdir}/dev/null -a \ 70188293Sbz -c ${named_chrootdir}/dev/random ]; then 71188293Sbz info "named chroot: using pre-mounted devfs." 72188293Sbz else 73188293Sbz err 1 "named chroot: devfs cannot be mounted from" \ 74188293Sbz "within a jail. Thus a chrooted named cannot" \ 75188293Sbz "be run from within a jail." \ 76188293Sbz "To run named without chrooting it, set" \ 77188293Sbz "named_chrootdir=\"\" in /etc/rc.conf." 78188293Sbz fi 79188293Sbz fi 80135875Sdougb 81192210Sdougb # Copy and/or update key files to the chroot /etc 82135875Sdougb # 83181114Sdougb for file in localtime protocols services; do 84181114Sdougb if [ -r /etc/$file ]; then 85181114Sdougb cmp -s /etc/$file "${named_chrootdir}/etc/$file" || 86181114Sdougb cp -p /etc/$file "${named_chrootdir}/etc/$file" 87181114Sdougb fi 88181114Sdougb done 8998184Sgordon} 9098184Sgordon 91135703Sdougb# Make symlinks to the correct pid file 9298184Sgordon# 9398184Sgordonmake_symlinks() 9498184Sgordon{ 95135703Sdougb checkyesno named_symlink_enable && 96155595Sdougb ln -fs "${named_chrootdir}${pidfile}" ${pidfile} 9798184Sgordon} 9898184Sgordon 99192215Sdougbnamed_poststart () { 100192215Sdougb make_symlinks 101192215Sdougb 102192215Sdougb if checkyesno named_wait; then 103192215Sdougb until ${command%/sbin/named}/bin/host $named_wait_host >/dev/null 2>&1; do 104192215Sdougb echo " Waiting for nameserver to resolve $named_wait_host" 105192215Sdougb sleep 1 106192215Sdougb done 107192215Sdougb fi 108192215Sdougb} 109192215Sdougb 110155595Sdougbnamed_reload() 111155595Sdougb{ 112172877Sdougb ${command%/named}/rndc reload 113155595Sdougb} 114155595Sdougb 115220962Sdougbfind_pidfile() 116220962Sdougb{ 117220962Sdougb if get_pidfile_from_conf pid-file $named_conf; then 118220962Sdougb pidfile="$_pidfile_from_conf" 119220962Sdougb else 120220962Sdougb pidfile="/var/run/named/pid" 121220962Sdougb fi 122220962Sdougb} 123220962Sdougb 124155595Sdougbnamed_stop() 125155595Sdougb{ 126220962Sdougb find_pidfile 127220962Sdougb 128172877Sdougb # This duplicates an undesirably large amount of code from the stop 129172877Sdougb # routine in rc.subr in order to use rndc to shut down the process, 130172877Sdougb # and to give it a second chance in case rndc fails. 131172877Sdougb rc_pid=$(check_pidfile $pidfile $command) 132172877Sdougb if [ -z "$rc_pid" ]; then 133172877Sdougb [ -n "$rc_fast" ] && return 0 134172877Sdougb _run_rc_notrunning 135172877Sdougb return 1 136172877Sdougb fi 137172877Sdougb echo 'Stopping named.' 138172877Sdougb if ${command%/named}/rndc stop 2>/dev/null; then 139172877Sdougb wait_for_pids $rc_pid 140155595Sdougb else 141172877Sdougb echo -n 'rndc failed, trying kill: ' 142172877Sdougb kill -TERM $rc_pid 143172877Sdougb wait_for_pids $rc_pid 144172877Sdougb fi 145155595Sdougb} 146155595Sdougb 147139066Speadarnamed_poststop() 148139066Speadar{ 149155595Sdougb if [ -n "${named_chrootdir}" -a -c ${named_chrootdir}/dev/null ]; then 150188293Sbz if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then 151188293Sbz umount ${named_chrootdir}/dev 2>/dev/null || true 152188293Sbz else 153188293Sbz warn "named chroot:" \ 154188293Sbz "cannot unmount devfs from inside jail!" 155188293Sbz fi 156139066Speadar fi 157139066Speadar} 158139066Speadar 159192215Sdougbcreate_file () { 160192215Sdougb if [ -e "$1" ]; then 161192215Sdougb unlink $1 162192215Sdougb fi 163192215Sdougb > $1 164192215Sdougb chown root:wheel $1 165192215Sdougb chmod 644 $1 166192215Sdougb} 167192215Sdougb 168200448Sdougbnamed_prestart() 16998184Sgordon{ 170220962Sdougb find_pidfile 171220962Sdougb 172220962Sdougb if [ -n "$named_pidfile" ]; then 173220962Sdougb warn 'named_pidfile: now determined from the conf file' 174220962Sdougb fi 175220962Sdougb 176200448Sdougb command_args="-u ${named_uid:=root}" 177200448Sdougb 178200448Sdougb if [ ! "$named_conf" = '/etc/namedb/named.conf' ]; then 179200448Sdougb case "$named_flags" in 180200448Sdougb -c*|*' -c'*) ;; # No need to add it 181200448Sdougb *) command_args="-c $named_conf $command_args" ;; 182200448Sdougb esac 183200448Sdougb fi 184200448Sdougb 185192215Sdougb local line nsip firstns 186192215Sdougb 187124622Smtm # Is the user using a sandbox? 188135875Sdougb # 189126978Sdougb if [ -n "$named_chrootdir" ]; then 190126978Sdougb rc_flags="$rc_flags -t $named_chrootdir" 191126978Sdougb checkyesno named_chroot_autoupdate && chroot_autoupdate 192135777Sdougb else 193135777Sdougb named_symlink_enable=NO 194124622Smtm fi 195135703Sdougb 196135703Sdougb # Create an rndc.key file for the user if none exists 197135875Sdougb # 198200448Sdougb confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \ 199201367Sdougb -c ${named_confdir}/rndc.key" 200201367Sdougb if [ -s "${named_confdir}/rndc.conf" ]; then 201200448Sdougb unset confgen_command 202135703Sdougb fi 203201370Sdougb if [ -s "${named_confdir}/rndc.key" ]; then 204201370Sdougb case `stat -f%Su ${named_confdir}/rndc.key` in 205172877Sdougb root|$named_uid) ;; 206172877Sdougb *) $confgen_command ;; 207172877Sdougb esac 208155595Sdougb else 209155595Sdougb $confgen_command 210155595Sdougb fi 211192215Sdougb 212207346Sdougb local checkconf 213207346Sdougb 214207346Sdougb checkconf="${command%/named}/named-checkconf" 215207346Sdougb if ! checkyesno named_chroot_autoupdate && [ -n "$named_chrootdir" ]; then 216207346Sdougb checkconf="$checkconf -t $named_chrootdir" 217207346Sdougb fi 218207346Sdougb 219192215Sdougb # Create a forwarder configuration based on /etc/resolv.conf 220192215Sdougb if checkyesno named_auto_forward; then 221192215Sdougb if [ ! -s /etc/resolv.conf ]; then 222192215Sdougb warn "named_auto_forward enabled, but no /etc/resolv.conf" 223192215Sdougb 224192215Sdougb # Empty the file in case it is included in named.conf 225201367Sdougb [ -s "${named_confdir}/auto_forward.conf" ] && 226201367Sdougb create_file ${named_confdir}/auto_forward.conf 227192215Sdougb 228207346Sdougb $checkconf $named_conf || 229192215Sdougb err 3 'named-checkconf for $named_conf failed' 230192215Sdougb return 231192215Sdougb fi 232192215Sdougb 233192215Sdougb create_file /var/run/naf-resolv.conf 234192215Sdougb create_file /var/run/auto_forward.conf 235192215Sdougb 236192215Sdougb echo ' forwarders {' > /var/run/auto_forward.conf 237192215Sdougb 238192215Sdougb while read line; do 239192215Sdougb case "$line" in 240192215Sdougb 'nameserver '*|'nameserver '*) 241192215Sdougb nsip=${line##nameserver[ ]} 242192215Sdougb 243192215Sdougb if [ -z "$firstns" ]; then 244192215Sdougb if [ ! "$nsip" = '127.0.0.1' ]; then 245192215Sdougb echo 'nameserver 127.0.0.1' 246192215Sdougb echo " ${nsip};" >> /var/run/auto_forward.conf 247192215Sdougb fi 248192215Sdougb 249192215Sdougb firstns=1 250192215Sdougb else 251192215Sdougb [ "$nsip" = '127.0.0.1' ] && continue 252192215Sdougb echo " ${nsip};" >> /var/run/auto_forward.conf 253192215Sdougb fi 254192215Sdougb ;; 255192215Sdougb esac 256192215Sdougb 257192215Sdougb echo $line 258192215Sdougb done < /etc/resolv.conf > /var/run/naf-resolv.conf 259192215Sdougb 260192215Sdougb echo ' };' >> /var/run/auto_forward.conf 261192215Sdougb echo '' >> /var/run/auto_forward.conf 262192215Sdougb if checkyesno named_auto_forward_only; then 263192215Sdougb echo " forward only;" >> /var/run/auto_forward.conf 264192215Sdougb else 265192215Sdougb echo " forward first;" >> /var/run/auto_forward.conf 266192215Sdougb fi 267192215Sdougb 268192215Sdougb if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then 269192215Sdougb unlink /var/run/naf-resolv.conf 270192215Sdougb else 271192215Sdougb [ -e /etc/resolv.conf ] && unlink /etc/resolv.conf 272192215Sdougb mv /var/run/naf-resolv.conf /etc/resolv.conf 273192215Sdougb fi 274192215Sdougb 275201367Sdougb if cmp -s ${named_confdir}/auto_forward.conf \ 276192215Sdougb /var/run/auto_forward.conf; then 277192215Sdougb unlink /var/run/auto_forward.conf 278192215Sdougb else 279201367Sdougb [ -e "${named_confdir}/auto_forward.conf" ] && 280201367Sdougb unlink ${named_confdir}/auto_forward.conf 281192215Sdougb mv /var/run/auto_forward.conf \ 282201367Sdougb ${named_confdir}/auto_forward.conf 283192215Sdougb fi 284192215Sdougb else 285192215Sdougb # Empty the file in case it is included in named.conf 286201367Sdougb [ -s "${named_confdir}/auto_forward.conf" ] && 287201367Sdougb create_file ${named_confdir}/auto_forward.conf 288192215Sdougb fi 289192215Sdougb 290207346Sdougb $checkconf $named_conf || err 3 'named-checkconf for $named_conf failed' 29198184Sgordon} 29298184Sgordon 29378344Sobrienload_rc_config $name 294200448Sdougb 295155595Sdougb# Updating the following variables requires that rc.conf be loaded first 29698184Sgordon# 29798184Sgordonrequired_dirs="$named_chrootdir" # if it is set, it must exist 298207346Sdougb 299201367Sdougbnamed_confdir="${named_chrootdir}${named_conf%/*}" 30098184Sgordon 30178344Sobrienrun_rc_command "$1" 302