[pkg-dhcp-commits] [isc-dhcp] 01/01: release 4.3.5-3

Michael Gilbert mgilbert at moszumanska.debian.org
Sun Jan 15 01:26:20 UTC 2017


This is an automated email from the git hooks/post-receive script.

mgilbert pushed a commit to branch master
in repository isc-dhcp.

commit 0f8146a98dcf5eea5467b2d5974695ac4d94b5ae
Author: Michael Gilbert <mgilbert at debian.org>
Date:   Sun Jan 15 01:27:16 2017 +0000

    release 4.3.5-3
---
 debian/changelog                         |  15 ++
 debian/control                           |   2 +-
 debian/dhclient-script.linux             |  56 +++-
 debian/isc-dhcp-server.init.d            |   3 +-
 debian/patches/dhcommon-getifaddrs.patch | 436 +++++++++++++++++++++++++++++++
 debian/patches/series                    |   2 +
 debian/rules                             |   2 +-
 7 files changed, 501 insertions(+), 15 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 3c6411a..38eaf7d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+isc-dhcp (4.3.5-3) unstable; urgency=medium
+
+  * Add support for read-only /etc (closes: #642544).
+    - Thanks to Scott Moser.
+  * Wait for /etc/resolv.conf to become writable (closes: #687337).
+    - Thanks to Stéphane Graber.
+  * Suggest policykit-1 instead of depending on it (closes: #850726).
+  * Fix typo in --with-randomdev configure argument (closes: #838382).
+  * Touch dhcpd6.leases before starting an ipv6 server (closes: #824770).
+    - Thanks to Terry Burton.
+  * Use getifaddrs() system call to handle alias interfaces (closes: #605657).
+    - Thanks to Jiri Popelka.
+
+ -- Michael Gilbert <mgilbert at debian.org>  Mon, 09 Jan 2017 04:55:32 +0000
+
 isc-dhcp (4.3.5-2) unstable; urgency=medium
 
   * Fix new upstream spelling errors.
diff --git a/debian/control b/debian/control
index 5191cb0..8274109 100644
--- a/debian/control
+++ b/debian/control
@@ -26,7 +26,6 @@ Depends:
  ${shlibs:Depends},
  debianutils (>= 2.8.2),
  lsb-base,
- policykit-1,
 Recommends:
  isc-dhcp-common,
  policycoreutils,
@@ -36,6 +35,7 @@ Breaks:
 Replaces:
  isc-dhcp-common (<= 4.3.3-1),
 Suggests:
+ policykit-1,
  isc-dhcp-server-ldap,
 Description: ISC DHCP server for automatic IP address assignment
  This is the Internet Software Consortium's DHCP server.
diff --git a/debian/dhclient-script.linux b/debian/dhclient-script.linux
index 6670c69..9b0d3f8 100644
--- a/debian/dhclient-script.linux
+++ b/debian/dhclient-script.linux
@@ -12,6 +12,30 @@
 
 # The alias handling in here probably still sucks. -mdz
 
+# wait for given file to be writable
+wait_for_rw() {
+    local file=$1
+    # Find out whether we are going to mount / rw
+    exec 9>&0 </etc/fstab
+    rootmode=rw
+    while read dev mnt type opts dump pass junk; do
+        [ "$mnt" != / ] && continue
+        case "$opts" in
+            ro|ro,*|*,ro|*,ro,*)
+               rootmode=ro
+               ;;
+             esac
+     done
+     exec 0>&9 9>&-
+
+    # Wait for $file to become writable
+    if [ "$rootmode" = "rw" ]; then
+        while ! { : >> "$file"; } 2>/dev/null; do
+            sleep 0.1
+        done
+    fi
+}
+
 # update /etc/resolv.conf based on received values
 make_resolv_conf() {
     local new_resolv_conf
@@ -19,7 +43,11 @@ make_resolv_conf() {
     # DHCPv4
     if [ -n "$new_domain_search" ] || [ -n "$new_domain_name" ] ||
        [ -n "$new_domain_name_servers" ]; then
-        new_resolv_conf=/etc/resolv.conf.dhclient-new
+        resolv_conf=$(readlink -f "/etc/resolv.conf" 2>/dev/null) ||
+            resolv_conf="/etc/resolv.conf"
+
+        new_resolv_conf="${resolv_conf}.dhclient-new.$$"
+        wait_for_rw "$new_resolv_conf"
         rm -f $new_resolv_conf
 
         if [ -n "$new_domain_name" ]; then
@@ -49,17 +77,21 @@ make_resolv_conf() {
                 echo nameserver $nameserver >>$new_resolv_conf
             done
         else # keep 'old' nameservers
-            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf
+            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p $resolv_conf >>$new_resolv_conf
         fi
 
-	if [ -f /etc/resolv.conf ]; then
-	    chown --reference=/etc/resolv.conf $new_resolv_conf
-	    chmod --reference=/etc/resolv.conf $new_resolv_conf
+	if [ -f $resolv_conf ]; then
+	    chown --reference=$resolv_conf $new_resolv_conf
+	    chmod --reference=$resolv_conf $new_resolv_conf
 	fi
-        mv -f $new_resolv_conf /etc/resolv.conf
+        mv -f $new_resolv_conf $resolv_conf
     # DHCPv6
     elif [ -n "$new_dhcp6_domain_search" ] || [ -n "$new_dhcp6_name_servers" ]; then
-        new_resolv_conf=/etc/resolv.conf.dhclient-new
+        resolv_conf=$(readlink -f "/etc/resolv.conf" 2>/dev/null) ||
+            resolv_conf="/etc/resolv.conf"
+
+        new_resolv_conf="${resolv_conf}.dhclient-new.$$"
+        wait_for_rw "$new_resolv_conf"
         rm -f $new_resolv_conf
 
         if [ -n "$new_dhcp6_domain_search" ]; then
@@ -76,14 +108,14 @@ make_resolv_conf() {
                 echo nameserver $nameserver >>$new_resolv_conf
             done
         else # keep 'old' nameservers
-            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf
+            sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p $resolv_conf >>$new_resolv_conf
         fi
 
-	if [ -f /etc/resolv.conf ]; then
-            chown --reference=/etc/resolv.conf $new_resolv_conf
-            chmod --reference=/etc/resolv.conf $new_resolv_conf
+	if [ -f $resolv_conf ]; then
+            chown --reference=$resolv_conf $new_resolv_conf
+            chmod --reference=$resolv_conf $new_resolv_conf
 	fi
-        mv -f $new_resolv_conf /etc/resolv.conf
+        mv -f $new_resolv_conf $resolv_conf
     fi
 }
 
diff --git a/debian/isc-dhcp-server.init.d b/debian/isc-dhcp-server.init.d
index 07db419..37f899f 100644
--- a/debian/isc-dhcp-server.init.d
+++ b/debian/isc-dhcp-server.init.d
@@ -63,7 +63,6 @@ test_config()
 		/usr/sbin/dhcpd -t $VERSION -cf "$CONF"
 		exit 1
 	fi
-	touch /var/lib/dhcp/dhcpd.leases
 }
 
 check_status()
@@ -105,6 +104,8 @@ start_daemon()
 		exit 1
 	fi
 
+	touch /var/lib/dhcp/$NAME.leases
+
 	start-stop-daemon --start --quiet --pidfile $PIDFILE \
 		--exec /usr/sbin/dhcpd -- $VERSION -q -cf $CONF $INTERFACES
 	sleep 2
diff --git a/debian/patches/dhcommon-getifaddrs.patch b/debian/patches/dhcommon-getifaddrs.patch
new file mode 100644
index 0000000..942b838
--- /dev/null
+++ b/debian/patches/dhcommon-getifaddrs.patch
@@ -0,0 +1,436 @@
+description: use getifaddrs() system call, rather than parsing /proc/net on linux
+author: Jiri Popelka <jpopelka at redhat.com>
+origin: http://pkgs.fedoraproject.org/cgit/dhcp.git/tree/dhcp-getifaddrs.patch?id=d12e0eb05e510268ce9b8dcb839e27d5eca9aff5
+bug-debian: https://bugs.debian.org/605657
+bug-ubuntu: https://bugs.launchpad.net/ubuntu/+source/isc-dhcp/+bug/1446767
+bug-fedora: https://bugzilla.redhat.com/show_bug.cgi?id=449946
+
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -373,392 +373,13 @@ end_iface_scan(struct iface_conf_list *i
+ 	ifaces->sock = -1;
+ }
+ 
+-#elif __linux /* !HAVE_SIOCGLIFCONF */
+-/* 
+- * Linux support
+- * -------------
+- *
+- * In Linux, we use the /proc pseudo-filesystem to get information
+- * about interfaces, along with selected ioctl() calls.
+- *
+- * Linux low level access is documented in the netdevice man page.
+- */
+-
+-/* 
+- * Structure holding state about the scan.
+- */
+-struct iface_conf_list {
+-	int sock;	/* file descriptor used to get information */
+-	FILE *fp;	/* input from /proc/net/dev */
+-#ifdef DHCPv6
+-	FILE *fp6;	/* input from /proc/net/if_inet6 */
+-#endif
+-};
+-
+-/* 
+- * Structure used to return information about a specific interface.
+- */
+-struct iface_info {
+-	char name[IFNAMSIZ];		/* name of the interface, e.g. "eth0" */
+-	struct sockaddr_storage addr;	/* address information */
+-	isc_uint64_t flags;		/* interface flags, e.g. IFF_LOOPBACK */
+-};
+-
+-/* 
+- * Start a scan of interfaces.
+- *
+- * The iface_conf_list structure maintains state for this process.
+- */
+-int 
+-begin_iface_scan(struct iface_conf_list *ifaces) {
+-	char buf[IF_LINE_LENGTH];
+-	int len;
+-	int i;
+-
+-	ifaces->fp = fopen("/proc/net/dev", "r");
+-	if (ifaces->fp == NULL) {
+-		log_error("Error opening '/proc/net/dev' to list interfaces");
+-		return 0;
+-	}
+-
+-	/*
+-	 * The first 2 lines are header information, so read and ignore them.
+-	 */
+-	for (i=0; i<2; i++) {
+-		if (fgets(buf, sizeof(buf), ifaces->fp) == NULL) {
+-			log_error("Error reading headers from '/proc/net/dev'");
+-			fclose(ifaces->fp);
+-			ifaces->fp = NULL;
+-			return 0;
+-		}
+-		len = strlen(buf);
+-		if ((len <= 0) || (buf[len-1] != '\n')) { 
+-			log_error("Bad header line in '/proc/net/dev'");
+-			fclose(ifaces->fp);
+-			ifaces->fp = NULL;
+-			return 0;
+-		}
+-	}
+-
+-	ifaces->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+-	if (ifaces->sock < 0) {
+-		log_error("Error creating socket to list interfaces; %m");
+-		fclose(ifaces->fp);
+-		ifaces->fp = NULL;
+-		return 0;
+-	}
+-
+-#ifdef DHCPv6
+-	if (local_family == AF_INET6) {
+-		ifaces->fp6 = fopen("/proc/net/if_inet6", "r");
+-		if (ifaces->fp6 == NULL) {
+-			log_error("Error opening '/proc/net/if_inet6' to "
+-				  "list IPv6 interfaces; %m");
+-			close(ifaces->sock);
+-			ifaces->sock = -1;
+-			fclose(ifaces->fp);
+-			ifaces->fp = NULL;
+-			return 0;
+-		}
+-	}
+-#endif
+-
+-	return 1;
+-}
+-
+-/*
+- * Read our IPv4 interfaces from /proc/net/dev.
+- *
+- * The file looks something like this:
+- *
+- * Inter-|   Receive ...
+- *  face |bytes    packets errs drop fifo frame ...
+- *     lo: 1580562    4207    0    0    0     0 ...
+- *   eth0:       0       0    0    0    0     0 ...
+- *   eth1:1801552440   37895    0   14    0     ...
+- *
+- * We only care about the interface name, which is at the start of 
+- * each line.
+- *
+- * We use an ioctl() to get the address and flags for each interface.
+- */
+-static int
+-next_iface4(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
+-	char buf[IF_LINE_LENGTH];
+-	int len;
+-	char *p;
+-	char *name;
+-	struct ifreq tmp;
+-
+-	/*
+-	 * Loop exits when we find an interface that has an address, or 
+-	 * when we run out of interfaces.
+-	 */
+-	for (;;) {
+-		do {
+-			/*
+-	 		 *  Read the next line in the file.
+-	 		 */
+-			if (fgets(buf, sizeof(buf), ifaces->fp) == NULL) {
+-				if (ferror(ifaces->fp)) {
+-					*err = 1;
+-					log_error("Error reading interface "
+-					  	"information");
+-				} else {
+-					*err = 0;
+-				}
+-				return 0;
+-			}
+-
+-			/*
+-	 		 * Make sure the line is a nice, 
+-			 * newline-terminated line.
+-	 		 */
+-			len = strlen(buf);
+-			if ((len <= 0) || (buf[len-1] != '\n')) { 
+-				log_error("Bad line reading interface "
+-					  "information");
+-				*err = 1;
+-				return 0;
+-			}
+-
+-			/*
+-	 		 * Figure out our name.
+-	 		 */
+-			p = strrchr(buf, ':');
+-			if (p == NULL) {
+-				log_error("Bad line reading interface "
+-					  "information (no colon)");
+-				*err = 1;
+-				return 0;
+-			}
+-			*p = '\0';
+-			name = buf;
+-			while (isspace(*name)) {
+-				name++;
+-			}
+-
+-			/* 
+-		 	 * Copy our name into our interface structure.
+-		 	 */
+-			len = p - name;
+-			if (len >= sizeof(info->name)) {
+-				*err = 1;
+-				log_error("Interface name '%s' too long", name);
+-				return 0;
+-			}
+-			strncpy(info->name, name, sizeof(info->name) - 1);
+-
+-#ifdef ALIAS_NAMED_PERMUTED
+-			/* interface aliases look like "eth0:1" or "wlan1:3" */
+-			s = strchr(info->name, ':');
+-			if (s != NULL) {
+-				*s = '\0';
+-			}
+-#endif
+-
+-#ifdef SKIP_DUMMY_INTERFACES
+-		} while (strncmp(info->name, "dummy", 5) == 0);
+-#else
+-		} while (0);
+-#endif
+-
+-		memset(&tmp, 0, sizeof(tmp));
+-		strncpy(tmp.ifr_name, name, sizeof(tmp.ifr_name) - 1);
+-		if (ioctl(ifaces->sock, SIOCGIFADDR, &tmp) < 0) {
+-			if (errno == EADDRNOTAVAIL) {
+-				continue;
+-			}
+-			log_error("Error getting interface address "
+-				  "for '%s'; %m", name);
+-			*err = 1;
+-			return 0;
+-		}
+-		memcpy(&info->addr, &tmp.ifr_addr, sizeof(tmp.ifr_addr));
+-
+-		memset(&tmp, 0, sizeof(tmp));
+-		strncpy(tmp.ifr_name, name, sizeof(tmp.ifr_name) - 1);
+-		if (ioctl(ifaces->sock, SIOCGIFFLAGS, &tmp) < 0) {
+-			log_error("Error getting interface flags for '%s'; %m", 
+-			  	name);
+-			*err = 1;
+-			return 0;
+-		}
+-		info->flags = tmp.ifr_flags;
+-
+-		*err = 0;
+-		return 1;
+-	}
+-}
+-
+-#ifdef DHCPv6
+-/*
+- * Read our IPv6 interfaces from /proc/net/if_inet6.
+- *
+- * The file looks something like this:
+- *
+- * fe80000000000000025056fffec00008 05 40 20 80   vmnet8
+- * 00000000000000000000000000000001 01 80 10 80       lo
+- * fe80000000000000025056fffec00001 06 40 20 80   vmnet1
+- * 200108881936000202166ffffe497d9b 03 40 00 00     eth1
+- * fe8000000000000002166ffffe497d9b 03 40 20 80     eth1
+- *
+- * We get IPv6 address from the start, the interface name from the end, 
+- * and ioctl() to get flags.
+- */
+-static int
+-next_iface6(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
+-	char buf[IF_LINE_LENGTH];
+-	int len;
+-	char *p;
+-	char *name;
+-	int i;
+-	struct sockaddr_in6 addr;
+-	struct ifreq tmp;
+-
+-	do {
+-		/*
+-		 *  Read the next line in the file.
+-		 */
+-		if (fgets(buf, sizeof(buf), ifaces->fp6) == NULL) {
+-			if (ferror(ifaces->fp6)) {
+-				*err = 1;
+-				log_error("Error reading IPv6 "
+-					  "interface information");
+-			} else {
+-				*err = 0;
+-			}
+-			return 0;
+-		}
+-
+-		/*
+-		 * Make sure the line is a nice, newline-terminated line.
+-		 */
+-		len = strlen(buf);
+-		if ((len <= 0) || (buf[len-1] != '\n')) { 
+-			log_error("Bad line reading IPv6 "
+-				  "interface information");
+-			*err = 1;
+-			return 0;
+-		}
+-
+-		/*
+- 		 * Figure out our name.
+- 		 */
+-		buf[--len] = '\0';
+-		p = strrchr(buf, ' ');
+-		if (p == NULL) {
+-			log_error("Bad line reading IPv6 interface "
+-			          "information (no space)");
+-			*err = 1;
+-			return 0;
+-		}
+-		name = p+1;
+-
+-		/* 
+- 		 * Copy our name into our interface structure.
+- 		 */
+-		len = strlen(name);
+-		if (len >= sizeof(info->name)) {
+-			*err = 1;
+-			log_error("IPv6 interface name '%s' too long", name);
+-			return 0;
+-		}
+-		strncpy(info->name, name, sizeof(info->name) - 1);
+-
+-#ifdef SKIP_DUMMY_INTERFACES
+-	} while (strncmp(info->name, "dummy", 5) == 0);
+-#else
+-	} while (0);
+-#endif
+-
+-	/*
+-	 * Double-check we start with the IPv6 address.
+-	 */
+-	for (i=0; i<32; i++) {
+-		if (!isxdigit(buf[i]) || isupper(buf[i])) {
+-			*err = 1;
+-			log_error("Bad line reading IPv6 interface address "
+-				  "for '%s'", name);
+-			return 0;
+-		}
+-	}
+-
+-	/* 
+-	 * Load our socket structure.
+-	 */
+-	memset(&addr, 0, sizeof(addr));
+-	addr.sin6_family = AF_INET6;
+-	for (i=0; i<16; i++) {
+-		unsigned char byte;
+-                static const char hex[] = "0123456789abcdef";
+-                byte = ((index(hex, buf[i * 2]) - hex) << 4) |
+-			(index(hex, buf[i * 2 + 1]) - hex);
+-		addr.sin6_addr.s6_addr[i] = byte;
+-	}
+-	memcpy(&info->addr, &addr, sizeof(addr));
+-
+-	/*
+-	 * Get our flags.
+-	 */
+-	memset(&tmp, 0, sizeof(tmp));
+-	strncpy(tmp.ifr_name, name, sizeof(tmp.ifr_name) - 1);
+-	if (ioctl(ifaces->sock, SIOCGIFFLAGS, &tmp) < 0) {
+-		log_error("Error getting interface flags for '%s'; %m", name);
+-		*err = 1;
+-		return 0;
+-	}
+-	info->flags = tmp.ifr_flags;
+-
+-	*err = 0;
+-	return 1;
+-}
+-#endif /* DHCPv6 */
+-
+-/*
+- * Retrieve the next interface.
+- *
+- * Returns information in the info structure. 
+- * Sets err to 1 if there is an error, otherwise 0.
+- */
+-int
+-next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
+-	memset(info, 0, sizeof(struct iface_info));
+-	if (next_iface4(info, err, ifaces)) {
+-		return 1;
+-	}
+-#ifdef DHCPv6
+-	if (!(*err)) {
+-		if (local_family == AF_INET6)
+-			return next_iface6(info, err, ifaces);
+-	}
+-#endif
+-	return 0;
+-}
+-
+-/*
+- * End scan of interfaces.
+- */
+-void
+-end_iface_scan(struct iface_conf_list *ifaces) {
+-	fclose(ifaces->fp);
+-	ifaces->fp = NULL;
+-	close(ifaces->sock);
+-	ifaces->sock = -1;
+-#ifdef DHCPv6
+-	if (local_family == AF_INET6) {
+-		fclose(ifaces->fp6);
+-		ifaces->fp6 = NULL;
+-	}
+-#endif
+-}
+ #else
+ 
+ /* 
+- * BSD support
++ * Unix support
+  * -----------
+  *
+- * FreeBSD, NetBSD, OpenBSD, and OS X all have the getifaddrs() 
++ * FreeBSD, NetBSD, OpenBSD, Linux, and OS X all have the getifaddrs()
+  * function.
+  *
+  * The getifaddrs() man page describes the use.
+@@ -806,6 +427,8 @@ begin_iface_scan(struct iface_conf_list
+  */
+ int
+ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
++	size_t sa_len = 0;
++
+ 	if (ifaces->next == NULL) {
+ 		*err = 0;
+ 		return 0;
+@@ -818,8 +441,20 @@ next_iface(struct iface_info *info, int
+ 	}
+ 	memset(info, 0, sizeof(struct iface_info));
+ 	strncpy(info->name, ifaces->next->ifa_name, sizeof(info->name) - 1);
+-	memcpy(&info->addr, ifaces->next->ifa_addr, 
+-	       ifaces->next->ifa_addr->sa_len);
++
++	memset(&info->addr, 0 , sizeof(info->addr));
++
++	if (ifaces->next->ifa_addr != NULL) {
++#ifdef HAVE_SA_LEN
++		sa_len = ifaces->next->ifa_addr->sa_len;
++#else
++		if (ifaces->next->ifa_addr->sa_family == AF_INET)
++			sa_len = sizeof(struct sockaddr_in);
++		else if (ifaces->next->ifa_addr->sa_family == AF_INET6)
++			sa_len = sizeof(struct sockaddr_in6);
++#endif
++		memcpy(&info->addr, ifaces->next->ifa_addr, sa_len);
++	}
+ 	info->flags = ifaces->next->ifa_flags;
+ 	ifaces->next = ifaces->next->ifa_next;
+ 	*err = 0;
diff --git a/debian/patches/series b/debian/patches/series
index fc67da9..1d20f18 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -7,6 +7,8 @@ dhclient-release.patch
 
 dhcrelay-listen.patch
 
+dhcommon-getifaddrs.patch
+
 dhcpd-conf.patch
 
 fix-exit-hook-manpage.patch
diff --git a/debian/rules b/debian/rules
index 48b04c8..114606b 100755
--- a/debian/rules
+++ b/debian/rules
@@ -27,7 +27,7 @@ CONFFLAGS=--prefix=/usr --enable-log-pid --enable-paranoia
 
 # cross-architecture building
 ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE))
-CONFFLAGS+=--build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE) --with-random=/dev/random
+CONFFLAGS+=--build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE) --with-randomdev=/dev/random
 endif
 
 # hurd support

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-dhcp/isc-dhcp.git



More information about the pkg-dhcp-commits mailing list