traceroute(8): drop to _ping user

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

traceroute(8): drop to _ping user

Florian Obser-2
like ping(8)...

OK?

diff --git traceroute.c traceroute.c
index 5c53f53..b1fde9d 100644
--- traceroute.c
+++ 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 "_ping"
+
 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 | Threaded
Open this post in threaded view
|

traceroute(8): drop to _traceroute user

Florian Obser-2
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 | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Sebastian Benoit-3
Florian Obser([hidden email]) on 2016.09.26 20:00:34 +0000:
> 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?

yes, 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 | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Theo de Raadt-2
In reply to this post by Florian Obser-2
> 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.

I am worried about the trend of creating shared users.

And also, less worried about independent users, since we may be
solving that in the next year.

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Stuart Henderson
In reply to this post by Florian Obser-2
I just discovered an implication of the ping/traceroute changes:
bgplg users now need pwd.db in /var/www/etc.

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Florian Obser-2
On Tue, Sep 27, 2016 at 11:32:00AM +0100, Stuart Henderson wrote:
> I just discovered an implication of the ping/traceroute changes:
> bgplg users now need pwd.db in /var/www/etc.
>

Ooops. I guess this is a documentation problem?

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

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Peter Hessler
On 2016 Sep 27 (Tue) at 11:12:40 +0000 (+0000), Florian Obser wrote:
:On Tue, Sep 27, 2016 at 11:32:00AM +0100, Stuart Henderson wrote:
:> I just discovered an implication of the ping/traceroute changes:
:> bgplg users now need pwd.db in /var/www/etc.
:>
:
:Ooops. I guess this is a documentation problem?
:

We already require a user to copy over /etc/resolv.conf, so copying over
the insecure db should be fine.  Add it to the man page, and maybe
current.html/upgrade guides.


--
As long as war is regarded as wicked, it will always have its
fascination.  When it is looked upon as vulgar, it will cease to be
popular.
                -- Oscar Wilde

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Stuart Henderson
In reply to this post by Florian Obser-2
On 2016/09/27 11:12, Florian Obser wrote:
> On Tue, Sep 27, 2016 at 11:32:00AM +0100, Stuart Henderson wrote:
> > I just discovered an implication of the ping/traceroute changes:
> > bgplg users now need pwd.db in /var/www/etc.
> >
>
> Ooops. I guess this is a documentation problem?

I think so ... this is one way to do it:

# grep -e ^_ping -e ^_traceroute /etc/master.passwd > /var/www/etc/master.passwd.bgplg
# pwd_mkdb -d /var/www/etc master.passwd.bgplg

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Stuart Henderson
On 2016/09/27 12:23, Stuart Henderson wrote:

> On 2016/09/27 11:12, Florian Obser wrote:
> > On Tue, Sep 27, 2016 at 11:32:00AM +0100, Stuart Henderson wrote:
> > > I just discovered an implication of the ping/traceroute changes:
> > > bgplg users now need pwd.db in /var/www/etc.
> > >
> >
> > Ooops. I guess this is a documentation problem?
>
> I think so ... this is one way to do it:
>
> # grep -e ^_ping -e ^_traceroute /etc/master.passwd > /var/www/etc/master.passwd.bgplg
> # pwd_mkdb -d /var/www/etc master.passwd.bgplg
>

An alternative might be to allow the privdrop to fail as long as
the calling user isn't root.

Index: usr.sbin/traceroute/traceroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/traceroute/traceroute.c,v
retrieving revision 1.148
diff -u -p -r1.148 traceroute.c
--- usr.sbin/traceroute/traceroute.c 27 Sep 2016 05:33:46 -0000 1.148
+++ usr.sbin/traceroute/traceroute.c 27 Sep 2016 12:03:19 -0000
@@ -347,9 +347,10 @@ main(int argc, char *argv[])
 
  /* revoke privs */
  uid = getuid();
- if ((pw = getpwnam(TRACEROUTE_USER)) == NULL)
- errx(1, "no %s user", TRACEROUTE_USER);
- if (setgroups(1, &pw->pw_gid) ||
+ if ((pw = getpwnam(TRACEROUTE_USER)) == NULL) {
+ if (uid == 0)
+ errx(1, "no %s user", TRACEROUTE_USER);
+ } else 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");
Index: sbin/ping/ping.c
===================================================================
RCS file: /cvs/src/sbin/ping/ping.c,v
retrieving revision 1.215
diff -u -p -r1.215 ping.c
--- sbin/ping/ping.c 26 Sep 2016 16:42:46 -0000 1.215
+++ sbin/ping/ping.c 27 Sep 2016 12:03:19 -0000
@@ -275,9 +275,10 @@ 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) ||
+ if ((pw = getpwnam(PING_USER)) == NULL) {
+ if (uid == 0)
+ errx(1, "no %s user", PING_USER);
+ } else 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");

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Sebastien Marie-3
On Tue, Sep 27, 2016 at 01:03:55PM +0100, Stuart Henderson wrote:

> On 2016/09/27 12:23, Stuart Henderson wrote:
> > On 2016/09/27 11:12, Florian Obser wrote:
> > > On Tue, Sep 27, 2016 at 11:32:00AM +0100, Stuart Henderson wrote:
> > > > I just discovered an implication of the ping/traceroute changes:
> > > > bgplg users now need pwd.db in /var/www/etc.
> > > >
> > >
> > > Ooops. I guess this is a documentation problem?
> >
> > I think so ... this is one way to do it:
> >
> > # grep -e ^_ping -e ^_traceroute /etc/master.passwd > /var/www/etc/master.passwd.bgplg
> > # pwd_mkdb -d /var/www/etc master.passwd.bgplg
> >
>
> An alternative might be to allow the privdrop to fail as long as
> the calling user isn't root.

Maybe I will say something stupid, but ping(1) or traceroute(1) are suid
root:

$ ls -l /usr/sbin/traceroute /sbin/ping
-r-sr-xr-x  2 root  bin  219408 Sep 23 03:04 /sbin/ping*
-r-sr-xr-x  2 root  bin   34616 Sep 23 03:04 /usr/sbin/traceroute*

So not calling privdrop (setgroups+setresgid+setresuid) when real uid
isn't root will still make the program run with effective uid as root,
isn't it ?

I think we always want to drop effective uid once SOCK_RAW socket has
been opened.

Thanks.
--
Sebastien Marie

> Index: usr.sbin/traceroute/traceroute.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/traceroute/traceroute.c,v
> retrieving revision 1.148
> diff -u -p -r1.148 traceroute.c
> --- usr.sbin/traceroute/traceroute.c 27 Sep 2016 05:33:46 -0000 1.148
> +++ usr.sbin/traceroute/traceroute.c 27 Sep 2016 12:03:19 -0000
> @@ -347,9 +347,10 @@ main(int argc, char *argv[])
>  
>   /* revoke privs */
>   uid = getuid();
> - if ((pw = getpwnam(TRACEROUTE_USER)) == NULL)
> - errx(1, "no %s user", TRACEROUTE_USER);
> - if (setgroups(1, &pw->pw_gid) ||
> + if ((pw = getpwnam(TRACEROUTE_USER)) == NULL) {
> + if (uid == 0)
> + errx(1, "no %s user", TRACEROUTE_USER);
> + } else 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");
> Index: sbin/ping/ping.c
> ===================================================================
> RCS file: /cvs/src/sbin/ping/ping.c,v
> retrieving revision 1.215
> diff -u -p -r1.215 ping.c
> --- sbin/ping/ping.c 26 Sep 2016 16:42:46 -0000 1.215
> +++ sbin/ping/ping.c 27 Sep 2016 12:03:19 -0000
> @@ -275,9 +275,10 @@ 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) ||
> + if ((pw = getpwnam(PING_USER)) == NULL) {
> + if (uid == 0)
> + errx(1, "no %s user", PING_USER);
> + } else 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");
>

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Florian Obser-2
On Tue, Sep 27, 2016 at 02:48:54PM +0200, Sebastien Marie wrote:
> I think we always want to drop effective uid once SOCK_RAW socket has
> been opened.

yes, I think this is better:

diff --git sbin/ping/ping.c sbin/ping/ping.c
index 383ef65..aa4c025 100644
--- sbin/ping/ping.c
+++ sbin/ping/ping.c
@@ -275,9 +275,11 @@ 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) ||
+ if ((pw = getpwnam(PING_USER)) == NULL) {
+ warnx(1, "no %s user", PING_USER);
+ if (setresuid(uid, uid, uid) == -1)
+ err(1, "setresuid");
+ } else 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");
diff --git usr.sbin/traceroute/traceroute.c usr.sbin/traceroute/traceroute.c
index ba04494..a32985a 100644
--- usr.sbin/traceroute/traceroute.c
+++ usr.sbin/traceroute/traceroute.c
@@ -347,9 +347,11 @@ main(int argc, char *argv[])
 
  /* revoke privs */
  uid = getuid();
- if ((pw = getpwnam(TRACEROUTE_USER)) == NULL)
- errx(1, "no %s user", TRACEROUTE_USER);
- if (setgroups(1, &pw->pw_gid) ||
+ if ((pw = getpwnam(TRACEROUTE_USER)) == NULL) {
+ warnx(1, "no %s user", TRACEROUTE_USER);
+ if (setresuid(uid, uid, uid) == -1)
+ err(1, "setresuid");
+ } else 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");
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,

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

Reply | Threaded
Open this post in threaded view
|

Re: traceroute(8): drop to _traceroute user

Florian Obser-2
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.