tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: inetd(8): continue or exit on error?

Le Fri, Jun 02, 2023 at 07:01:40AM +0000, David Holland a écrit :
> On Mon, May 29, 2023 at 10:11:09AM +0200, wrote:
>  > There are infelicities in /usr/src/usr.sbin/inetd/parse.c and I will
>  > send a PR with patches attached.
>  > 
>  > The question is what to do in case of a config file not found (this is
>  > the initial problem: the realpath() return status is not tested and a
>  > structure is inconditionnally added to a linked list with an unreachable
>  > config file).
>  > 
>  > It seems to me, since these are services, that the failure to load a
>  > config is critical enough (since the server may be then servicing what
>  > was not intended to be serviced; the reverse is less problematic)
>  > to exit at least on this error.
>  > 
>  > What do others think?
> I have not read most of the traffic yet, but I feel, fairly strongly,
> that inetd should _not_ exit, except (maybe) if the config is broken
> during its initial startup. It's a critical service.

So I will put together the result of the exchanges in the thread and of
my reading of the source:

Not stopping on an error was logical with the old syntax since _all the
directives were independent_: failing to read a line for a service
shouldn't have the side effect of failing to serve the other services.

But this assumption does not anymore with the new syntax: the feature of
the implicit address---one does not need to specify an address: it will
then be what is the default at the moment---makes the config a whole,
and failing on a line may define the default address with something
completely different from what was intended: what will be the result of
runnin login on the external interface instead of an internal one?

=> a failure in the config now must discard the whole config.

Hence to address this and the need for essential services the following
will be done (in the process in fact):

Two modes:

Server mode: inetd [-rl] [-f [-d]] [rooted_config]

Checker mode: inetd -c [-d] [rooted_config]

inetd always checks the config it is asked to serve first and does not
serve anything before validating the config. If default mode, a failure
to check the config causes an exit of the daemon.

Disentangling the parsing from the executing/serving, there is a check
mode that just parses the config and returns EXIT_SUCCESS if the config
is OK, EXIT_FAILURE if not (unfortunately, there is no EXIT_RTFM to
indicate that the call was nonsense...).

Checker mode:

So inetd just exits with the status in check mode. In check mode, if -d
is given, debug message about the parsing (and the errors) are sent to
stderr and, if successful, the parsed config in new syntax is sent to
stdout. Nothing is printed if [-d] is not given.

Server mode:

Inetd always checks the config and if the convid is invalid it exits
with error (default mode).

If the [-r] mode is asked for (r for "resilient"), in case of failure to
validate the config, inetd falls back to "/etc/inetd.fallback.conf" that
is also parses and, if checking successful, served. If even this
fallback fails, inetd(8) does not exit but serves the "no-op" config: it
does nothing simply waiting for the instruction to reload the config
("the config" is always the one passed, explicitely or implicitely, on
the call).

Still in resilient mode, if the server is instructed to reload the
config, it does not stop serving the old but first checks the new. If
the new is valid, it switches to these new instructions. If the new is
not valid, it continues to serve the current served one.

In daemon mode but in foreground mode, messages are logged via syslog.

When in foreground, messages go to stderr.

A new control is added:

Sending USR1 signal instruct inetd to switch to the fallback config (it
is not "sticky": when instructed to reload via HUP, it will reload "the
config" not the fallback one).


I was unhappy about:

-d run in foreground and add debug messages
-f run in foreground

that seems to me not very Unix like.

Hence the [-f [-d]] but for compatibility in the switch it is a
fallthrough: case d will fallthrough f so the behavior will be the same.

-c takes also -d; no problem since -cfd will invoke the checker, not the
daemon: "inetd is human and always grasps to the first opportunity to do
less work".
        Thierry Laronde <tlaronde +AT+ polynum +dot+ com>
Key fingerprint = 0FF7 E906 FBAF FE95 FD89  250D 52B1 AE95 6006 F40C

Home | Main Index | Thread Index | Old Index