1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Database-specific definitions for the getXXXbyYYY routines
* (e.g getpwuid_r(), ether_ntohost()) that use the name-service switch.
* Database-independent definitions are in <nss_common.h>
*
* Ideally, this is the only switch header file one would add things
* to in order to support a new database.
*
* NOTE: The interfaces documented in this file may change in a minor
* release. It is intended that in the future a stronger committment
* will be made to these interface definitions which will guarantee
* them across minor releases.
*/
#ifndef _NSS_DBDEFS_H
#define _NSS_DBDEFS_H
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h> /* MAXALIASES, MAXADDRS */
#include <limits.h> /* LOGNAME_MAX */
#include <nss_common.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef NSS_INCLUDE_UNSAFE
#define NSS_INCLUDE_UNSAFE 1 /* Build old, MT-unsafe interfaces, */
#endif /* NSS_INCLUDE_UNSAFE */ /* e.g. getpwnam (c.f. getpwnam_r) */
/*
* Names of the well-known databases.
*/
#define NSS_DBNAM_ALIASES "aliases" /* E-mail aliases, that is */
#define NSS_DBNAM_AUTOMOUNT "automount"
#define NSS_DBNAM_BOOTPARAMS "bootparams"
#define NSS_DBNAM_ETHERS "ethers"
#define NSS_DBNAM_GROUP "group"
#define NSS_DBNAM_HOSTS "hosts"
#define NSS_DBNAM_IPNODES "ipnodes"
#define NSS_DBNAM_NETGROUP "netgroup"
#define NSS_DBNAM_NETMASKS "netmasks"
#define NSS_DBNAM_NETWORKS "networks"
#define NSS_DBNAM_PASSWD "passwd"
#define NSS_DBNAM_PRINTERS "printers"
#define NSS_DBNAM_PROJECT "project"
#define NSS_DBNAM_PROTOCOLS "protocols"
#define NSS_DBNAM_PUBLICKEY "publickey"
#define NSS_DBNAM_RPC "rpc"
#define NSS_DBNAM_SERVICES "services"
#define NSS_DBNAM_AUDITUSER "audit_user"
#define NSS_DBNAM_AUTHATTR "auth_attr"
#define NSS_DBNAM_EXECATTR "exec_attr"
#define NSS_DBNAM_PROFATTR "prof_attr"
#define NSS_DBNAM_USERATTR "user_attr"
#define NSS_DBNAM_TSOL_TP "tnrhtp"
#define NSS_DBNAM_TSOL_RH "tnrhdb"
#define NSS_DBNAM_TSOL_ZC "tnzonecfg"
/* getspnam() et al use the "passwd" config entry but the "shadow" backend */
#define NSS_DBNAM_SHADOW "shadow"
/* The "compat" backend gets config entries for these pseudo-databases */
#define NSS_DBNAM_PASSWD_COMPAT "passwd_compat"
#define NSS_DBNAM_GROUP_COMPAT "group_compat"
/*
* Default switch configuration, compiled into the front-ends.
*
* Absent good reasons to the contrary, this should be compatible with the
* default /etc/nsswitch.conf file.
*/
#define NSS_FILES_ONLY "files"
#define NSS_FILES_NS "files nis"
#define NSS_NS_FALLBACK "nis [NOTFOUND=return] files"
#define NSS_NS_ONLY "nis"
#define NSS_TSOL_FALLBACK "files ldap"
#define NSS_DEFCONF_ALIASES NSS_FILES_NS
#define NSS_DEFCONF_AUTOMOUNT NSS_FILES_NS
#define NSS_DEFCONF_BOOTPARAMS NSS_NS_FALLBACK
#define NSS_DEFCONF_ETHERS NSS_NS_FALLBACK
#define NSS_DEFCONF_GROUP NSS_FILES_NS
#define NSS_DEFCONF_HOSTS NSS_NS_FALLBACK
#define NSS_DEFCONF_IPNODES NSS_NS_FALLBACK
#define NSS_DEFCONF_NETGROUP NSS_NS_ONLY
#define NSS_DEFCONF_NETMASKS NSS_NS_FALLBACK
#define NSS_DEFCONF_NETWORKS NSS_NS_FALLBACK
#define NSS_DEFCONF_PASSWD NSS_FILES_NS
#define NSS_DEFCONF_PRINTERS "user files nis"
#define NSS_DEFCONF_PROJECT NSS_FILES_NS
#define NSS_DEFCONF_PROTOCOLS NSS_NS_FALLBACK
#define NSS_DEFCONF_PUBLICKEY NSS_FILES_NS
#define NSS_DEFCONF_RPC NSS_NS_FALLBACK
#define NSS_DEFCONF_SERVICES NSS_FILES_NS /* speeds up byname() */
#define NSS_DEFCONF_GROUP_COMPAT NSS_NS_ONLY
#define NSS_DEFCONF_PASSWD_COMPAT NSS_NS_ONLY
#define NSS_DEFCONF_ATTRDB NSS_FILES_NS
#define NSS_DEFCONF_AUDITUSER NSS_DEFCONF_PASSWD
#define NSS_DEFCONF_USERATTR NSS_DEFCONF_PASSWD
#define NSS_DEFCONF_AUTHATTR NSS_DEFCONF_ATTRDB
#define NSS_DEFCONF_PROFATTR NSS_DEFCONF_ATTRDB
#define NSS_DEFCONF_EXECATTR NSS_DEFCONF_PROFATTR
#define NSS_DEFCONF_TSOL_TP NSS_TSOL_FALLBACK
#define NSS_DEFCONF_TSOL_RH NSS_TSOL_FALLBACK
#define NSS_DEFCONF_TSOL_ZC NSS_TSOL_FALLBACK
/*
* Line-lengths that the "files" and "compat" backends will try to support.
* It may be reasonable (even advisable) to use smaller values than these.
*/
#define NSS_BUFSIZ 1024
#define NSS_LINELEN_GROUP ((NSS_BUFSIZ) * 8)
#define NSS_LINELEN_HOSTS ((NSS_BUFSIZ) * 8)
#define NSS_LINELEN_IPNODES ((NSS_BUFSIZ) * 8)
#define NSS_LINELEN_NETMASKS NSS_BUFSIZ
#define NSS_LINELEN_NETWORKS NSS_BUFSIZ
#define NSS_LINELEN_PASSWD NSS_BUFSIZ
#define NSS_LINELEN_PRINTERS NSS_BUFSIZ
#define NSS_LINELEN_PROJECT ((NSS_BUFSIZ) * 4)
#define NSS_LINELEN_PROTOCOLS NSS_BUFSIZ
#define NSS_LINELEN_PUBLICKEY NSS_BUFSIZ
#define NSS_LINELEN_RPC NSS_BUFSIZ
#define NSS_LINELEN_SERVICES NSS_BUFSIZ
#define NSS_LINELEN_SHADOW NSS_BUFSIZ
#define NSS_LINELEN_ETHERS NSS_BUFSIZ
#define NSS_LINELEN_BOOTPARAMS NSS_BUFSIZ
#define NSS_LINELEN_ATTRDB NSS_BUFSIZ
#define NSS_LINELEN_AUDITUSER NSS_LINELEN_ATTRDB
#define NSS_LINELEN_AUTHATTR NSS_LINELEN_ATTRDB
#define NSS_LINELEN_EXECATTR NSS_LINELEN_ATTRDB
#define NSS_LINELEN_PROFATTR NSS_LINELEN_ATTRDB
#define NSS_LINELEN_USERATTR NSS_LINELEN_ATTRDB
#define NSS_MMAPLEN_EXECATTR NSS_LINELEN_EXECATTR * 8
#define NSS_LINELEN_TSOL NSS_BUFSIZ
#define NSS_LINELEN_TSOL_TP NSS_LINELEN_TSOL
#define NSS_LINELEN_TSOL_RH NSS_LINELEN_TSOL
#define NSS_LINELEN_TSOL_ZC NSS_LINELEN_TSOL
/*
* Reasonable defaults for 'buflen' values passed to _r functions. The BSD
* and SunOS 4.x implementations of the getXXXbyYYY() functions used hard-
* coded array sizes; the values here are meant to handle anything that
* those implementations handled.
* === These might more reasonably go in <pwd.h>, <netdb.h> et al
*/
#define NSS_BUFLEN_GROUP NSS_LINELEN_GROUP
#define NSS_BUFLEN_HOSTS \
(NSS_LINELEN_HOSTS + (MAXALIASES + MAXADDRS + 2) * sizeof (char *))
#define NSS_BUFLEN_IPNODES \
(NSS_LINELEN_IPNODES + (MAXALIASES + MAXADDRS + 2) * sizeof (char *))
#define NSS_BUFLEN_NETGROUP (MAXHOSTNAMELEN * 2 + LOGNAME_MAX + 3)
#define NSS_BUFLEN_NETWORKS NSS_LINELEN_NETWORKS /* === ? + 35 * 4 */
#define NSS_BUFLEN_PASSWD NSS_LINELEN_PASSWD
#define NSS_BUFLEN_PROJECT (NSS_LINELEN_PROJECT + 800 * sizeof (char *))
#define NSS_BUFLEN_PROTOCOLS NSS_LINELEN_PROTOCOLS /* === ? + 35 * 4 */
#define NSS_BUFLEN_PUBLICKEY NSS_LINELEN_PUBLICKEY
#define NSS_BUFLEN_RPC NSS_LINELEN_RPC /* === ? + 35 * 4 */
#define NSS_BUFLEN_SERVICES NSS_LINELEN_SERVICES /* === ? + 35 * 4 */
#define NSS_BUFLEN_SHADOW NSS_LINELEN_SHADOW
#define NSS_BUFLEN_ETHERS NSS_LINELEN_ETHERS
#define NSS_BUFLEN_BOOTPARAMS NSS_LINELEN_BOOTPARAMS
#define NSS_BUFLEN_ATTRDB NSS_LINELEN_ATTRDB
#define NSS_BUFLEN_AUDITUSER NSS_BUFLEN_ATTRDB
#define NSS_BUFLEN_AUTHATTR NSS_BUFLEN_ATTRDB
#define NSS_BUFLEN_EXECATTR NSS_BUFLEN_ATTRDB
#define NSS_BUFLEN_PROFATTR NSS_BUFLEN_ATTRDB
#define NSS_BUFLEN_USERATTR ((NSS_BUFLEN_ATTRDB) * 8)
#define NSS_BUFLEN_TSOL NSS_LINELEN_TSOL
#define NSS_BUFLEN_TSOL_TP NSS_BUFLEN_TSOL
#define NSS_BUFLEN_TSOL_RH NSS_BUFLEN_TSOL
#define NSS_BUFLEN_TSOL_ZC NSS_BUFLEN_TSOL
/*
* Default cache door buffer size (2x largest buffer)
*/
#define NSS_BUFLEN_DOOR ((NSS_BUFSIZ) * 16)
/*
* Arguments and results, passed between the frontends and backends for
* the well-known databases. The getXbyY_r() and getXent_r() routines
* use a common format that is further described below; other routines
* use their own formats.
*/
/*
* The nss_str2ent_t routine is the data marshaller for the nsswitch.
* it converts 'native files' format into 'entry' format as part of the
* return processing for a getXbyY interface.
*
* The nss_groupstr_t routine does the real work for any backend
* that can supply a netgroup entry as a string in /etc/group format
*/
typedef int (*nss_str2ent_t)(const char *in, int inlen,
void *ent, char *buf, int buflen);
struct nss_groupsbymem; /* forward definition */
typedef nss_status_t (*nss_groupstr_t)(const char *instr, int inlen,
struct nss_groupsbymem *);
/*
* The initgroups() function [see initgroups(3c)] needs to find all the
* groups to which a given user belongs. To do this it calls
* _getgroupsbymember(), which is part of the frontend for the "group"
* database.
* We want the same effect as if we used getgrent_r() to enumerate the
* entire groups database (possibly from multiple sources), but getgrent_r()
* is too inefficient. Most backends can do better if they know they're
* meant to scan all groups; hence there's a separate backend operation,
* NSS_DBOP_GROUP_BYMEMBER, which uses the nss_groupsbymem struct.
* Note that the normal return-value from such a backend, even when it
* successfully finds matching group entries, is NSS_NOTFOUND, because
* this tells the switch engine to keep searching in any more sources.
* In fact, the backends only return NSS_SUCCESS if they find enough
* matching entries that the gid_array is completely filled, in which
* case the switch engine should stop searching.
* If the force_slow_way field is set, the backend should eschew any cached
* information (e.g. the YP netid.byname map or the NIS+ cred.org_dir table)
* and should instead grind its way through the group map/table/whatever.
*/
struct nss_groupsbymem { /* For _getgroupsbymember() */
/* in: */
const char *username;
gid_t *gid_array;
int maxgids;
int force_slow_way;
nss_str2ent_t str2ent;
nss_groupstr_t process_cstr;
/* in_out: */
int numgids;
};
/*
* The netgroup routines are handled as follows:
*
* Policy decision:
* If netgroup A refers to netgroup B, both must occur in the same
* source (other choices give very confusing semantics). This
* assumption is deeply embedded in the frontend and backends.
*
* - setnetgrent(), despite its name, is really a getXXXbyYYY operation:
* it takes a name and finds a netgroup with that name (see the
* nss_setnetgrent_args struct below). The "result" that it returns
* to the frontend is an nss_backend_t for a pseudo-backend that allows
* one to enumerate the members of that netgroup.
*
* - getnetgrent() calls the 'getXXXent' function in the pseudo-backend;
* it doesn't go through the switch engine at all. It uses the
* nss_getnetgrent_args struct below.
*
* - innetgr() is implemented on top of __multi_innetgr(), which replaces
* each (char *) argument of innetgr() with a counted vector of (char *).
* The semantics are the same as an OR of the results of innetgr()
* operations on each possible 4-tuple picked from the arguments, but
* it's possible to implement some cases more efficiently. This is
* important for mountd, which used to read YP netgroup.byhost directly
* in order to determine efficiently whether a given host belonged to any
* one of a long list of netgroups. Wildcarded arguments are indicated
* by a count of zero.
*
* - __multi_innetgr() uses the nss_innetgr_args struct. A backend whose
* source contains at least one of the groups listed in the 'groups'
* vector will return NSS_SUCCESS and will set the 'status' field to
* indicate whether any 4-tuple was satisfied. A backend will only
* return NSS_NOTFOUND if the source contained none of the groups
* listed in the 'groups' vector.
*/
enum nss_netgr_argn { /* We need (machine, user, domain) triples */
NSS_NETGR_MACHINE = 0,
NSS_NETGR_USER = 1,
NSS_NETGR_DOMAIN = 2,
NSS_NETGR_N = 3
};
enum nss_netgr_status { /* Status from setnetgrent, multi_innetgr */
NSS_NETGR_FOUND = 0,
NSS_NETGR_NO = 1,
NSS_NETGR_NOMEM = 2
};
struct nss_setnetgrent_args {
/* in: */
const char *netgroup;
/* out: */
nss_backend_t *iterator; /* <==== Explain */
};
struct nss_getnetgrent_args {
/* in: */
char *buffer;
int buflen;
/* out: */
enum nss_netgr_status status;
char *retp[NSS_NETGR_N];
};
typedef unsigned nss_innetgr_argc; /* 0 means wildcard */
typedef char ** nss_innetgr_argv; /* === Do we really need these? */
struct nss_innetgr_1arg {
nss_innetgr_argc argc;
nss_innetgr_argv argv;
};
struct nss_innetgr_args {
/* in: */
struct nss_innetgr_1arg arg[NSS_NETGR_N];
struct nss_innetgr_1arg groups;
/* out: */
enum nss_netgr_status status;
};
/*
* nss_XbyY_buf_t -- structure containing the generic arguments passwd to
* getXXXbyYYY_r() and getXXXent_r() routines. The (void *) value points to
* a struct of the appropriate type, e.g. struct passwd or struct hostent.
*
* The functions that allocate and free these structures do no locking at
* all, since the routines that use them are inherently MT-unsafe anyway.
*/
typedef struct {
void *result; /* "result" parameter to getXbyY_r() */
char *buffer; /* "buffer" " " */
int buflen; /* "buflen" " " */
} nss_XbyY_buf_t;
extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size);
extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *);
#define NSS_XbyY_ALLOC(bufpp, str_size, buf_size) (\
(*bufpp) == 0 \
? (*bufpp) = _nss_XbyY_buf_alloc(str_size, buf_size) \
: (*bufpp))
#define NSS_XbyY_FREE(bufpp) (_nss_XbyY_buf_free(*bufpp), (*bufpp) = 0)
/*
* The nss_XbyY_args_t struct contains all the information passed between
* frontends and backends for the getXbyY_r() and getXent() routines,
* including an nss_XbyY_buf_t and the lookup key (unused for getXXXent_r).
*
* The (*str2ent)() member converts a single XXXent from ASCII text to the
* appropriate struct, storing any pointer data (strings, in_addrs, arrays
* of these) in the buffer. The ASCII text is a counted string (*not* a
* zero-terminated string) whose length is specified by the instr_len
* parameter. The text is found at the address specified by instr and
* the string is treated as readonly. buffer and instr must be non-
* intersecting memory areas.
*
* With the exception of passwd, shadow and group, the text form for these
* databases allows trailing comments and arbitrary whitespace. The
* corresponding str2ent routine assumes that comments, leading whitespace
* and trailing whitespace have been stripped (and thus assumes that entries
* consisting only of these have been discarded).
*
* The text entries for "rpc" and for the databases described in <netdb.h>
* follow a common format (a canonical name with a possibly empty list
* of aliases, and some other value), albeit with minor variations.
* The function _nss_netdb_aliases() does most of the generic work involved
* in parsing and marshalling these into the buffer.
*/
typedef union nss_XbyY_key { /* No tag; backend should know what to expect */
uid_t uid;
gid_t gid;
projid_t projid;
const char *name;
int number;
struct {
int net;
int type;
} netaddr;
struct {
const char *addr;
int len;
int type;
} hostaddr;
struct {
union {
const char *name;
int port;
} serv;
const char *proto;
} serv;
void *ether;
struct {
const char *name;
const char *keytype;
} pkey;
struct {
const char *name;
int af_family;
int flags;
} ipnode;
void *attrp; /* for the new attr databases */
} nss_XbyY_key_t;
typedef int (*nss_key2str_t)(void *buffer, size_t buflen,
nss_XbyY_key_t *key, size_t *len);
typedef struct nss_XbyY_args {
/* IN */
nss_XbyY_buf_t buf;
int stayopen;
/*
* Support for setXXXent(stayopen)
* Used only in hosts, protocols,
* networks, rpc, and services.
*/
nss_str2ent_t str2ent;
union nss_XbyY_key key;
/* OUT */
void *returnval;
int erange;
int h_errno; /* For gethost*_r() */
nss_status_t status; /* from the backend last called */
/* NSS2 */
nss_key2str_t key2str; /* IN */
size_t returnlen; /* OUT */
/* NSCD/DOOR data */
/* ... buffer arena follows... */
} nss_XbyY_args_t;
/*
* nss/nscd v2 interface, packed buffer format
*
* A key component of the v2 name service switch is the redirection
* of all activity to nscd for actual processing. In the original
* switch most activity took place in each application, and the nscd
* cache component was an add-on optional interface.
*
* The nscd v1 format was a completely private interface that
* implemented specific bufferiing formats on a per getXbyY API basis.
*
* The nss/nscd v2 interface uses a common header and commonalizes
* the buffering format as consistently as possible. The general rule
* of thumb is that backends are required to assemble their results in
* "files based" format [IE the format used on a per result basis as
* returned by the files backend] and then call the standard str2ent
* interface. This is the original intended design as used in the files
* and nis backends.
*
* The benefit of this is that the application side library can assemble
* a request and provide a header and a variable length result buffer via
* a doors API, and then the nscd side switch can assemble a a getXbyY
* request providing the result buffer and a str2ent function that copies
* but does not unpack the result.
*
* This results is returned back via the door, and unpacked using the
* native library side str2ent interface.
*
* Additionally, the common header allows extensibility to add new
* getXbyYs, putXbyYs or other maintenance APIs to/from nscd without
* changing the existing "old style" backend interfaces.
*
* Finally new style getXbyY, putXbyY and backend interfaces can be
* by adding new operation requests to the header, while old style
* backwards compatability.
*/
/*
* nss/nscd v2 callnumber definitions
*/
/*
* callnumbers are separated by categories, such as:
* application to nscd requests, nscd to nscd requests,
* smf to nscd requests, etc.
*/
#define NSCDV2CATMASK (0xFF000000)
#define NSCDV2CALLMASK (0x00FFFFFF)
/*
* nss/nscd v2 categories
*/
#define NSCD_CALLCAT_APP ('a'<<24)
#define NSCD_CALLCAT_N2N ('n'<<24)
/* nscd v2 app-> nscd callnumbers */
#define NSCD_SEARCH (NSCD_CALLCAT_APP|0x01)
#define NSCD_SETENT (NSCD_CALLCAT_APP|0x02)
#define NSCD_GETENT (NSCD_CALLCAT_APP|0x03)
#define NSCD_ENDENT (NSCD_CALLCAT_APP|0x04)
#define NSCD_PUT (NSCD_CALLCAT_APP|0x05)
#define NSCD_GETHINTS (NSCD_CALLCAT_APP|0x06)
/* nscd v2 SETENT cookie markers */
#define NSCD_NEW_COOKIE 0
#define NSCD_LOCAL_COOKIE 1
/* nscd v2 header revision */
/* treated as 0xMMMMmmmm MMMM - Major Rev, mmmm - Minor Rev */
#define NSCD_HEADER_REV 0x00020000
/*
* ptr/uint data type used to calculate shared nscd buffer struct sizes
* sizes/offsets are arbitrarily limited to 32 bits for 32/64 compatibility
* datatype is 64 bits for possible pointer storage and future use
*/
typedef uint64_t nssuint_t;
/*
* nscd v2 buffer layout overview
*
* The key interface to nscd moving forward is the doors interface
* between applications and nscd (NSCD_CALLCAT_APP), and nscd and
* it's children (NSCD_CALLCAT_N2N).
*
* Regardless of the interface used, the buffer layout is consistent.
* The General Layout is:
* [nss_pheader_t][IN key][OUT data results]{extend results}
*
* The header (nss_pheader_t) remains constant.
* Keys and key layouts vary between call numbers/requests
* NSCD_CALLCAT_APP use key layouts mimics/defines in nss_dbdefs.h
* NSCD_CALLCAT_NSN use layouts defined by nscd headers
* Data and data results vary between results
* NSCD_CALLCAT_APP return "file standard format" output buffers
* NSCD_CALLCAT_NSN return data defined by nscd headers
* extended results are optional and vary
*
*/
/*
* nss_pheader_t -- buffer header structure that contains switch data
* "packed" by the client into a buffer suitable for transport over
* nscd's door, and that can be unpacked into a native form within
* nscd's switch. Capable of packing and unpacking data ans results.
*
* NSCD_HEADER_REV: 0x00020000 16 x uint64 = (128 byte header)
*/
typedef struct {
uint32_t nsc_callnumber; /* packed buffer request */
uint32_t nss_dbop; /* old nss dbop */
uint32_t p_ruid; /* real uid */
uint32_t p_euid; /* effective uid */
uint32_t p_version; /* 0xMMMMmmmm Major/minor */
uint32_t p_status; /* nss_status_t */
uint32_t p_errno; /* errno */
uint32_t p_herrno; /* h_errno */
nssuint_t libpriv; /* reserved (for lib/client) */
nssuint_t pbufsiz; /* buffer size */
nssuint_t dbd_off; /* IN: db desc off */
nssuint_t dbd_len; /* IN: db desc len */
nssuint_t key_off; /* IN: key off */
nssuint_t key_len; /* IN: key len */
nssuint_t data_off; /* OUT: data off */
nssuint_t data_len; /* OUT: data len */
nssuint_t ext_off; /* OUT: extended results off */
nssuint_t ext_len; /* OUT: extended results len */
nssuint_t nscdpriv; /* reserved (for nscd) */
nssuint_t reserved1; /* reserved (TBD) */
} nss_pheader_t;
/*
* nss_pnetgr_t -- packed offset structure for holding keys used
* by innetgr (__multi_innetgr) key
* Key format is:
* nss_pnetgr_t
* (nssuint_t)[machine_argc] offsets to strings
* (nssuint_t)[user_argc] offsets to strings
* (nssuint_t)[domain_argc] offsets to strings
* (nssuint_t)[groups_argc] offsets to strings
* machine,user,domain,groups strings
*/
typedef struct {
uint32_t machine_argc;
uint32_t user_argc;
uint32_t domain_argc;
uint32_t groups_argc;
nssuint_t machine_offv;
nssuint_t user_offv;
nssuint_t domain_offv;
nssuint_t groups_offv;
} nss_pnetgr_t;
/* status returned by the str2ent parsing routines */
#define NSS_STR_PARSE_SUCCESS 0
#define NSS_STR_PARSE_PARSE 1
#define NSS_STR_PARSE_ERANGE 2
#define NSS_XbyY_INIT(str, res, bufp, len, func) (\
(str)->buf.result = (res), \
(str)->buf.buffer = (bufp), \
(str)->buf.buflen = (len), \
(str)->stayopen = 0, \
(str)->str2ent = (func), \
(str)->key2str = NULL, \
(str)->returnval = 0, \
(str)->returnlen = 0, \
(str)->h_errno = 0, \
(str)->erange = 0)
#define NSS_XbyY_INIT_EXT(str, res, bufp, len, func, kfunc) (\
(str)->buf.result = (res), \
(str)->buf.buffer = (bufp), \
(str)->buf.buflen = (len), \
(str)->stayopen = 0, \
(str)->str2ent = (func), \
(str)->key2str = (kfunc), \
(str)->returnval = 0, \
(str)->returnlen = 0, \
(str)->h_errno = 0, \
(str)->erange = 0)
#define NSS_XbyY_FINI(str) (\
(str)->returnval == 0 && (str)->erange && (errno = ERANGE), \
(str)->returnval)
#define NSS_PACKED_CRED_CHECK(buf, ruid, euid) (\
((nss_pheader_t *)(buf))->p_ruid == (ruid) && \
((nss_pheader_t *)(buf))->p_euid == (euid))
extern char **_nss_netdb_aliases(const char *, int, char *, int);
extern nss_status_t nss_default_key2str(void *, size_t, nss_XbyY_args_t *,
const char *, int, size_t *);
extern nss_status_t nss_packed_arg_init(void *, size_t, nss_db_root_t *,
nss_db_initf_t *, int *,
nss_XbyY_args_t *);
extern nss_status_t nss_packed_context_init(void *, size_t, nss_db_root_t *,
nss_db_initf_t *, nss_getent_t **,
nss_XbyY_args_t *);
extern void nss_packed_set_status(void *, size_t, nss_status_t,
nss_XbyY_args_t *);
extern nss_status_t nss_packed_getkey(void *, size_t, char **, int *,
nss_XbyY_args_t *);
/*
* nss_dbop_t values for searches with various keys; values for
* destructor/endent/setent/getent are defined in <nss_common.h>
*/
/*
* These are part of the "Over the wire" IE app->nscd getXbyY
* op for well known getXbyY's. Cannot use NSS_DBOP_X_Y directly
* because NSS_DBOP_next_iter is NOT an incrementing counter value
* it's a starting offset into an array value.
*/
#define NSS_DBOP_X(x) ((x)<<16)
#define NSS_DBOP_XY(x, y) ((x)|(y))
#define NSS_DBOP_ALIASES NSS_DBOP_X(1)
#define NSS_DBOP_AUTOMOUNT NSS_DBOP_X(2)
#define NSS_DBOP_BOOTPARAMS NSS_DBOP_X(3)
#define NSS_DBOP_ETHERS NSS_DBOP_X(4)
#define NSS_DBOP_GROUP NSS_DBOP_X(5)
#define NSS_DBOP_HOSTS NSS_DBOP_X(6)
#define NSS_DBOP_IPNODES NSS_DBOP_X(7)
#define NSS_DBOP_NETGROUP NSS_DBOP_X(8)
#define NSS_DBOP_NETMASKS NSS_DBOP_X(9)
#define NSS_DBOP_NETWORKS NSS_DBOP_X(10)
#define NSS_DBOP_PASSWD NSS_DBOP_X(11)
#define NSS_DBOP_PRINTERS NSS_DBOP_X(12)
#define NSS_DBOP_PROJECT NSS_DBOP_X(13)
#define NSS_DBOP_PROTOCOLS NSS_DBOP_X(14)
#define NSS_DBOP_PUBLICKEY NSS_DBOP_X(15)
#define NSS_DBOP_RPC NSS_DBOP_X(16)
#define NSS_DBOP_SERVICES NSS_DBOP_X(17)
#define NSS_DBOP_AUDITUSER NSS_DBOP_X(18)
#define NSS_DBOP_AUTHATTR NSS_DBOP_X(19)
#define NSS_DBOP_EXECATTR NSS_DBOP_X(20)
#define NSS_DBOP_PROFATTR NSS_DBOP_X(21)
#define NSS_DBOP_USERATTR NSS_DBOP_X(22)
#define NSS_DBOP_GROUP_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_GROUP_BYGID (NSS_DBOP_GROUP_BYNAME + 1)
#define NSS_DBOP_GROUP_BYMEMBER (NSS_DBOP_GROUP_BYGID + 1)
#define NSS_DBOP_PASSWD_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_PASSWD_BYUID (NSS_DBOP_PASSWD_BYNAME + 1)
/* The "compat" backend requires that PASSWD_BYNAME == SHADOW_BYNAME */
/* (it also requires that both use key.name to pass the username). */
#define NSS_DBOP_SHADOW_BYNAME (NSS_DBOP_PASSWD_BYNAME)
#define NSS_DBOP_PROJECT_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_PROJECT_BYID (NSS_DBOP_PROJECT_BYNAME + 1)
#define NSS_DBOP_HOSTS_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_HOSTS_BYADDR (NSS_DBOP_HOSTS_BYNAME + 1)
#define NSS_DBOP_IPNODES_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_IPNODES_BYADDR (NSS_DBOP_IPNODES_BYNAME + 1)
/*
* NSS_DBOP_NAME_2ADDR
* NSS_DBOP_ADDR_2NAME
* : are defines for ipv6 api's
*/
#define NSS_DBOP_NAME_2ADDR (NSS_DBOP_next_ipv6_iter)
#define NSS_DBOP_ADDR_2NAME (NSS_DBOP_NAME_2ADDR + 1)
#define NSS_DBOP_RPC_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_RPC_BYNUMBER (NSS_DBOP_RPC_BYNAME + 1)
#define NSS_DBOP_NETWORKS_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_NETWORKS_BYADDR (NSS_DBOP_NETWORKS_BYNAME + 1)
#define NSS_DBOP_SERVICES_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_SERVICES_BYPORT (NSS_DBOP_SERVICES_BYNAME + 1)
#define NSS_DBOP_PROTOCOLS_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_PROTOCOLS_BYNUMBER (NSS_DBOP_PROTOCOLS_BYNAME + 1)
#define NSS_DBOP_ETHERS_HOSTTON (NSS_DBOP_next_noiter)
#define NSS_DBOP_ETHERS_NTOHOST (NSS_DBOP_ETHERS_HOSTTON + 1)
#define NSS_DBOP_BOOTPARAMS_BYNAME (NSS_DBOP_next_noiter)
#define NSS_DBOP_NETMASKS_BYNET (NSS_DBOP_next_noiter)
#define NSS_DBOP_PRINTERS_BYNAME (NSS_DBOP_next_iter)
/*
* The "real" backend for netgroup (__multi_innetgr, setnetgrent)
*/
#define NSS_DBOP_NETGROUP_IN (NSS_DBOP_next_iter)
#define NSS_DBOP_NETGROUP_SET (NSS_DBOP_NETGROUP_IN + 1)
/*
* The backend for getpublickey and getsecretkey (getkeys)
*/
#define NSS_DBOP_KEYS_BYNAME (NSS_DBOP_next_iter)
/*
* The pseudo-backend for netgroup (returned by setnetgrent) doesn't have
* any getXXXbyYYY operations, just the usual destr/end/set/get ops,
* so needs no definitions here.
*/
#define NSS_DBOP_ATTRDB_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_AUDITUSER_BYNAME NSS_DBOP_ATTRDB_BYNAME
#define NSS_DBOP_AUTHATTR_BYNAME NSS_DBOP_ATTRDB_BYNAME
#define NSS_DBOP_EXECATTR_BYNAME NSS_DBOP_ATTRDB_BYNAME
#define NSS_DBOP_EXECATTR_BYID (NSS_DBOP_EXECATTR_BYNAME + 1)
#define NSS_DBOP_EXECATTR_BYNAMEID (NSS_DBOP_EXECATTR_BYID + 1)
#define NSS_DBOP_PROFATTR_BYNAME NSS_DBOP_ATTRDB_BYNAME
#define NSS_DBOP_USERATTR_BYNAME NSS_DBOP_ATTRDB_BYNAME
#define NSS_DBOP_TSOL_TP_BYNAME (NSS_DBOP_next_iter)
#define NSS_DBOP_TSOL_RH_BYADDR (NSS_DBOP_next_iter)
#define NSS_DBOP_TSOL_ZC_BYNAME (NSS_DBOP_next_iter)
/*
* Used all over in the switch code. The best home for it I can think of.
* Power-of-two alignments only.
*/
#define ROUND_DOWN(n, align) (((uintptr_t)n) & ~((align) - 1l))
#define ROUND_UP(n, align) ROUND_DOWN(((uintptr_t)n) + (align) - 1l, \
(align))
#ifdef __cplusplus
}
#endif
#endif /* _NSS_DBDEFS_H */
|