nsss
Software
skarnet.org
The nsssd-switch program
nsssd-switch is a daemon providing a backend for clients using the
nsss library - more precisely, clients using
the nsss-all or
the nsss-switch functions.
The nsssd-switch backend is the real point of the nsss
package: it allows a complex configuration using different other backends,
similarly to the /etc/nsswitch.conf mechanism
but without its drawbacks:
- Backends that access the user/group/shadow databases are not implemented
via dynamically loaded shared libraries, but executables that are spawned by
nsssd-switch. The executables use the same protocol as nsssd-switch
itself, so the provided nsssd-unix and
nsssd-nslcd programs can be used as backends.
- No configuration file is needed, so no parsing is necessary. Backends
are sequentially listed on the nsssd-switch command line, along with
a single argument telling nsssd-switch what to do in case of failure.
This makes the decision automaton very simple.
Interface
s6-ipcserver -l0 /run/service/nsssd/s nsssd-switch [ -t timeout ] bitfield1 backend1... "" bitfield2 backend2... "" ...
or, in an execline script:
s6-ipcserver -l0 /run/service/nsssd/s
nsssd-switch
bitfield1 { backend1... }
bitfield2 { backend2... }
...
- nsssd-switch is normally spawned by a super-server like
s6-ipcserver.
There is one instance of nsssd-switch per client connection.
- nsssd-switch interprets its command line as a script that
configures all its backends. The script is a series of directives:
- First a bitfield is read: it's a number between 0 and 7.
This number determines how the backend will behave in case of failure.
- Then a backend is read: it is a full command-line, terminated
by an empty word. (In an execline
script, the backend is a block, without the empty word.) The command
line is an implementation of the server side of the nsss protocol: for instance,
nsssd-unix "" declares a Unix backend with user, group and shadow
credentials in /etc/passwd, /etc/group and /etc/shadow.
- nsssd-switch spawns all its declared backends.
- It then reads queries from its client. It transmits every query to
its backends, in the order given on the command line. A success means
that the answer is immediately returned to the client, and no further
backend is contacted. A failure can be handled in different ways, depending
on the type of failure and on the bitfield associated to the
backend.
- nsssd-switch (and all the backends it spawned) exits when
the client connection is closed, or in some cases, after a timeout.
Exit codes
These exit codes are not important because only the super-server can see them.
- 0: normal exit or timeout while waiting for a client query
- 100: wrong usage
- 111: system call failed or timeout during a nsss protocol exchange
Options
- -t timeout : enforce a limit of
timeout milliseconds when communicating with a backend. If a
backend fails to answer a query under timeout milliseconds,
nsssd-switch will return a failure code to the client, and
the backend will be considered permanently failed. The default is 0,
meaning no such timeout - backends can take as much time as they want
to answer queries.
Environment variables
nsssd-switch can read a number x in the NSSSD_TIMEOUT
environment variable. If this variable is present and valid, it means that
nsssd-switch will die if x milliseconds elapse without
the client reading or writing during a nsss protocol exchange, which usually
means the client either is not speaking the protocol correctly or has become
unresponsive. It is a safety measure to avoid having nsssd processes
sticking around forever when a client is buggy.
Note that the NSSSD_TIMEOUT variable refers to a timeout during an exchange
with the client, while the argument to the -t option refers
to a timeout enforced on the backends.
Bitfields
A bitfield is a value between 0 and 7, representing 3 bits. If a
bit is 0, it means that the query resolution will continue to the next
backend if the corresponding failure condition is triggered. If the
bit is 1, it means that the failure will instantly be reported to the client
and the query will not be transmitted to the next backend in the chain.
- Bit 0: the backend is in a state of permanent failure: it failed to start,
it crashed, or it timed out.
- Bit 1: the backend answered the query with a failure.
- Bit 2: the requested entry was not found in the backend's database.
So, for instance, a bitfield of 5 means: report failure to the client if the
current backend is in a failed state or if a requested entry cannot be found.
Proceed to the next backend if the current backend reports failure when
processing a query.
This format allows the administrator to configure various fallback strategies.
Note that in case of success, the requested data is immediately returned to the
client. nsssd-switch does not provide the equivalent of the merge
directive in /etc/nsswitch.conf.
Notes
-
nsssd-switch is not meant to be called directly; instead, it is expected to be run from
a script as a part of a "nsssd"
local service.
-
The examples/ subdirectory of the nsss package provides examples
on how to run such a service.
The simplest way to do so, for testing purposes, is a command line such as:
s6-ipcserver -l0 /run/service/nsssd/s nsssd-switch 0 nsssd-unix ""
-
/run/service/nsssd/s is the default place where nsss's
implementation of the pwd.h, grp.h and shadow.h
functions expects the nsssd
service to be. It can be changed at nsss build time by giving the
--with-nsssd-socket=PATH option to configure.
-
nsssd-switch does not listen to the socket itself: it reads from its
standard input and writes to its standard output. It relies
on a superserver such as
s6-ipcserver
to manage connections to the socket. An instance of nsssd-switch is run
for every client connection.
-
If fine-grained authorizations are required (only allowing
certain users and groups to connect to the service), the superserver
can be configured to enforce them.
-
nsssd-switch does not need to run as root, provided it has all the
permissions needed by the backends it spawns.
It is recommended to create a nsss user and group, dedicated to
the nsssd service, and run the superserver as this user and group.
-
nsssd-switch is limited to 8 backends. If you need more, you can
chain another nsssd-switch invocation as the 8th backend,
which gives you another batch of 8.