Subject: pppd/ip-up needs uid=0 not euid
To: None <current-users@NetBSD.ORG>
From: Simon J. Gerraty <sjg@zen.void.oz.au>
List: current-users
Date: 04/07/1995 14:57:19
The pppd man page describes ip-up and ip-down as being used to
manipulate routes etc.  Sadly this is not the case on NetBSD as things
stand - unless you want to have dialin ppp with a uid of 0.

/sbin/route for instance refuses to modify routing tables unless uid==0

Similarly I run a separate inetd process for a dialin ppp to provide
only the services _I_ want the remote end to see.  However, this
currently results in inetd running with ppp's uid not root. So when
telnet tries to run login -h "host" uid!=0 so login gets upset.

Solution?  After the fork() in run_program() try to setuid(0) if it
fails you are no worse off, and if it succeeds (euid was 0) then
ip-up/down can behave as advertised.   Routes get established,
sendmail's mailertable gets updated to deliver mail directly rather
than via a relay and inetd runs the limited services desired...

While at present it would appear that only ipcp_script() calls
run_program(), I thought it might be better to allow for other
callers. 

Hope others find it useful.

--- main.c.~1~  Sat Dec 24 22:51:57 1994
+++ main.c      Fri Apr  7 14:46:49 1995
@@ -1175,10 +1175,10 @@
  * must_exist is 0 and the program file doesn't exist.
  */
 int
-run_program(prog, args, must_exist)
+run_program(prog, args, flags)
     char *prog;
     char **args;
-    int must_exist;
+    int flags;
 {
     int pid;
 
@@ -1188,8 +1188,10 @@
        return -1;
     }
     if (pid == 0) {
+       if (flags & 2)
+               setuid(0);                      /* need uid=0 not just
euid */
        execv(prog, args);
-       if (must_exist || errno != ENOENT)
+       if ((flags & 1) || errno != ENOENT)
            syslog(LOG_WARNING, "can't execute %s: %m", prog);
        _exit(-1);
     }
--- ipcp.c.~1~  Thu Jul  7 18:43:04 1994
+++ ipcp.c      Fri Apr  7 14:44:17 1995
@@ -1088,7 +1088,7 @@
     argv[4] = strlocal;
     argv[5] = strremote;
     argv[6] = NULL;
-    run_program(script, argv, 0);
+    run_program(script, argv, 2);
 }
 
 /*