diff options
Diffstat (limited to 'manual/nss.texi')
-rw-r--r-- | manual/nss.texi | 586 |
1 files changed, 586 insertions, 0 deletions
diff --git a/manual/nss.texi b/manual/nss.texi new file mode 100644 index 0000000000..cd1f4af0ec --- /dev/null +++ b/manual/nss.texi @@ -0,0 +1,586 @@ +@c each section should have index entries corresponding to the section title + +@node Name Service Switch +@chapter System Databases and Name Service Switch + +Various functions in the C Library need to be configured to work +correctly in the local environment. Traditionally, this was done by +using files (e.g., @file{/etc/passwd}), but other nameservices (line the +Network Information Service (NIS) and the Domain Name Service (DNS)) +became popular, and were hacked into the C library, usually with a fixed +search order @pxref{frobnicate, frobnicate, ,jargon}. + +The GNU C Library contains a cleaner solution of this problem. It is +designed after a method used by Sun Microsystems in the C library of +@w{Solaris 2}. GNU C Library follows their name and calls this +scheme @dfn{Name Service Switch} (NSS). + +Though the interface might be similar to Sun's version there is no +common code. We never saw any source code of Sun's implementation and +so the internal interface are incompatible. This is also manifest in the +file names we use as we will see later. + + +@menu +* NSS Basics:: What is this NSS good for. +* NSS Configuration File:: Configuring NSS. +* NSS Module Internals:: How does it work internally. +* Extending NSS:: What to do to add services or databases. +@end menu + +@node NSS Basics, NSS Configuration File, Name Service Switch, Name Service Switch +@section NSS Basics + +The basic idea is to put the implementation of the different services +offered to access the databases in separate modules. This has some +advantages: + +@enumerate +@item +Contributors can add new services without adding them to GNU C Library. +@item +The modules can be updated separately. +@item +The C library image is smaller. +@end enumerate + +To fulfill the first goal above the ABI of the modules will be described +below. For getting the implementation of a new service right it is +important to understand how the functions in the modules get called. +They are in no way designed to be used by the programmer directly. +Instead the programmer should only use the documented and standardized +functions to access the databases. + +@noindent +The databases available in the NSS are + +@cindex ethers +@cindex group +@cindex hosts +@cindex network +@cindex protocols +@cindex passwd +@cindex rpc +@cindex services +@cindex shadow +@vtable @code +@item ethers +Ethernet numbers, +@comment @pxref{Ethernet Numbers}. +@item group +Groups of users, @pxref{Group Database}. +@item hosts +Host names and numbers, @pxref{Host Names}. +@item network +Network names and numbers, @pxref{Networks Database}. +@item protocols +Network protocols, @pxref{Protocols Database}. +@item passwd +User passwords, @pxref{User Database}. +@item rpc +Remote procedure call names and numbers, +@comment @pxref{RPC Database}. +@item services +Network services, @pxref{Services Database}. +@item shadow +Shadow user passwords, +@comment @pxref{Shadow Password Database}. +@end vtable + +@noindent +There will be some more added later (@code{aliases}, @code{automount}, +@code{bootparams}, @code{netgroup}, @code{netmasks}, and +@code{publickey}). + +@node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch +@section The NSS Configuration File + +@cindex @file{/etc/nsswitch.conf} +@cindex @file{nsswitch.conf} +Somehow the NSS code must be told about the wishes of the user. For +this reason there is the file @file{/etc/nsswitch.conf}. For each +database this file contain a specification how the lookup process should +work. The file could look like this: + +@example +@include nsswitch.texi +@end example + +The first column is the database as you can guess from the table above. +The rest of the line specifies how the lookup process works. Please +note that you specify the way it works for each database individually. +This cannot be done with the old way of a monolithic implementation. + +The configuration specification for each database can contain two +different items: + +@itemize @bullet +@item +the service specification like @code{files}, @code{db}, or @code{nis}. +@item +the reaction on lookup result line @code{[NOTFOUND=return]}. +@end itemize + +@menu +* Services in the NSS configuration:: Service names in the NSS configuratin. +* Actions in the NSS configuration:: React approprite on the lookup result. +* Notes on NSS Configuration File:: Things to take care about while + configuring NSS. +@end menu + +@node Services in the NSS configuration, Actions in the NSS configuration, NSS Configuration File, NSS Configuration File +@subsection Services in the NSS configuration File + +The above example file mentions four different services: @code{files}, +@code{db}, @code{nis}, and @code{nisplus}. This does not mean these +services are available on all sites and it does also not mean these are +all the services which will ever be available. + +In fact, these names are simply strings which the NSS code uses to find +the implicitly addressed functions. The internal interface will be +described later. Visible to the user are the modules which implement an +individual service. + +Assume the service @var{name} shall be used for a lookup. The code for +this service is implemented in a module called @file{libnss_@var{name}}. +On a system supporting shared libraries this is in fact a shared library +with the name (for example) @file{libnss_@var{name}.so.1}. The number +at the end is the currently used version of the interface which will not +change frequently. Normally the user should not have to be cognizant of +these files since they should be placed in a directory where they are +found automatically. Only the names of all available services are +important. + +@node Actions in the NSS configuration, Notes on NSS Configuration File, Services in the NSS configuration, NSS Configuration File +@subsection Actions in the NSS configuration + +The second item in the specification gives the user much finer control +on the lookup process. Action items are placed between two service +names and are written within brackets. The general form is + +@smallexample +[ @r{(}!@r{?} @var{status} = @var{action}@r{)+} ] +@end smallexample + +@noindent +where + +@smallexample +@var{status} @result{} success | notfound | unavail | tryagain +@var{action} @result{} return | continue +@end smallexample + +The case of the keywords is insignificant. The @var{status} +values are the results of a call to a lookup function of a specific +service. They mean + +@ftable @samp +@item success +No error occured an the wanted entry is returned. The default action +for this is @code{return}. + +@item notfound +The lookup process works ok but the needed value was not found. The +default action is @code{continue}. + +@item unavail +@cindex DNS server unavailable +The service is permanently unavailable. This can either mean the needed +file is not available, or, for DNS, the server is not available or does +not allow queries. The default action is @code{continue}. + +@item tryagain +The service is temporarily unavailable. This could mean a file is +locked or a server currently cannot accept more connections. The +default action is @code{continue}. +@end ftable + +@noindent +If we have a line like + +@smallexample +ethers: nisplus [NOTFOUND=return] db files +@end smallexample + +@noindent +this is equivalent to + +@smallexample +ethers: nisplus [SUCCESS=return NOTFOUND=return UNAVAIL=continue + TRYAGAIN=continue] + db [SUCCESS=return NOTFOUND=continue UNAVAIL=continue + TRYAGAIN=continue] + files +@end smallexample + +@noindent +(except that it would have to be written on one line). The default +value for the actions are normally what you want, and only need to be +changed in exceptional cases. + +If the optional @code{!} is placed before the @var{status} this means +the following action is used for all statii but @var{status} itself. +I.e., @code{!} is negation as in the C language (and others). + +Before we explain the exception which makes this action item necessary +one more remark: obviously it makes no sense to add another action +item after the @code{files} service. Since there is no other service +following the action @emph{always} is @code{return}. + +@cindex nisplus, and completeness +Now, why is this @code{[NOTFOUND=return]} action useful? To understand +this we should know that the @code{nisplus} service is often +complete; i.e., if an entry is not available in the NIS+ tables it is +not available anywhere else. This is what is expressed by this action +item: it is useless to examine further services since they will not give +us a result. + +@cindex nisplus, and booting +@cindex bootstrapping, and services +The situation would be different if the NIS+ service is not available +because the machine is booting. In this case the return value of the +lookup function is not @code{notfound} but instead @code{unavail}. And +as you can see in the complete form above: in this situation the +@code{db} and @code{files} services are used. Neat, isn't it? The +system administrator need not pay special care for the time the system +is not completely ready to work (while booting or shutdown or +network problems). + + +@node Notes on NSS Configuration File, , Actions in the NSS configuration, NSS Configuration File +@subsection Notes on the NSS Configuration File + +Finally a few more hints. The NSS implementation is not completely +helpless if @file{/etc/nsswitch.conf} does not exist. For +all supported databases there is a default value so it should normally +be possible to get the system running even if the file is corrupted or +missing. + +A second point is that the user should try to optimize the lookup +process. The different service have different response times. A simple +file look up on a local file could be fast, but if the file is long and the +needed entry is near the end of the file this may take quite some time. +In this case it might be better to use the @code{db} service which +allows fast local access to large data sets. + +Often the situation is that some global information like NIS must be +used. So it is unavoidable to use service entries like @code{nis} etc. +But one should avoid slow services like this if possible. + + +@node NSS Module Internals, Extending NSS, NSS Configuration File, Name Service Switch +@section NSS Module Internals + +Now it is time to described how the modules look like. The functions +contained in a module are identified by their names. I.e., there is no +jump table or the like. How this is done is of no interest here; those +interested in this topic should read about Dynamic Linking. +@comment @ref{Dynamic Linking}. + + +@menu +* NSS Module Names:: Construction of the interface function of + the NSS modules. +* NSS Modules Interface:: Programming interface in the NSS module + functions. +@end menu + +@node NSS Module Names, NSS Modules Interface, NSS Module Internals, NSS Module Internals +@subsection The Naming Scheme of the NSS Modules + +@noindent +The name of each function consist of various parts: + +@quotation + _nss_@var{service}_@var{function} +@end quotation + +@var{service} of course corresponds to the name of the module this +function is found in.@footnote{Now you might ask why to duplicate this +information. The answer is that we want to keep the possibility to link +directly with these shared objects.} The @var{function} part is derived +from the interface function in the C library itself. If the user calls +the function @code{gethostbyname} and the service used is @code{files} +the function + +@smallexample + _nss_files_gethostbyname_r +@end smallexample + +@noindent +in the module + +@smallexample + libnss_files.so.1 +@end smallexample + +@noindent +@cindex reentrant NSS functions +is used. You see, what is explained above in not the whole truth. In +fact the NSS modules only contain reentrant versions of the lookup +functions. I.e., if the user would call the @code{gethostbyname_r} +function this also would end in the above function. For all user +interface functions the C library maps this call to a call to the +reentrant function. For reentrant functions this is trivial since the +interface is (nearly) the same. For the non-reentrant version pointers +to static buffers are used to replace the user supplied buffers. + +I.e., the reentrant functions @emph{can} have counterparts. No service +module is forced to have functions for all databases and all kinds to +access them. If a function is not available it is simply treated as if +the function would return @code{unavail} +(@pxref{Actions in the NSS configuration}). + + +@node NSS Modules Interface, , NSS Module Names, NSS Module Internals +@subsection The Interface of the Function in NSS Modules + +Now we know about the functions contained in the modules. It is now +time to describe the types. When we mentioned the reentrant versions of +the functions above, this means there are some additional arguments +(compared with the standard, non-reentrant version). The prototypes for +the non-reentrant and reentrant versions of our function above are: + +@smallexample +struct hostent *gethostbyname (const char *name) + +struct hostent *gethostbyname_r (const char *name, + struct hostent *result_buf, char *buf, + int buflen, int *h_errnop) +@end smallexample + +@noindent +The actual prototype of the function is the NSS modules in this case is + +@smallexample +int _nss_files_gethostbyname_r (const char *name, + struct hostent *result_buf, char *buf, + int buflen, int *h_errnop) +@end smallexample + +I.e., the interface function is in fact the reentrant function with +the change of the return value. While the user-level function returns a +pointer to the result the reentrant function return an @code{int} value: + +@cindex NSS_STATUS_TRYAGAIN +@cindex NSS_STATUS_UNAVAIL +@cindex NSS_STATUS_NOTFOUND +@cindex NSS_STATUS_SUCCESS +@ftable @code +@item NSS_STATUS_TRYAGAIN +numeric value @code{-2} + +@item NSS_STATUS_UNAVAIL +numeric value @code{-1} + +@item NSS_STATUS_NOTFOUND +numeric value @code{0} + +@item NSS_STATUS_SUCCESS +numeric value @code{1} +@end ftable + +@noindent +Now you see where the action items of the @file{/etc/nsswitch.conf} file +are used. + +The above function has somthing special which is missing for almost all +the other module functions. There is an argument @var{h_errnop}. This +points to a variable which will be filled with the error code in case +the execution of the function fails for some reason. The reentrant +function cannot use the global variable @var{h_errno}; +@code{gethostbyname} calls @code{gethostbyname_r} with the +last argument set to @code{&h_errno}. + +The @code{get@var{XXX}by@var{YYY}} functions are the most important +functions in the NSS modules. But there are others which implement +the other ways to access system databases (say for the +password database, there are @code{setpwent}, @code{getpwent}, and +@code{endpwent}). These will be described in more detail later. +Here we give a general way to determine the +signature of the module function: + +@itemize @bullet +@item +the return value is @code{int}; +@item +the name is as explain in @pxref{NSS Module Names}; +@item +the first arguments are identical to the arguments of the non-reentrant +function; +@item +the next three arguments are: + +@table @code +@item STRUCT_TYPE result_buf +pointer to buffer where the result is stored. @code{STRUCT_TYPE} is +normally a struct which corresponds to the database. +@item char *buffer +pointer to a buffer where the function can store additional adata for +the result etc. +@item int buflen +length of the buffer pointed to by @var{buffer}. +@end table + +@item +possibly a last argument @var{h_errnop}, for the host name and network +name lookup functions. +@end itemize + +@noindent +This table is correct for all functions but the @code{set@dots{}ent} +and @code{end@dots{}ent} functions. + + +@node Extending NSS, , NSS Module Internals, Name Service Switch +@section Extending NSS + +One of the advantages of NSS mentioned above is that it can be extended +quite easily. There are two ways in which the extension can happen: +adding another database or adding another service. The former is +normally done only by the C library developers. It is +here only important to remember that adding another database is +independent from adding another service because a service need not +support all databases or lookup functions. + +A designer/implementor of a new service is therefore free to choose the +databases s/he is interested in and leave the rest for later (or +completely aside). + +@menu +* Adding another Service to NSS:: What is to do to add a new service. +* NSS Module Function Internals:: Guidelines for writing new NSS + service functions. +@end menu + +@node Adding another Service to NSS, NSS Module Function Internals, Extending NSS, Extending NSS +@subsection Adding another Service to NSS + +The sources for a new service need not (and should not) be part of the +GNU C Library itself. The developer retains complete control over the +sources and its development. The links between the C library and the +new service module consists solely of the interface functions. + +Each module is designed following a specific interface specification. +For now the version is 1 and this manifests in the version number of the +shared library object of the NSS modules: they have the extension +@code{.1}. If the interface ever changes in an incompatible way, +this number will be increased---hopefully this will never be necessary. +Modules using the old interface will still be usable. + +Developers of a new service will have to make sure that their module is +created using the correct interface number. This means the file itself +must have the correct name and on ElF systems the @dfn{soname} (Shared +Object Name) must also have this number. Building a module from a bunch +of object files on an ELF system using GNU CC could be done like this: + +@smallexample +gcc -shared -o libnss_NAME.so.1 -Wl,-soname,libnss_NAME.so.1 OBJECTS +@end smallexample + +@noindent +@ref{Link Options, Options for Linking, , gcc, GNU CC}, to learn +more about this command line. + +To use the new module the library must be able to find it. This can be +achieved by using options for the dynamic linker so that it will search +directory where the binary is placed. For an ELF system this could be +done by adding the wanted directory to the value of +@code{LD_LIBRARY_PATH}. + +But this is not always possible since some program (those which run +under IDs which do not belong to the user) ignore this variable. +Therefore the stable version of the module should be placed into a +directory which is searched by the dynamic linker. Normally this should +be the directory @file{$prefix/lib}, where @file{$prefix} corresponds to +the value given to configure using the @code{--prefix} option. But be +careful: this should only be done if it is clear the module does not +cause any harm. System administrators should be careful. + + +@node NSS Module Function Internals, , Adding another Service to NSS, Extending NSS +@subsection Internals of the NSS Module Functions + +Until now we only provided the syntactic interface for the functions in +the NSS module. In fact there is not more much we can tell since the +implementation obviously is different for each function. But a few +general rules must be followed by all functions. + +In fact there are four kinds of different functions which may appear in +the interface. All derive from the traditional ones for system databases. +@var{db} in the following table is normally an abbreviation for the +database (e.g., it is @code{pw} for the password database). + +@table @code +@item int _nss_@var{database}_set@var{db}ent (void) +This function prepares the service for following operations. For a +simple file based lookup this means files could be opened, for other +services this function simply is a noop. + +One special case for this function is that it takes an additional +argument for some @var{database}s (i.e., the interface is +@code{int set@var{db}ent (int)}). @ref{Host Names}, which describes the +@code{sethostent} function. + +The return value should be @var{NSS_STATUS_SUCCESS} or according to the +table above in case of an error (@pxref{NSS Modules Interface}). + +@item int _nss_@var{database}_end@var{db}ent (void) +This function simply closes all files which are still open or removes +buffer caches. If there are no files or buffers to remove this is again +a simple noop. + +There normally is no return value different to @var{NSS_STATUS_SUCCESS}. + +@item int _nss_@var{database}_get@var{db}ent_r (@var{STRUCTURE} *result, char *buffer, int buflen) +Since this function will be called several times in a row to retrieve +one entry after the other it must keep some kind of state. But this +also means the functions are not really reentrant. They are reentrant +only in that simultaneous calls to this function will not try to +write the retrieved data in the same place (as it would be the case for +the non-reentrant functions); instead, it writes to the structure +pointed to by the @var{result} parameter. But the calls share a common +state and in the case of a file access this means they return neighboring +entries in the file. + +The buffer of length @var{buflen} pointed to by @var{buffer} can be used +for storing some additional data for the result. It is @emph{not} +guaranteed that the same buffer will be passed for the next call of this +function. Therefore one must not misuse this buffer to save some state +information from one call to another. + +As explained above this function could also have an additional last +argument. This depends on the database used; it happens only for +@code{host} and @code{network}. + +The function shall return @code{NSS_STATUS_SUCCESS} as long as their are +more entries. When the last entry was read it should return +@code{NSS_STATUS_NOTFOUND}. When the buffer given as an argument is too +small for the data to be returned @code{NSS_STATUS_TRYAGAIN} should be +returned. When the service was not formerly initialized by a call to +@code{_nss_@var{DATABASE}_set@var{db}ent} all return value allowed for +this function can also be returned here. + +@item int _nss_@var{DATABASE}_get@var{db}by@var{XX}_r (@var{PARAMS}, @var{STRUCTURE} *result, char *buffer, int buflen) +This function shall return the entry from the database which is +addressed by the @var{PARAMS}. The type and number of these arguments +vary. It must be individually determined by looking to the user-level +interface functions. All arguments given to the non-reentrant version +are here described by @var{PARAMS}. + +The result must be stored in the structure pointed to by @var{result}. +If there is additional data to return (say strings, where the +@var{result} structure only contains pointers) the function must use the +@var{buffer} or length @var{buflen}. There must not be any references +to non-constant global data. + +The implementation of this function should honour the @var{stayopen} +flag set by the @code{set@var{DB}ent} function whenever this makes sense. + +Again, this function takes an additional last argument for the +@code{host} and @code{network} database. + +The return value should as always follow the rules given above +(@pxref{NSS Modules Interface}). + +@end table |