272e48a
diff -up dhcp-4.1-ESV/client/dhclient.8.capability dhcp-4.1-ESV/client/dhclient.8
272e48a
--- dhcp-4.1-ESV/client/dhclient.8.capability	2010-12-14 12:44:49.000000000 +0100
272e48a
+++ dhcp-4.1-ESV/client/dhclient.8	2010-12-14 12:49:50.000000000 +0100
272e48a
@@ -94,6 +94,9 @@ dhclient - Dynamic Host Configuration Pr
272e48a
 .I script-file
dc107d6
 ]
dc107d6
 [
dc107d6
+.B -nc
dc107d6
+]
dc107d6
+[
272e48a
 .B -s
272e48a
 .I server
dc107d6
 ]
272e48a
@@ -404,6 +407,32 @@ when it gets a lease.  If unspecified, t
272e48a
 is used.  See \fBdhclient-script(8)\fR for a description of this file.
6364c8b
 
6364c8b
 .TP
6364c8b
+.BI \-nc
6364c8b
+Do not drop capabilities.
6364c8b
+
6364c8b
+Normally, if
6364c8b
+.B dhclient
6364c8b
+was compiled with libcap-ng support,
6364c8b
+.B dhclient
6364c8b
+drops most capabilities immediately upon startup.  While more secure,
6364c8b
+this greatly restricts the additional actions that hooks in
6364c8b
+.B dhclient-script (8)
6364c8b
+can take.  (For example, any daemons that 
6364c8b
+.B dhclient-script (8)
6364c8b
+starts or restarts will inherit the restricted capabilities as well,
6364c8b
+which may interfere with their correct operation.)  Thus, the
6364c8b
+.BI \-nc
6364c8b
+option can be used to prevent
6364c8b
+.B dhclient
6364c8b
+from dropping capabilities.
6364c8b
+
6364c8b
+The
6364c8b
+.BI \-nc
6364c8b
+option is ignored if
6364c8b
+.B dhclient
6364c8b
+was not compiled with libcap-ng support.
6364c8b
+
6364c8b
+.TP
272e48a
 .BI \-B
272e48a
 Set the BOOTP broadcast flag in request packets so servers will always
272e48a
 broadcast replies.
272e48a
diff -up dhcp-4.1-ESV/client/dhclient.c.capability dhcp-4.1-ESV/client/dhclient.c
272e48a
--- dhcp-4.1-ESV/client/dhclient.c.capability	2010-12-14 12:44:49.000000000 +0100
272e48a
+++ dhcp-4.1-ESV/client/dhclient.c	2010-12-14 12:44:49.000000000 +0100
32e9820
@@ -37,6 +37,9 @@
32e9820
 #include <sys/time.h>
32e9820
 #include <sys/wait.h>
32e9820
 #include <limits.h>
32e9820
+#ifdef HAVE_LIBCAP_NG
32e9820
+#include <cap-ng.h>
32e9820
+#endif
32e9820
 
32e9820
 /*
32e9820
  * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
530150d
@@ -89,6 +92,9 @@ int wanted_ia_ta = 0;
530150d
 int wanted_ia_pd = 0;
530150d
 char *mockup_relay = NULL;
530150d
 int bootp_broadcast_always = 0;
530150d
+#ifdef HAVE_LIBCAP_NG
530150d
+static int keep_capabilities = 0;
530150d
+#endif
530150d
 
530150d
 extern u_int32_t default_requested_options[];
530150d
 
272e48a
@@ -384,6 +390,10 @@ main(int argc, char **argv) {
530150d
 			}
530150d
 
530150d
 			dhclient_request_options = argv[i];
530150d
+		} else if (!strcmp(argv[i], "-nc")) {
6364c8b
+#ifdef HAVE_LIBCAP_NG
530150d
+			keep_capabilities = 1;
530150d
+#endif
530150d
 		} else if (argv[i][0] == '-') {
530150d
 		    usage();
530150d
 		} else if (interfaces_requested < 0) {
272e48a
@@ -432,6 +442,19 @@ main(int argc, char **argv) {
32e9820
 		path_dhclient_script = s;
32e9820
 	}
32e9820
 
32e9820
+#ifdef HAVE_LIBCAP_NG
32e9820
+	/* Drop capabilities */
530150d
+	if (!keep_capabilities) {
530150d
+		capng_clear(CAPNG_SELECT_CAPS);
530150d
+		capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
530150d
+				CAP_DAC_OVERRIDE); // Drop this someday
530150d
+		capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
530150d
+				CAP_NET_ADMIN, CAP_NET_RAW,
530150d
+				CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
530150d
+		capng_apply(CAPNG_SELECT_CAPS);
530150d
+	}
32e9820
+#endif
32e9820
+
32e9820
 	/* Set up the initial dhcp option universe. */
32e9820
 	initialize_common_option_spaces();
32e9820
 
272e48a
diff -up dhcp-4.1-ESV/client/dhclient-script.8.capability dhcp-4.1-ESV/client/dhclient-script.8
272e48a
--- dhcp-4.1-ESV/client/dhclient-script.8.capability	2010-12-14 12:44:49.000000000 +0100
272e48a
+++ dhcp-4.1-ESV/client/dhclient-script.8	2010-12-14 12:44:49.000000000 +0100
eda5617
@@ -239,6 +239,16 @@ repeatedly initialized to the values pro
eda5617
 the other.   Assuming the information provided by both servers is
eda5617
 valid, this shouldn't cause any real problems, but it could be
eda5617
 confusing.
eda5617
+.PP
eda5617
+Normally, if dhclient was compiled with libcap-ng support,
eda5617
+dhclient drops most capabilities immediately upon startup.
eda5617
+While more secure, this greatly restricts the additional actions that
eda5617
+hooks in dhclient-script can take. For example, any daemons that
eda5617
+dhclient-script starts or restarts will inherit the restricted
eda5617
+capabilities as well, which may interfere with their correct operation.
eda5617
+Thus, the
eda5617
+.BI \-nc
eda5617
+option can be used to prevent dhclient from dropping capabilities.
eda5617
 .SH SEE ALSO
eda5617
 dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
eda5617
 dhclient.leases(5).
272e48a
diff -up dhcp-4.1-ESV/client/Makefile.am.capability dhcp-4.1-ESV/client/Makefile.am
272e48a
--- dhcp-4.1-ESV/client/Makefile.am.capability	2010-09-15 00:49:47.000000000 +0200
272e48a
+++ dhcp-4.1-ESV/client/Makefile.am	2010-12-14 12:44:49.000000000 +0100
32e9820
@@ -5,7 +5,7 @@ dhclient_SOURCES = clparse.c dhclient.c 
32e9820
 		   scripts/netbsd scripts/nextstep scripts/openbsd \
32e9820
 		   scripts/solaris scripts/openwrt
32e9820
 dhclient_LDADD = ../common/libdhcp.a ../minires/libres.a \
32e9820
-		 ../omapip/libomapi.a ../dst/libdst.a
32e9820
+		 ../omapip/libomapi.a ../dst/libdst.a $(CAPNG_LDADD)
32e9820
 man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
32e9820
 EXTRA_DIST = $(man_MANS)
32e9820
 
272e48a
diff -up dhcp-4.1-ESV/configure.ac.capability dhcp-4.1-ESV/configure.ac
272e48a
--- dhcp-4.1-ESV/configure.ac.capability	2010-12-14 12:44:49.000000000 +0100
272e48a
+++ dhcp-4.1-ESV/configure.ac	2010-12-14 12:51:42.000000000 +0100
272e48a
@@ -425,6 +425,41 @@ AC_TRY_LINK(
32e9820
 # Look for optional headers.
32e9820
 AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
32e9820
 
32e9820
+# look for capabilities library
530150d
+AC_ARG_WITH(libcap-ng,
530150d
+    [  --with-libcap-ng=[auto/yes/no]  Add Libcap-ng support [default=auto]],,
530150d
+    with_libcap_ng=auto)
530150d
+
530150d
+# Check for Libcap-ng API
530150d
+#
530150d
+# libcap-ng detection
530150d
+if test x$with_libcap_ng = xno ; then
530150d
+    have_libcap_ng=no;
530150d
+else
530150d
+    # Start by checking for header file
530150d
+    AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
530150d
+
530150d
+    # See if we have libcap-ng library
530150d
+    AC_CHECK_LIB(cap-ng, capng_clear,
530150d
+                 CAPNG_LDADD=-lcap-ng,)
530150d
+
530150d
+    # Check results are usable
530150d
+    if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
530150d
+       AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
530150d
+    fi
530150d
+    if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
530150d
+       AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
530150d
+    fi
530150d
+fi
530150d
+AC_SUBST(CAPNG_LDADD)
530150d
+AC_MSG_CHECKING(whether to use libcap-ng)
530150d
+if test x$CAPNG_LDADD != x ; then
530150d
+    AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
530150d
+    AC_MSG_RESULT(yes)
530150d
+else
530150d
+    AC_MSG_RESULT(no)
530150d
+fi
32e9820
+
272e48a
 # Solaris needs some libraries for functions
272e48a
 AC_SEARCH_LIBS(socket, [socket])
272e48a
 AC_SEARCH_LIBS(inet_ntoa, [nsl])