8173a6
diff -up dhcp-4.3.4/client/dhclient.8.capability dhcp-4.3.4/client/dhclient.8
8173a6
--- dhcp-4.3.4/client/dhclient.8.capability	2016-04-29 12:19:40.657129322 +0200
8173a6
+++ dhcp-4.3.4/client/dhclient.8	2016-04-29 12:19:40.715129297 +0200
8173a6
@@ -134,6 +134,9 @@ dhclient - Dynamic Host Configuration Pr
45c037
 .B -w
d44b39
 ]
d44b39
 [
d44b39
+.B -nc
d44b39
+]
d44b39
+[
45c037
 .B -B
d44b39
 ]
d44b39
 [
8173a6
@@ -318,6 +321,32 @@ has been added or removed, so that the c
45c037
 address on that interface.
cd8c86
 
cd8c86
 .TP
cd8c86
+.BI \-nc
cd8c86
+Do not drop capabilities.
cd8c86
+
cd8c86
+Normally, if
cd8c86
+.B dhclient
cd8c86
+was compiled with libcap-ng support,
cd8c86
+.B dhclient
cd8c86
+drops most capabilities immediately upon startup.  While more secure,
cd8c86
+this greatly restricts the additional actions that hooks in
cd8c86
+.B dhclient-script (8)
cd8c86
+can take.  (For example, any daemons that 
cd8c86
+.B dhclient-script (8)
cd8c86
+starts or restarts will inherit the restricted capabilities as well,
cd8c86
+which may interfere with their correct operation.)  Thus, the
cd8c86
+.BI \-nc
cd8c86
+option can be used to prevent
cd8c86
+.B dhclient
cd8c86
+from dropping capabilities.
cd8c86
+
cd8c86
+The
cd8c86
+.BI \-nc
cd8c86
+option is ignored if
cd8c86
+.B dhclient
cd8c86
+was not compiled with libcap-ng support.
cd8c86
+
cd8c86
+.TP
45c037
 .BI \-B
45c037
 Set the BOOTP broadcast flag in request packets so servers will always
45c037
 broadcast replies.
8173a6
diff -up dhcp-4.3.4/client/dhclient.c.capability dhcp-4.3.4/client/dhclient.c
8173a6
--- dhcp-4.3.4/client/dhclient.c.capability	2016-04-29 12:19:40.691129307 +0200
8173a6
+++ dhcp-4.3.4/client/dhclient.c	2016-04-29 12:21:07.620091930 +0200
8173a6
@@ -40,6 +40,10 @@
8173a6
 #include <isc file.h="">
5a3797
 #include <dns result.h="">
5a3797
 
3b84ae
+#ifdef HAVE_LIBCAP_NG
3b84ae
+#include <cap-ng.h>
3b84ae
+#endif
5a3797
+
3b84ae
 /*
3b84ae
  * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
5a3797
  * that when building ISC code.
8173a6
@@ -237,6 +241,9 @@ main(int argc, char **argv) {
48c398
 	int timeout_arg = 0;
48c398
 	char *arg_conf = NULL;
48c398
 	int arg_conf_len = 0;
798599
+#ifdef HAVE_LIBCAP_NG
48c398
+	int keep_capabilities = 0;
798599
+#endif
798599
 
48c398
 	/* Initialize client globals. */
48c398
 	memset(&default_duid, 0, sizeof(default_duid));
8173a6
@@ -537,6 +544,10 @@ main(int argc, char **argv) {
798599
 			}
798599
 
798599
 			dhclient_request_options = argv[i];
798599
+		} else if (!strcmp(argv[i], "-nc")) {
cd8c86
+#ifdef HAVE_LIBCAP_NG
798599
+			keep_capabilities = 1;
798599
+#endif
798599
 		} else if (argv[i][0] == '-') {
8173a6
 			usage("Unknown command: %s", argv[i]);
798599
 		} else if (interfaces_requested < 0) {
8173a6
@@ -597,6 +608,19 @@ main(int argc, char **argv) {
3b84ae
 		path_dhclient_script = s;
3b84ae
 	}
3b84ae
 
3b84ae
+#ifdef HAVE_LIBCAP_NG
3b84ae
+	/* Drop capabilities */
798599
+	if (!keep_capabilities) {
798599
+		capng_clear(CAPNG_SELECT_CAPS);
798599
+		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
798599
+				CAP_DAC_OVERRIDE); // Drop this someday
798599
+		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
798599
+				CAP_NET_ADMIN, CAP_NET_RAW,
798599
+				CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
798599
+		capng_apply(CAPNG_SELECT_CAPS);
798599
+	}
3b84ae
+#endif
3b84ae
+
3b84ae
 	/* Set up the initial dhcp option universe. */
3b84ae
 	initialize_common_option_spaces();
3b84ae
 
8173a6
diff -up dhcp-4.3.4/client/dhclient-script.8.capability dhcp-4.3.4/client/dhclient-script.8
8173a6
--- dhcp-4.3.4/client/dhclient-script.8.capability	2016-04-29 12:19:40.668129317 +0200
8173a6
+++ dhcp-4.3.4/client/dhclient-script.8	2016-04-29 12:19:40.717129296 +0200
7b69e5
@@ -243,6 +243,16 @@ repeatedly initialized to the values pro
7b69e5
 the other.   Assuming the information provided by both servers is
7b69e5
 valid, this shouldn't cause any real problems, but it could be
7b69e5
 confusing.
7b69e5
+.PP
7b69e5
+Normally, if dhclient was compiled with libcap-ng support,
7b69e5
+dhclient drops most capabilities immediately upon startup.
7b69e5
+While more secure, this greatly restricts the additional actions that
7b69e5
+hooks in dhclient-script can take. For example, any daemons that
7b69e5
+dhclient-script starts or restarts will inherit the restricted
7b69e5
+capabilities as well, which may interfere with their correct operation.
7b69e5
+Thus, the
7b69e5
+.BI \-nc
7b69e5
+option can be used to prevent dhclient from dropping capabilities.
7b69e5
 .SH SEE ALSO
7b69e5
 dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
7b69e5
 dhclient.leases(5).
8173a6
diff -up dhcp-4.3.4/client/Makefile.am.capability dhcp-4.3.4/client/Makefile.am
8173a6
--- dhcp-4.3.4/client/Makefile.am.capability	2016-04-29 12:19:40.652129324 +0200
8173a6
+++ dhcp-4.3.4/client/Makefile.am	2016-04-29 12:19:40.717129296 +0200
8173a6
@@ -13,7 +13,7 @@ dhclient_SOURCES = clparse.c dhclient.c
7b69e5
 		   scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
7b69e5
 		   scripts/netbsd scripts/nextstep scripts/openbsd \
7b69e5
 		   scripts/solaris scripts/openwrt
7b69e5
-dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
7b69e5
+dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(CAPNG_LDADD) \
cccec2
 		 $(BIND9_LIBDIR) -lirs-export -ldns-export -lisccfg-export -lisc-export
7b69e5
 man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
7b69e5
 EXTRA_DIST = $(man_MANS)
8173a6
diff -up dhcp-4.3.4/configure.ac.capability dhcp-4.3.4/configure.ac
8173a6
--- dhcp-4.3.4/configure.ac.capability	2016-04-29 12:19:40.652129324 +0200
8173a6
+++ dhcp-4.3.4/configure.ac	2016-04-29 12:19:40.717129296 +0200
8173a6
@@ -585,6 +585,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],
3b84ae
 # Look for optional headers.
3b84ae
 AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
3b84ae
 
3b84ae
+# look for capabilities library
798599
+AC_ARG_WITH(libcap-ng,
798599
+    [  --with-libcap-ng=[auto/yes/no]  Add Libcap-ng support [default=auto]],,
798599
+    with_libcap_ng=auto)
798599
+
798599
+# Check for Libcap-ng API
798599
+#
798599
+# libcap-ng detection
798599
+if test x$with_libcap_ng = xno ; then
798599
+    have_libcap_ng=no;
798599
+else
798599
+    # Start by checking for header file
798599
+    AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
798599
+
798599
+    # See if we have libcap-ng library
798599
+    AC_CHECK_LIB(cap-ng, capng_clear,
798599
+                 CAPNG_LDADD=-lcap-ng,)
798599
+
798599
+    # Check results are usable
798599
+    if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
798599
+       AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
798599
+    fi
798599
+    if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
798599
+       AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
798599
+    fi
798599
+fi
798599
+AC_SUBST(CAPNG_LDADD)
798599
+AC_MSG_CHECKING(whether to use libcap-ng)
798599
+if test x$CAPNG_LDADD != x ; then
798599
+    AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
798599
+    AC_MSG_RESULT(yes)
798599
+else
798599
+    AC_MSG_RESULT(no)
798599
+fi
3b84ae
+
45c037
 # Solaris needs some libraries for functions
45c037
 AC_SEARCH_LIBS(socket, [socket])
45c037
 AC_SEARCH_LIBS(inet_ntoa, [nsl])
8173a6
diff -up dhcp-4.3.4/relay/dhcrelay.c.capability dhcp-4.3.4/relay/dhcrelay.c
8173a6
--- dhcp-4.3.4/relay/dhcrelay.c.capability	2016-04-29 12:19:40.694129306 +0200
8173a6
+++ dhcp-4.3.4/relay/dhcrelay.c	2016-04-29 12:22:30.278056386 +0200
8173a6
@@ -32,6 +32,11 @@
48c398
 #include <sys time.h="">
8173a6
 #include <isc file.h="">
48c398
 
48c398
+#ifdef HAVE_LIBCAP_NG
48c398
+#  include <cap-ng.h>
48c398
+   int keep_capabilities = 0;
48c398
+#endif
48c398
+
48c398
 TIME default_lease_time = 43200; /* 12 hours... */
48c398
 TIME max_lease_time = 86400; /* 24 hours... */
48c398
 struct tree_cache *global_options[256];
8173a6
@@ -454,6 +459,10 @@ main(int argc, char **argv) {
8173a6
 				usage(use_noarg, argv[i-1]);
e83fb1
 			dhcrelay_sub_id = argv[i];
48c398
 #endif
48c398
+		} else if (!strcmp(argv[i], "-nc")) {
48c398
+#ifdef HAVE_LIBCAP_NG
48c398
+			keep_capabilities = 1;
48c398
+#endif
48c398
 		} else if (!strcmp(argv[i], "-pf")) {
48c398
 			if (++i == argc)
8173a6
 				usage(use_noarg, argv[i-1]);
8173a6
@@ -528,6 +537,17 @@ main(int argc, char **argv) {
48c398
 #endif
48c398
 	}
48c398
 
48c398
+#ifdef HAVE_LIBCAP_NG
48c398
+	/* Drop capabilities */
48c398
+	if (!keep_capabilities) {
48c398
+		capng_clear(CAPNG_SELECT_BOTH);
48c398
+		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
48c398
+				CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1);
48c398
+		capng_apply(CAPNG_SELECT_BOTH);
be9baa
+		log_info ("Dropped all unnecessary capabilities.");
48c398
+	}
48c398
+#endif
48c398
+
48c398
 	if (!quiet) {
48c398
 		log_info("%s %s", message, PACKAGE_VERSION);
48c398
 		log_info(copyright);
8173a6
@@ -680,6 +700,15 @@ main(int argc, char **argv) {
e83fb1
 	signal(SIGTERM, dhcp_signal_handler);  /* kill */
7b69e5
 #endif
48c398
 
48c398
+#ifdef HAVE_LIBCAP_NG
48c398
+	/* Drop all capabilities */
48c398
+	if (!keep_capabilities) {
48c398
+		capng_clear(CAPNG_SELECT_BOTH);
48c398
+		capng_apply(CAPNG_SELECT_BOTH);
be9baa
+		log_info ("Dropped all capabilities.");
48c398
+	}
48c398
+#endif
48c398
+
48c398
 	/* Start dispatching packets and timeouts... */
48c398
 	dispatch();
48c398
 
8173a6
diff -up dhcp-4.3.4/relay/Makefile.am.capability dhcp-4.3.4/relay/Makefile.am
8173a6
--- dhcp-4.3.4/relay/Makefile.am.capability	2016-04-29 12:19:40.653129323 +0200
8173a6
+++ dhcp-4.3.4/relay/Makefile.am	2016-04-29 12:19:40.718129295 +0200
7b69e5
@@ -2,7 +2,7 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localst
7b69e5
 
7b69e5
 sbin_PROGRAMS = dhcrelay
7b69e5
 dhcrelay_SOURCES = dhcrelay.c
7b69e5
-dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
7b69e5
+dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(CAPNG_LDADD) \
cccec2
 		 $(BIND9_LIBDIR) -lirs-export -ldns-export -lisccfg-export -lisc-export
7b69e5
 man_MANS = dhcrelay.8
7b69e5
 EXTRA_DIST = $(man_MANS)