diff -crN ircd-hybrid-7.3/src/fdlist.c ircd-hybrid-7.3-modified/src/fdlist.c
*** ircd-hybrid-7.3/src/fdlist.c	Tue Feb  2 17:23:10 2010
--- ircd-hybrid-7.3-modified/src/fdlist.c	Thu Feb 11 00:59:16 2010
***************
*** 224,231 ****
    for (i = 0; i < LOWEST_SAFE_FD; i++)
    {
      close(i);
!     if (open(PATH_DEVNULL, O_RDWR) < 0)
!       exit(-1); /* we're hosed if we can't even open /dev/null */
    }
  }
  
--- 224,231 ----
    for (i = 0; i < LOWEST_SAFE_FD; i++)
    {
      close(i);
!     /* if (open(PATH_DEVNULL, O_RDWR) < 0) */
!     /*   exit(-1); *//* we're hosed if we can't even open /dev/null */
    }
  }
  
diff -crN ircd-hybrid-7.3/src/irc_res.c ircd-hybrid-7.3-modified/src/irc_res.c
*** ircd-hybrid-7.3/src/irc_res.c	Tue Feb  2 17:23:10 2010
--- ircd-hybrid-7.3-modified/src/irc_res.c	Thu Feb 11 00:59:45 2010
***************
*** 231,237 ****
  static void
  start_resolver(void)
  {
!   irc_res_init();
  
    if (!ResolverFileDescriptor.flags.open)
    {
--- 231,237 ----
  static void
  start_resolver(void)
  {
!   /* irc_res_init(); */
  
    if (!ResolverFileDescriptor.flags.open)
    {
diff -crN ircd-hybrid-7.3/src/ircd.c ircd-hybrid-7.3-modified/src/ircd.c
*** ircd-hybrid-7.3/src/ircd.c	Tue Feb  2 17:23:10 2010
--- ircd-hybrid-7.3-modified/src/ircd.c	Thu Feb 11 00:57:37 2010
***************
*** 63,68 ****
--- 63,69 ----
  #include "motd.h"
  #include "supported.h"
  #include "watch.h"
+ #include "irc_reslib.h"
  
  /* Try and find the correct name to use with getrlimit() for setting the max.
   * number of files allowed to be open by this process.
***************
*** 94,99 ****
--- 95,105 ----
  int dorehash = 0;
  int doremotd = 0;
  
+ char *newroot = NULL; /* The root directory to set. */
+ 
+ int newgid = -1; /* The real and effective gid to set if root. */
+ int newuid = -1; /* The real and effective uid to set if root. */
+ 
  /* Set to zero because it should be initialized later using
   * initialize_server_capabs
   */
***************
*** 171,176 ****
--- 177,188 ----
     YESNO, "Run in foreground (don't detach)"},
    {"version",    &printVersion, 
     YESNO, "Print version and exit"},
+   {"chroot",     &newroot,
+    STRING, "Change root directory"},
+   {"gid",        &newgid,
+    INTEGER, "Change the real and effective group ID"},
+   {"uid",        &newuid,
+    INTEGER, "Change the real and effective user ID"},
    {"help", NULL, USAGE, "Print this text"},
    {NULL, NULL, STRING, NULL},
  };
***************
*** 486,503 ****
  int
  main(int argc, char *argv[])
  {
-   /* Check to see if the user is running
-    * us as root, which is a nono
-    */
-   if (geteuid() == 0)
-   {
-     fprintf(stderr, "Don't run ircd as root!!!\n");
-     return -1;
-   }
- 
-   /* Setup corefile size immediately after boot -kre */
-   setup_corefile();
- 
    /* save server boot time right away, so getrusage works correctly */
    set_time();
  
--- 498,503 ----
***************
*** 531,536 ****
--- 531,648 ----
  
    parseargs(&argc, &argv, myopts);
  
+   /* Initialize the DNS resolver library here because it will require
+    * read access to /etc/resolv.conf and that will not be available if
+    * a chroot is requested.
+    */
+   irc_res_init();
+ 
+   if (newroot != NULL)
+   {
+     /* The chdir() system call causes the named directory to become the current
+      * working directory, that is, the starting point for path searches of
+      * pathnames not beginning with a slash, `/'.
+      *
+      * In order for a directory to become the current directory, a process must
+      * have execute (search) access to the directory.
+      */
+     if (chdir(newroot) != 0)
+     {
+       perror("chdir()");
+       exit(EXIT_FAILURE);
+     }
+ 
+     /* The chroot() system call causes dirname to become the root directory,
+      * that is, the starting point for path searches of pathnames beginning
+      * with `/'.
+      *
+      * In order for a directory to become the root directory a process must
+      * have execute (search) access for that directory.
+      *
+      * It should be noted that chroot() has no effect on the process's current
+      * directory.
+      *
+      * This call is restricted to the super-user.
+      */
+     if (chroot(newroot) != 0)
+     {
+       perror("chroot()");
+       exit(EXIT_FAILURE);
+     }
+ 
+     printf("ircd: root directory now %s\n", newroot);
+   }
+ 
+   /* The seteuid() system call (setegid()) sets the effective user ID (group
+    * ID) of the current process.  The effective user ID may be set to the
+    * value of the real user ID or the saved set-user-ID (see intro(2) and
+    * execve(2)); in this way, the effective user ID of a set-user-ID exe-
+    * cutable may be toggled by switching to the real user ID, then re-enabled
+    * by reverting to the set-user-ID value.  Similarly, the effective group ID
+    * may be set to the value of the real group ID or the saved set-group-ID.
+    */
+   if (getuid() == 0 && geteuid() != 0)
+   {
+     if (seteuid(0) != 0)
+     {
+       perror("seteuid()");
+       exit(EXIT_FAILURE);
+     }
+   }
+ 
+   /* The setgid() system call sets the real and effective group IDs and the
+    * saved set-group-ID of the current process to the specified value.  The
+    * setgid() system call is permitted if the specified ID is equal to the
+    * real group ID or the effective group ID of the process, or if the effec-
+    * tive user ID is that of the super user.
+    */
+   if (newgid != -1 && (setgid(newgid) != 0))
+   {
+     perror("setgid()");
+     exit(EXIT_FAILURE);
+   }
+   else
+   {
+     assert(getgid() == newgid);
+     assert(getegid() == newgid);
+ 
+     printf("ircd: real and effective group ID now %u\n", newgid);
+   }
+ 
+   /* The setuid() system call sets the real and effective user IDs and the
+    * saved set-user-ID of the current process to the specified value.  The
+    * setuid() system call is permitted if the specified ID is equal to the
+    * real user ID or the effective user ID of the process, or if the effective
+    * user ID is that of the super user.
+    */
+   if (newuid != -1 && (setuid(newuid) != 0))
+   {
+     perror("setuid()");
+     exit(EXIT_FAILURE);
+   }
+   else
+   {
+     assert(getuid() == newuid);
+     assert(geteuid() == newuid);
+ 
+     printf("ircd: real and effective user ID now %u\n", newuid);
+   }
+ 
+   /* Check to see if the user is running
+    * us as root, which is a nono
+    */
+   if (geteuid() == 0)
+   {
+     fprintf(stderr, "Don't run ircd as root!!!\n");
+     return -1;
+   }
+ 
+   /* Setup corefile size immediately after boot -kre
+    * Move this down so the core file size is proper relative to the
+    * uid/gid set. -pm
+    */
+   setup_corefile();
+ 
    if (printVersion)
    {
      printf("ircd: version %s\n", ircd_version);
