Just attaching the patch here in the BTS for reference (it was only linked to before).
-- - mdz
diff -u dhcp3-3.0.1/debian/dhcp3-server.postrm dhcp3-3.0.1/debian/dhcp3-server.postrm --- dhcp3-3.0.1/debian/dhcp3-server.postrm +++ dhcp3-3.0.1/debian/dhcp3-server.postrm @@ -20,6 +20,12 @@ # Remove init.d configuration file rm -f /etc/default/dhcp3-server + # Remove pid directory + rm -rf /var/run/dhcp3-server + + # Remove user + deluser --system --quiet dhcpd + update-rc.d dhcp3-server remove >/dev/null ;; diff -u dhcp3-3.0.1/debian/dhcp3-server.init.d dhcp3-3.0.1/debian/dhcp3-server.init.d --- dhcp3-3.0.1/debian/dhcp3-server.init.d +++ dhcp3-3.0.1/debian/dhcp3-server.init.d @@ -16,13 +16,22 @@ # should listen on.) . /etc/default/dhcp3-server -DHCPDPID=/var/run/dhcpd.pid +DHCPDPID=/var/run/dhcp3-server/dhcpd.pid case "$1" in start) + # allow dhcp server to write lease and pid file + mkdir -p /var/run/dhcp3-server + chown dhcpd:dhcpd /var/run/dhcp3-server + [ -e /var/lib/dhcp3/dhcpd.leases ] || touch /var/lib/dhcp3/dhcpd.leases + chown dhcpd:dhcpd /var/lib/dhcp3 /var/lib/dhcp3/dhcpd.leases + if [ -e /var/lib/dhcp3/dhcpd.leases~ ]; then + chown dhcpd:dhcpd /var/lib/dhcp3/dhcpd.leases~ + fi + echo -n "Starting DHCP server: " start-stop-daemon --start --quiet --pidfile $DHCPDPID \ - --exec /usr/sbin/dhcpd3 -- -q $INTERFACES + --exec /usr/sbin/dhcpd3 -- -q $INTERFACES -pf $DHCPDPID sleep 2 if [ -f "$DHCPDPID" ] && ps h `cat "$DHCPDPID"` >/dev/null; then @@ -35,6 +44,10 @@ stop) echo -n "Stopping DHCP server: dhcpd3" start-stop-daemon --stop --quiet --pidfile $DHCPDPID + # remove PID file if it is still present + if [ -e $DHCPDPID ] && ! ps h $(< $DHCPDPID) > /dev/null; then + rm -f $DHCPDPID + fi echo "." ;; restart | force-reload) diff -u dhcp3-3.0.1/debian/dhcp3-server.postinst dhcp3-3.0.1/debian/dhcp3-server.postinst --- dhcp3-3.0.1/debian/dhcp3-server.postinst +++ dhcp3-3.0.1/debian/dhcp3-server.postinst @@ -9,7 +9,8 @@ case "$1" in configure) - # continue below + # create system dhcpd user and group + adduser --system --quiet --no-create-home --home /nonexistent --group dhcpd ;; abort-upgrade|abort-remove|abort-deconfigure) diff -u dhcp3-3.0.1/debian/changelog dhcp3-3.0.1/debian/changelog --- dhcp3-3.0.1/debian/changelog +++ dhcp3-3.0.1/debian/changelog @@ -1,3 +1,32 @@ +dhcp3 (3.0.1-2ubuntu3) breezy; urgency=low + + Derooted the DHCP server: + * Added debian/patches/droppriv.patch: + - Provide function drop_privileges() in common/droppriv.c. + - Interface: includes/droppriv.h. + * Added debian/patches/deroot-server.patch: + - server/dhcpd.c: Immediately chown to dhcpd:dhcpd and only keep + CAP_NET_RAW and CAP_NET_BIND_SERVICE for the initialization phase. + - Drop these remaining capabilities after opening the sockets. + * debian/dhcp3-server.init.d: + - Create /var/run/dhcp3-server with proper permissions. + - Set proper permissions of /var/lib/dhcp3 and + /var/lib/dhcp3/dhcpd.leases[~]. + - Change PID file path to /var/run/dhcp3-server/dhcpd.pid. + * debian/dhcp3-server.postinst: Create system user dhcpd. + * debian/dhcp3-server.postrm: + - Remove /var/run/dhcp3-server on purge. + - Remove system user dhcpd on purge. + * debian/control: Added build-dependency libcap-dev. + + Bug fixes: + * debian/rules: Remove client/scripts/debian in "clean" since it is copied + there on build. + * debian/dhcp3-server.init.d: Remove PID file after stop if it still exists + (dhcpd does not remove it on its own). + + -- Martin Pitt <martin.p...@ubuntu.com> Thu, 12 May 2005 16:19:48 +0200 + dhcp3 (3.0.1-2ubuntu2) breezy; urgency=low * Remove 1-second sleep from dhclient-script. In my testing it isn't diff -u dhcp3-3.0.1/debian/rules dhcp3-3.0.1/debian/rules --- dhcp3-3.0.1/debian/rules +++ dhcp3-3.0.1/debian/rules @@ -42,7 +42,7 @@ clean: unpatch dh_testdir - rm -f build-stamp install-stamp + rm -f build-stamp install-stamp client/scripts/debian # Add here commands to clean up after the build process. -$(MAKE) distclean diff -u dhcp3-3.0.1/debian/control dhcp3-3.0.1/debian/control --- dhcp3-3.0.1/debian/control +++ dhcp3-3.0.1/debian/control @@ -3,7 +3,7 @@ Priority: optional Maintainer: Eloy A. Paris <pe...@debian.org> Uploaders: Matt Zimmerman <m...@debian.org>, Andrew Pollock <apoll...@debian.org> -Build-Depends: debhelper (>= 4.1.16), dpkg-dev (>= 1.7.0), groff +Build-Depends: debhelper (>= 4.1.16), dpkg-dev (>= 1.7.0), groff, libcap-dev Standards-Version: 2.4.0.0 Package: dhcp3-server only in patch2: unchanged: --- dhcp3-3.0.1.orig/debian/patches/deroot-server.patch +++ dhcp3-3.0.1/debian/patches/deroot-server.patch @@ -0,0 +1,43 @@ +diff -Nur dhcp3-3.0.1.old/server/dhcpd.c dhcp3-3.0.1/server/dhcpd.c +--- dhcp3-3.0.1.old/server/dhcpd.c 2005-04-11 18:39:29.845552696 +0200 ++++ dhcp3-3.0.1/server/dhcpd.c 2005-04-11 19:19:24.436519536 +0200 +@@ -45,6 +45,7 @@ + + #include "dhcpd.h" + #include "version.h" ++#include "droppriv.h" + #include <omapip/omapip_p.h> + + static void usage PROTO ((void)); +@@ -226,6 +227,10 @@ + char *traceoutfile = (char *)0; + #endif + ++ /* drop privileges */ ++ cap_value_t capsneeded[] = { CAP_NET_RAW, CAP_NET_BIND_SERVICE }; ++ drop_privileges( "dhcpd", "dhcpd", 2, capsneeded, -1 ); ++ + /* Make sure we have stdin, stdout and stderr. */ + status = open ("/dev/null", O_RDWR); + if (status == 0) +@@ -599,6 +604,9 @@ + omapi_set_int_value ((omapi_object_t *)dhcp_control_object, + (omapi_object_t *)0, "state", server_running); + ++ /* drop all remaining capabilities */ ++ drop_privileges( "dhcpd", "dhcpd", 0, NULL, -1 ); ++ + /* Receive packets and dispatch them... */ + dispatch (); + +diff -Nur dhcp3-3.0.1.old/server/Makefile.dist dhcp3-3.0.1/server/Makefile.dist +--- dhcp3-3.0.1.old/server/Makefile.dist 2005-04-11 18:39:29.845552696 +0200 ++++ dhcp3-3.0.1/server/Makefile.dist 2005-04-11 18:50:07.370634152 +0200 +@@ -34,6 +34,7 @@ + INCLUDES = -I$(TOP) $(BINDINC) -I$(TOP)/includes + DHCPLIB = ../common/libdhcp.a $(BINDLIB) ../omapip/libomapi.a ../dst/libdst.a + CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) ++LIBS = -lcap + + all: $(PROG) $(CATMANPAGES) + only in patch2: unchanged: --- dhcp3-3.0.1.orig/debian/patches/droppriv.patch +++ dhcp3-3.0.1/debian/patches/droppriv.patch @@ -0,0 +1,152 @@ +diff -Nurp dhcp3-3.0.1.old/common/droppriv.c dhcp3-3.0.1/common/droppriv.c +--- dhcp3-3.0.1.old/common/droppriv.c 1970-01-01 01:00:00.000000000 +0100 ++++ dhcp3-3.0.1/common/droppriv.c 2005-05-12 15:38:52.000000000 +0200 +@@ -0,0 +1,96 @@ ++/** ++ * droppriv.c - drop privileges of a program running as root ++ * ++ * (C) 2004 Martin Pitt <mar...@piware.de> ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ */ ++ ++#include "droppriv.h" ++#include <sys/prctl.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <pwd.h> ++#include <grp.h> ++ ++void ++drop_privileges( const char* user, const char* group, int numcaps, ++ cap_value_t* caps, int errorexit ) ++{ ++ cap_t cap; ++ struct passwd *pw = NULL; ++ struct group *gr = NULL; ++ ++ /* determine user and group id */ ++ if( user != NULL ) { ++ pw = getpwnam( user ); ++ if( !pw ) { ++ fprintf( stderr, "drop_privileges: user %s does not exist\n", user ); ++ exit( errorexit ); ++ } ++ } ++ ++ if( group != NULL ) { ++ gr = getgrnam( group ); ++ if( !gr ) { ++ fprintf( stderr, "drop_privileges: group %s does not exist\n", group ); ++ exit( errorexit ); ++ } ++ } ++ ++ /* keep capabilities */ ++ if( numcaps > 0 ) { ++ int result; ++ ++ if( prctl( PR_SET_KEEPCAPS, 1, 0, 0, 0 ) ) { ++ perror( "drop_privileges: could not keep capabilities" ); ++ exit( errorexit ); ++ } ++ ++ /* test whether cap_set_proc works */ ++ cap = cap_get_proc(); ++ if( cap ) { ++ result = cap_set_proc( cap ); ++ cap_free( cap ); ++ if( result ) ++ return; ++ } else ++ return; ++ } ++ ++ ++ /* change uid/gid */ ++ if( gr != NULL && setgid( gr->gr_gid ) ) { ++ perror( "drop_privileges: could not set group id" ); ++ exit( errorexit ); ++ } ++ ++ if( pw != NULL && setuid( pw->pw_uid ) ) { ++ perror( "drop_privileges: could not set user id" ); ++ exit( errorexit ); ++ } ++ ++ /* set necessary capabilities */ ++ if( numcaps > 0 ) { ++ cap = cap_init(); ++ if( cap_set_flag( cap, CAP_PERMITTED, numcaps, caps, CAP_SET ) || ++ cap_set_flag( cap, CAP_EFFECTIVE, numcaps, caps, CAP_SET ) ) { ++ perror( "drop_privileges: cap_set_flag" ); ++ exit( errorexit ); ++ } ++ ++ if( cap_set_proc( cap ) ) { ++ perror( "drop_privileges: could not install capabilities" ); ++ exit( errorexit ); ++ } ++ ++ if( cap_free( cap ) ) { ++ perror( "drop_privileges: cap_free" ); ++ exit( errorexit ); ++ } ++ } ++} ++ +diff -Nurp dhcp3-3.0.1.old/common/Makefile.dist dhcp3-3.0.1/common/Makefile.dist +--- dhcp3-3.0.1.old/common/Makefile.dist 2004-06-14 23:08:42.000000000 +0200 ++++ dhcp3-3.0.1/common/Makefile.dist 2005-05-12 15:31:47.000000000 +0200 +@@ -25,11 +25,11 @@ SEDMANPAGES = dhcp-options.man5 dhcp-eva + SRC = raw.c parse.c nit.c icmp.c dispatch.c conflex.c upf.c bpf.c socket.c \ + lpf.c dlpi.c packet.c tr.c ethernet.c iscprint.c memory.c print.c \ + options.c inet.c tree.c tables.c alloc.c fddi.c ctrace.c dns.c \ +- resolv.c execute.c discover.c comapi.c ++ resolv.c execute.c discover.c comapi.c droppriv.c + OBJ = raw.o parse.o nit.o icmp.o dispatch.o conflex.o upf.o bpf.o socket.o \ + lpf.o dlpi.o packet.o tr.o ethernet.o iscprint.o memory.o print.o \ + options.o inet.o tree.o tables.o alloc.o fddi.o ctrace.o dns.o \ +- resolv.o execute.o discover.o comapi.o ++ resolv.o execute.o discover.o comapi.o droppriv.o + MAN = dhcp-options.5 dhcp-eval.5 + + INCLUDES = -I$(TOP) $(BINDINC) -I$(TOP)/includes +diff -Nurp dhcp3-3.0.1.old/includes/droppriv.h dhcp3-3.0.1/includes/droppriv.h +--- dhcp3-3.0.1.old/includes/droppriv.h 1970-01-01 01:00:00.000000000 +0100 ++++ dhcp3-3.0.1/includes/droppriv.h 2005-05-12 15:31:47.000000000 +0200 +@@ -0,0 +1,31 @@ ++/** ++ * droppriv.h - drop privileges of a program running as root ++ * ++ * (C) 2004 Martin Pitt <mar...@piware.de> ++ * ++ * Permission to use, copy, modify, and distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ */ ++ ++#ifndef _DROPPRIV_H ++#define _DROPPRIV_H ++ ++#include <sys/capability.h> ++ ++/** ++ * Drop all but necessary privileges from a program that is started as ++ * root. Set the running user id and group id to the corresponding ++ * values of 'user' and 'group' (NULL values cause the current ++ * user/group not to change). Drops all capabilities but the ++ * ones specified in caps. numcaps is the number of entries in ++ * caps. On error, a message is printed to stderr and the program ++ * terminates with exit code 'errorexit'. ++ */ ++void ++drop_privileges( const char* user, const char* group, int numcaps, ++ cap_value_t* caps, int errorexit ); ++ ++#endif ++