this always does the 3 part setgroups, setresgid, setresuid dance...
diff --git sbin/ping/ping.c sbin/ping/ping.c
index 383ef65..6ea138c 100644
--- sbin/ping/ping.c
+++ sbin/ping/ping.c
@@ -259,7 +259,8 @@ main(int argc, char *argv[])
char rspace[3 + 4 * NROUTES + 1]; /* record route space */
const char *errstr;
double intval;
- uid_t uid;
+ uid_t ouid, uid;
+ gid_t gid;
u_int rtableid = 0;
extern char *__progname;
@@ -274,12 +275,17 @@ main(int argc, char *argv[])
}
/* revoke privs */
- uid = getuid();
- if ((pw = getpwnam(PING_USER)) == NULL)
- errx(1, "no %s user", PING_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))
+ ouid = getuid();
+ if ((pw = getpwnam(PING_USER)) != NULL) {
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ } else {
+ uid = getuid();
+ gid = getgid();
+ }
+ if (setgroups(1, &gid) ||
+ setresgid(gid, gid, gid) ||
+ setresuid(uid, uid, uid))
err(1, "unable to revoke privs");
preload = 0;
@@ -309,7 +315,7 @@ main(int argc, char *argv[])
options |= F_AUD_RECV;
break;
case 'f':
- if (uid)
+ if (ouid)
errc(1, EPERM, NULL);
options |= F_FLOOD;
setvbuf(stdout, NULL, _IONBF, 0);
@@ -330,7 +336,7 @@ main(int argc, char *argv[])
intval = strtod(optarg, &e);
if (*optarg == '\0' || *e != '\0')
errx(1, "illegal timing interval %s", optarg);
- if (intval < 1 && uid)
+ if (intval < 1 && ouid)
errx(1, "only root may use interval < 1s");
interval.tv_sec = (time_t)intval;
interval.tv_usec =
@@ -349,7 +355,7 @@ main(int argc, char *argv[])
loop = 0;
break;
case 'l':
- if (uid)
+ if (ouid)
errc(1, EPERM, NULL);
preload = strtonum(optarg, 1, INT64_MAX, &errstr);
if (errstr)
diff --git usr.bin/bgplg/bgplg.8 usr.bin/bgplg/bgplg.8
index d2f0f0d..15e15b2 100644
--- usr.bin/bgplg/bgplg.8
+++ usr.bin/bgplg/bgplg.8
@@ -77,12 +77,19 @@ and
.Xr traceroute6 8
will require a copy of the resolver configuration file
.Xr resolv.conf 5
+for optional host name lookups and the password database with the users
+.Qq _ping
+and
+.Qq _traceroute
in the
.Xr chroot 2
-environment for optional host name lookups.
+environment.
.Bd -literal -offset indent
# mkdir /var/www/etc
# cp /etc/resolv.conf /var/www/etc
+# grep -e ^_ping -e ^_traceroute /etc/master.passwd > \\
+ /var/www/etc/master.passwd.bgplg
+# pwd_mkdb -d /var/www/etc master.passwd.bgplg
.Ed
.It
Start the Border Gateway Protocol daemon with a second,
diff --git usr.sbin/traceroute/traceroute.c usr.sbin/traceroute/traceroute.c
index ba04494..f0ed493 100644
--- usr.sbin/traceroute/traceroute.c
+++ usr.sbin/traceroute/traceroute.c
@@ -328,7 +328,8 @@ main(int argc, char *argv[])
char *ep, hbuf[NI_MAXHOST], *dest, *source = NULL;
const char *errstr;
long l;
- uid_t uid;
+ uid_t ouid, uid;
+ gid_t gid;
u_int rtableid;
socklen_t len;
@@ -346,12 +347,17 @@ main(int argc, char *argv[])
v4sock_errno = errno;
/* revoke privs */
- uid = getuid();
- 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))
+ ouid = getuid();
+ if ((pw = getpwnam(TRACEROUTE_USER)) != NULL) {
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ } else {
+ uid = getuid();
+ gid = getgid();
+ }
+ if (setgroups(1, &gid) ||
+ setresgid(gid, gid, gid) ||
+ setresuid(uid, uid, uid))
err(1, "unable to revoke privs");
if (strcmp("traceroute6", __progname) == 0) {
@@ -670,13 +676,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 (uid != 0 &&
+ if (ouid != 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 (uid && bind(sndsock, (struct sockaddr *)&from4,
+ if (ouid && bind(sndsock, (struct sockaddr *)&from4,
sizeof(from4)) < 0)
err(1, "bind");
}
--
I'm not entirely sure you are real.