--- mtr-0.72/mtr.c.orig 2006-09-29 23:38:49 +0400 +++ mtr-0.72/mtr.c 2006-12-11 02:31:36 +0300 @@ -27,6 +27,10 @@ #include #include #include +#include +#include +#include +#include #include "mtr.h" #include "mtr-curses.h" @@ -114,6 +118,46 @@ available_options[i] = 0; } +static void +drop_priv(void) +{ + uid_t ruid = getuid(); + + if (ruid && geteuid()) + return; + + if (setgroups(0, NULL) < 0) + error(EXIT_FAILURE, errno, "setgroups"); + + if (ruid) + { + if (setgid(getgid()) < 0 || setuid(ruid) < 0) + error(EXIT_FAILURE, errno, "setgid/setuid failed"); + } else + { + const char *user = "mtruser"; + struct passwd *pw = getpwnam(user); + uid_t uid; + gid_t gid; + + if (!pw) + error(EXIT_FAILURE, 0, + "lookup of user \"%s\" failed", user); + uid = pw->pw_uid; + gid = pw->pw_gid; + endpwent(); + + if (!uid) + error(EXIT_FAILURE, 0, + "user \"%s\" should not be root", user); + + if (setgid(gid) < 0 || setuid(uid) < 0) + error(EXIT_FAILURE, errno, "setgid/setuid failed"); + } + + if (chdir("/") < 0) + error(EXIT_FAILURE, errno, "chdir"); +} void parse_arg (int argc, char **argv) { @@ -330,16 +374,7 @@ } /* Now drop to user permissions */ - if (setuid(getuid())) { - fprintf (stderr, "mtr: Unable to drop permissions.\n"); - exit(1); - } - - /* Double check, just in case */ - if (geteuid() != getuid()) { - fprintf (stderr, "mtr: Unable to drop permissions.\n"); - exit(1); - } + drop_priv(); /* reset the random seed */ srand (getpid());