Print this page
remove support for non-ANSI compilation
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/head/nss_common.h
+++ new/usr/src/head/nss_common.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 + * Copyright 2014 Garrett D'Amore <garrett@damore.org>
23 + *
22 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 25 * Use is subject to license terms.
24 26 */
25 27
26 28 /*
27 29 *
28 30 * NOTE: The interfaces documented in this file may change in a minor
29 31 * release. It is intended that in the future a stronger committment
30 32 * will be made to these interface definitions which will guarantee
31 33 * them across minor releases.
32 34 */
33 35
34 36 #ifndef _NSS_COMMON_H
35 37 #define _NSS_COMMON_H
36 38
37 -#pragma ident "%Z%%M% %I% %E% SMI"
38 -
39 39 #include <synch.h>
40 40
41 41 #ifdef __cplusplus
42 42 extern "C" {
43 43 #endif
44 44
45 45 /*
46 46 * The name-service switch
47 47 * -----------------------
48 48 *
49 49 * From nsswitch.conf(4):
50 50 *
51 51 * The operating system uses a number of "databases" of information
52 52 * about hosts, users (passwd/shadow), groups and so forth. Data for
53 53 * these can come from a variety of "sources": host-names and
54 54 * -addresses, for example, may be found in /etc/hosts, NIS, NIS+ or
55 55 * DNS. One or more sources may be used for each database; the
56 56 * sources and their lookup order are specified in the
57 57 * /etc/nsswitch.conf file.
58 58 *
59 59 * The implementation of this consists of:
60 60 *
61 61 * - a "frontend" for each database, which provides a programming
62 62 * interface for that database [for example, the "passwd" frontend
63 63 * consists of getpwnam_r(), getpwuid_r(), getpwent_r(), setpwent(),
64 64 * endpwent(), and the old MT-unsafe routines getpwnam() and getpwuid()]
65 65 * and is implemented by calls to...
66 66 *
67 67 * - the common core of the switch (called the "switch" or "policy" engine);
68 68 * that determines what sources to use and when to invoke them. This
69 69 * component works in conjunction with the name service switch (nscd).
70 70 * Usually nscd is the policy engine for an application lookup.
71 71 *
72 72 * - Old style backend interfaces follow this pointer to function interface:
73 73 *
74 74 * A "backend" exists for useful <database, source> pairs. Each backend
75 75 * consists of whatever private data it needs and a set of functions
76 76 * that the switch engine may invoke on behalf of the frontend
77 77 * [e.g. the "nis" backend for "passwd" provides routines to lookup
78 78 * by name and by uid, as well as set/get/end iterator routines].
79 79 * The set of functions, and their expected arguments and results,
80 80 * constitutes a (database-specific) interface between a frontend and
81 81 * all its backends. The switch engine knows as little as possible
82 82 * about these interfaces.
83 83 *
84 84 * (The term "backend" is used ambiguously; it may also refer to a
85 85 * particular instantiation of a backend, or to the set of all backends
86 86 * for a particular source, e.g. "the nis backend").
87 87 *
88 88 * This header file defines the interface between the switch engine and the
89 89 * frontends and backends. Interfaces between specific frontends and
90 90 * backends are defined elsewhere; many are in <nss_dbdefs.h>.
91 91 * Most of these definitions are in the form of pointer to function
92 92 * indicies used to call specific backend APIs.
93 93 *
94 94 *
95 95 * Switch-engine outline
96 96 * ---------------------
97 97 *
98 98 * Frontends may call the following routines in the switch engine:
99 99 *
100 100 * nss_search() does getXXXbyYYY, e.g. getpwnam_r(), getpwuid_r()
101 101 * nss_getent() does getXXXent, e.g. getpwent_r()
102 102 * nss_setent() does setXXXent, e.g. setpwent()
103 103 * nss_endent() does endXXXent, e.g. endpwent()
104 104 * nss_delete() releases resources, in the style of endpwent().
105 105 *
106 106 * A getpwnam_r() call might proceed thus (with many details omitted):
107 107 *
108 108 * (1) getpwnam_r fills in (getpwnam-specific) argument/result struct,
109 109 * calls nss_search(),
110 110 * (2) nss_search queries the name service cache for an existing
111 111 * result via a call to _nsc_search(). if the cache
112 112 * (nscd) has a definitive answer skip to step 7
113 113 * (3) nss_search looks up configuration info, gets "passwd: files nis",
114 114 * (4) nss_search decides to try first source ("files"),
115 115 * (a) nss_search locates code for <"passwd", "files"> backend,
116 116 * (b) nss_search creates instance of backend,
117 117 * (c) nss_search calls get-by-name routine in backend,
118 118 * through a function pointer interface,
119 119 * (d) backend searches /etc/passwd, doesn't find the name,
120 120 * returns "not found" status to nss_search,
121 121 * (5) nss_search examines status and config info, decides to try
122 122 * next source ("nis"),
123 123 * (a) nss_search locates code for <"passwd", "nis"> backend,
124 124 * (b) nss_search creates instance of backend,
125 125 * (c) nss_search calls get-by-name routine in backend,
126 126 * through a function pointer interface,
127 127 * (d) backend searches passwd.byname, finds the desired entry,
128 128 * fills in the result part of the getpwnam-specific
129 129 * struct, returns "success" status to nss_search,
130 130 * (6) nss_search examines status and config info, decides to return
131 131 * to caller,
132 132 * (7) getpwnam_r extracts result from getpwnam-specific struct,
133 133 * returns to caller.
134 134 *
135 135 *
136 136 * Data structures
137 137 * ---------------
138 138 *
139 139 * Both databases and sources are represented by case-sensitive strings
140 140 * (the same strings that appear in the configuration file).
141 141 *
142 142 * The switch engine maintains a per-frontend data structure so that the
143 143 * results of steps (2), (a) and (b) can be cached. The frontend holds a
144 144 * handle (nss_db_root_t) to this structure and passes it in to the
145 145 * nss_*() routines.
146 146 *
147 147 * The nss_setent(), nss_getent() and nss_endent() routines introduce another
148 148 * variety of state (the current position in the enumeration process).
149 149 * Within a single source, this information is maintained by private data
150 150 * in the backend instance -- but, in the presence of multiple sources, the
151 151 * switch engine must keep track of the current backend instance [e.g either
152 152 * <"passwd", "files"> or <"passwd", "nis"> instances]. The switch engine
153 153 * has a separate per-enumeration data structure for this; again, the
154 154 * frontend holds a handle (nss_getent_t) and passes it in, along with the
155 155 * nss_db_root_t handle, to nss_setent(), nss_getent() and nss_endent().
156 156 *
157 157 *
158 158 * Multithreading
159 159 * --------------
160 160 *
161 161 * The switch engine takes care of locking; frontends should be written to
162 162 * be reentrant, and a backend instance may assume that all calls to it are
163 163 * serialized.
164 164 *
165 165 * If multiple threads simultaneously want to use a particular backend, the
166 166 * switch engine creates multiple backend instances (up to some limit
167 167 * specified by the frontend). Backends must of course lock any state that
168 168 * is shared between instances, and must serialize calls to any MT-unsafe
169 169 * code.
170 170 *
171 171 * The switch engine has no notion of per-thread state.
172 172 *
173 173 * Frontends can use the nss_getent_t handle to define the scope of the
174 174 * enumeration (set/get/endXXXent) state: a static handle gives global state
175 175 * (which is what Posix has specified for the getXXXent_r routines), handles
176 176 * in Thread-Specific Data give per-thread state, and handles on the stack
177 177 * give per-invocation state.
178 178 */
179 179
180 180 /*
181 181 * Backend instances
182 182 * -----------------
183 183 *
184 184 * As far as the switch engine is concerned, an instance of a backend is a
185 185 * struct whose first two members are:
186 186 * - A pointer to a vector of function pointers, one for each
187 187 * database-specific function,
188 188 * - The length of the vector (an int), used for bounds-checking.
189 189 * There are four well-known function slots in the vector:
190 190 * [0] is a destructor for the backend instance,
191 191 * [1] is the endXXXent routine,
192 192 * [2] is the setXXXent routine,
193 193 * [3] is the getXXXent routine.
194 194 * Any other slots are database-specific getXXXbyYYY routines; the frontend
195 195 * specifies a slot-number to nss_search().
196 196 *
197 197 * The functions take two arguments:
198 198 * - a pointer to the backend instance (like a C++ "this" pointer)
199 199 * - a single (void *) pointer to the database-specific argument/result
200 200 * structure (the contents are opaque to the switch engine).
201 201 * The four well-known functions ignore the (void *) pointer.
202 202 *
203 203 * Backend routines return the following status codes to the switch engine:
204 204 *
205 205 * SUCCESS, UNAVAIL, NOTFOUND, TRYAGAIN (these are the same codes that may
206 206 * be specified in the config information; see nsswitch.conf(4))
207 207 *
208 208 * The remaining conditions/errors are internally generated and if
209 209 * necessary are translated, as to one of the above external errors,
210 210 * usually NOTFOUND or UNAVAIL.
211 211 *
212 212 * NSS_NISSERVDNS_TRYAGAIN (should only be used by the NIS backend for
213 213 * NIS server in DNS forwarding mode to indicate DNS server non-response).
214 214 *
215 215 * The policy component may return NSS_TRYLOCAL which signifies that nscd
216 216 * is not going to process the request, and it should be performed locally.
217 217 *
218 218 * NSS_ERROR is a catchall for internal error conditions, errno will be set
219 219 * to a system <errno.h> error that can help track down the problem if
220 220 * it is persistent. This error is the result of some internal error
221 221 * condition and should not be seen during or exposed to aan application.
222 222 * The error may be from the application side switch component or from the
223 223 * nscd side switch component.
224 224 *
225 225 * NSS_ALTRETRY and NSS_ALTRESET are internal codes used by the application
226 226 * side policy component and nscd to direct the policy component to
227 227 * communicate to a per-user nscd if/when per-user authentication is enabled.
228 228 *
229 229 * NSS_NSCD_PRIV is a catchall for internal nscd errors or status
230 230 * conditions. This return code is not visible to applications. nscd
231 231 * may use this as a status flag and maintain additional error or status
232 232 * information elsewhere in other private nscd data. This status value
233 233 * is for nscd private/internal use only.
234 234 */
235 235
236 236 typedef enum {
237 237 NSS_SUCCESS = 0,
238 238 NSS_NOTFOUND = 1,
239 239 NSS_UNAVAIL = 2,
240 240 NSS_TRYAGAIN = 3,
↓ open down ↓ |
192 lines elided |
↑ open up ↑ |
241 241 NSS_NISSERVDNS_TRYAGAIN = 4,
242 242 NSS_TRYLOCAL = 5,
243 243 NSS_ERROR = 6,
244 244 NSS_ALTRETRY = 7,
245 245 NSS_ALTRESET = 8,
246 246 NSS_NSCD_PRIV = 9
247 247 } nss_status_t;
248 248
249 249 struct nss_backend;
250 250
251 -#if defined(__STDC__)
252 251 typedef nss_status_t (*nss_backend_op_t)(struct nss_backend *, void *args);
253 -#else
254 -typedef nss_status_t (*nss_backend_op_t)();
255 -#endif
256 252
257 253 struct nss_backend {
258 254 nss_backend_op_t *ops;
259 255 int n_ops;
260 256 };
261 257 typedef struct nss_backend nss_backend_t;
262 258 typedef int nss_dbop_t;
263 259
264 260 #define NSS_DBOP_DESTRUCTOR 0
265 261 #define NSS_DBOP_ENDENT 1
266 262 #define NSS_DBOP_SETENT 2
267 263 #define NSS_DBOP_GETENT 3
268 264 #define NSS_DBOP_next_iter (NSS_DBOP_GETENT + 1)
269 265 #define NSS_DBOP_next_noiter (NSS_DBOP_DESTRUCTOR + 1)
270 266 #define NSS_DBOP_next_ipv6_iter (NSS_DBOP_GETENT + 3)
271 267
272 268 #define NSS_LOOKUP_DBOP(instp, n) \
273 269 (((n) >= 0 && (n) < (instp)->n_ops) ? (instp)->ops[n] : 0)
274 270
275 271 #define NSS_INVOKE_DBOP(instp, n, argp) (\
276 272 ((n) >= 0 && (n) < (instp)->n_ops && (instp)->ops[n] != 0) \
277 273 ? (*(instp)->ops[n])(instp, argp) \
278 274 : NSS_UNAVAIL)
279 275
280 276 /*
281 277 * Locating and instantiating backends
282 278 * -----------------------------------
283 279 *
284 280 * To perform step (a), the switch consults a list of backend-finder routines,
285 281 * passing a <database, source> pair.
286 282 *
287 283 * There is a standard backend-finder; frontends may augment or replace this
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
288 284 * in order to, say, indicate that some backends are "compiled in" with the
289 285 * frontend.
290 286 *
291 287 * Backend-finders return a pointer to a constructor function for the backend.
292 288 * (or NULL if they can't find the backend). The switch engine caches these
293 289 * function pointers; when it needs to perform step (b), it calls the
294 290 * constructor function, which returns a pointer to a new instance of the
295 291 * backend, properly initialized (or returns NULL).
296 292 */
297 293
298 -#if defined(__STDC__)
299 294 typedef nss_backend_t *(*nss_backend_constr_t)(const char *db_name,
300 295 const char *src_name,
301 296 /* Hook for (unimplemented) args in nsswitch.conf */ const char *cfg_args);
302 -#else
303 -typedef nss_backend_t *(*nss_backend_constr_t)();
304 -#endif
305 297
306 298 struct nss_backend_finder {
307 -#if defined(__STDC__)
308 299 nss_backend_constr_t (*lookup)
309 300 (void *lkp_priv, const char *, const char *, void **del_privp);
310 301 void (*delete)
311 302 (void *del_priv, nss_backend_constr_t);
312 -#else
313 - nss_backend_constr_t (*lookup)();
314 - void (*delete)();
315 -#endif
316 303 struct nss_backend_finder *next;
317 304 void *lookup_priv;
318 305 };
319 306
320 307 typedef struct nss_backend_finder nss_backend_finder_t;
321 308
322 309 extern nss_backend_finder_t *nss_default_finders;
323 310
324 311 /*
325 312 * Frontend parameters
326 313 * -------------------
327 314 *
328 315 * The frontend must tell the switch engine:
329 316 * - the database name,
330 317 * - the compiled-in default configuration entry.
331 318 * It may also override default values for:
332 319 * - the database name to use when looking up the configuration
333 320 * information (e.g. "shadow" uses the config entry for "passwd"),
334 321 * - a limit on the number of instances of each backend that are
335 322 * simultaneously active,
336 323 * - a limit on the number of instances of each backend that are
337 324 * simultaneously dormant (waiting for new requests),
338 325 * - a flag that tells the switch engine to use the default configuration
339 326 * entry and ignore any other config entry for this database,
340 327 * - backend-finders (see above)
341 328 * - a cleanup routine that should be called when these parameters are
342 329 * about to be deleted.
343 330 *
344 331 * In order to do this, the frontend includes a pointer to an initialization
345 332 * function (nss_db_initf_t) in every nss_*() call. When necessary (normally
346 333 * just on the first invocation), the switch engine allocates a parameter
347 334 * structure (nss_db_params_t), fills in the default values, then calls
348 335 * the initialization function, which should update the parameter structure
349 336 * as necessary.
350 337 *
351 338 * (This might look more natural if we put nss_db_initf_t in nss_db_root_t,
352 339 * or abolished nss_db_initf_t and put nss_db_params_t in nss_db_root_t.
353 340 * It's done the way it is for shared-library efficiency, namely:
354 341 * - keep the unshared data (nss_db_root_t) to a minimum,
355 342 * - keep the symbol lookups and relocations to a minimum.
356 343 * In particular this means that non-null pointers, e.g. strings and
357 344 * function pointers, in global data are a bad thing).
358 345 */
359 346
360 347 enum nss_dbp_flags {
361 348 NSS_USE_DEFAULT_CONFIG = 0x1
362 349 };
363 350
364 351 struct nss_db_params {
365 352 const char *name; /* Mandatory: database name */
366 353 const char *config_name; /* config-file database name */
367 354 const char *default_config; /* Mandatory: default config */
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
368 355 unsigned max_active_per_src;
369 356 unsigned max_dormant_per_src;
370 357 enum nss_dbp_flags flags;
371 358 nss_backend_finder_t *finders;
372 359 void *private; /* Not used by switch */
373 360 void (*cleanup)(struct nss_db_params *);
374 361 };
375 362
376 363 typedef struct nss_db_params nss_db_params_t;
377 364
378 -#if defined(__STDC__)
379 365 typedef void (*nss_db_initf_t)(nss_db_params_t *);
380 -#else
381 -typedef void (*nss_db_initf_t)();
382 -#endif
383 366
384 367 /*
385 368 * DBD param offsets in NSS2 nscd header.
386 369 * Offsets are relative to beginning of dbd section.
387 370 * 32 bit offsets should be sufficient, forever.
388 371 * 0 offset == NULL
389 372 * flags == nss_dbp_flags
390 373 */
391 374 typedef struct nss_dbd {
392 375 uint32_t o_name;
393 376 uint32_t o_config_name;
394 377 uint32_t o_default_config;
395 378 uint32_t flags;
396 379 } nss_dbd_t;
397 380
398 381 /*
399 382 * These structures are defined inside the implementation of the switch
400 383 * engine; the interface just holds pointers to them.
401 384 */
402 385 struct nss_db_state;
403 386 struct nss_getent_context;
404 387
405 388 /*
406 389 * Finally, the two handles that frontends hold:
407 390 */
408 391
409 392 struct nss_db_root {
410 393 struct nss_db_state *s;
411 394 mutex_t lock;
412 395 };
413 396 typedef struct nss_db_root nss_db_root_t;
414 397 #define NSS_DB_ROOT_INIT { 0, DEFAULTMUTEX }
415 398 #define DEFINE_NSS_DB_ROOT(name) nss_db_root_t name = NSS_DB_ROOT_INIT
416 399
417 400
418 401 typedef struct {
419 402 struct nss_getent_context *ctx;
420 403 mutex_t lock;
421 404 } nss_getent_t;
422 405
423 406 #define NSS_GETENT_INIT { 0, DEFAULTMUTEX }
424 407 #define DEFINE_NSS_GETENT(name) nss_getent_t name = NSS_GETENT_INIT
425 408
426 409 /*
427 410 * Policy Engine Configuration
428 411 * ---------------------------
429 412 *
430 413 * When nscd is running it can reconfigure it's internal policy engine
431 414 * as well as advise an application's front-end and policy engine on how
432 415 * respond optimally to results being returned from nscd. This is done
433 416 * through the policy engine configuration interface.
434 417 */
435 418
436 419 typedef enum {
437 420 NSS_CONFIG_GET,
438 421 NSS_CONFIG_PUT,
439 422 NSS_CONFIG_ADD,
440 423 NSS_CONFIG_DELETE,
441 424 NSS_CONFIG_LIST
442 425 } nss_config_op_t;
443 426
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
444 427 struct nss_config {
445 428 char *name;
446 429 nss_config_op_t cop;
447 430 mutex_t *lock;
448 431 void *buffer;
449 432 size_t length;
450 433 };
451 434 typedef struct nss_config nss_config_t;
452 435
453 436
454 -#if defined(__STDC__)
455 437 extern nss_status_t nss_config(nss_config_t **, int);
456 438
457 439 extern nss_status_t nss_search(nss_db_root_t *, nss_db_initf_t,
458 440 int search_fnum, void *search_args);
459 441 extern nss_status_t nss_getent(nss_db_root_t *, nss_db_initf_t, nss_getent_t *,
460 442 void *getent_args);
461 443 extern void nss_setent(nss_db_root_t *, nss_db_initf_t, nss_getent_t *);
462 444 extern void nss_endent(nss_db_root_t *, nss_db_initf_t, nss_getent_t *);
463 445 extern void nss_delete(nss_db_root_t *);
464 446
465 447 extern nss_status_t nss_pack(void *, size_t, nss_db_root_t *,
466 448 nss_db_initf_t, int, void *);
467 449 extern nss_status_t nss_pack_ent(void *, size_t, nss_db_root_t *,
468 450 nss_db_initf_t, nss_getent_t *);
469 451 extern nss_status_t nss_unpack(void *, size_t, nss_db_root_t *,
470 452 nss_db_initf_t, int, void *);
471 453 extern nss_status_t nss_unpack_ent(void *, size_t, nss_db_root_t *,
472 454 nss_db_initf_t, nss_getent_t *, void *);
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
473 455
474 456 extern nss_status_t _nsc_search(nss_db_root_t *, nss_db_initf_t,
475 457 int search_fnum, void *search_args);
476 458 extern nss_status_t _nsc_getent_u(nss_db_root_t *, nss_db_initf_t,
477 459 nss_getent_t *, void *getent_args);
478 460 extern nss_status_t _nsc_setent_u(nss_db_root_t *, nss_db_initf_t,
479 461 nss_getent_t *);
480 462 extern nss_status_t _nsc_endent_u(nss_db_root_t *, nss_db_initf_t,
481 463 nss_getent_t *);
482 464
483 -#else
484 -extern nss_status_t nss_config();
485 465
486 -extern nss_status_t nss_search();
487 -extern nss_status_t nss_getent();
488 -extern void nss_setent();
489 -extern void nss_endent();
490 -extern void nss_delete();
491 -
492 -extern int nss_pack();
493 -extern int nss_pack_ent();
494 -extern int nss_unpack();
495 -extern int nss_unpack_ent();
496 -
497 -extern nss_status_t _nsc_search();
498 -extern nss_status_t _nsc_getent_u();
499 -extern nss_status_t _nsc_setent_u();
500 -extern nss_status_t _nsc_endent_u();
501 -#endif
502 -
503 466 #ifdef __cplusplus
504 467 }
505 468 #endif
506 469
507 470 #endif /* _NSS_COMMON_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX