Re: unowned processes and who controls them (was: Re: passwd entry for uid -1
Quoth Niels Möller:
> I don't know. I would expect the code to create a socket and bind it
> to port 20 to be isolated to one or two functions, but I haven't read
> nor written any real ftp daemon.
That would be correct. But in the general ftp daemon, you _might_ also
need to be able to setuid() to some user (to provide logins), and to
chroot (which is not a privileged operation for the hurd anyway). If
you want to provide logins, you also need read access to /etc/shadow to
be able to verify peoples passwords.
> And they're not very flexible compared to using ports to represent
> capabilities: if you happen to need some new specialized capability
> (say, editing a certain record in the utmp file), it would be a lot
> easier to write a new server to implement the capability than to hack a
> new capability bit into the kernel.
Agreed, I think ;)
> I hadn't thought about glibc hack. Cute idea. It would make the common
> cases easier to use, while keeping the powerful port-based
> implementation for use when you need something special.
> For the "bind-port-X" capability example, you would take the following
> 1. Start the capability service, and get a port to it.
> 2. Set some environment variable to tell glibc to try the special
> port if the normal way of doing bind fails.
> 3. Drop the ports/uids etc that normal processes use for that
> 4. Start the *completely unmodified* daemon binary.
What do you mean with *completely unmodified* here? Do you mean that if
I would compile bsd-ftpd today, it would be able to use your capability
service out of the box in two years without changing any source or even
recompiling? (provided the library APIs and ABIs are stable, and that
somebody actually wrote that capability thing, of course).
The current implementation in bsd-ftpd, and I think most ftpds, is that
you run the daemon with full root access, fork() at logins, and when
somebody has successfully authenticated themselves, "their" server
process will seteuid() to the user, keeping 0 as the saved id. When the
server needs to open port 20, it will seteuid(0), do its stuff, and
change back to the user again. Capabilities handle this nicely, can
keep a clear effective set most of the time and have only the capability
for opening low ports in your permitted set, copying it to the effective
set when needed. (This is at least better than keeping "potential" root
I guess it is possible to make setxuid(), socket(), open(), and most
other functions in glibc understand and make use of this capability
service. This would at least work for dynamically linked libraries, but
I believe it would be a quite intrusive to libc, and I have not made my
mind up yet as to whether I really like it...
Nobody really reads these signatures anyway.