Blame SOURCES/dhcp-4.2.2-capability.patch

c8bb8f
diff -up dhcp-4.2.2b1/client/dhclient.8.capability dhcp-4.2.2b1/client/dhclient.8
c8bb8f
--- dhcp-4.2.2b1/client/dhclient.8.capability	2011-07-01 15:09:06.603784531 +0200
c8bb8f
+++ dhcp-4.2.2b1/client/dhclient.8	2011-07-01 15:09:06.663783913 +0200
c8bb8f
@@ -118,6 +118,9 @@ dhclient - Dynamic Host Configuration Pr
c8bb8f
 .B -w
c8bb8f
 ]
c8bb8f
 [
c8bb8f
+.B -nc
c8bb8f
+]
c8bb8f
+[
c8bb8f
 .B -B
c8bb8f
 ]
c8bb8f
 [
c8bb8f
@@ -296,6 +299,32 @@ has been added or removed, so that the c
c8bb8f
 address on that interface.
c8bb8f
 
c8bb8f
 .TP
c8bb8f
+.BI \-nc
c8bb8f
+Do not drop capabilities.
c8bb8f
+
c8bb8f
+Normally, if
c8bb8f
+.B dhclient
c8bb8f
+was compiled with libcap-ng support,
c8bb8f
+.B dhclient
c8bb8f
+drops most capabilities immediately upon startup.  While more secure,
c8bb8f
+this greatly restricts the additional actions that hooks in
c8bb8f
+.B dhclient-script (8)
c8bb8f
+can take.  (For example, any daemons that 
c8bb8f
+.B dhclient-script (8)
c8bb8f
+starts or restarts will inherit the restricted capabilities as well,
c8bb8f
+which may interfere with their correct operation.)  Thus, the
c8bb8f
+.BI \-nc
c8bb8f
+option can be used to prevent
c8bb8f
+.B dhclient
c8bb8f
+from dropping capabilities.
c8bb8f
+
c8bb8f
+The
c8bb8f
+.BI \-nc
c8bb8f
+option is ignored if
c8bb8f
+.B dhclient
c8bb8f
+was not compiled with libcap-ng support.
c8bb8f
+
c8bb8f
+.TP
c8bb8f
 .BI \-B
c8bb8f
 Set the BOOTP broadcast flag in request packets so servers will always
c8bb8f
 broadcast replies.
c8bb8f
diff -up dhcp-4.2.2b1/client/dhclient.c.capability dhcp-4.2.2b1/client/dhclient.c
c8bb8f
--- dhcp-4.2.2b1/client/dhclient.c.capability	2011-07-01 15:09:06.644784107 +0200
c8bb8f
+++ dhcp-4.2.2b1/client/dhclient.c	2011-07-01 15:09:06.664783903 +0200
c8bb8f
@@ -39,6 +39,10 @@
c8bb8f
 #include <limits.h>
c8bb8f
 #include <dns/result.h>
c8bb8f
 
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+#include <cap-ng.h>
c8bb8f
+#endif
c8bb8f
+
c8bb8f
 /*
c8bb8f
  * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
c8bb8f
  * that when building ISC code.
c8bb8f
@@ -141,6 +145,9 @@ main(int argc, char **argv) {
c8bb8f
 	int timeout_arg = 0;
c8bb8f
 	char *arg_conf = NULL;
c8bb8f
 	int arg_conf_len = 0;
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+	int keep_capabilities = 0;
c8bb8f
+#endif
c8bb8f
 
c8bb8f
 	/* Initialize client globals. */
c8bb8f
 	memset(&default_duid, 0, sizeof(default_duid));
c8bb8f
@@ -410,6 +417,10 @@ main(int argc, char **argv) {
c8bb8f
 			}
c8bb8f
 
c8bb8f
 			dhclient_request_options = argv[i];
c8bb8f
+		} else if (!strcmp(argv[i], "-nc")) {
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+			keep_capabilities = 1;
c8bb8f
+#endif
c8bb8f
 		} else if (argv[i][0] == '-') {
c8bb8f
 		    usage();
c8bb8f
 		} else if (interfaces_requested < 0) {
c8bb8f
@@ -458,6 +469,19 @@ main(int argc, char **argv) {
c8bb8f
 		path_dhclient_script = s;
c8bb8f
 	}
c8bb8f
 
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+	/* Drop capabilities */
c8bb8f
+	if (!keep_capabilities) {
c8bb8f
+		capng_clear(CAPNG_SELECT_CAPS);
c8bb8f
+		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
c8bb8f
+				CAP_DAC_OVERRIDE); // Drop this someday
c8bb8f
+		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
c8bb8f
+				CAP_NET_ADMIN, CAP_NET_RAW,
c8bb8f
+				CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
c8bb8f
+		capng_apply(CAPNG_SELECT_CAPS);
c8bb8f
+	}
c8bb8f
+#endif
c8bb8f
+
c8bb8f
 	/* Set up the initial dhcp option universe. */
c8bb8f
 	initialize_common_option_spaces();
c8bb8f
 
c8bb8f
diff -up dhcp-4.2.2b1/client/dhclient-script.8.capability dhcp-4.2.2b1/client/dhclient-script.8
c8bb8f
--- dhcp-4.2.2b1/client/dhclient-script.8.capability	2011-07-01 15:09:06.604784521 +0200
c8bb8f
+++ dhcp-4.2.2b1/client/dhclient-script.8	2011-07-01 15:09:06.666783883 +0200
c8bb8f
@@ -239,6 +239,16 @@ repeatedly initialized to the values pro
c8bb8f
 the other.   Assuming the information provided by both servers is
c8bb8f
 valid, this shouldn't cause any real problems, but it could be
c8bb8f
 confusing.
c8bb8f
+.PP
c8bb8f
+Normally, if dhclient was compiled with libcap-ng support,
c8bb8f
+dhclient drops most capabilities immediately upon startup.
c8bb8f
+While more secure, this greatly restricts the additional actions that
c8bb8f
+hooks in dhclient-script can take. For example, any daemons that
c8bb8f
+dhclient-script starts or restarts will inherit the restricted
c8bb8f
+capabilities as well, which may interfere with their correct operation.
c8bb8f
+Thus, the
c8bb8f
+.BI \-nc
c8bb8f
+option can be used to prevent dhclient from dropping capabilities.
c8bb8f
 .SH SEE ALSO
c8bb8f
 dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
c8bb8f
 dhclient.leases(5).
c8bb8f
diff -up dhcp-4.2.2b1/client/Makefile.am.capability dhcp-4.2.2b1/client/Makefile.am
c8bb8f
--- dhcp-4.2.2b1/client/Makefile.am.capability	2011-07-01 15:09:06.526785327 +0200
c8bb8f
+++ dhcp-4.2.2b1/client/Makefile.am	2011-07-01 15:09:06.667783873 +0200
c8bb8f
@@ -5,7 +5,7 @@ dhclient_SOURCES = clparse.c dhclient.c 
c8bb8f
 		   scripts/netbsd scripts/nextstep scripts/openbsd \
c8bb8f
 		   scripts/solaris scripts/openwrt
c8bb8f
 dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
c8bb8f
-		 $(BIND9_LIBDIR) -ldns-export -lisc-export
c8bb8f
+		 $(BIND9_LIBDIR) -ldns-export -lisc-export $(CAPNG_LDADD)
c8bb8f
 man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
c8bb8f
 EXTRA_DIST = $(man_MANS)
c8bb8f
 
c8bb8f
diff -up dhcp-4.2.2b1/configure.ac.capability dhcp-4.2.2b1/configure.ac
c8bb8f
--- dhcp-4.2.2b1/configure.ac.capability	2011-07-01 15:09:06.527785317 +0200
c8bb8f
+++ dhcp-4.2.2b1/configure.ac	2011-07-01 15:09:06.667783873 +0200
c8bb8f
@@ -449,6 +449,41 @@ AC_TRY_LINK(
c8bb8f
 # Look for optional headers.
c8bb8f
 AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
c8bb8f
 
c8bb8f
+# look for capabilities library
c8bb8f
+AC_ARG_WITH(libcap-ng,
c8bb8f
+    [  --with-libcap-ng=[auto/yes/no]  Add Libcap-ng support [default=auto]],,
c8bb8f
+    with_libcap_ng=auto)
c8bb8f
+
c8bb8f
+# Check for Libcap-ng API
c8bb8f
+#
c8bb8f
+# libcap-ng detection
c8bb8f
+if test x$with_libcap_ng = xno ; then
c8bb8f
+    have_libcap_ng=no;
c8bb8f
+else
c8bb8f
+    # Start by checking for header file
c8bb8f
+    AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
c8bb8f
+
c8bb8f
+    # See if we have libcap-ng library
c8bb8f
+    AC_CHECK_LIB(cap-ng, capng_clear,
c8bb8f
+                 CAPNG_LDADD=-lcap-ng,)
c8bb8f
+
c8bb8f
+    # Check results are usable
c8bb8f
+    if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
c8bb8f
+       AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
c8bb8f
+    fi
c8bb8f
+    if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
c8bb8f
+       AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
c8bb8f
+    fi
c8bb8f
+fi
c8bb8f
+AC_SUBST(CAPNG_LDADD)
c8bb8f
+AC_MSG_CHECKING(whether to use libcap-ng)
c8bb8f
+if test x$CAPNG_LDADD != x ; then
c8bb8f
+    AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
c8bb8f
+    AC_MSG_RESULT(yes)
c8bb8f
+else
c8bb8f
+    AC_MSG_RESULT(no)
c8bb8f
+fi
c8bb8f
+
c8bb8f
 # Solaris needs some libraries for functions
c8bb8f
 AC_SEARCH_LIBS(socket, [socket])
c8bb8f
 AC_SEARCH_LIBS(inet_ntoa, [nsl])
c8bb8f
diff -up dhcp-4.2.2b1/relay/dhcrelay.c.capability dhcp-4.2.2b1/relay/dhcrelay.c
c8bb8f
--- dhcp-4.2.2b1/relay/dhcrelay.c.capability	2011-07-01 15:09:06.626784295 +0200
c8bb8f
+++ dhcp-4.2.2b1/relay/dhcrelay.c	2011-07-01 15:12:05.362223794 +0200
c8bb8f
@@ -36,6 +36,11 @@
c8bb8f
 #include <syslog.h>
c8bb8f
 #include <sys/time.h>
c8bb8f
 
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+#  include <cap-ng.h>
c8bb8f
+   int keep_capabilities = 0;
c8bb8f
+#endif
c8bb8f
+
c8bb8f
 TIME default_lease_time = 43200; /* 12 hours... */
c8bb8f
 TIME max_lease_time = 86400; /* 24 hours... */
c8bb8f
 struct tree_cache *global_options[256];
c8bb8f
@@ -356,6 +361,10 @@ main(int argc, char **argv) {
c8bb8f
 			sl->next = upstreams;
c8bb8f
 			upstreams = sl;
c8bb8f
 #endif
c8bb8f
+		} else if (!strcmp(argv[i], "-nc")) {
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+			keep_capabilities = 1;
c8bb8f
+#endif
c8bb8f
 		} else if (!strcmp(argv[i], "-pf")) {
c8bb8f
 			if (++i == argc)
c8bb8f
 				usage();
c8bb8f
@@ -426,6 +435,17 @@ main(int argc, char **argv) {
c8bb8f
 #endif
c8bb8f
 	}
c8bb8f
 
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+	/* Drop capabilities */
c8bb8f
+	if (!keep_capabilities) {
c8bb8f
+		capng_clear(CAPNG_SELECT_BOTH);
c8bb8f
+		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
c8bb8f
+				CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1);
c8bb8f
+		capng_apply(CAPNG_SELECT_BOTH);
c8bb8f
+		log_info ("Dropped all unnecessary capabilities.");
c8bb8f
+	}
c8bb8f
+#endif
c8bb8f
+
c8bb8f
 	if (!quiet) {
c8bb8f
 		log_info("%s %s", message, PACKAGE_VERSION);
c8bb8f
 		log_info(copyright);
c8bb8f
@@ -573,6 +593,15 @@ main(int argc, char **argv) {
c8bb8f
 		dhcpv6_packet_handler = do_packet6;
c8bb8f
 #endif
c8bb8f
 
c8bb8f
+#ifdef HAVE_LIBCAP_NG
c8bb8f
+	/* Drop all capabilities */
c8bb8f
+	if (!keep_capabilities) {
c8bb8f
+		capng_clear(CAPNG_SELECT_BOTH);
c8bb8f
+		capng_apply(CAPNG_SELECT_BOTH);
c8bb8f
+		log_info ("Dropped all capabilities.");
c8bb8f
+	}
c8bb8f
+#endif
c8bb8f
+
c8bb8f
 	/* Start dispatching packets and timeouts... */
c8bb8f
 	dispatch();
c8bb8f
 
c8bb8f
diff -up dhcp-4.2.2b1/relay/Makefile.am.capability dhcp-4.2.2b1/relay/Makefile.am
c8bb8f
--- dhcp-4.2.2b1/relay/Makefile.am.capability	2011-07-01 15:09:06.546785121 +0200
c8bb8f
+++ dhcp-4.2.2b1/relay/Makefile.am	2011-07-01 15:09:06.670783841 +0200
c8bb8f
@@ -3,7 +3,7 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localst
c8bb8f
 sbin_PROGRAMS = dhcrelay
c8bb8f
 dhcrelay_SOURCES = dhcrelay.c
c8bb8f
 dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.a \
c8bb8f
-		 $(BIND9_LIBDIR) -ldns-export -lisc-export
c8bb8f
+		 $(BIND9_LIBDIR) -ldns-export -lisc-export $(CAPNG_LDADD)
c8bb8f
 man_MANS = dhcrelay.8
c8bb8f
 EXTRA_DIST = $(man_MANS)
c8bb8f