xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame] | 1 | @node Name Service Switch, Users and Groups, Job Control, Top |
| 2 | @chapter System Databases and Name Service Switch |
| 3 | @c %MENU% Accessing system databases |
| 4 | @cindex Name Service Switch |
| 5 | @cindex NSS |
| 6 | @cindex databases |
| 7 | |
| 8 | Various functions in the C Library need to be configured to work |
| 9 | correctly in the local environment. Traditionally, this was done by |
| 10 | using files (e.g., @file{/etc/passwd}), but other nameservices (like the |
| 11 | Network Information Service (NIS) and the Domain Name Service (DNS)) |
| 12 | became popular, and were hacked into the C library, usually with a fixed |
| 13 | search order. |
| 14 | |
| 15 | @Theglibc{} contains a cleaner solution of this problem. It is |
| 16 | designed after a method used by Sun Microsystems in the C library of |
| 17 | @w{Solaris 2}. @Theglibc{} follows their name and calls this |
| 18 | scheme @dfn{Name Service Switch} (NSS). |
| 19 | |
| 20 | Though the interface might be similar to Sun's version there is no |
| 21 | common code. We never saw any source code of Sun's implementation and |
| 22 | so the internal interface is incompatible. This also manifests in the |
| 23 | file names we use as we will see later. |
| 24 | |
| 25 | |
| 26 | @menu |
| 27 | * NSS Basics:: What is this NSS good for. |
| 28 | * NSS Configuration File:: Configuring NSS. |
| 29 | * NSS Module Internals:: How does it work internally. |
| 30 | * Extending NSS:: What to do to add services or databases. |
| 31 | @end menu |
| 32 | |
| 33 | @node NSS Basics, NSS Configuration File, Name Service Switch, Name Service Switch |
| 34 | @section NSS Basics |
| 35 | |
| 36 | The basic idea is to put the implementation of the different services |
| 37 | offered to access the databases in separate modules. This has some |
| 38 | advantages: |
| 39 | |
| 40 | @enumerate |
| 41 | @item |
| 42 | Contributors can add new services without adding them to @theglibc{}. |
| 43 | @item |
| 44 | The modules can be updated separately. |
| 45 | @item |
| 46 | The C library image is smaller. |
| 47 | @end enumerate |
| 48 | |
| 49 | To fulfill the first goal above the ABI of the modules will be described |
| 50 | below. For getting the implementation of a new service right it is |
| 51 | important to understand how the functions in the modules get called. |
| 52 | They are in no way designed to be used by the programmer directly. |
| 53 | Instead the programmer should only use the documented and standardized |
| 54 | functions to access the databases. |
| 55 | |
| 56 | @noindent |
| 57 | The databases available in the NSS are |
| 58 | |
| 59 | @cindex ethers |
| 60 | @cindex group |
| 61 | @cindex hosts |
| 62 | @cindex netgroup |
| 63 | @cindex networks |
| 64 | @cindex protocols |
| 65 | @cindex passwd |
| 66 | @cindex rpc |
| 67 | @cindex services |
| 68 | @cindex shadow |
| 69 | @vtable @code |
| 70 | @item aliases |
| 71 | Mail aliases |
| 72 | @comment @pxref{Mail Aliases}. |
| 73 | @item ethers |
| 74 | Ethernet numbers, |
| 75 | @comment @pxref{Ethernet Numbers}. |
| 76 | @item group |
| 77 | Groups of users, @pxref{Group Database}. |
| 78 | @item hosts |
| 79 | Host names and numbers, @pxref{Host Names}. |
| 80 | @item netgroup |
| 81 | Network wide list of host and users, @pxref{Netgroup Database}. |
| 82 | @item networks |
| 83 | Network names and numbers, @pxref{Networks Database}. |
| 84 | @item protocols |
| 85 | Network protocols, @pxref{Protocols Database}. |
| 86 | @item passwd |
| 87 | User passwords, @pxref{User Database}. |
| 88 | @item rpc |
| 89 | Remote procedure call names and numbers, |
| 90 | @comment @pxref{RPC Database}. |
| 91 | @item services |
| 92 | Network services, @pxref{Services Database}. |
| 93 | @item shadow |
| 94 | Shadow user passwords, |
| 95 | @comment @pxref{Shadow Password Database}. |
| 96 | @end vtable |
| 97 | |
| 98 | @noindent |
| 99 | There will be some more added later (@code{automount}, @code{bootparams}, |
| 100 | @code{netmasks}, and @code{publickey}). |
| 101 | |
| 102 | @node NSS Configuration File, NSS Module Internals, NSS Basics, Name Service Switch |
| 103 | @section The NSS Configuration File |
| 104 | |
| 105 | @cindex @file{/etc/nsswitch.conf} |
| 106 | @cindex @file{nsswitch.conf} |
| 107 | Somehow the NSS code must be told about the wishes of the user. For |
| 108 | this reason there is the file @file{/etc/nsswitch.conf}. For each |
| 109 | database this file contain a specification how the lookup process should |
| 110 | work. The file could look like this: |
| 111 | |
| 112 | @example |
| 113 | @include nsswitch.texi |
| 114 | @end example |
| 115 | |
| 116 | The first column is the database as you can guess from the table above. |
| 117 | The rest of the line specifies how the lookup process works. Please |
| 118 | note that you specify the way it works for each database individually. |
| 119 | This cannot be done with the old way of a monolithic implementation. |
| 120 | |
| 121 | The configuration specification for each database can contain two |
| 122 | different items: |
| 123 | |
| 124 | @itemize @bullet |
| 125 | @item |
| 126 | the service specification like @code{files}, @code{db}, or @code{nis}. |
| 127 | @item |
| 128 | the reaction on lookup result like @code{[NOTFOUND=return]}. |
| 129 | @end itemize |
| 130 | |
| 131 | @menu |
| 132 | * Services in the NSS configuration:: Service names in the NSS configuration. |
| 133 | * Actions in the NSS configuration:: React appropriately to the lookup result. |
| 134 | * Notes on NSS Configuration File:: Things to take care about while |
| 135 | configuring NSS. |
| 136 | @end menu |
| 137 | |
| 138 | @node Services in the NSS configuration, Actions in the NSS configuration, NSS Configuration File, NSS Configuration File |
| 139 | @subsection Services in the NSS configuration File |
| 140 | |
| 141 | The above example file mentions five different services: @code{files}, |
| 142 | @code{db}, @code{dns}, @code{nis}, and @code{nisplus}. This does not |
| 143 | mean these |
| 144 | services are available on all sites and it does also not mean these are |
| 145 | all the services which will ever be available. |
| 146 | |
| 147 | In fact, these names are simply strings which the NSS code uses to find |
| 148 | the implicitly addressed functions. The internal interface will be |
| 149 | described later. Visible to the user are the modules which implement an |
| 150 | individual service. |
| 151 | |
| 152 | Assume the service @var{name} shall be used for a lookup. The code for |
| 153 | this service is implemented in a module called @file{libnss_@var{name}}. |
| 154 | On a system supporting shared libraries this is in fact a shared library |
| 155 | with the name (for example) @file{libnss_@var{name}.so.2}. The number |
| 156 | at the end is the currently used version of the interface which will not |
| 157 | change frequently. Normally the user should not have to be cognizant of |
| 158 | these files since they should be placed in a directory where they are |
| 159 | found automatically. Only the names of all available services are |
| 160 | important. |
| 161 | |
| 162 | @node Actions in the NSS configuration, Notes on NSS Configuration File, Services in the NSS configuration, NSS Configuration File |
| 163 | @subsection Actions in the NSS configuration |
| 164 | |
| 165 | The second item in the specification gives the user much finer control |
| 166 | on the lookup process. Action items are placed between two service |
| 167 | names and are written within brackets. The general form is |
| 168 | |
| 169 | @display |
| 170 | @code{[} ( @code{!}? @var{status} @code{=} @var{action} )+ @code{]} |
| 171 | @end display |
| 172 | |
| 173 | @noindent |
| 174 | where |
| 175 | |
| 176 | @smallexample |
| 177 | @var{status} @result{} success | notfound | unavail | tryagain |
| 178 | @var{action} @result{} return | continue |
| 179 | @end smallexample |
| 180 | |
| 181 | The case of the keywords is insignificant. The @var{status} |
| 182 | values are the results of a call to a lookup function of a specific |
| 183 | service. They mean |
| 184 | |
| 185 | @ftable @samp |
| 186 | @item success |
| 187 | No error occurred and the wanted entry is returned. The default action |
| 188 | for this is @code{return}. |
| 189 | |
| 190 | @item notfound |
| 191 | The lookup process works ok but the needed value was not found. The |
| 192 | default action is @code{continue}. |
| 193 | |
| 194 | @item unavail |
| 195 | @cindex DNS server unavailable |
| 196 | The service is permanently unavailable. This can either mean the needed |
| 197 | file is not available, or, for DNS, the server is not available or does |
| 198 | not allow queries. The default action is @code{continue}. |
| 199 | |
| 200 | @item tryagain |
| 201 | The service is temporarily unavailable. This could mean a file is |
| 202 | locked or a server currently cannot accept more connections. The |
| 203 | default action is @code{continue}. |
| 204 | @end ftable |
| 205 | |
| 206 | @noindent |
| 207 | If we have a line like |
| 208 | |
| 209 | @smallexample |
| 210 | ethers: nisplus [NOTFOUND=return] db files |
| 211 | @end smallexample |
| 212 | |
| 213 | @noindent |
| 214 | this is equivalent to |
| 215 | |
| 216 | @smallexample |
| 217 | ethers: nisplus [SUCCESS=return NOTFOUND=return UNAVAIL=continue |
| 218 | TRYAGAIN=continue] |
| 219 | db [SUCCESS=return NOTFOUND=continue UNAVAIL=continue |
| 220 | TRYAGAIN=continue] |
| 221 | files |
| 222 | @end smallexample |
| 223 | |
| 224 | @noindent |
| 225 | (except that it would have to be written on one line). The default |
| 226 | value for the actions are normally what you want, and only need to be |
| 227 | changed in exceptional cases. |
| 228 | |
| 229 | If the optional @code{!} is placed before the @var{status} this means |
| 230 | the following action is used for all statuses but @var{status} itself. |
| 231 | I.e., @code{!} is negation as in the C language (and others). |
| 232 | |
| 233 | Before we explain the exception which makes this action item necessary |
| 234 | one more remark: obviously it makes no sense to add another action |
| 235 | item after the @code{files} service. Since there is no other service |
| 236 | following the action @emph{always} is @code{return}. |
| 237 | |
| 238 | @cindex nisplus, and completeness |
| 239 | Now, why is this @code{[NOTFOUND=return]} action useful? To understand |
| 240 | this we should know that the @code{nisplus} service is often |
| 241 | complete; i.e., if an entry is not available in the NIS+ tables it is |
| 242 | not available anywhere else. This is what is expressed by this action |
| 243 | item: it is useless to examine further services since they will not give |
| 244 | us a result. |
| 245 | |
| 246 | @cindex nisplus, and booting |
| 247 | @cindex bootstrapping, and services |
| 248 | The situation would be different if the NIS+ service is not available |
| 249 | because the machine is booting. In this case the return value of the |
| 250 | lookup function is not @code{notfound} but instead @code{unavail}. And |
| 251 | as you can see in the complete form above: in this situation the |
| 252 | @code{db} and @code{files} services are used. Neat, isn't it? The |
| 253 | system administrator need not pay special care for the time the system |
| 254 | is not completely ready to work (while booting or shutdown or |
| 255 | network problems). |
| 256 | |
| 257 | |
| 258 | @node Notes on NSS Configuration File, , Actions in the NSS configuration, NSS Configuration File |
| 259 | @subsection Notes on the NSS Configuration File |
| 260 | |
| 261 | Finally a few more hints. The NSS implementation is not completely |
| 262 | helpless if @file{/etc/nsswitch.conf} does not exist. For |
| 263 | all supported databases there is a default value so it should normally |
| 264 | be possible to get the system running even if the file is corrupted or |
| 265 | missing. |
| 266 | |
| 267 | @cindex default value, and NSS |
| 268 | For the @code{hosts} and @code{networks} databases the default value is |
| 269 | @code{dns [!UNAVAIL=return] files}. I.e., the system is prepared for |
| 270 | the DNS service not to be available but if it is available the answer it |
| 271 | returns is definitive. |
| 272 | |
| 273 | The @code{passwd}, @code{group}, and @code{shadow} databases are |
| 274 | traditionally handled in a special way. The appropriate files in the |
| 275 | @file{/etc} directory are read but if an entry with a name starting |
| 276 | with a @code{+} character is found NIS is used. This kind of lookup |
| 277 | remains possible by using the special lookup service @code{compat} |
| 278 | and the default value for the three databases above is |
| 279 | @code{compat [NOTFOUND=return] files}. |
| 280 | |
| 281 | For all other databases the default value is |
| 282 | @code{nis [NOTFOUND=return] files}. This solution give the best |
| 283 | chance to be correct since NIS and file based lookup is used. |
| 284 | |
| 285 | @cindex optimizing NSS |
| 286 | A second point is that the user should try to optimize the lookup |
| 287 | process. The different service have different response times. |
| 288 | A simple file look up on a local file could be fast, but if the file |
| 289 | is long and the needed entry is near the end of the file this may take |
| 290 | quite some time. In this case it might be better to use the @code{db} |
| 291 | service which allows fast local access to large data sets. |
| 292 | |
| 293 | Often the situation is that some global information like NIS must be |
| 294 | used. So it is unavoidable to use service entries like @code{nis} etc. |
| 295 | But one should avoid slow services like this if possible. |
| 296 | |
| 297 | |
| 298 | @node NSS Module Internals, Extending NSS, NSS Configuration File, Name Service Switch |
| 299 | @section NSS Module Internals |
| 300 | |
| 301 | Now it is time to describe what the modules look like. The functions |
| 302 | contained in a module are identified by their names. I.e., there is no |
| 303 | jump table or the like. How this is done is of no interest here; those |
| 304 | interested in this topic should read about Dynamic Linking. |
| 305 | @comment @ref{Dynamic Linking}. |
| 306 | |
| 307 | |
| 308 | @menu |
| 309 | * NSS Module Names:: Construction of the interface function of |
| 310 | the NSS modules. |
| 311 | * NSS Modules Interface:: Programming interface in the NSS module |
| 312 | functions. |
| 313 | @end menu |
| 314 | |
| 315 | @node NSS Module Names, NSS Modules Interface, NSS Module Internals, NSS Module Internals |
| 316 | @subsection The Naming Scheme of the NSS Modules |
| 317 | |
| 318 | @noindent |
| 319 | The name of each function consist of various parts: |
| 320 | |
| 321 | @quotation |
| 322 | _nss_@var{service}_@var{function} |
| 323 | @end quotation |
| 324 | |
| 325 | @var{service} of course corresponds to the name of the module this |
| 326 | function is found in.@footnote{Now you might ask why this information is |
| 327 | duplicated. The answer is that we want to make it possible to link |
| 328 | directly with these shared objects.} The @var{function} part is derived |
| 329 | from the interface function in the C library itself. If the user calls |
| 330 | the function @code{gethostbyname} and the service used is @code{files} |
| 331 | the function |
| 332 | |
| 333 | @smallexample |
| 334 | _nss_files_gethostbyname_r |
| 335 | @end smallexample |
| 336 | |
| 337 | @noindent |
| 338 | in the module |
| 339 | |
| 340 | @smallexample |
| 341 | libnss_files.so.2 |
| 342 | @end smallexample |
| 343 | |
| 344 | @noindent |
| 345 | @cindex reentrant NSS functions |
| 346 | is used. You see, what is explained above in not the whole truth. In |
| 347 | fact the NSS modules only contain reentrant versions of the lookup |
| 348 | functions. I.e., if the user would call the @code{gethostbyname_r} |
| 349 | function this also would end in the above function. For all user |
| 350 | interface functions the C library maps this call to a call to the |
| 351 | reentrant function. For reentrant functions this is trivial since the |
| 352 | interface is (nearly) the same. For the non-reentrant version The |
| 353 | library keeps internal buffers which are used to replace the user |
| 354 | supplied buffer. |
| 355 | |
| 356 | I.e., the reentrant functions @emph{can} have counterparts. No service |
| 357 | module is forced to have functions for all databases and all kinds to |
| 358 | access them. If a function is not available it is simply treated as if |
| 359 | the function would return @code{unavail} |
| 360 | (@pxref{Actions in the NSS configuration}). |
| 361 | |
| 362 | The file name @file{libnss_files.so.2} would be on a @w{Solaris 2} |
| 363 | system @file{nss_files.so.2}. This is the difference mentioned above. |
| 364 | Sun's NSS modules are usable as modules which get indirectly loaded |
| 365 | only. |
| 366 | |
| 367 | The NSS modules in @theglibc{} are prepared to be used as normal |
| 368 | libraries themselves. This is @emph{not} true at the moment, though. |
| 369 | However, the organization of the name space in the modules does not make it |
| 370 | impossible like it is for Solaris. Now you can see why the modules are |
| 371 | still libraries.@footnote{There is a second explanation: we were too |
| 372 | lazy to change the Makefiles to allow the generation of shared objects |
| 373 | not starting with @file{lib} but don't tell this to anybody.} |
| 374 | |
| 375 | |
| 376 | @node NSS Modules Interface, , NSS Module Names, NSS Module Internals |
| 377 | @subsection The Interface of the Function in NSS Modules |
| 378 | |
| 379 | Now we know about the functions contained in the modules. It is now |
| 380 | time to describe the types. When we mentioned the reentrant versions of |
| 381 | the functions above, this means there are some additional arguments |
| 382 | (compared with the standard, non-reentrant version). The prototypes for |
| 383 | the non-reentrant and reentrant versions of our function above are: |
| 384 | |
| 385 | @smallexample |
| 386 | struct hostent *gethostbyname (const char *name) |
| 387 | |
| 388 | int gethostbyname_r (const char *name, struct hostent *result_buf, |
| 389 | char *buf, size_t buflen, struct hostent **result, |
| 390 | int *h_errnop) |
| 391 | @end smallexample |
| 392 | |
| 393 | @noindent |
| 394 | The actual prototype of the function in the NSS modules in this case is |
| 395 | |
| 396 | @smallexample |
| 397 | enum nss_status _nss_files_gethostbyname_r (const char *name, |
| 398 | struct hostent *result_buf, |
| 399 | char *buf, size_t buflen, |
| 400 | int *errnop, int *h_errnop) |
| 401 | @end smallexample |
| 402 | |
| 403 | I.e., the interface function is in fact the reentrant function with the |
| 404 | change of the return value and the omission of the @var{result} |
| 405 | parameter. While the user-level function returns a pointer to the |
| 406 | result the reentrant function return an @code{enum nss_status} value: |
| 407 | |
| 408 | @vtable @code |
| 409 | @item NSS_STATUS_TRYAGAIN |
| 410 | numeric value @code{-2} |
| 411 | |
| 412 | @item NSS_STATUS_UNAVAIL |
| 413 | numeric value @code{-1} |
| 414 | |
| 415 | @item NSS_STATUS_NOTFOUND |
| 416 | numeric value @code{0} |
| 417 | |
| 418 | @item NSS_STATUS_SUCCESS |
| 419 | numeric value @code{1} |
| 420 | @end vtable |
| 421 | |
| 422 | @noindent |
| 423 | Now you see where the action items of the @file{/etc/nsswitch.conf} file |
| 424 | are used. |
| 425 | |
| 426 | If you study the source code you will find there is a fifth value: |
| 427 | @code{NSS_STATUS_RETURN}. This is an internal use only value, used by a |
| 428 | few functions in places where none of the above value can be used. If |
| 429 | necessary the source code should be examined to learn about the details. |
| 430 | |
| 431 | In case the interface function has to return an error it is important |
| 432 | that the correct error code is stored in @code{*@var{errnop}}. Some |
| 433 | return status value have only one associated error code, others have |
| 434 | more. |
| 435 | |
| 436 | @multitable @columnfractions .3 .2 .50 |
| 437 | @item |
| 438 | @code{NSS_STATUS_TRYAGAIN} @tab |
| 439 | @code{EAGAIN} @tab One of the functions used ran temporarily out of |
| 440 | resources or a service is currently not available. |
| 441 | @item |
| 442 | @tab |
| 443 | @code{ERANGE} @tab The provided buffer is not large enough. |
| 444 | The function should be called again with a larger buffer. |
| 445 | @item |
| 446 | @code{NSS_STATUS_UNAVAIL} @tab |
| 447 | @code{ENOENT} @tab A necessary input file cannot be found. |
| 448 | @item |
| 449 | @code{NSS_STATUS_NOTFOUND} @tab |
| 450 | @code{ENOENT} @tab The requested entry is not available. |
| 451 | |
| 452 | @item |
| 453 | @code{NSS_STATUS_NOTFOUND} @tab |
| 454 | @code{SUCCESS} @tab There are no entries. |
| 455 | Use this to avoid returning errors for inactive services which may |
| 456 | be enabled at a later time. This is not the same as the service |
| 457 | being temporarily unavailable. |
| 458 | @end multitable |
| 459 | |
| 460 | These are proposed values. There can be other error codes and the |
| 461 | described error codes can have different meaning. @strong{With one |
| 462 | exception:} when returning @code{NSS_STATUS_TRYAGAIN} the error code |
| 463 | @code{ERANGE} @emph{must} mean that the user provided buffer is too |
| 464 | small. Everything is non-critical. |
| 465 | |
| 466 | The above function has something special which is missing for almost all |
| 467 | the other module functions. There is an argument @var{h_errnop}. This |
| 468 | points to a variable which will be filled with the error code in case |
| 469 | the execution of the function fails for some reason. The reentrant |
| 470 | function cannot use the global variable @var{h_errno}; |
| 471 | @code{gethostbyname} calls @code{gethostbyname_r} with the last argument |
| 472 | set to @code{&h_errno}. |
| 473 | |
| 474 | The @code{get@var{XXX}by@var{YYY}} functions are the most important |
| 475 | functions in the NSS modules. But there are others which implement |
| 476 | the other ways to access system databases (say for the |
| 477 | password database, there are @code{setpwent}, @code{getpwent}, and |
| 478 | @code{endpwent}). These will be described in more detail later. |
| 479 | Here we give a general way to determine the |
| 480 | signature of the module function: |
| 481 | |
| 482 | @itemize @bullet |
| 483 | @item |
| 484 | the return value is @code{int}; |
| 485 | @item |
| 486 | the name is as explained in @pxref{NSS Module Names}; |
| 487 | @item |
| 488 | the first arguments are identical to the arguments of the non-reentrant |
| 489 | function; |
| 490 | @item |
| 491 | the next three arguments are: |
| 492 | |
| 493 | @table @code |
| 494 | @item STRUCT_TYPE *result_buf |
| 495 | pointer to buffer where the result is stored. @code{STRUCT_TYPE} is |
| 496 | normally a struct which corresponds to the database. |
| 497 | @item char *buffer |
| 498 | pointer to a buffer where the function can store additional data for |
| 499 | the result etc. |
| 500 | @item size_t buflen |
| 501 | length of the buffer pointed to by @var{buffer}. |
| 502 | @end table |
| 503 | |
| 504 | @item |
| 505 | possibly a last argument @var{h_errnop}, for the host name and network |
| 506 | name lookup functions. |
| 507 | @end itemize |
| 508 | |
| 509 | @noindent |
| 510 | This table is correct for all functions but the @code{set@dots{}ent} |
| 511 | and @code{end@dots{}ent} functions. |
| 512 | |
| 513 | |
| 514 | @node Extending NSS, , NSS Module Internals, Name Service Switch |
| 515 | @section Extending NSS |
| 516 | |
| 517 | One of the advantages of NSS mentioned above is that it can be extended |
| 518 | quite easily. There are two ways in which the extension can happen: |
| 519 | adding another database or adding another service. The former is |
| 520 | normally done only by the C library developers. It is |
| 521 | here only important to remember that adding another database is |
| 522 | independent from adding another service because a service need not |
| 523 | support all databases or lookup functions. |
| 524 | |
| 525 | A designer/implementor of a new service is therefore free to choose the |
| 526 | databases s/he is interested in and leave the rest for later (or |
| 527 | completely aside). |
| 528 | |
| 529 | @menu |
| 530 | * Adding another Service to NSS:: What is to do to add a new service. |
| 531 | * NSS Module Function Internals:: Guidelines for writing new NSS |
| 532 | service functions. |
| 533 | @end menu |
| 534 | |
| 535 | @node Adding another Service to NSS, NSS Module Function Internals, Extending NSS, Extending NSS |
| 536 | @subsection Adding another Service to NSS |
| 537 | |
| 538 | The sources for a new service need not (and should not) be part of @theglibc{} |
| 539 | itself. The developer retains complete control over the |
| 540 | sources and its development. The links between the C library and the |
| 541 | new service module consists solely of the interface functions. |
| 542 | |
| 543 | Each module is designed following a specific interface specification. |
| 544 | For now the version is 2 (the interface in version 1 was not adequate) |
| 545 | and this manifests in the version number of the shared library object of |
| 546 | the NSS modules: they have the extension @code{.2}. If the interface |
| 547 | changes again in an incompatible way, this number will be increased. |
| 548 | Modules using the old interface will still be usable. |
| 549 | |
| 550 | Developers of a new service will have to make sure that their module is |
| 551 | created using the correct interface number. This means the file itself |
| 552 | must have the correct name and on ELF systems the @dfn{soname} (Shared |
| 553 | Object Name) must also have this number. Building a module from a bunch |
| 554 | of object files on an ELF system using GNU CC could be done like this: |
| 555 | |
| 556 | @smallexample |
| 557 | gcc -shared -o libnss_NAME.so.2 -Wl,-soname,libnss_NAME.so.2 OBJECTS |
| 558 | @end smallexample |
| 559 | |
| 560 | @noindent |
| 561 | @ref{Link Options, Options for Linking, , gcc, GNU CC}, to learn |
| 562 | more about this command line. |
| 563 | |
| 564 | To use the new module the library must be able to find it. This can be |
| 565 | achieved by using options for the dynamic linker so that it will search |
| 566 | the directory where the binary is placed. For an ELF system this could be |
| 567 | done by adding the wanted directory to the value of |
| 568 | @code{LD_LIBRARY_PATH}. |
| 569 | |
| 570 | But this is not always possible since some programs (those which run |
| 571 | under IDs which do not belong to the user) ignore this variable. |
| 572 | Therefore the stable version of the module should be placed into a |
| 573 | directory which is searched by the dynamic linker. Normally this should |
| 574 | be the directory @file{$prefix/lib}, where @file{$prefix} corresponds to |
| 575 | the value given to configure using the @code{--prefix} option. But be |
| 576 | careful: this should only be done if it is clear the module does not |
| 577 | cause any harm. System administrators should be careful. |
| 578 | |
| 579 | |
| 580 | @node NSS Module Function Internals, , Adding another Service to NSS, Extending NSS |
| 581 | @subsection Internals of the NSS Module Functions |
| 582 | |
| 583 | Until now we only provided the syntactic interface for the functions in |
| 584 | the NSS module. In fact there is not much more we can say since the |
| 585 | implementation obviously is different for each function. But a few |
| 586 | general rules must be followed by all functions. |
| 587 | |
| 588 | In fact there are four kinds of different functions which may appear in |
| 589 | the interface. All derive from the traditional ones for system databases. |
| 590 | @var{db} in the following table is normally an abbreviation for the |
| 591 | database (e.g., it is @code{pw} for the password database). |
| 592 | |
| 593 | @table @code |
| 594 | @item enum nss_status _nss_@var{database}_set@var{db}ent (void) |
| 595 | This function prepares the service for following operations. For a |
| 596 | simple file based lookup this means files could be opened, for other |
| 597 | services this function simply is a noop. |
| 598 | |
| 599 | One special case for this function is that it takes an additional |
| 600 | argument for some @var{database}s (i.e., the interface is |
| 601 | @code{int set@var{db}ent (int)}). @ref{Host Names}, which describes the |
| 602 | @code{sethostent} function. |
| 603 | |
| 604 | The return value should be @var{NSS_STATUS_SUCCESS} or according to the |
| 605 | table above in case of an error (@pxref{NSS Modules Interface}). |
| 606 | |
| 607 | @item enum nss_status _nss_@var{database}_end@var{db}ent (void) |
| 608 | This function simply closes all files which are still open or removes |
| 609 | buffer caches. If there are no files or buffers to remove this is again |
| 610 | a simple noop. |
| 611 | |
| 612 | There normally is no return value different to @var{NSS_STATUS_SUCCESS}. |
| 613 | |
| 614 | @item enum nss_status _nss_@var{database}_get@var{db}ent_r (@var{STRUCTURE} *result, char *buffer, size_t buflen, int *errnop) |
| 615 | Since this function will be called several times in a row to retrieve |
| 616 | one entry after the other it must keep some kind of state. But this |
| 617 | also means the functions are not really reentrant. They are reentrant |
| 618 | only in that simultaneous calls to this function will not try to |
| 619 | write the retrieved data in the same place (as it would be the case for |
| 620 | the non-reentrant functions); instead, it writes to the structure |
| 621 | pointed to by the @var{result} parameter. But the calls share a common |
| 622 | state and in the case of a file access this means they return neighboring |
| 623 | entries in the file. |
| 624 | |
| 625 | The buffer of length @var{buflen} pointed to by @var{buffer} can be used |
| 626 | for storing some additional data for the result. It is @emph{not} |
| 627 | guaranteed that the same buffer will be passed for the next call of this |
| 628 | function. Therefore one must not misuse this buffer to save some state |
| 629 | information from one call to another. |
| 630 | |
| 631 | Before the function returns the implementation should store the value of |
| 632 | the local @var{errno} variable in the variable pointed to be |
| 633 | @var{errnop}. This is important to guarantee the module working in |
| 634 | statically linked programs. |
| 635 | |
| 636 | As explained above this function could also have an additional last |
| 637 | argument. This depends on the database used; it happens only for |
| 638 | @code{host} and @code{networks}. |
| 639 | |
| 640 | The function shall return @code{NSS_STATUS_SUCCESS} as long as there are |
| 641 | more entries. When the last entry was read it should return |
| 642 | @code{NSS_STATUS_NOTFOUND}. When the buffer given as an argument is too |
| 643 | small for the data to be returned @code{NSS_STATUS_TRYAGAIN} should be |
| 644 | returned. When the service was not formerly initialized by a call to |
| 645 | @code{_nss_@var{DATABASE}_set@var{db}ent} all return value allowed for |
| 646 | this function can also be returned here. |
| 647 | |
| 648 | @item enum nss_status _nss_@var{DATABASE}_get@var{db}by@var{XX}_r (@var{PARAMS}, @var{STRUCTURE} *result, char *buffer, size_t buflen, int *errnop) |
| 649 | This function shall return the entry from the database which is |
| 650 | addressed by the @var{PARAMS}. The type and number of these arguments |
| 651 | vary. It must be individually determined by looking to the user-level |
| 652 | interface functions. All arguments given to the non-reentrant version |
| 653 | are here described by @var{PARAMS}. |
| 654 | |
| 655 | The result must be stored in the structure pointed to by @var{result}. |
| 656 | If there is additional data to return (say strings, where the |
| 657 | @var{result} structure only contains pointers) the function must use the |
| 658 | @var{buffer} or length @var{buflen}. There must not be any references |
| 659 | to non-constant global data. |
| 660 | |
| 661 | The implementation of this function should honor the @var{stayopen} |
| 662 | flag set by the @code{set@var{DB}ent} function whenever this makes sense. |
| 663 | |
| 664 | Before the function returns the implementation should store the value of |
| 665 | the local @var{errno} variable in the variable pointed to be |
| 666 | @var{errnop}. This is important to guarantee the module working in |
| 667 | statically linked programs. |
| 668 | |
| 669 | Again, this function takes an additional last argument for the |
| 670 | @code{host} and @code{networks} database. |
| 671 | |
| 672 | The return value should as always follow the rules given above |
| 673 | (@pxref{NSS Modules Interface}). |
| 674 | |
| 675 | @end table |