aboutsummaryrefslogtreecommitdiffstats
nsss: the nsssd-switch program

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:
    1. 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.
    2. 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.