1#!/bin/sh 2# 3# $FreeBSD$ 4# 5 6# PROVIDE: named 7# REQUIRE: SERVERS FILESYSTEMS 8# KEYWORD: shutdown 9 10. /etc/rc.subr 11 12name="named" 13rcvar=named_enable 14 15extra_commands="reload" 16 17start_precmd="named_prestart" 18start_postcmd="named_poststart" 19reload_cmd="named_reload" 20stop_cmd="named_stop" 21stop_postcmd="named_poststop" 22 23# If running in a chroot cage, ensure that the appropriate files 24# exist inside the cage, as well as helper symlinks into the cage 25# from outside. 26# 27# As this is called after the is_running and required_dir checks 28# are made in run_rc_command(), we can safely assume ${named_chrootdir} 29# exists and named isn't running at this point (unless forcestart 30# is used). 31# 32chroot_autoupdate() 33{ 34 local file 35 36 # Create (or update) the chroot directory structure 37 # 38 if [ -r /etc/mtree/BIND.chroot.dist ]; then 39 mtree -deU -f /etc/mtree/BIND.chroot.dist \ 40 -p ${named_chrootdir} 41 else 42 warn "/etc/mtree/BIND.chroot.dist missing," 43 warn "chroot directory structure not updated" 44 fi 45 46 # Create (or update) the configuration directory symlink 47 # 48 if [ ! -L "${named_conf%/*}" ]; then 49 if [ -d "${named_conf%/*}" ]; then 50 warn "named chroot: ${named_conf%/*} is a directory!" 51 elif [ -e "${named_conf%/*}" ]; then 52 warn "named chroot: ${named_conf%/*} exists!" 53 else 54 ln -s ${named_confdir} ${named_conf%/*} 55 fi 56 else 57 # Make sure it points to the right place. 58 ln -shf ${named_confdir} ${named_conf%/*} 59 fi 60 61 # Mount a devfs in the chroot directory if needed 62 # 63 if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then 64 umount ${named_chrootdir}/dev 2>/dev/null 65 devfs_domount ${named_chrootdir}/dev devfsrules_hide_all 66 devfs -m ${named_chrootdir}/dev rule apply path null unhide 67 devfs -m ${named_chrootdir}/dev rule apply path random unhide 68 else 69 if [ -c ${named_chrootdir}/dev/null -a \ 70 -c ${named_chrootdir}/dev/random ]; then 71 info "named chroot: using pre-mounted devfs." 72 else 73 err 1 "named chroot: devfs cannot be mounted from" \ 74 "within a jail. Thus a chrooted named cannot" \ 75 "be run from within a jail." \ 76 "To run named without chrooting it, set" \ 77 "named_chrootdir=\"\" in /etc/rc.conf." 78 fi 79 fi 80 81 # Copy and/or update key files to the chroot /etc 82 # 83 for file in localtime protocols services; do 84 if [ -r /etc/$file ]; then 85 cmp -s /etc/$file "${named_chrootdir}/etc/$file" || 86 cp -p /etc/$file "${named_chrootdir}/etc/$file" 87 fi 88 done 89} 90 91# Make symlinks to the correct pid file 92# 93make_symlinks() 94{ 95 checkyesno named_symlink_enable && 96 ln -fs "${named_chrootdir}${pidfile}" ${pidfile} 97} 98 99named_poststart () { 100 make_symlinks 101 102 if checkyesno named_wait; then 103 until ${command%/sbin/named}/bin/host $named_wait_host >/dev/null 2>&1; do 104 echo " Waiting for nameserver to resolve $named_wait_host" 105 sleep 1 106 done 107 fi 108} 109 110named_reload() 111{ 112 ${command%/named}/rndc reload 113} 114 115find_pidfile() 116{ 117 if get_pidfile_from_conf pid-file $named_conf; then 118 pidfile="$_pidfile_from_conf" 119 else 120 pidfile="/var/run/named/pid" 121 fi 122} 123 124named_stop() 125{ 126 find_pidfile 127 128 # This duplicates an undesirably large amount of code from the stop 129 # routine in rc.subr in order to use rndc to shut down the process, 130 # and to give it a second chance in case rndc fails. 131 rc_pid=$(check_pidfile $pidfile $command) 132 if [ -z "$rc_pid" ]; then 133 [ -n "$rc_fast" ] && return 0 134 _run_rc_notrunning 135 return 1 136 fi 137 echo 'Stopping named.' 138 if ${command%/named}/rndc stop 2>/dev/null; then 139 wait_for_pids $rc_pid 140 else 141 echo -n 'rndc failed, trying kill: ' 142 kill -TERM $rc_pid 143 wait_for_pids $rc_pid 144 fi 145} 146 147named_poststop() 148{ 149 if [ -n "${named_chrootdir}" -a -c ${named_chrootdir}/dev/null ]; then 150 if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then 151 umount ${named_chrootdir}/dev 2>/dev/null || true 152 else 153 warn "named chroot:" \ 154 "cannot unmount devfs from inside jail!" 155 fi 156 fi 157} 158 159create_file () { 160 if [ -e "$1" ]; then 161 unlink $1 162 fi 163 > $1 164 chown root:wheel $1 165 chmod 644 $1 166} 167 168named_prestart() 169{ 170 find_pidfile 171 172 if [ -n "$named_pidfile" ]; then 173 warn 'named_pidfile: now determined from the conf file' 174 fi 175 176 command_args="-u ${named_uid:=root}" 177 178 if [ ! "$named_conf" = '/etc/namedb/named.conf' ]; then 179 case "$named_flags" in 180 -c*|*' -c'*) ;; # No need to add it 181 *) command_args="-c $named_conf $command_args" ;; 182 esac 183 fi 184 185 local line nsip firstns 186 187 # Is the user using a sandbox? 188 # 189 if [ -n "$named_chrootdir" ]; then 190 rc_flags="$rc_flags -t $named_chrootdir" 191 checkyesno named_chroot_autoupdate && chroot_autoupdate 192 else 193 named_symlink_enable=NO 194 fi 195 196 # Create an rndc.key file for the user if none exists 197 # 198 confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \ 199 -c ${named_confdir}/rndc.key" 200 if [ -s "${named_confdir}/rndc.conf" ]; then 201 unset confgen_command 202 fi 203 if [ -s "${named_confdir}/rndc.key" ]; then 204 case `stat -f%Su ${named_confdir}/rndc.key` in 205 root|$named_uid) ;; 206 *) $confgen_command ;; 207 esac 208 else 209 $confgen_command 210 fi 211 212 local checkconf 213 214 checkconf="${command%/named}/named-checkconf" 215 if ! checkyesno named_chroot_autoupdate && [ -n "$named_chrootdir" ]; then 216 checkconf="$checkconf -t $named_chrootdir" 217 fi 218 219 # Create a forwarder configuration based on /etc/resolv.conf 220 if checkyesno named_auto_forward; then 221 if [ ! -s /etc/resolv.conf ]; then 222 warn "named_auto_forward enabled, but no /etc/resolv.conf" 223 224 # Empty the file in case it is included in named.conf 225 [ -s "${named_confdir}/auto_forward.conf" ] && 226 create_file ${named_confdir}/auto_forward.conf 227 228 $checkconf $named_conf || 229 err 3 'named-checkconf for $named_conf failed' 230 return 231 fi 232 233 create_file /var/run/naf-resolv.conf 234 create_file /var/run/auto_forward.conf 235 236 echo ' forwarders {' > /var/run/auto_forward.conf 237 238 while read line; do 239 case "$line" in 240 'nameserver '*|'nameserver '*) 241 nsip=${line##nameserver[ ]} 242 243 if [ -z "$firstns" ]; then 244 if [ ! "$nsip" = '127.0.0.1' ]; then 245 echo 'nameserver 127.0.0.1' 246 echo " ${nsip};" >> /var/run/auto_forward.conf 247 fi 248 249 firstns=1 250 else 251 [ "$nsip" = '127.0.0.1' ] && continue 252 echo " ${nsip};" >> /var/run/auto_forward.conf 253 fi 254 ;; 255 esac 256 257 echo $line 258 done < /etc/resolv.conf > /var/run/naf-resolv.conf 259 260 echo ' };' >> /var/run/auto_forward.conf 261 echo '' >> /var/run/auto_forward.conf 262 if checkyesno named_auto_forward_only; then 263 echo " forward only;" >> /var/run/auto_forward.conf 264 else 265 echo " forward first;" >> /var/run/auto_forward.conf 266 fi 267 268 if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then 269 unlink /var/run/naf-resolv.conf 270 else 271 [ -e /etc/resolv.conf ] && unlink /etc/resolv.conf 272 mv /var/run/naf-resolv.conf /etc/resolv.conf 273 fi 274 275 if cmp -s ${named_confdir}/auto_forward.conf \ 276 /var/run/auto_forward.conf; then 277 unlink /var/run/auto_forward.conf 278 else 279 [ -e "${named_confdir}/auto_forward.conf" ] && 280 unlink ${named_confdir}/auto_forward.conf 281 mv /var/run/auto_forward.conf \ 282 ${named_confdir}/auto_forward.conf 283 fi 284 else 285 # Empty the file in case it is included in named.conf 286 [ -s "${named_confdir}/auto_forward.conf" ] && 287 create_file ${named_confdir}/auto_forward.conf 288 fi 289 290 $checkconf $named_conf || err 3 'named-checkconf for $named_conf failed' 291} 292 293load_rc_config $name 294 295# Updating the following variables requires that rc.conf be loaded first 296# 297required_dirs="$named_chrootdir" # if it is set, it must exist 298 299named_confdir="${named_chrootdir}${named_conf%/*}" 300 301run_rc_command "$1" 302