]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - etc/rc.d/named
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / etc / rc.d / named
1 #!/bin/sh
2 #
3 # $FreeBSD$
4 #
5
6 # PROVIDE: named
7 # REQUIRE: SERVERS cleanvar
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 named_stop()
116 {
117         # This duplicates an undesirably large amount of code from the stop
118         # routine in rc.subr in order to use rndc to shut down the process,
119         # and to give it a second chance in case rndc fails.
120         rc_pid=$(check_pidfile $pidfile $command)
121         if [ -z "$rc_pid" ]; then
122                 [ -n "$rc_fast" ] && return 0
123                 _run_rc_notrunning
124                 return 1
125         fi
126         echo 'Stopping named.'
127         if ${command%/named}/rndc stop 2>/dev/null; then
128                 wait_for_pids $rc_pid
129         else
130                 echo -n 'rndc failed, trying kill: '
131                 kill -TERM $rc_pid
132                 wait_for_pids $rc_pid
133         fi
134 }
135
136 named_poststop()
137 {
138         if [ -n "${named_chrootdir}" -a -c ${named_chrootdir}/dev/null ]; then
139                 if [ `${SYSCTL_N} security.jail.jailed` -eq 0 ]; then
140                         umount ${named_chrootdir}/dev 2>/dev/null || true
141                 else
142                         warn "named chroot:" \
143                             "cannot unmount devfs from inside jail!"
144                 fi
145         fi
146 }
147
148 create_file () {
149         if [ -e "$1" ]; then
150                 unlink $1
151         fi
152         > $1
153         chown root:wheel $1
154         chmod 644 $1
155 }
156
157 named_prestart()
158 {
159         command_args="-u ${named_uid:=root}"
160
161         if [ ! "$named_conf" = '/etc/namedb/named.conf' ]; then
162                 case "$named_flags" in
163                 -c*|*' -c'*) ;;         # No need to add it
164                 *) command_args="-c $named_conf $command_args" ;;
165                 esac
166         fi
167
168         local line nsip firstns
169
170         # Is the user using a sandbox?
171         #
172         if [ -n "$named_chrootdir" ]; then
173                 rc_flags="$rc_flags -t $named_chrootdir"
174                 checkyesno named_chroot_autoupdate && chroot_autoupdate
175         else
176                 named_symlink_enable=NO
177         fi
178
179         # Create an rndc.key file for the user if none exists
180         #
181         confgen_command="${command%/named}/rndc-confgen -a -b256 -u $named_uid \
182             -c ${named_confdir}/rndc.key"
183         if [ -s "${named_confdir}/rndc.conf" ]; then
184                 unset confgen_command
185         fi
186         if [ -s "${named_confdir}/rndc.key" ]; then
187                 case `stat -f%Su ${named_confdir}/rndc.key` in
188                 root|$named_uid) ;;
189                 *) $confgen_command ;;
190                 esac
191         else
192                 $confgen_command
193         fi
194
195         local checkconf
196
197         checkconf="${command%/named}/named-checkconf"
198         if ! checkyesno named_chroot_autoupdate && [ -n "$named_chrootdir" ]; then
199                 checkconf="$checkconf -t $named_chrootdir"
200         fi
201
202         # Create a forwarder configuration based on /etc/resolv.conf
203         if checkyesno named_auto_forward; then
204                 if [ ! -s /etc/resolv.conf ]; then
205                         warn "named_auto_forward enabled, but no /etc/resolv.conf"
206
207                         # Empty the file in case it is included in named.conf
208                         [ -s "${named_confdir}/auto_forward.conf" ] &&
209                             create_file ${named_confdir}/auto_forward.conf
210
211                         $checkconf $named_conf ||
212                             err 3 'named-checkconf for $named_conf failed'
213                         return
214                 fi
215
216                 create_file /var/run/naf-resolv.conf
217                 create_file /var/run/auto_forward.conf
218
219                 echo '  forwarders {' > /var/run/auto_forward.conf
220
221                 while read line; do
222                         case "$line" in
223                         'nameserver '*|'nameserver      '*)
224                                 nsip=${line##nameserver[         ]}
225
226                                 if [ -z "$firstns" ]; then
227                                         if [ ! "$nsip" = '127.0.0.1' ]; then
228                                                 echo 'nameserver 127.0.0.1'
229                                                 echo "          ${nsip};" >> /var/run/auto_forward.conf
230                                         fi
231
232                                         firstns=1
233                                 else
234                                         [ "$nsip" = '127.0.0.1' ] && continue
235                                         echo "          ${nsip};" >> /var/run/auto_forward.conf
236                                 fi
237                                 ;;
238                         esac
239
240                         echo $line
241                 done < /etc/resolv.conf > /var/run/naf-resolv.conf
242
243                 echo '  };' >> /var/run/auto_forward.conf
244                 echo '' >> /var/run/auto_forward.conf
245                 if checkyesno named_auto_forward_only; then
246                         echo "  forward only;" >> /var/run/auto_forward.conf
247                 else
248                         echo "  forward first;" >> /var/run/auto_forward.conf
249                 fi
250
251                 if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then
252                         unlink /var/run/naf-resolv.conf
253                 else
254                         [ -e /etc/resolv.conf ] && unlink /etc/resolv.conf
255                         mv /var/run/naf-resolv.conf /etc/resolv.conf
256                 fi
257
258                 if cmp -s ${named_confdir}/auto_forward.conf \
259                     /var/run/auto_forward.conf; then
260                         unlink /var/run/auto_forward.conf
261                 else
262                         [ -e "${named_confdir}/auto_forward.conf" ] &&
263                             unlink ${named_confdir}/auto_forward.conf
264                         mv /var/run/auto_forward.conf \
265                             ${named_confdir}/auto_forward.conf
266                 fi
267         else
268                 # Empty the file in case it is included in named.conf
269                 [ -s "${named_confdir}/auto_forward.conf" ] &&
270                     create_file ${named_confdir}/auto_forward.conf
271         fi
272
273         $checkconf $named_conf || err 3 'named-checkconf for $named_conf failed'
274 }
275
276 load_rc_config $name
277
278 # Updating the following variables requires that rc.conf be loaded first
279 #
280 required_dirs="$named_chrootdir"        # if it is set, it must exist
281
282 pidfile="${named_pidfile:-/var/run/named/pid}"
283 named_confdir="${named_chrootdir}${named_conf%/*}"
284
285 run_rc_command "$1"