It's not *that* expensive to have a dedicated user for this, so we
don't need to think about if it's a problem to share with ping(8) or
not. And we might be able to get rid of it again in the future.

Pointed out by deraadt@

OK?

diff --git etc/group etc/group
index 7c050ef..e823310 100644
--- etc/group
+++ etc/group
@@ -21,6 +21,7 @@ _fingerd:*:33:
 _sshagnt:*:34:
 _x11:*:35:
 utmp:*:45:
+_traceroute:*:50:
 _ping:*:51:
 _rebound:*:52:
 _unbound:*:53:
diff --git etc/mail/aliases etc/mail/aliases
index ea13fc4..759ee28 100644
--- etc/mail/aliases
+++ etc/mail/aliases
@@ -65,6 +65,7 @@ _snmpd: /dev/null
 _spamd: /dev/null
 _syslogd: /dev/null
 _tcpdump: /dev/null
+_traceroute: /dev/null
 _tftpd: /dev/null
 _unbound: /dev/null
 _vmd: /dev/null
diff --git etc/master.passwd etc/master.passwd
index 80be75a..82aa4e9 100644
--- etc/master.passwd
+++ etc/master.passwd
@@ -9,6 +9,7 @@ _rstatd:*:30:30::0:0:rpc.rstatd:/var/empty:/sbin/nologin
 _rusersd:*:32:32::0:0:rpc.rusersd:/var/empty:/sbin/nologin
 _fingerd:*:33:33::0:0:fingerd:/var/empty:/sbin/nologin
 _x11:*:35:35::0:0:X Server:/var/empty:/sbin/nologin
+_traceroute:*:50:50::0:0:traceroute privdrop user:/var/empty:/sbin/nologin
 _ping:*:51:51::0:0:ping privdrop user:/var/empty:/sbin/nologin
 _rebound:*:52:52::0:0:Rebound DNS Daemon:/var/empty:/sbin/nologin
 _unbound:*:53:53:unbound:0:0:Unbound Daemon:/var/unbound:/sbin/nologin
diff --git usr.sbin/traceroute/traceroute.c usr.sbin/traceroute/traceroute.c
index 5c53f53..9331f04 100644
--- usr.sbin/traceroute/traceroute.c
+++ usr.sbin/traceroute/traceroute.c
@@ -246,6 +246,7 @@
 #include <netinet/ip6.h>
 #include <netinet/ip_icmp.h>
 #include <netinet/udp.h>
+#include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -303,6 +304,8 @@ int         last_tos;
 
 void   usage(void);
 
+#define        TRACEROUTE_USER "_traceroute"
+
 int
 main(int argc, char *argv[])
 {
@@ -312,6 +315,7 @@ main(int argc, char *argv[])
        int rcvcmsglen, rcvsock4, rcvsock6, sndsock4, sndsock6;
        int v4sock_errno, v6sock_errno;
        struct addrinfo hints, *res;
+       struct passwd *pw;
        size_t size;
        static u_char *rcvcmsgbuf;
        struct sockaddr_in from4, to4;
@@ -343,8 +347,12 @@ main(int argc, char *argv[])
 
        /* revoke privs */
        uid = getuid();
-       if (setresuid(uid, uid, uid) == -1)
-               err(1, "setresuid");
+       if ((pw = getpwnam(TRACEROUTE_USER)) == NULL)
+               errx(1, "no %s user", TRACEROUTE_USER);
+       if (setgroups(1, &pw->pw_gid) ||
+           setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
+           setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
+               err(1, "unable to revoke privs");
 
        if (strcmp("traceroute6", __progname) == 0) {
                v6flag = 1;
@@ -662,13 +670,13 @@ main(int argc, char *argv[])
                        if (inet_aton(source, &from4.sin_addr) == 0)
                                errx(1, "unknown host %s", source);
                        ip->ip_src = from4.sin_addr;
-                       if (getuid() != 0 &&
+                       if (uid != 0 &&
                            (ntohl(from4.sin_addr.s_addr) & 0xff000000U) ==
                            0x7f000000U && (ntohl(to4.sin_addr.s_addr) &
                            0xff000000U) != 0x7f000000U)
                                errx(1, "source is on 127/8, destination is"
                                    " not");
-                       if (getuid() && bind(sndsock, (struct sockaddr *)&from4,
+                       if (uid && bind(sndsock, (struct sockaddr *)&from4,
                            sizeof(from4)) < 0)
                                err(1, "bind");
                }


-- 
I'm not entirely sure you are real.

Reply via email to