Subject: bin/21109: dhclient-script mis-handles resolv.conf sometimes
To: None <gnats-bugs@gnats.netbsd.org>
From: None <kre@munnari.OZ.AU>
List: netbsd-bugs
Date: 04/12/2003 20:53:00
>Number:         21109
>Category:       bin
>Synopsis:       dhclient-script mis-handles resolv.conf sometimes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 12 06:56:00 PDT 2003
>Closed-Date:
>Last-Modified:
>Originator:     Robert Elz
>Release:        NetBSD 1.6Q  (-- current of 2003-04-12)
>Organization:
	Prince of Songkla University
>Environment:
	
	
System: NetBSD delta.cs.mu.OZ.AU 1.6L NetBSD 1.6L (DELTA) #29: Fri Jan 10 11:40:50 ICT 2003 kre@fuchsia.cs.mu.OZ.AU:/usr/obj/sys/DELTA i386
	This is just the system I'm running send-pr from and is irrelevant.

Architecture: i386
Machine: i386

>Description:
	If dhclient is run (without specifying a particular interface)
	on a system with more than one interface, and it can only contact
	a DHCP server on one (or less than all) of the available
	interfaces, and if, before dhclient started there was an
	/etc/resolv.conf that was not created by DHCP (say a fallback for
	times when DHCP supplies no nameserver info, or there is no DHCP)
	then after a while, rather than having an /etc/resolv.conf with
	the results from DHCP, and the other saved, the fallback resolv.conf
	will be in /etc/resolv.conf, and information from DHCP will have
	been ignored.

>How-To-Repeat:
	Get a system with more than one interface.   A moden laptop with
	802.11 and 802.3 is a good choice for this.

	Connect one of the two interfaces to a working net, complete with
	a DHCP server that supplies nameserver information, and leave the
	other interface disconnected (no cable for 802.3, no WEP key for
	802.11 - or no AP - or just no DHCP server - having a DHCP server
	which just doesn't bother to send nameserver info isn't sufficient
	to trigger the bug, I don't think).

	Before starting dhclient, create an /etc/resolv.conf file that
	contains just
		search my.dom.ain
	or something similar (it doesn't matter much what it contains,
	just provided it isn't a resolv.conf that was previously created
	by dhclient).

	Run
		dhclient
	with no interface specification (include -q if you prefer, most do).

	After a short time (a second or two), an address should be
	assigned to the working interface, and /etc/resolv.conf should
	contain the nameserver information (and domain to search if any
	was supplied by the DHCP server).   This is the desired end state.

	At this point, dhclient will (having obtained an address) vanish
	into the background, and continue attempting to contact a
	server for the other interface (while also renewing the lease
	that has been obtained, when that becomes due).

	Eventually, it will decide that it isn't going to succeed on the
	unconnected interface, and run dhclient-script in its "cleanup" mode,
	to put the world back to "no dhcp being attempted" state (this does
	things like getting rid of the 0.0.0.0 address that dhclient needs
	configured into the interface).

	When that happens, dhclient-script notices that it had installed
	the /etc/resolv.conf file, and as a part of its cleanup, it
	restores the file that had existed previously (if there had been
	none, it just leaves the file it created).  This is despite
	dhclient still being active on the interface that supplied the
	information that was put in resolv.conf.

>Fix:
	The patch below cause the interface name to be included in the
	"signature" that dhclient-script uses to detect whether or not
	it should restore the old resolv.conf - the old one will only be
	restored when dhclient shuts down on the interface which supplied
	the new resolv.conf information.

	Note: the interface remains still not used in that part of the
	script that determines whether a resolv.conf file that existed
	when dhclient starts is a resolv.conf that was created by a
	previous incarnation of dhclient (say, from before an OS crash)
	and which therefore doesn't need to be saved.   This has the
	side effect of causing dhclient to use the last of the nameserver
	information received, when more than one interface is successfully
	configured, rather than the first, which might be preferred
	normally (though it is probably rare that it will differ).
	Fixing that is non-trivial (and may require some changes to
	dhclient itself, rather than just the script).

--- dhclient-script	Thu May 30 06:18:34 2002
+++ dhclient-script.FIXED	Sat Apr 12 20:24:36 2003
@@ -5,7 +5,8 @@
 ENTERHOOKS=/etc/dhclient-enter-hooks
 EXITHOOKS=/etc/dhclient-exit-hooks
 RESOLV=/etc/resolv.conf
-SIGNATURE="# Created by dhclient at: "
+SIGNATURE="# Created by dhclient from"
+INTSIG="$SIGNATURE $interface at: "
 
 make_resolv_conf() {
 	if [ ! -z "$new_domain_name_servers" ]; then
@@ -21,7 +22,7 @@
 				break
 			done < $RESOLV
 		fi
-		echo "$SIGNATURE$(date)" > $RESOLV
+		echo "$INTSIG$(date)" > $RESOLV
 		if [ ! -z "$new_domain_name" ]
 		then
 			echo search $new_domain_name >> $RESOLV
@@ -37,7 +38,7 @@
 	then
 		while read line; do
 			case $line in
-			"$SIGNATURE"*)
+			"$INTSIG"*)
 				mv $RESOLV.save $RESOLV;;
 			esac
 			break
>Release-Note:
>Audit-Trail:
>Unformatted: