Status of innbind and Solaris

Russ Allbery rra at stanford.edu
Wed May 19 06:49:19 UTC 2004


I didn't quite get this finished tonight, but I'm close.  A bit more work
on it tomorrow should finish it off.

The problem, as those who have tried to run CURRENT on Solaris know, is
that the neat hack of creating a socket and then running a setuid root
helper program to bind the socket only works on operating systems that
actually implement native Berkeley sockets.  On streams-based systems like
Solaris, somehow the privileges of the creator of the socket attach to it,
rather than the privileges of the person running bind, and the sub-process
can't bind even though it has an effective UID of root.

This means there's no choice but the old-style inndstart wrapper on those
operating systems.

This is a lot more complex, though, and I really don't want to resurrect
inndstart.  I also want something relatively generic that can also be used
for nnrpd.  Thankfully, only long-running daemons have to bind in this
fashion, which means it doesn't have to be blazingly fast.

The plan is therefore to keep innbind as-is for those operating systems
that support it.  Linux, *BSD, and the like will continue to get the nice,
new semantics.  The only change is that innbind will have two other modes:

    innbind -t 119
    innbind -e 0,2,0.0.0.0,119 -- /news/bin/innd

The first will try using innbind the way that it's meant to be used to
bind something to port 119.  If this works, innd will proceed as normal.
It will just always run this during startup to check to see if it has to
do something complicated.

The second is something complicated.  Run with -e, innbind will walk
through its arguments as before but will also do the socket creation as
well as the bind.  It will stop when it gets to -- and then take
everything after that as a command to run.  It will add -p <fdss> to the
beginning of the argument list (where <fdss> is a comma-separated list of
open, bound file descriptors) and then exec the command it was given.

So innd will first see if its port is >= 1024 or if it's already running
as root, and if so, will just continue as normal.  Otherwise, it will run
innbind -t on its port.  If that succeeds, it will continue as normal.

If that fails, it will build a list of all of the addresses it wants to
listen to, and then exec innbind -e in the above manner, passing it innd's
original argument list.  Then, the second time around, it will see the -p
option, skip all of the network setup, and just use those file descriptors
as is.

The flow of this in the Solaris case is more complex than the original
inndstart solution, but everything is much simpler for Linux.  For
Solaris, it's still significantly nicer than what we had before, because
inndstart isn't necessary, you don't have to remember to run it instead of
innd, and we don't need the code for it in places like ctlinnd xexec.

innd will be far easier to debug on Linux, where the tricks of before
won't be necessary.  On Solaris, you'll still have to replace innd with a
wrapper or the like to get good debugging information, or start it
manually with innbind.

Comments?

-- 
Russ Allbery (rra at stanford.edu)             <http://www.eyrie.org/~eagle/>


More information about the inn-workers mailing list