Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Apr 2008 14:31:25 +0400
From:      Eygene Ryabinkin <rea-fbsd@codelabs.ru>
To:        Jeremie Le Hen <jeremie@le-hen.org>
Cc:        freebsd-current@freebsd.org
Subject:   Re: [RFC] Automated generation of /etc/resolv.conf from the rc.d script
Message-ID:  <HLegrdNFV10zl33MHY7jBDOb%2BA4@EEu6nkWAZTlxOp7ENdKMY8AImHg>
In-Reply-To: <20080423190659.GT92168@obiwan.tataz.chchile.org>
References:  <dEZnki0Fi32EvMrDEnqcgDeNQSc@Bbw9J2Iynx0QjNoWuQ4YSitYS3A> <72389.1197629858@critter.freebsd.dk> <MIKiw94aov2StL37zxYPU2cwfyE@NKorCT8tqQREs5VbYbldlgOz9%2B8> <RlIwVx1VnA2Q57cUUvUPn30sch4@BBB3ZKOzjjN0cxeKaWhgH87x7VY> <20080423190659.GT92168@obiwan.tataz.chchile.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--LyciRD1jyfeSSjG0
Content-Type: text/plain; charset=koi8-r
Content-Disposition: inline

Jeremie, good day.

Wed, Apr 23, 2008 at 09:06:59PM +0200, Jeremie Le Hen wrote:
> On Mon, Apr 14, 2008 at 07:44:13PM +0400, Eygene Ryabinkin wrote:
> > [...]
> > Testing and feedback are more than welcome.
> 
> I didn't test your patch but I have a have a few comments about it:
> 
> In install_new_file(), I don't think you should test for $CMP being an
> executable file...  It is in the base system and the rule of thumb in
> other rc.d scripts is to use those directly.

OK, I just followed the practice of dhclient-script, since some of
the code was written after looking at that file.  But if the
FreeBSD'sh way to do it is just to use $CMP as is, I am not against
it.  Although, such check should not harm anything and since it
uses built-in '[' command, it even does not invoke fork/exec sequence.
But it uses fstat ;))  I had not changed it yet, but I am currently
thinking about it.  More opinions are welcome ;))

> I'm not sure you should chown/chmod the forwarders file.  People may
> have custom setup that you should not interfere with without a good
> reason.

OK, I will do chown/chmod only for previously nonexistent forwarders
file.  No changes will be done for the existing object.

> Also, I would rather let add_new_bind_forwarders() build the "empty"
> forwarders file, it would make more sense IMHO.  You could then put a
> single call to add_new_bind_forwarders() at the end of the script under
> a $resolv_build_named_forwarders condition.  It makes more sense indeed
> to test this outside of the function, my personal feeling being that it
> makes the reading less puzzling.

OK, I took your idea and developed it a bit further: now the if-elif-else
branch just sets some variables and the creation of the files tooks
place at the end of the script.

The patch with these modifications is attached.  It is not very much
tested by me now, so I will not add it to the PR until it will receive
the good amount of testing.  But I am attaching it here for you and
others to have the possibility to test and/or comment.

I had slightly changed the second patch, making temporary filenames
be PID-based to catch two concurrent instances of the script running
at the same time.  This is not the best way to do it, but at least
file contents will be sane.  The modified version of the second patch
is also attached.  It needs testing too, so it is preliminary as well.

> Anyway, thank you very much for your work.  I think many people will
> enjoy it once it will hit the source tree.

Thank you!
-- 
Eygene

--LyciRD1jyfeSSjG0
Content-Type: text/x-diff; charset=koi8-r
Content-Disposition: attachment; filename="resolv.2.patch"

>From 6537efa58e4a454c2f54c25091f85a5c6557d49b Mon Sep 17 00:00:00 2001
From: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
Date: Sun, 13 Apr 2008 15:24:55 +0400
Subject: [PATCH] Implement creation of named(8) forwarders file via /etc/rc.d/resolv

Following the idea of Poul Henning-Kamp, the automated creation of
the named forwarders file is implemented.  In such configuration
local named is thought to be used as the smart DNS cache.

The following new rc.conf variables were introduced:
- resolv_build_named_forwarders,
- resolv_named_forwarders_file,
- resolv_named_ip.

New manual page, resolv(8), was written.  Manual page rc.conf(5)
was updated, reflecting the introduction of new variables.

dhclient-script was changed to use /etc/rc.d/resolv to create
/etc/resolv.conf.  New kenv leaf, dhclient.*, was created (actually,
there is no kenv registry, so I just used variables from the kenv's
dhclient.* namespace) and DNS variables, obtained by dhclient, are
stored there.

I tried to minimize the impact of the dhclient-script changes upon
the next updates of dhclient(8) from OpenBSD, so a new function
that replaced add_new_resolv_conf was introduced.

Commented entries about the usage of the generated forwarders file
were added to the stock named.conf file.

Signed-off-by: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
---
 etc/defaults/rc.conf          |    8 ++
 etc/namedb/named.conf         |   12 ++
 etc/rc.d/resolv               |  124 ++++++++++++++++++--
 sbin/dhclient/dhclient-script |   23 ++++-
 share/man/man5/rc.conf.5      |   18 +++
 share/man/man8/Makefile       |    1 +
 share/man/man8/resolv.8       |  259 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 434 insertions(+), 11 deletions(-)
 create mode 100644 share/man/man8/resolv.8

diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf
index cd9c142..8ef35d7 100644
--- a/etc/defaults/rc.conf
+++ b/etc/defaults/rc.conf
@@ -243,6 +243,14 @@ resolv_domain=""		# DNS domain we're in.
 resolv_nameservers=""		# List of DNS server IPs, separated by comma or space.
 
 #
+# resolv. Building of named's forwarders file via dhclient or
+# directly via /etc/rc.d/resolv.
+#
+resolv_build_named_forwarders="NO"	# Build forwarders?
+resolv_named_forwarders_file=/etc/namedb/named.forwarders.conf	# Forwarders file
+resolv_named_ip=127.0.0.1		# Where named is listening for requests
+
+#
 # kerberos. Do not run the admin daemons on slave servers
 #
 kerberos5_server_enable="NO"	# Run a kerberos 5 master server (or NO).
diff --git a/etc/namedb/named.conf b/etc/namedb/named.conf
index bda9a02..508abf5 100644
--- a/etc/namedb/named.conf
+++ b/etc/namedb/named.conf
@@ -45,6 +45,18 @@ options {
 		127.0.0.1;
 	};
 */
+
+// If you're building the forwarders table automatically (option
+// resolv_build_named_forwarders is set to the appropriate value
+// in the /etc/rc.conf), then you will want to uncomment the next
+// line to include the created forwarders table.
+// The default forwarders file name is used.  If you had customized
+// its location via rc.conf's variable resolv_named_forwarders_file,
+// replace the name here as well.
+/*
+	include "/etc/namedb/named.forwarders.conf";
+ */
+
 	/*
 	 * If there is a firewall between you and nameservers you want
 	 * to talk to, you might need to uncomment the query-source
diff --git a/etc/rc.d/resolv b/etc/rc.d/resolv
index 3f36a0c..e5f9f32 100644
--- a/etc/rc.d/resolv
+++ b/etc/rc.d/resolv
@@ -38,6 +38,9 @@ stop_cmd=':'
 
 load_rc_config $name
 
+RNDC=/usr/sbin/rndc
+CMP=/usr/bin/cmp
+
 # Helper that echoes the contents of the resolv.conf to the stdout.
 # Arguments:
 # 1. domain name,
@@ -47,26 +50,129 @@ load_rc_config $name
 build_resolv () {
 	if [ -n "$1" ]; then
 		echo domain "$1"
+		echo search "$1"
+	fi
+
+	if checkyesno resolv_build_named_forwarders &&
+	    checkyesno named_enable; then
+		echo "nameserver $resolv_named_ip"
 	fi
 
 	set -- "$2"
 	for ns in `IFS=', '; echo $*`; do
 		echo nameserver $ns
 	done
+
+	if [ -f /etc/resolv.conf.tail ]; then
+		cat /etc/resolv.conf.tail
+	fi
+}
+
+# Restarts named, if it is already running
+named_condreload() {
+	if "$RNDC" status > /dev/null 2>&1; then
+		"$RNDC" reload
+	fi
+}
+
+# Installs new version of the file.  If the file to be installed is the
+# same as the current one, nothing will be installed.
+# Arguments.
+# - $1: new file,
+# - $2: old file that will be overwritten with the contents of a new one.
+#
+# Returns zero if the new content was installed and returns one
+# when the old file was left untouched.
+#
+# New file will be removed before the function return.
+install_new_file() {
+	[ -z "$1" ] && return 0
+	if [ -z "$2" ]; then
+		rm -f "$1"
+		return 0
+	fi
+
+	[ -e "$1" -a -f "$1" ] || return 0
+	if [ -e "$2" -a -f "$CMP" -a -x "$CMP" ] && \
+	    "$CMP" "$1" "$2" >/dev/null 2>/dev/null; then
+		rm -f "$1"
+		return 1
+	else
+		cp -f "$1" "$2"
+	fi
+
+	rm -f "$1"
+	return 0
 }
 
-# if the info is available via dhcp/kenv
-# build the resolv.conf
+# Build named's forwarders file if it is requested by configuration.
+# Reloads named via 'rndc'.
 #
-if [ ! -e /etc/resolv.conf -a \
+# Arguments.
+#   $1 - the list of forwarders, separated by ',' or ' '.
+add_new_bind_forwarders() {
+	local tmpf
+
+	tmpf="$resolv_named_forwarders_file".new.$$
+
+	[ -z "$1" ] && return
+	checkyesno resolv_build_named_forwarders || return
+
+	echo 'forwarders {' > "$tmpf"
+	set -- "$1"
+	for nameserver in `IFS=', '; echo $*`; do
+		echo "$nameserver;"
+	done >> "$tmpf"
+	echo '};' >> "$tmpf"
+
+	# New contents?  Try to reload named.
+	if install_new_file "$tmpf" "$resolv_named_forwarders_file"; then
+		chown -RL root:wheel "$resolv_named_forwarders_file"
+		chmod -RL 644 "$resolv_named_forwarders_file"
+
+		named_condreload
+	fi
+}
+
+tmp_resolv=/etc/resolv.conf.new.$$
+rm -f "$tmp_resolv"
+# If user specified static resolv parameters, use them.
+if [ -n "${resolv_domain}" -o -n "${resolv_nameservers}" ]; then
+	build_resolv \
+	    "${resolv_domain}" "${resolv_nameservers}" \
+	    > "$tmp_resolv"
+	add_new_bind_forwarders "${resolv_nameservers}"
+# dhclient-script calls us using kenv's dhclient.* parameters
+elif [ -n "`/bin/kenv dhclient.domain-name-servers 2> /dev/null`" -o \
+    -n "`/bin/kenv dhclient.domain-name 2> /dev/null`" ]; then
+	build_resolv \
+	    "`/bin/kenv dhclient.domain-name 2> /dev/null`" \
+	    "`/bin/kenv dhclient.domain-name-servers`" \
+	    > "$tmp_resolv"
+	add_new_bind_forwarders "`/bin/kenv dhclient.domain-name-servers`"
+# If the info is available via dhcp/kenv (from the boot time)
+# build the resolv.conf, but only if it is not already exists.
+# This is the old historical behaviour of /etc/rc.d/resolv.
+elif [ ! -e /etc/resolv.conf -a \
     -n "`/bin/kenv dhcp.domain-name-servers 2> /dev/null`" ]; then
 	build_resolv \
 	    "`/bin/kenv dhcp.domain-name 2> /dev/null`" \
-	    "`/bin/kenv dhcp.domain-name-servers`" \
-	    > /etc/resolv.conf
-elif [ -n "${resolv_domain}" -o -n "${resolv_nameservers}" ]; then
-	build_resolv \
-	    "${resolv_domain}" "${resolv_nameservers}" \
-	    > /etc/resolv.conf
+	    "`/bin/kenv dhcp.domain-name-servers`" > "$tmp_resolv"
+	add_new_bind_forwarders "`/bin/kenv dhcp.domain-name-servers`"
+else
+	# Create forwarders file without forwarding servers.
+	# We can not just make it empty, because in the case
+	# of the 'forward only;' directives, named will throw
+	# error about non-existent 'forwarders' clause.
+	if checkyesno resolv_build_named_forwarders; then
+		if [ -e "$resolv_named_forwarders_file" ]; then
+			cat << "EOF" > "$resolv_named_forwarders_file"
+forwarders {};
+EOF
+			named_condreload
+		fi
+	fi
 fi
 
+install_new_file "$tmp_resolv" /etc/resolv.conf
+
diff --git a/sbin/dhclient/dhclient-script b/sbin/dhclient/dhclient-script
index f66da5a..9b14962 100644
--- a/sbin/dhclient/dhclient-script
+++ b/sbin/dhclient/dhclient-script
@@ -22,6 +22,7 @@
 ARP=/usr/sbin/arp
 HOSTNAME=/bin/hostname
 IFCONFIG='/sbin/ifconfig -n'
+KENV=/bin/kenv
 
 LOCALHOST=127.0.0.1
 
@@ -246,6 +247,22 @@ add_new_resolv_conf() {
 	return 1
 }
 
+# This is the FreeBSD-specific implementation of resolv.conf updater.
+# It sets appropriate variables and invokes the rc.d script that does
+# the actual job.
+fbsd_resolv () {
+	"$KENV" -u dhclient.domain-name 2>/dev/null
+	"$KENV" -u dhclient.domain-name-servers 2>/dev/null
+
+	if [ -n "$new_domain_name" ]; then
+		"$KENV" dhclient.domain-name="$new_domain_name"
+	fi
+	if [ -n "$new_domain_name_servers" ]; then
+		"$KENV" dhclient.domain-name-servers="$new_domain_name_servers"
+	fi
+	/etc/rc.d/resolv restart
+}
+
 # Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
 exit_with_hooks() {
 	exit_status=$1
@@ -333,7 +350,8 @@ BOUND|RENEW|REBIND|REBOOT)
 		add_new_alias
 	fi
 	if is_default_interface; then
-		add_new_resolv_conf
+		# ORIGINAL CODE: add_new_resolv_conf
+		fbsd_resolv
 	fi
 	;;
 
@@ -370,7 +388,8 @@ TIMEOUT)
 			if ! is_default_interface; then
 				exit_with_hooks 0
 			fi
-			if add_new_resolv_conf; then
+			# ORIGINAL CODE: if add_new_resolv_conf; then
+			if fbsd_resolv; then
 				exit_with_hooks 0
 			fi
 		fi
diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5
index af5d61f..cd3f039 100644
--- a/share/man/man5/rc.conf.5
+++ b/share/man/man5/rc.conf.5
@@ -1612,6 +1612,24 @@ Used for the programmatical building of
 comma- or space-separated list of nameservers.
 Used for the programmatical building of
 .Pa /etc/resolv.conf .
+.It Va resolv_build_named_forwarders
+.Pq Vt bool
+Set to
+.Dq Li YES
+to create forwarders file for
+.Xr named 8 .
+See the stock
+.Pa /etc/namedb/named.conf
+for the example of forwarders file usage.
+.It Va resolv_named_forwarders_file
+.Pq Vt str
+Location of the forwarders file.
+.It Va resolv_named_ip
+IP address where local named instance is listening for the queries.
+Will be inserted to the
+.Pa /etc/resolv.conf
+as the first DNS server when building of the forwarders file is enabled.
+Defaults to 127.0.0.1.
 .It Va kerberos5_server_enable
 .Pq Vt bool
 Set to
diff --git a/share/man/man8/Makefile b/share/man/man8/Makefile
index 4f50312..0613659 100644
--- a/share/man/man8/Makefile
+++ b/share/man/man8/Makefile
@@ -12,6 +12,7 @@ MAN=	adding_user.8 \
 	rc.sendmail.8 \
 	rc.subr.8 \
 	rescue.8 \
+	resolv.8 \
 	sticky.8 \
 	yp.8
 
diff --git a/share/man/man8/resolv.8 b/share/man/man8/resolv.8
new file mode 100644
index 0000000..e15e15c
--- /dev/null
+++ b/share/man/man8/resolv.8
@@ -0,0 +1,259 @@
+.\" Copyright (c) 2008
+.\"	Eygene Ryabinkin <rea-fbsd@codelabs.ru>.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"	This product includes software developed by the University of
+.\"	California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd April 13, 2008
+.Dt RESOLV 8
+.Os
+.
+.
+.Sh NAME
+.Nm resolv
+.Nd resolver library rc.d script
+.
+.
+.Sh SYNOPSIS
+.Nm /etc/rc.d/resolv Cm Bro start | stop | restart Brc
+.
+.
+.Sh DESCRIPTION
+Startup script
+.Pa /etc/rc.d/resolv
+configures the
+.Xr resolver 3
+library and can configure forwarders for the
+.Xr named 8 .
+.
+.
+.Sh OPTIONS
+.Pp
+Look into
+.Xr rc.conf 5
+manual page and search for the
+.Va resolv_*
+entries to obtain the complete list of directives and the description
+of their syntax.
+.
+.
+.Sh IMPLEMENTATION NOTES
+.
+.Ss Generation of /etc/resolv.conf
+.
+.Pp
+In order to generate
+.Pa /etc/resolv.conf
+on the fly, one should set the
+.Xr rc.conf 5
+variables
+.Va resolv_domain
+and/or
+.Va resolv_nameservers.
+The current logic for the generation of
+.Pa /etc/resolv.conf
+is the following.
+.Bl -enum
+.It
+Check if any
+.Xr rc.conf 5
+variable, mentioned just above, is defined.
+If yes, generate
+.Pa /etc/resolv.conf
+using the supplied values.
+.It
+Check if
+.Xr kenv 2
+node
+.Va kenv.domain-name-servers
+is present.
+If yes, generate
+.Pa /etc/resolv.conf
+using
+.Va kenv.domain-name
+and
+.Va kenv.domain-name-servers .
+.It
+Check if
+.Xr kenv 2
+nodes
+.Va dhclient.domain-name-servers
+and/or
+.Va dhclient.domain-name
+are present.
+If yes, generate
+.Pa /etc/resolv.conf
+using their values.
+The mentioned
+.Xr kenv 1
+variables are produced by the
+.Xr dhclient 8
+utility.
+.El
+.Pp
+If the file
+.Pa /etc/resolv.conf.tail
+is present, its contents will be appended to the generated
+.Pa /etc/resolv.conf .
+.
+.Ss Generation of named forwarders table
+.
+.Pp
+.Nm
+also can generate forwarders table for
+.Xr named 8 .
+The file can be used to point the local
+.Xr named 8
+instance to the upstream DNS servers.
+The typical usage this functionality is to make local DNS cache
+that will consult upstream servers.
+.Pp
+This mode is activated when the variable
+.Va resolv_build_named_forwarders
+is enabled in
+.Xr rc.conf 5 .
+The file, whose name is stored in the
+.Xr rc.conf 5
+variable
+.Va resolv_named_forwarders_file ,
+is populated with the upstream DNS server addresses.
+The addresses are obtained with the same algorithm as the
+.Va nameserver
+options in
+.Pa /etc/resolv.conf ,
+described above.
+.Pp
+If
+.Va named_enable
+is set in the
+.Xr rc.conf 5 ,
+then one additional
+.Va nameserver
+entry in the
+.Pa /etc/resolv.conf
+will be generated.
+It will be put as the first DNS server and the IP will be taken
+from the
+.Xr rc.conf 5
+variable
+.Va resolv_named_ip .
+It is done to
+.Qq glue
+the
+.Xr resolver 3
+library and the local
+.Xr named 8
+instance.
+.
+.
+.Sh FILES
+.Bl -tag -width /etc/namedb/named_conf
+.It Pa /etc/rc.conf
+system-wide configuration variables.
+.It Pa /etc/namedb/named.conf
+.Xr named 9
+configuration file.
+.It Pa /etc/namedb/named.forwarders.conf
+default location of the produced forwarders file.
+.It Pa /etc/resolv.conf
+default
+.Xr resolver 3
+configuration file.
+.El
+.
+.
+.Sh EXAMPLES
+.
+.Pp
+The following
+.Xr rc.conf 5
+options will automatically build
+.Pa /etc/resolv.conf
+with the corresponding configuration:
+.Bd -literal -offset indent
+resolv_domain="some.name.tld"
+resolv_nameservers="192.168.2.1 192.168.100.254"
+.Ed
+.
+.Pp
+The addition the strings
+.Bd -literal -offset indent
+resolv_build_named_forwarders="YES"
+resolv_named_ip="127.0.0.2"
+.Ed
+will result in the following contents of
+.Pa /etc/resolv.conf
+.Bd -literal -offset indent
+domain some.name.tld
+search some.name.tld
+nameserver 127.0.0.2
+nameserver 192.168.2.1
+nameserver 192.168.100.254
+<the contents of /etc/resolv.conf.tail, if any>
+.Ed
+.
+.Pp
+Additionally, the file
+.Pa /etc/namedb/named.forwarders.conf
+will be populated with the servers 192.168.2.1 and 192.168.100.254.
+In order to activate these servers in
+.Xr named 9 ,
+one should uncomment (or add) the following lines to the
+.Pa /etc/namedb/named.conf
+.Bd -literal -offset indent
+// Include the generated forwarders table.
+//
+// The default forwarders file name is used.
+// If you had customized its location via rc.conf variable
+// resolv_named_forwarders_file, replace the name here as well.
+	include "/etc/namedb/named.forwarders.conf";
+.Ed
+.
+.
+.Sh SEE ALSO
+.Xr resolver 3 ,
+.Xr resolver 5 ,
+.Xr rc.conf 5 ,
+.Xr named 9 ,
+.Xr kenv 1 ,
+.Xr kenv 2 ,
+.Xr dhclient 8
+.
+.
+.Sh HISTORY
+The
+.Nm
+manual page first appeared in
+.Fx 7.1 .
+.Sh AUTHORS
+The
+.Nm
+manual page was written by
+.An Eygene Ryabinkin Aq rea-fbsd@codelabs.ru .
-- 
1.5.3.8


--LyciRD1jyfeSSjG0
Content-Type: text/x-diff; charset=koi8-r
Content-Disposition: attachment; filename="resolv.3.patch"

>From 12a53657696ecb768ac23bb7b0ce8a2cda4f64f7 Mon Sep 17 00:00:00 2001
From: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
Date: Thu, 24 Apr 2008 13:56:48 +0400
Subject: [PATCH] Some modifications to the new rc.d/resolv code.

Following comments by Jeremie Le Hen in the freebsd-current list,
  http://lists.freebsd.org/pipermail/freebsd-current/2008-April/085077.html
I had made the following changes:

- the existing forwarders file is never chowned/chmodded, only the
  new one does;
- add_new_bind_forwarders() now accepts empty arguments to create
  empty forwarders list; it also checks for the empty server names
  in the list and omits them;
- now there is a single place for the creation of the forwarders
  and resolv files -- at the end of the script; the actual contents
  of the files are governed by the variables that are set in the
  respective places;
- prepended underscores for the script-global variables to avoid
  interfering with other global variables; not a strict measure,
  since there is no policy on variable names.

Signed-off-by: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
---
 etc/rc.d/resolv |   68 ++++++++++++++++++++++++++++++-------------------------
 1 files changed, 37 insertions(+), 31 deletions(-)

diff --git a/etc/rc.d/resolv b/etc/rc.d/resolv
index e5f9f32..0d42278 100644
--- a/etc/rc.d/resolv
+++ b/etc/rc.d/resolv
@@ -98,7 +98,7 @@ install_new_file() {
 		rm -f "$1"
 		return 1
 	else
-		cp -f "$1" "$2"
+		cat "$1" > "$2"
 	fi
 
 	rm -f "$1"
@@ -111,68 +111,74 @@ install_new_file() {
 # Arguments.
 #   $1 - the list of forwarders, separated by ',' or ' '.
 add_new_bind_forwarders() {
-	local tmpf
+	local tmpf existed
 
 	tmpf="$resolv_named_forwarders_file".new.$$
 
-	[ -z "$1" ] && return
 	checkyesno resolv_build_named_forwarders || return
 
+	existed=no
+	if [ -e "$resolv_named_forwarders_file" ]; then
+		existed=yes
+	fi
+
 	echo 'forwarders {' > "$tmpf"
 	set -- "$1"
 	for nameserver in `IFS=', '; echo $*`; do
-		echo "$nameserver;"
+		[ -n "$nameserver" ] && echo "$nameserver;"
 	done >> "$tmpf"
 	echo '};' >> "$tmpf"
 
 	# New contents?  Try to reload named.
 	if install_new_file "$tmpf" "$resolv_named_forwarders_file"; then
-		chown -RL root:wheel "$resolv_named_forwarders_file"
-		chmod -RL 644 "$resolv_named_forwarders_file"
+		if [ "$existed" = no ]; then
+			chown -RL root:wheel "$resolv_named_forwarders_file"
+			chmod -RL 644 "$resolv_named_forwarders_file"
+		fi
 
 		named_condreload
 	fi
 }
 
-tmp_resolv=/etc/resolv.conf.new.$$
-rm -f "$tmp_resolv"
+_tmp_resolv=/etc/resolv.conf.new.$$
+rm -f "${_tmp_resolv}"
+_nslist=""
+_defdomain=""
+_mkresolv=no
 # If user specified static resolv parameters, use them.
 if [ -n "${resolv_domain}" -o -n "${resolv_nameservers}" ]; then
-	build_resolv \
-	    "${resolv_domain}" "${resolv_nameservers}" \
-	    > "$tmp_resolv"
-	add_new_bind_forwarders "${resolv_nameservers}"
+	_nslist="${resolv_nameservers}"
+	_defdomain="${resolv_domain}"
+	_mkresolv=yes
 # dhclient-script calls us using kenv's dhclient.* parameters
 elif [ -n "`/bin/kenv dhclient.domain-name-servers 2> /dev/null`" -o \
     -n "`/bin/kenv dhclient.domain-name 2> /dev/null`" ]; then
-	build_resolv \
-	    "`/bin/kenv dhclient.domain-name 2> /dev/null`" \
-	    "`/bin/kenv dhclient.domain-name-servers`" \
-	    > "$tmp_resolv"
-	add_new_bind_forwarders "`/bin/kenv dhclient.domain-name-servers`"
+	_nslist="`/bin/kenv dhclient.domain-name-servers`"
+	_defdomain="`/bin/kenv dhclient.domain-name 2> /dev/null`"
+	_mkresolv=yes
 # If the info is available via dhcp/kenv (from the boot time)
 # build the resolv.conf, but only if it is not already exists.
 # This is the old historical behaviour of /etc/rc.d/resolv.
 elif [ ! -e /etc/resolv.conf -a \
     -n "`/bin/kenv dhcp.domain-name-servers 2> /dev/null`" ]; then
-	build_resolv \
-	    "`/bin/kenv dhcp.domain-name 2> /dev/null`" \
-	    "`/bin/kenv dhcp.domain-name-servers`" > "$tmp_resolv"
-	add_new_bind_forwarders "`/bin/kenv dhcp.domain-name-servers`"
+	_nslist="`/bin/kenv dhcp.domain-name-servers`"
+	_defdomain="`/bin/kenv dhcp.domain-name 2> /dev/null`"
+	_mkresolv=yes
 else
-	# Create forwarders file without forwarding servers.
+	# Create forwarders file without forwarding servers to clear
+	# the server list possibly left from the previous invocations.
+	# Eventually, this creates the file if its creation was requested,
+	# but no file currently exists.
+	#
 	# We can not just make it empty, because in the case
 	# of the 'forward only;' directives, named will throw
 	# error about non-existent 'forwarders' clause.
-	if checkyesno resolv_build_named_forwarders; then
-		if [ -e "$resolv_named_forwarders_file" ]; then
-			cat << "EOF" > "$resolv_named_forwarders_file"
-forwarders {};
-EOF
-			named_condreload
-		fi
-	fi
+	_nslist=""
 fi
 
-install_new_file "$tmp_resolv" /etc/resolv.conf
+add_new_bind_forwarders "${_nslist}"
 
+if [ "${_mkresolv}" = yes ]; then
+	build_resolv "${_defdomain}" "${_nslist}" > "${_tmp_resolv}"
+	install_new_file "${_tmp_resolv}" /etc/resolv.conf
+fi
-- 
1.5.3.8


--LyciRD1jyfeSSjG0--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?HLegrdNFV10zl33MHY7jBDOb%2BA4>