Re: [RFC] Automated generation of /etc/resolv.conf from the rc.d script

From: Brooks Davis <brooks_at_freebsd.org>
Date: Thu, 24 Apr 2008 09:58:06 -0500
On Thu, Apr 24, 2008 at 02:31:25PM +0400, Eygene Ryabinkin wrote:
> 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 ;))

The problem here is that you can't use programs in /usr before it is
mounted.  This usually isn't a problem, but currently we theoretically
support mounting /usr via nfs on systems that don't have an IP address when
init is started.  I'm not entierly convinced we should support that, but for
now that's the way it is.

-- Brooks

> > 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

> >From 6537efa58e4a454c2f54c25091f85a5c6557d49b Mon Sep 17 00:00:00 2001
> From: Eygene Ryabinkin <rea-fbsd_at_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_at_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
> _at__at_ -243,6 +243,14 _at__at_ 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
> _at__at_ -45,6 +45,18 _at__at_ 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
> _at__at_ -38,6 +38,9 _at__at_ 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,
> _at__at_ -47,26 +50,129 _at__at_ 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
> _at__at_ -22,6 +22,7 _at__at_
>  ARP=/usr/sbin/arp
>  HOSTNAME=/bin/hostname
>  IFCONFIG='/sbin/ifconfig -n'
> +KENV=/bin/kenv
>  
>  LOCALHOST=127.0.0.1
>  
> _at__at_ -246,6 +247,22 _at__at_ 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
> _at__at_ -333,7 +350,8 _at__at_ 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
>  	;;
>  
> _at__at_ -370,7 +388,8 _at__at_ 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
> _at__at_ -1612,6 +1612,24 _at__at_ 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
> _at__at_ -12,6 +12,7 _at__at_ 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
> _at__at_ -0,0 +1,259 _at__at_
> +.\" Copyright (c) 2008
> +.\"	Eygene Ryabinkin <rea-fbsd_at_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_at_codelabs.ru .
> -- 
> 1.5.3.8
> 

> >From 12a53657696ecb768ac23bb7b0ce8a2cda4f64f7 Mon Sep 17 00:00:00 2001
> From: Eygene Ryabinkin <rea-fbsd_at_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_at_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
> _at__at_ -98,7 +98,7 _at__at_ install_new_file() {
>  		rm -f "$1"
>  		return 1
>  	else
> -		cp -f "$1" "$2"
> +		cat "$1" > "$2"
>  	fi
>  
>  	rm -f "$1"
> _at__at_ -111,68 +111,74 _at__at_ 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
> 

> _______________________________________________
> freebsd-current_at_freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe_at_freebsd.org"


Received on Thu Apr 24 2008 - 12:58:12 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:30 UTC