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);