mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-22 13:00:06 +00:00
57ba7bb471
Thu Sep 5 03:20:42 1996 Ulrich Drepper <drepper@cygnus.com> Change configuration and Makefiles to allow add-ons to have a sysdeps/ directory hierachy. * configure.in: Test for sysdeps/ directory in add-ons. Before all test and searches in these hierachies, too. * Makeconfig (full-config-subdirs): Define based on $(config-sysdirs). Extend with $(..) if not absolute path. Use $(full-config-subdirs) where $(config-sysdirs) was used. * Makefile ($(objpfx)sysd-dirs): Use config-sysdirs. * MakeTAGS: Use $(full-config-subdirs). * Makerules: Change comment to libc.so link script. (sysdirs): Define based on $(full-config-subdirs). (sysd-Makefile): Define using config-sysdirs. (sysd-rules): Likewise. * sysdeps/unix/Makefile (sysd-syscalls): Define based on +sysdep-dirs. * sysdeps/unix/make-syscalls.sh: Remove basedir argument. Wed Sep 4 01:32:21 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/m68k/fpu/k_cos.c: Rewritten for better accuracy. * sysdeps/m68k/fpu/k_sin.c: Likewise. * sysdeps/m68k/fpu/k_tan.c: Likewise. Thu Sep 5 01:06:09 1996 Richard Henderson <rth@tamu.edu> * malloc/free.c (free): Protect by using __libc_malloc_lock. * malloc/malloc-find.c (malloc_find_object_address): Likewise. * malloc/malloc-size.c (malloc_usable_size): Likewise. * malloc/malloc-walk.c (malloc_walk): Likewise. * malloc/memalign.c (memalign): Likewise. * malloc/realloc.c (realloc): Likewise. * malloc/malloc.c: Define __libc_malloc_lock. (_malloc_internal): Don't use `malloc'. Instead look for `__malloc_hook' or call `_malloc_internal'. (malloc): Protect by using `__libc_malloc_lock'. * malloc/malloc.h: Declare `__libc_malloc_lock'. Mon Sep 2 22:42:59 1996 Richard Henderson <rth@tamu.edu> * sysdeps/alpha/elf/start.S: Use weak_alias for __start instead of the hard definition. * sysdeps/alpha/dl-machine.h (RTLD_START): Add type info for _start and _dl_start_user. * sysdeps/unix/sysv/linux/alpha/init-first.h (SYSDEP_CALL_INIT): Make _dl_starting_up weak. Add type info for NAME. Mon Sep 2 22:15:14 1996 Richard Henderson <rth@tamu.edu> * Makefile (all): Add extra_solibs pass. (+subdir_targets): Same. * Rules (extra_solibs): New phony empty target for subdirs without extra libs. * extra-lib.mk: Build lib*.so* in extra_solibs not lib-noranlib. * manual/Makefile: Add dummy extra_solibs target. Sun Sep 1 15:41:22 1996 Richard Henderson <rth@tamu.edu> * Makeconfig (+link): Add $(link-extra-libs). (link-extra-libs): New variable which expands to the full paths of the other libraries needed by a program, as controled by LDLIBS-$(@F). * db/Makefile: Use LDLIBS-makedb to link libdb not a dependency, as the later attempts to install the library before linking it. * sysdeps/unix/alpha/sysdep.S: Align errno. * sysdeps/unix/sysv/linux/alpha/ioperm.c (struct platform): Add hae_shift entry. (io): Move bus_memory_base and sparse_bus_memory_base into struct. (_hae_shift): New function. * sysdeps/unix/sysv/linux/alpha/sys/io.h: New file. Prototypes for the bus query functions. Sat Aug 31 18:14:54 1996 Richard Henderson <rth@tamu.edu> * elf/dl-close.c (_dl_close): In static executables, map->l_prev can be NULL when unloading a library. * elf/dl-open.c (_dl_open): Pass __environ instead of __libc_envp to the library .init function. * sysdeps/alpha/dl-machine.h (elf_machine_rela): Since we omitted part of the COPY reloc processing earlier, omit the rest now -- we'll get into less trouble later when some fool does use a COPY. * sysdeps/unix/sysv/linux/init-first.c (init): Accept argc et al as parameters. Move all argc and __libc_multiple_libcs calculation out to init-first.h. Use __environ not __libc_envp. * sysdeps/unix/sysv/linux/alpha/init-first.h: Rewrite. * sysdeps/unix/sysv/linux/i386/init-first.h: Rewrite. Thu Aug 29 20:26:40 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/posix/profil.c (profil): Don't clobber saved timer and signal settings when profiling was already turned on. * csu/gmon-start.c (__gmon_start__) [HAVE_INITFINI]: Protect from being called twice. Wed Sep 4 01:31:50 1996 Ulrich Drepper <drepper@cygnus.com> * sysdeps/unix/sysv/linux/i386/mmap.S: Test for 0 < return value < -4096 and not < 0 to decide about failure. Reported by Andreas Jaeger. Tue Sep 3 19:04:05 1996 Ulrich Drepper <drepper@cygnus.com> * stdio-common/vfscanf.c (__vfscanf): Don't count EOF char in %c format. Sat Aug 31 18:10:51 1996 Ulrich Drepper <drepper@cygnus.com> * wcsmbs/wchar.h: Define prototypes for wcstoq and wcstouq only #ifdef __USE_GNU. Sat Aug 31 12:34:29 1996 Ulrich Drepper <drepper@cygnus.com> * version.c: Add missing newline character in banner. * sysdeps/unix/sysv/linux/alpha/Dist: Correct typo. * sysdeps/unix/sysv/linux/i386/Dist: Likewise. Sat Aug 31 03:07:39 1996 Ulrich Drepper <drepper@cygnus.com> * intl/l10nflist.c (_nl_normalize_codeset): We convert to lower case, so don't prepend uppercase `ISO' for only numeric arg.
602 lines
24 KiB
Plaintext
602 lines
24 KiB
Plaintext
@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 is incompatible. This is also manifests 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
|
|
|
|
@display
|
|
@code{[} ( @code{!}? @var{status} @code{=} @var{action} )+ @code{]}
|
|
@end display
|
|
|
|
@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}).
|
|
|
|
The file name @file{libnss_files.so.1} would be on a @w{Solaris 2}
|
|
system @file{nss_files.so.1}. This is the difference mentioned above.
|
|
Sun's NSS modules are usable as modules which get indirectly loaded
|
|
only.
|
|
|
|
The NSS modules in the GNU C Library are prepared to be used as normal
|
|
libraries itself.
|
|
@comment Fix me if necessary.
|
|
This is @emph{not} true in the moment, though. But the different
|
|
organization of the name space in the modules does not make it
|
|
impossible like it is for Solaris. Now you can see why the modules are
|
|
still libraries.@footnote{There is a second explanation: we were too
|
|
lazy to change the Makefiles to allow the generation of shared objects
|
|
not starting with @file{lib} but do not tell this anybody.}
|
|
|
|
|
|
@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
|