45c0371
diff -up dhcp-4.2.1b1/client/dhclient.8.capability dhcp-4.2.1b1/client/dhclient.8
45c0371
--- dhcp-4.2.1b1/client/dhclient.8.capability	2011-01-28 08:05:51.000000000 +0100
45c0371
+++ dhcp-4.2.1b1/client/dhclient.8	2011-01-28 08:24:48.000000000 +0100
45c0371
@@ -115,6 +115,9 @@ dhclient - Dynamic Host Configuration Pr
45c0371
 .B -w
d44b399
 ]
d44b399
 [
d44b399
+.B -nc
d44b399
+]
d44b399
+[
45c0371
 .B -B
d44b399
 ]
d44b399
 [
45c0371
@@ -293,6 +296,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.
45c0371
diff -up dhcp-4.2.1b1/client/dhclient.c.capability dhcp-4.2.1b1/client/dhclient.c
45c0371
--- dhcp-4.2.1b1/client/dhclient.c.capability	2011-01-28 08:05:51.000000000 +0100
45c0371
+++ dhcp-4.2.1b1/client/dhclient.c	2011-01-28 08:05:51.000000000 +0100
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.
45c0371
@@ -91,6 +95,9 @@ int wanted_ia_ta = 0;
7985996
 int wanted_ia_pd = 0;
7985996
 char *mockup_relay = NULL;
7985996
 int bootp_broadcast_always = 0;
7985996
+#ifdef HAVE_LIBCAP_NG
7985996
+static int keep_capabilities = 0;
7985996
+#endif
7985996
 
7985996
 extern u_int32_t default_requested_options[];
7985996
 
45c0371
@@ -399,6 +406,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) {
45c0371
@@ -447,6 +458,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
 
45c0371
diff -up dhcp-4.2.1b1/client/dhclient-script.8.capability dhcp-4.2.1b1/client/dhclient-script.8
45c0371
--- dhcp-4.2.1b1/client/dhclient-script.8.capability	2011-01-28 08:05:51.000000000 +0100
45c0371
+++ dhcp-4.2.1b1/client/dhclient-script.8	2011-01-28 08:05:51.000000000 +0100
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).
45c0371
diff -up dhcp-4.2.1b1/client/Makefile.am.capability dhcp-4.2.1b1/client/Makefile.am
45c0371
--- dhcp-4.2.1b1/client/Makefile.am.capability	2010-09-15 00:32:36.000000000 +0200
45c0371
+++ dhcp-4.2.1b1/client/Makefile.am	2011-01-28 08:05:51.000000000 +0100
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 \
5a3797e
-		 ../bind/lib/libdns.a ../bind/lib/libisc.a
5a3797e
+		 ../bind/lib/libdns.a ../bind/lib/libisc.a $(CAPNG_LDADD)
3b84ae4
 man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
3b84ae4
 EXTRA_DIST = $(man_MANS)
3b84ae4
 
45c0371
diff -up dhcp-4.2.1b1/configure.ac.capability dhcp-4.2.1b1/configure.ac
45c0371
--- dhcp-4.2.1b1/configure.ac.capability	2011-01-28 08:05:51.000000000 +0100
45c0371
+++ dhcp-4.2.1b1/configure.ac	2011-01-28 08:26:11.000000000 +0100
45c0371
@@ -425,6 +425,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])