|
|
The file /etc/nsswitch.conf specifies the handling of these and other similar APIs, by specifying one or more single-line entries of the following form:
database : sourcelistwhere database is the case insensitive name of a database, such as passwd or group, and sourcelist is a sequence of zero or more white-space separated module specifications:
source handling
Each source is the name of a module such as files or nis, and handling is either absent or is a pair of square brackets surrounding a sequence of one or more white-space separated processing specifications:
[ processing ... ]
Each processing specification takes the form of
status = actionwhere status must be one of the following four case insensitive identifiers:
success unavail notfound tryagainand action must be either of these two case insensitive identifiers:
return continueor, only for a tryagain status, a decimal integer or the case insensitive identifier forever, indicating the limit on the number of retries to perform. A default handling of
success = returnis used if no handling is specified. If success is not present in handling, its default action is return; for any other status not present, the default action is continue.
Valid database and module names begin with a letter and are followed by any number of letters, digits, or underscore; they cannot be "forever" or the status or action keywords. Case is significant for modules, but is ignored for the databases.
White space within an /etc/nsswitch.conf entry has no effect other than to separate and end tokens. Long lines can be continued to the next line by having a backslash character at the end of the current line. Lines with only white space are ignored. A # and the remainder of that line (which cannot be continued with a backslash) are taken to be a comment and are ignored other than to end the current entry, if any.
A return action causes nsdispatch(S) to return to its caller with the value of the corresponding status --
NS_SUCCESS NS_UNAVAIL NS_NOTFOUND NS_TRYAGAINas defined in the nsswitch.h header -- when the specified status is returned by the called method. A continue action causes nsdispatch(S) to go on to try the next matching method for the requested operation.
For tryagain, a decimal value for action causes nsdispatch(S) to retry the current method no more than the specified number of tries as long as it returns NS_TRYAGAIN; the forever action causes nsdispatch(S) to call the current method until it returns some other status.
For example, the following /etc/nsswitch.conf file
passwd: nis [unavail=return] files group: files nis [tryagain=2 notfound=return] shadow: compatsays that for the passwd database, first use the nis and then files modules, and the reverse for the group database. For passwd's nis, don't go on to files when the nis method returns NS_UNAVAIL or NS_SUCCESS. For group's nis, if nis is reached, it can return NS_TRYAGAIN if that is returned by the method three times, or NS_NOTFOUND or NS_SUCCESS. For the shadow database, behavior compatible with older UnixWare systems is specified.
The /etc/nsswitch.conf file will periodically be checked for a newer modification time stamp by nsdispatch(S) so long-running processes will automatically track updates to this file.
Any problems with the configuration file are reported via syslog(S).
When a source is specified, nsdispatch(S) tries opening the pathname /usr/lib/nss/source.so.1 as a dynamic shared library and expects to find the exported function nss_module_register with shape matching that pointed to by the type nss_module_register_fn as defined in the nsswitch.h header.
When a reentrant method is called, its first argument is the original pointer-to-pointer-to-structure final parameter of the reentrant API; the variable arguments are the others, in order, as passed to the reentrant API, with a pointer-to-int extra argument added at the end. The integer pointed to by this extra argument is where the method needs to assign the value to be returned by the reentrant API. So, for example, the following call to getpwuid_r:
ret = getpwuid_r(uid, pwd, buf, len, ptr);becomes
ns_dtab dtab[]; int err;and the method(s) called are expected to fill in err and the pointer pointed-to by ptr, as well as, if successful, the structure pointed to by pwd.nsdispatch(ptr, dtab, "passwd", "getpwuid_r", 0, uid, pwd, buf, len, &err); return err;
If no reentrant routine exists for the API, generally the method is called with the variable arguments exactly the same as those passed to the API; the first argument is either a null pointer (when the API returns void) or is a pointer to an int into which the method assigns the return value for the API.
Thus
ret = ia_openinfo(name, uipp);becomes
ns_dtab dtab[]; int rv;nsdispatch(&rv, dtab, "iaf", "ia_openinfo", 0, name, uipp); return rv;