7b69e54
diff -up dhcp-4.3.1b1/client/dhclient.8.zzftXp dhcp-4.3.1b1/client/dhclient.8
7b69e54
--- dhcp-4.3.1b1/client/dhclient.8.zzftXp	2014-07-10 17:38:26.938599402 +0200
7b69e54
+++ dhcp-4.3.1b1/client/dhclient.8	2014-07-10 17:39:25.852763873 +0200
7b69e54
@@ -128,6 +128,9 @@ dhclient - Dynamic Host Configuration Pr
45c0371
 .B -w
d44b399
 ]
d44b399
 [
d44b399
+.B -nc
d44b399
+]
d44b399
+[
45c0371
 .B -B
d44b399
 ]
d44b399
 [
7b69e54
@@ -304,6 +307,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.
7b69e54
diff -up dhcp-4.3.1b1/client/dhclient.c.zzftXp dhcp-4.3.1b1/client/dhclient.c
7b69e54
--- dhcp-4.3.1b1/client/dhclient.c.zzftXp	2014-07-10 17:39:25.797764653 +0200
7b69e54
+++ dhcp-4.3.1b1/client/dhclient.c	2014-07-10 17:39:25.853763858 +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.
7b69e54
@@ -143,6 +147,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));
7b69e54
@@ -425,6 +432,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) {
7b69e54
@@ -473,6 +484,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
 
7b69e54
diff -up dhcp-4.3.1b1/client/dhclient-script.8.zzftXp dhcp-4.3.1b1/client/dhclient-script.8
7b69e54
--- dhcp-4.3.1b1/client/dhclient-script.8.zzftXp	2014-07-10 17:39:25.761765163 +0200
7b69e54
+++ dhcp-4.3.1b1/client/dhclient-script.8	2014-07-10 17:39:25.851763887 +0200
7b69e54
@@ -243,6 +243,16 @@ repeatedly initialized to the values pro
7b69e54
 the other.   Assuming the information provided by both servers is
7b69e54
 valid, this shouldn't cause any real problems, but it could be
7b69e54
 confusing.
7b69e54
+.PP
7b69e54
+Normally, if dhclient was compiled with libcap-ng support,
7b69e54
+dhclient drops most capabilities immediately upon startup.
7b69e54
+While more secure, this greatly restricts the additional actions that
7b69e54
+hooks in dhclient-script can take. For example, any daemons that
7b69e54
+dhclient-script starts or restarts will inherit the restricted
7b69e54
+capabilities as well, which may interfere with their correct operation.
7b69e54
+Thus, the
7b69e54
+.BI \-nc
7b69e54
+option can be used to prevent dhclient from dropping capabilities.
7b69e54
 .SH SEE ALSO
7b69e54
 dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
7b69e54
 dhclient.leases(5).
7b69e54
diff -up dhcp-4.3.1b1/client/Makefile.am.zzftXp dhcp-4.3.1b1/client/Makefile.am
7b69e54
--- dhcp-4.3.1b1/client/Makefile.am.zzftXp	2014-07-10 17:38:10.778828583 +0200
7b69e54
+++ dhcp-4.3.1b1/client/Makefile.am	2014-07-10 17:39:25.851763887 +0200
7b69e54
@@ -10,7 +10,7 @@ dhclient_SOURCES = clparse.c dhclient.c
7b69e54
 		   scripts/bsdos scripts/freebsd scripts/linux scripts/macos \
7b69e54
 		   scripts/netbsd scripts/nextstep scripts/openbsd \
7b69e54
 		   scripts/solaris scripts/openwrt
7b69e54
-dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
7b69e54
+dhclient_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(CAPNG_LDADD) \
cccec22
 		 $(BIND9_LIBDIR) -lirs-export -ldns-export -lisccfg-export -lisc-export
7b69e54
 man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
7b69e54
 EXTRA_DIST = $(man_MANS)
7b69e54
diff -up dhcp-4.3.1b1/configure.ac.zzftXp dhcp-4.3.1b1/configure.ac
7b69e54
--- dhcp-4.3.1b1/configure.ac.zzftXp	2014-07-10 17:38:10.779828569 +0200
7b69e54
+++ dhcp-4.3.1b1/configure.ac	2014-07-10 17:39:25.854763844 +0200
7b69e54
@@ -499,6 +499,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],
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])
7b69e54
diff -up dhcp-4.3.1b1/relay/dhcrelay.c.zzftXp dhcp-4.3.1b1/relay/dhcrelay.c
7b69e54
--- dhcp-4.3.1b1/relay/dhcrelay.c.zzftXp	2014-07-10 17:39:25.799764624 +0200
7b69e54
+++ dhcp-4.3.1b1/relay/dhcrelay.c	2014-07-10 17:40:19.191007421 +0200
7b69e54
@@ -31,6 +31,11 @@
e83fb19
 #include <signal.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];
7b69e54
@@ -376,6 +381,10 @@ main(int argc, char **argv) {
e83fb19
 				usage();
e83fb19
 			dhcrelay_sub_id = argv[i];
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();
7b69e54
@@ -446,6 +455,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);
7b69e54
@@ -598,6 +618,15 @@ main(int argc, char **argv) {
e83fb19
 	signal(SIGTERM, dhcp_signal_handler);  /* kill */
7b69e54
 #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
 
7b69e54
diff -up dhcp-4.3.1b1/relay/Makefile.am.zzftXp dhcp-4.3.1b1/relay/Makefile.am
7b69e54
--- dhcp-4.3.1b1/relay/Makefile.am.zzftXp	2014-07-10 17:38:10.780828554 +0200
7b69e54
+++ dhcp-4.3.1b1/relay/Makefile.am	2014-07-10 17:39:25.854763844 +0200
7b69e54
@@ -2,7 +2,7 @@ AM_CPPFLAGS = -DLOCALSTATEDIR='"@localst
7b69e54
 
7b69e54
 sbin_PROGRAMS = dhcrelay
7b69e54
 dhcrelay_SOURCES = dhcrelay.c
7b69e54
-dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.la \
7b69e54
+dhcrelay_LDADD = ../common/libdhcp.a ../omapip/libomapi.la $(CAPNG_LDADD) \
cccec22
 		 $(BIND9_LIBDIR) -lirs-export -ldns-export -lisccfg-export -lisc-export
7b69e54
 man_MANS = dhcrelay.8
7b69e54
 EXTRA_DIST = $(man_MANS)