]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - etc/rc.d/named
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / etc / rc.d / named
1 #!/bin/sh
2 #
3 # $FreeBSD$
4 #
5
6 # PROVIDE: named
7 # REQUIRE: SERVERS FILESYSTEMS
8 # KEYWORD: shutdown
9
10 . /etc/rc.subr
11
12 name="named"
13 rcvar=named_enable
14
15 extra_commands="reload"
16
17 start_precmd="named_prestart"
18 start_postcmd="named_poststart"
19 reload_cmd="named_reload"
20 stop_cmd="named_stop"
21 stop_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 #
32 chroot_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 #
93 make_symlinks()
94 {
95         checkyesno named_symlink_enable &&
96             ln -fs "${named_chrootdir}${pidfile}" ${pidfile}
97 }
98
99 named_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
110 named_reload()
111 {
112         ${command%/named}/rndc reload
113 }
114
115 find_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
124 named_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
147 named_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
159 create_file () {
160         if [ -e "$1" ]; then
161                 unlink $1
162         fi
163         > $1
164         chown root:wheel $1
165         chmod 644 $1
166 }
167
168 named_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
293 load_rc_config $name
294
295 # Updating the following variables requires that rc.conf be loaded first
296 #
297 required_dirs="$named_chrootdir"        # if it is set, it must exist
298
299 named_confdir="${named_chrootdir}${named_conf%/*}"
300
301 run_rc_command "$1"