]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- Ari Edelkind's PARANOIA patch has been included and may be compiled in
authorDavid Hankins <dhankins@isc.org>
Wed, 27 Feb 2008 21:22:17 +0000 (21:22 +0000)
committerDavid Hankins <dhankins@isc.org>
Wed, 27 Feb 2008 21:22:17 +0000 (21:22 +0000)
  via two ./configure parameters, --enable-paranoia and
  --enable-early-chroot.  [ISC-Bugs #17611]

RELNOTES
configure.ac
server/dhcpd.c

index a6b2e896b67343dae77bd99b6d90cbb610e1c529..dd06e76ef54957f5c9f81fdae0e6084bd1cd2c5e 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -48,6 +48,12 @@ work on other platforms. Please report any problems and suggested fixes to
 <dhcp-users@isc.org>.
 
 
+                       Changes since 4.1.0a1
+
+- Ari Edelkind's PARANOIA patch has been included and may be compiled in
+  via two ./configure parameters, --enable-paranoia and
+  --enable-early-chroot.
+
                        Changes since 4.0.0 (new features)
 
 - Added DHCPv6 rapid commit support.
index 0f43814e24ecbc0df4014f960ddf6f6a998c65af..f09ad129d6ac25b1b82ea45635aae7b805a04b5d 100644 (file)
@@ -39,6 +39,29 @@ if test "$enable_dhcpv6" != "no"; then
                  [Define to 1 to include DHCPv6 support.])
 fi
 
+# PARANOIA is off by default (until we can test it with all features)
+AC_ARG_ENABLE(paranoia,
+       AC_HELP_STRING([--enable-paranoia],
+               [enable support for chroot/setuid (default is no)]))
+AC_ARG_ENABLE(early_chroot,
+       AC_HELP_STRING([--eanble-early-chroot],
+               [enable chrooting prior to configuration (default is no)]))
+# If someone enables early chroot, but does not enable paranoia, do so for
+# them.
+if test "$enable_paranoia" != "yes" && \
+   test "$enable_early_chroot" = "yes" ; then
+       enable_paranoia="yes"
+fi
+
+if test "$enable_paranoia" = "yes" ; then
+       AC_DEFINE([PARANOIA], [1],
+                 [Define to any value to include Ari's PARANOIA patch.])
+fi
+if test "$enable_early_chroot" = "yes" ; then
+       AC_DEFINE([EARLY_CHROOT], [1],
+                 [Define to any value to chroot() prior to loading config.])
+fi
+
 ###
 ### Path fun.  Older versions of DHCP were installed in /usr/sbin, so we
 ### need to look there and potentially overwrite by default (but not if
index 0b488d38df49388475696e2a0a01da6b97acfc04..c6084df319266f716305f1f6a9ba2f1de8fdb7a2 100644 (file)
@@ -47,6 +47,16 @@ static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/";
 #include <sys/time.h>
 #include <signal.h>
 
+#if defined (PARANOIA)
+#  include <sys/types.h>
+#  include <unistd.h>
+#  include <pwd.h>
+/* get around the ISC declaration of group */
+#  define group real_group 
+#    include <grp.h>
+#  undef group
+#endif /* PARANOIA */
+
 static void usage(void);
 
 struct iaddr server_identifier;
@@ -196,6 +206,22 @@ static void omapi_listener_start (void *foo)
        omapi_object_dereference (&listener, MDL);
 }
 
+#if defined (PARANOIA)
+/* to be used in one of two possible scenarios */
+static void setup_chroot (char *chroot_dir) {
+  if (geteuid())
+    log_fatal ("you must be root to use chroot");
+
+  if (chroot(chroot_dir)) {
+    log_fatal ("chroot(\"%s\"): %m", chroot_dir);
+  }
+  if (chdir ("/")) {
+    /* probably permission denied */
+    log_fatal ("chdir(\"/\"): %m");
+  }
+}
+#endif /* PARANOIA */
+
 #ifndef UNIT_TEST
 int 
 main(int argc, char **argv) {
@@ -228,6 +254,15 @@ main(int argc, char **argv) {
        char *traceoutfile = (char *)0;
 #endif
 
+#if defined (PARANOIA)
+       char *set_user   = 0;
+       char *set_group  = 0;
+       char *set_chroot = 0;
+
+       uid_t set_uid = 0;
+       gid_t set_gid = 0;
+#endif /* PARANOIA */
+
         /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
            2 (stderr) are open. To do this, we assume that when we
            open a file the lowest available file descriptor is used. */
@@ -287,6 +322,20 @@ main(int argc, char **argv) {
                        if (++i == argc)
                                usage ();
                        server = argv [i];
+#if defined (PARANOIA)
+               } else if (!strcmp (argv [i], "-user")) {
+                       if (++i == argc)
+                               usage ();
+                       set_user = argv [i];
+               } else if (!strcmp (argv [i], "-group")) {
+                       if (++i == argc)
+                               usage ();
+                       set_group = argv [i];
+               } else if (!strcmp (argv [i], "-chroot")) {
+                       if (++i == argc)
+                               usage ();
+                       set_chroot = argv [i];
+#endif /* PARANOIA */
                } else if (!strcmp (argv [i], "-cf")) {
                        if (++i == argc)
                                usage ();
@@ -440,6 +489,44 @@ main(int argc, char **argv) {
                                             trace_seed_stop, MDL);
 #endif
 
+#if defined (PARANOIA)
+       /* get user and group info if those options were given */
+       if (set_user) {
+               struct passwd *tmp_pwd;
+
+               if (geteuid())
+                       log_fatal ("you must be root to set user");
+
+               if (!(tmp_pwd = getpwnam(set_user)))
+                       log_fatal ("no such user: %s", set_user);
+
+               set_uid = tmp_pwd->pw_uid;
+
+               /* use the user's group as the default gid */
+               if (!set_group)
+                       set_gid = tmp_pwd->pw_gid;
+       }
+
+       if (set_group) {
+/* get around the ISC declaration of group */
+#define group real_group
+               struct group *tmp_grp;
+
+               if (geteuid())
+                       log_fatal ("you must be root to set group");
+
+               if (!(tmp_grp = getgrnam(set_group)))
+                       log_fatal ("no such group: %s", set_group);
+
+               set_gid = tmp_grp->gr_gid;
+#undef group
+       }
+
+#  if defined (EARLY_CHROOT)
+       if (set_chroot) setup_chroot (set_chroot);
+#  endif /* EARLY_CHROOT */
+#endif /* PARANOIA */
+
        /* Default to the DHCP/BOOTP port. */
        if (!local_port)
        {
@@ -583,6 +670,10 @@ main(int argc, char **argv) {
                log_fatal ("Configuration file errors encountered -- exiting");
 
        postconf_initialization (quiet);
+#if defined (PARANOIA) && !defined (EARLY_CHROOT)
+       if (set_chroot) setup_chroot (set_chroot);
+#endif /* PARANOIA && !EARLY_CHROOT */
 
         /* test option should cause an early exit */
        if (cftest && !lftest) 
@@ -661,6 +752,22 @@ main(int argc, char **argv) {
                else if (pid)
                        exit (0);
        }
+#if defined (PARANOIA)
+       /* change uid to the specified one */
+
+       if (set_gid) {
+               if (setgroups (0, (void *)0))
+                       log_fatal ("setgroups: %m");
+               if (setgid (set_gid))
+                       log_fatal ("setgid(%d): %m", (int) set_gid);
+       }       
+
+       if (set_uid) {
+               if (setuid (set_uid))
+                       log_fatal ("setuid(%d): %m", (int) set_uid);
+       }
+#endif /* PARANOIA */
 
        /* Read previous pid file. */
        if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) {
@@ -1056,6 +1163,10 @@ usage(void) {
 #else /* !DHCPv6 */
                  "             [-cf config-file] [-lf lease-file]\n"
 #endif /* DHCPv6 */
+#if defined (PARANOIA)
+                  /* meld into the following string */
+                 "             [-user user] [-group group] [-chroot dir]\n"
+#endif /* PARANOIA */
 #if defined (TRACING)
                  "             [-tf trace-output-file]\n"
                  "             [-play trace-input-file]\n"