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