1 /* $NetBSD: getgrent.c,v 1.61 2007/02/03 16:12:47 christos Exp $ */
4 * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1989, 1993
34 * The Regents of the University of California. All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions
67 * 1. Redistributions of source code must retain the above copyright
68 * notice, this list of conditions and the following disclaimer.
69 * 2. Redistributions in binary form must reproduce the above copyright
70 * notice, this list of conditions and the following disclaimer in the
71 * documentation and/or other materials provided with the distribution.
73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
74 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
75 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
76 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
77 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
78 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
79 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
80 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
86 #include <sys/cdefs.h>
87 #if defined(LIBC_SCCS) && !defined(lint)
89 static char sccsid
[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
91 __RCSID("$NetBSD: getgrent.c,v 1.61 2007/02/03 16:12:47 christos Exp $");
93 #endif /* LIBC_SCCS and not lint */
95 #include "namespace.h"
96 #include "reentrant.h"
98 #include <sys/param.h>
104 #include <nsswitch.h>
117 #include <rpcsvc/yp_prot.h>
118 #include <rpcsvc/ypclnt.h>
121 #include "gr_private.h"
124 __weak_alias(endgrent
,_endgrent
)
125 __weak_alias(getgrent
,_getgrent
)
126 __weak_alias(getgrent_r
,_getgrent_r
)
127 __weak_alias(getgrgid
,_getgrgid
)
128 __weak_alias(getgrgid_r
,_getgrgid_r
)
129 __weak_alias(getgrnam
,_getgrnam
)
130 __weak_alias(getgrnam_r
,_getgrnam_r
)
131 __weak_alias(setgrent
,_setgrent
)
132 __weak_alias(setgroupent
,_setgroupent
)
136 mutex_t __grmutex
= MUTEX_INITIALIZER
;
141 * Obtain want bytes from buffer (of size buflen) and return a pointer
142 * to the available memory after adjusting buffer/buflen.
143 * Returns NULL if there is insufficient space.
146 _gr_memfrombuf(size_t want
, char **buffer
, size_t *buflen
)
150 if (want
> *buflen
) {
162 * Parses entry as a line per group(5) (without the trailing \n)
163 * and fills in grp with corresponding values; memory for strings
164 * and arrays will be allocated from buf (of size buflen).
165 * Returns 1 if parsed successfully, 0 on parse failure.
168 _gr_parse(const char *entry
, struct group
*grp
, char *buf
, size_t buflen
)
176 _DIAGASSERT(entry
!= NULL
);
177 _DIAGASSERT(grp
!= NULL
);
178 _DIAGASSERT(buf
!= NULL
);
180 #define COPYTOBUF(to) \
182 (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
185 memmove((to), entry, count); \
187 } while (0) /* LINTED */
190 if (*entry
== '+') /* fail on compat `+' token */
194 count
= strcspn(entry
, ":"); /* parse gr_name */
195 if (entry
[count
] == '\0')
197 COPYTOBUF(grp
->gr_name
);
200 count
= strcspn(entry
, ":"); /* parse gr_passwd */
201 if (entry
[count
] == '\0')
203 COPYTOBUF(grp
->gr_passwd
);
206 count
= strcspn(entry
, ":"); /* parse gr_gid */
207 if (entry
[count
] == '\0')
209 id
= strtoul(entry
, &ep
, 10);
210 if (id
> GID_MAX
|| *ep
!= ':')
212 grp
->gr_gid
= (gid_t
)id
;
215 memc
= 1; /* for final NULL */
217 memc
++; /* for first item */
218 for (bp
= entry
; *bp
!= '\0'; bp
++) {
222 /* grab ALIGNed char **gr_mem from buf */
223 ep
= _gr_memfrombuf(memc
* sizeof(char *) + ALIGNBYTES
, &buf
, &buflen
);
224 grp
->gr_mem
= (char **)ALIGN(ep
);
225 if (grp
->gr_mem
== NULL
)
228 for (memc
= 0; *entry
!= '\0'; memc
++) {
229 count
= strcspn(entry
, ","); /* parse member */
230 COPYTOBUF(grp
->gr_mem
[memc
]);
238 grp
->gr_mem
[memc
] = NULL
;
244 * Copy the contents of fromgrp to grp; memory for strings
245 * and arrays will be allocated from buf (of size buflen).
246 * Returns 1 if copied successfully, 0 on copy failure.
247 * NOTE: fromgrp must not use buf for its own pointers.
250 _gr_copy(struct group
*fromgrp
, struct group
*grp
, char *buf
, size_t buflen
)
255 _DIAGASSERT(fromgrp
!= NULL
);
256 _DIAGASSERT(grp
!= NULL
);
257 _DIAGASSERT(buf
!= NULL
);
259 #define COPYSTR(to, from) \
261 size_t count = strlen((from)); \
262 (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
265 memmove((to), (from), count); \
267 } while (0) /* LINTED */
269 COPYSTR(grp
->gr_name
, fromgrp
->gr_name
);
270 COPYSTR(grp
->gr_passwd
, fromgrp
->gr_passwd
);
271 grp
->gr_gid
= fromgrp
->gr_gid
;
273 for (memc
= 0; fromgrp
->gr_mem
[memc
]; memc
++)
275 memc
++; /* for final NULL */
277 /* grab ALIGNed char **gr_mem from buf */
278 ep
= _gr_memfrombuf(memc
* sizeof(char *) + ALIGNBYTES
, &buf
, &buflen
);
279 grp
->gr_mem
= (char **)ALIGN(ep
);
280 if (grp
->gr_mem
== NULL
)
283 for (memc
= 0; fromgrp
->gr_mem
[memc
]; memc
++) {
284 COPYSTR(grp
->gr_mem
[memc
], fromgrp
->gr_mem
[memc
]);
289 grp
->gr_mem
[memc
] = NULL
;
298 __grstart_files(struct __grstate_files
*state
)
301 _DIAGASSERT(state
!= NULL
);
303 if (state
->fp
== NULL
) {
304 state
->fp
= fopen(_PATH_GROUP
, "r");
305 if (state
->fp
== NULL
)
314 __grend_files(struct __grstate_files
*state
)
317 _DIAGASSERT(state
!= NULL
);
320 (void) fclose(state
->fp
);
328 * Scan state->fp for the next desired entry.
329 * If search is zero, return the next entry.
330 * If search is non-zero, look for a specific name (if name != NULL),
331 * or a specific gid (if name == NULL).
332 * Sets *retval to the errno if the result is not NS_SUCCESS
336 __grscan_files(int *retval
, struct group
*grp
, char *buffer
, size_t buflen
,
337 struct __grstate_files
*state
, int search
, const char *name
, gid_t gid
)
340 char filebuf
[_GETGR_R_SIZE_MAX
], *ep
;
342 _DIAGASSERT(retval
!= NULL
);
343 _DIAGASSERT(grp
!= NULL
);
344 _DIAGASSERT(buffer
!= NULL
);
345 _DIAGASSERT(state
!= NULL
);
346 /* name is NULL to indicate searching for gid */
350 if (state
->fp
== NULL
) { /* only start if file not open yet */
351 rv
= __grstart_files(state
);
352 if (rv
!= NS_SUCCESS
)
353 goto filesgrscan_out
;
358 /* scan line by line */
359 while (fgets(filebuf
, sizeof(filebuf
), state
->fp
) != NULL
) {
360 ep
= strchr(filebuf
, '\n');
361 if (ep
== NULL
) { /* skip lines that are too big */
364 while ((ch
= getc(state
->fp
)) != '\n' && ch
!= EOF
)
368 *ep
= '\0'; /* clear trailing \n */
370 if (filebuf
[0] == '+') /* skip compat line */
374 if (! _gr_parse(filebuf
, grp
, buffer
, buflen
)) {
375 continue; /* skip bad lines */
377 if (! search
) { /* just want this one */
382 if ((name
&& strcmp(name
, grp
->gr_name
) == 0) ||
383 (!name
&& gid
== grp
->gr_gid
)) {
390 if (rv
!= NS_SUCCESS
&& rv
!= NS_NOTFOUND
)
396 static struct __grstate_files _files_state
;
397 /* storage for non _r functions */
398 static struct group _files_group
;
399 static char _files_groupbuf
[_GETGR_R_SIZE_MAX
];
403 _files_setgrent(void *nsrv
, void *nscb
, va_list ap
)
406 _files_state
.stayopen
= 0;
407 return __grstart_files(&_files_state
);
412 _files_setgroupent(void *nsrv
, void *nscb
, va_list ap
)
414 int *retval
= va_arg(ap
, int *);
415 int stayopen
= va_arg(ap
, int);
419 _files_state
.stayopen
= stayopen
;
420 rv
= __grstart_files(&_files_state
);
421 *retval
= (rv
== NS_SUCCESS
);
427 _files_endgrent(void *nsrv
, void *nscb
, va_list ap
)
430 _files_state
.stayopen
= 0;
431 return __grend_files(&_files_state
);
436 _files_getgrent(void *nsrv
, void *nscb
, va_list ap
)
438 struct group
**retval
= va_arg(ap
, struct group
**);
442 _DIAGASSERT(retval
!= NULL
);
445 rv
= __grscan_files(&rerror
, &_files_group
,
446 _files_groupbuf
, sizeof(_files_groupbuf
),
447 &_files_state
, 0, NULL
, 0);
448 if (rv
== NS_SUCCESS
)
449 *retval
= &_files_group
;
455 _files_getgrent_r(void *nsrv
, void *nscb
, va_list ap
)
457 int *retval
= va_arg(ap
, int *);
458 struct group
*grp
= va_arg(ap
, struct group
*);
459 char *buffer
= va_arg(ap
, char *);
460 size_t buflen
= va_arg(ap
, size_t);
461 struct group
**result
= va_arg(ap
, struct group
**);
465 _DIAGASSERT(retval
!= NULL
);
466 _DIAGASSERT(grp
!= NULL
);
467 _DIAGASSERT(buffer
!= NULL
);
468 _DIAGASSERT(result
!= NULL
);
470 rv
= __grscan_files(retval
, grp
, buffer
, buflen
,
471 &_files_state
, 0, NULL
, 0);
472 if (rv
== NS_SUCCESS
)
481 _files_getgrgid(void *nsrv
, void *nscb
, va_list ap
)
483 struct group
**retval
= va_arg(ap
, struct group
**);
484 gid_t gid
= va_arg(ap
, gid_t
);
488 _DIAGASSERT(retval
!= NULL
);
491 rv
= __grstart_files(&_files_state
);
492 if (rv
!= NS_SUCCESS
)
494 rv
= __grscan_files(&rerror
, &_files_group
,
495 _files_groupbuf
, sizeof(_files_groupbuf
),
496 &_files_state
, 1, NULL
, gid
);
497 if (!_files_state
.stayopen
)
498 __grend_files(&_files_state
);
499 if (rv
== NS_SUCCESS
)
500 *retval
= &_files_group
;
506 _files_getgrgid_r(void *nsrv
, void *nscb
, va_list ap
)
508 int *retval
= va_arg(ap
, int *);
509 gid_t gid
= va_arg(ap
, gid_t
);
510 struct group
*grp
= va_arg(ap
, struct group
*);
511 char *buffer
= va_arg(ap
, char *);
512 size_t buflen
= va_arg(ap
, size_t);
513 struct group
**result
= va_arg(ap
, struct group
**);
515 struct __grstate_files state
;
518 _DIAGASSERT(retval
!= NULL
);
519 _DIAGASSERT(grp
!= NULL
);
520 _DIAGASSERT(buffer
!= NULL
);
521 _DIAGASSERT(result
!= NULL
);
524 memset(&state
, 0, sizeof(state
));
525 rv
= __grscan_files(retval
, grp
, buffer
, buflen
, &state
, 1, NULL
, gid
);
526 __grend_files(&state
);
527 if (rv
== NS_SUCCESS
)
534 _files_getgrnam(void *nsrv
, void *nscb
, va_list ap
)
536 struct group
**retval
= va_arg(ap
, struct group
**);
537 const char *name
= va_arg(ap
, const char *);
541 _DIAGASSERT(retval
!= NULL
);
544 rv
= __grstart_files(&_files_state
);
545 if (rv
!= NS_SUCCESS
)
547 rv
= __grscan_files(&rerror
, &_files_group
,
548 _files_groupbuf
, sizeof(_files_groupbuf
),
549 &_files_state
, 1, name
, 0);
550 if (!_files_state
.stayopen
)
551 __grend_files(&_files_state
);
552 if (rv
== NS_SUCCESS
)
553 *retval
= &_files_group
;
559 _files_getgrnam_r(void *nsrv
, void *nscb
, va_list ap
)
561 int *retval
= va_arg(ap
, int *);
562 const char *name
= va_arg(ap
, const char *);
563 struct group
*grp
= va_arg(ap
, struct group
*);
564 char *buffer
= va_arg(ap
, char *);
565 size_t buflen
= va_arg(ap
, size_t);
566 struct group
**result
= va_arg(ap
, struct group
**);
568 struct __grstate_files state
;
571 _DIAGASSERT(retval
!= NULL
);
572 _DIAGASSERT(grp
!= NULL
);
573 _DIAGASSERT(buffer
!= NULL
);
574 _DIAGASSERT(result
!= NULL
);
577 memset(&state
, 0, sizeof(state
));
578 rv
= __grscan_files(retval
, grp
, buffer
, buflen
, &state
, 1, name
, 0);
579 __grend_files(&state
);
580 if (rv
== NS_SUCCESS
)
592 __grstart_dns(struct __grstate_dns
*state
)
595 _DIAGASSERT(state
!= NULL
);
598 if (state
->context
== NULL
) { /* setup Hesiod */
599 if (hesiod_init(&state
->context
) == -1)
607 __grend_dns(struct __grstate_dns
*state
)
610 _DIAGASSERT(state
!= NULL
);
613 if (state
->context
) {
614 hesiod_end(state
->context
);
615 state
->context
= NULL
;
622 * Search Hesiod for the next desired entry.
623 * If search is zero, return the next entry.
624 * If search is non-zero, look for a specific name (if name != NULL),
625 * or a specific gid (if name == NULL).
628 __grscan_dns(int *retval
, struct group
*grp
, char *buffer
, size_t buflen
,
629 struct __grstate_dns
*state
, int search
, const char *name
, gid_t gid
)
631 const char **curzone
;
635 static const char *zones_gid_group
[] = {
641 static const char *zones_group
[] = {
646 _DIAGASSERT(retval
!= NULL
);
647 _DIAGASSERT(grp
!= NULL
);
648 _DIAGASSERT(buffer
!= NULL
);
649 _DIAGASSERT(state
!= NULL
);
650 /* name is NULL to indicate searching for gid */
654 if (state
->context
== NULL
) { /* only start if Hesiod not setup */
655 rv
= __grstart_dns(state
);
656 if (rv
!= NS_SUCCESS
)
664 if (! search
) { /* find next entry */
665 if (state
->num
== -1) /* exhausted search */
668 snprintf(buffer
, buflen
, "group-%u", state
->num
);
670 curzone
= zones_group
;
671 } else if (name
) { /* find group name */
672 snprintf(buffer
, buflen
, "%s", name
);
673 curzone
= zones_group
;
674 } else { /* find gid */
675 snprintf(buffer
, buflen
, "%u", (unsigned int)gid
);
676 curzone
= zones_gid_group
;
679 for (; *curzone
; curzone
++) { /* search zones */
680 hp
= hesiod_resolve(state
->context
, buffer
, *curzone
);
683 if (errno
!= ENOENT
) {
688 if (*curzone
== NULL
) {
694 if ((ep
= strchr(hp
[0], '\n')) != NULL
)
695 *ep
= '\0'; /* clear trailing \n */
696 if (_gr_parse(hp
[0], grp
, buffer
, buflen
)) { /* validate line */
697 if (! search
) { /* just want this one */
699 } else if ((name
&& strcmp(name
, grp
->gr_name
) == 0) ||
700 (!name
&& gid
== grp
->gr_gid
)) { /* want specific */
703 } else { /* dodgy entry */
704 if (!search
) { /* try again if ! searching */
705 hesiod_free_list(state
->context
, hp
);
711 if (rv
!= NS_SUCCESS
&& rv
!= NS_NOTFOUND
)
714 hesiod_free_list(state
->context
, hp
);
718 static struct __grstate_dns _dns_state
;
719 /* storage for non _r functions */
720 static struct group _dns_group
;
721 static char _dns_groupbuf
[_GETGR_R_SIZE_MAX
];
725 _dns_setgrent(void *nsrv
, void *nscb
, va_list ap
)
728 _dns_state
.stayopen
= 0;
729 return __grstart_dns(&_dns_state
);
734 _dns_setgroupent(void *nsrv
, void *nscb
, va_list ap
)
736 int *retval
= va_arg(ap
, int *);
737 int stayopen
= va_arg(ap
, int);
741 _dns_state
.stayopen
= stayopen
;
742 rv
= __grstart_dns(&_dns_state
);
743 *retval
= (rv
== NS_SUCCESS
);
749 _dns_endgrent(void *nsrv
, void *nscb
, va_list ap
)
752 _dns_state
.stayopen
= 0;
753 return __grend_dns(&_dns_state
);
758 _dns_getgrent(void *nsrv
, void *nscb
, va_list ap
)
760 struct group
**retval
= va_arg(ap
, struct group
**);
764 _DIAGASSERT(retval
!= NULL
);
767 rv
= __grscan_dns(&rerror
, &_dns_group
,
768 _dns_groupbuf
, sizeof(_dns_groupbuf
), &_dns_state
, 0, NULL
, 0);
769 if (rv
== NS_SUCCESS
)
770 *retval
= &_dns_group
;
776 _dns_getgrent_r(void *nsrv
, void *nscb
, va_list ap
)
778 int *retval
= va_arg(ap
, int *);
779 struct group
*grp
= va_arg(ap
, struct group
*);
780 char *buffer
= va_arg(ap
, char *);
781 size_t buflen
= va_arg(ap
, size_t);
782 struct group
**result
= va_arg(ap
, struct group
**);
786 _DIAGASSERT(retval
!= NULL
);
787 _DIAGASSERT(grp
!= NULL
);
788 _DIAGASSERT(buffer
!= NULL
);
789 _DIAGASSERT(result
!= NULL
);
791 rv
= __grscan_dns(retval
, grp
, buffer
, buflen
,
792 &_dns_state
, 0, NULL
, 0);
793 if (rv
== NS_SUCCESS
)
801 _dns_getgrgid(void *nsrv
, void *nscb
, va_list ap
)
803 struct group
**retval
= va_arg(ap
, struct group
**);
804 gid_t gid
= va_arg(ap
, gid_t
);
808 _DIAGASSERT(retval
!= NULL
);
811 rv
= __grstart_dns(&_dns_state
);
812 if (rv
!= NS_SUCCESS
)
814 rv
= __grscan_dns(&rerror
, &_dns_group
,
815 _dns_groupbuf
, sizeof(_dns_groupbuf
), &_dns_state
, 1, NULL
, gid
);
816 if (!_dns_state
.stayopen
)
817 __grend_dns(&_dns_state
);
818 if (rv
== NS_SUCCESS
)
819 *retval
= &_dns_group
;
825 _dns_getgrgid_r(void *nsrv
, void *nscb
, va_list ap
)
827 int *retval
= va_arg(ap
, int *);
828 gid_t gid
= va_arg(ap
, gid_t
);
829 struct group
*grp
= va_arg(ap
, struct group
*);
830 char *buffer
= va_arg(ap
, char *);
831 size_t buflen
= va_arg(ap
, size_t);
832 struct group
**result
= va_arg(ap
, struct group
**);
834 struct __grstate_dns state
;
837 _DIAGASSERT(retval
!= NULL
);
838 _DIAGASSERT(grp
!= NULL
);
839 _DIAGASSERT(buffer
!= NULL
);
840 _DIAGASSERT(result
!= NULL
);
843 memset(&state
, 0, sizeof(state
));
844 rv
= __grscan_dns(retval
, grp
, buffer
, buflen
, &state
, 1, NULL
, gid
);
846 if (rv
== NS_SUCCESS
)
853 _dns_getgrnam(void *nsrv
, void *nscb
, va_list ap
)
855 struct group
**retval
= va_arg(ap
, struct group
**);
856 const char *name
= va_arg(ap
, const char *);
860 _DIAGASSERT(retval
!= NULL
);
863 rv
= __grstart_dns(&_dns_state
);
864 if (rv
!= NS_SUCCESS
)
866 rv
= __grscan_dns(&rerror
, &_dns_group
,
867 _dns_groupbuf
, sizeof(_dns_groupbuf
), &_dns_state
, 1, name
, 0);
868 if (!_dns_state
.stayopen
)
869 __grend_dns(&_dns_state
);
870 if (rv
== NS_SUCCESS
)
871 *retval
= &_dns_group
;
877 _dns_getgrnam_r(void *nsrv
, void *nscb
, va_list ap
)
879 int *retval
= va_arg(ap
, int *);
880 const char *name
= va_arg(ap
, const char *);
881 struct group
*grp
= va_arg(ap
, struct group
*);
882 char *buffer
= va_arg(ap
, char *);
883 size_t buflen
= va_arg(ap
, size_t);
884 struct group
**result
= va_arg(ap
, struct group
**);
886 struct __grstate_dns state
;
889 _DIAGASSERT(retval
!= NULL
);
890 _DIAGASSERT(grp
!= NULL
);
891 _DIAGASSERT(buffer
!= NULL
);
892 _DIAGASSERT(result
!= NULL
);
895 memset(&state
, 0, sizeof(state
));
896 rv
= __grscan_dns(retval
, grp
, buffer
, buflen
, &state
, 1, name
, 0);
898 if (rv
== NS_SUCCESS
)
912 __grstart_nis(struct __grstate_nis
*state
)
915 _DIAGASSERT(state
!= NULL
);
918 if (state
->current
) {
919 free(state
->current
);
920 state
->current
= NULL
;
922 if (state
->domain
== NULL
) { /* setup NIS */
923 switch (yp_get_default_domain(&state
->domain
)) {
936 __grend_nis(struct __grstate_nis
*state
)
939 _DIAGASSERT(state
!= NULL
);
942 state
->domain
= NULL
;
945 if (state
->current
) {
946 free(state
->current
);
947 state
->current
= NULL
;
954 * Search NIS for the next desired entry.
955 * If search is zero, return the next entry.
956 * If search is non-zero, look for a specific name (if name != NULL),
957 * or a specific gid (if name == NULL).
960 __grscan_nis(int *retval
, struct group
*grp
, char *buffer
, size_t buflen
,
961 struct __grstate_nis
*state
, int search
, const char *name
, gid_t gid
)
965 int nisr
, rv
, keylen
, datalen
;
967 _DIAGASSERT(retval
!= NULL
);
968 _DIAGASSERT(grp
!= NULL
);
969 _DIAGASSERT(buffer
!= NULL
);
970 _DIAGASSERT(state
!= NULL
);
971 /* name is NULL to indicate searching for gid */
975 if (state
->domain
== NULL
) { /* only start if NIS not setup */
976 rv
= __grstart_nis(state
);
977 if (rv
!= NS_SUCCESS
)
986 if (! search
) { /* find next entry */
987 if (state
->done
) /* exhausted search */
989 map
= "group.byname";
990 if (state
->current
) { /* already searching */
991 nisr
= yp_next(state
->domain
, map
,
992 state
->current
, state
->currentlen
,
993 &key
, &keylen
, &data
, &datalen
);
994 free(state
->current
);
995 state
->current
= NULL
;
998 state
->current
= key
;
999 state
->currentlen
= keylen
;
1010 } else { /* new search */
1011 if (yp_first(state
->domain
, map
,
1012 &state
->current
, &state
->currentlen
,
1017 } else { /* search for specific item */
1018 if (name
) { /* find group name */
1019 snprintf(buffer
, buflen
, "%s", name
);
1020 map
= "group.byname";
1021 } else { /* find gid */
1022 snprintf(buffer
, buflen
, "%u", (unsigned int)gid
);
1023 map
= "group.bygid";
1025 nisr
= yp_match(state
->domain
, map
, buffer
, (int)strlen(buffer
),
1038 if (rv
== NS_SUCCESS
) { /* validate data */
1039 data
[datalen
] = '\0'; /* clear trailing \n */
1040 if (_gr_parse(data
, grp
, buffer
, buflen
)) {
1041 if (! search
) { /* just want this one */
1043 } else if ((name
&& strcmp(name
, grp
->gr_name
) == 0) ||
1044 (!name
&& gid
== grp
->gr_gid
)) {
1048 } else { /* dodgy entry */
1049 if (!search
) { /* try again if ! searching */
1051 goto next_nis_entry
;
1056 if (rv
!= NS_SUCCESS
&& rv
!= NS_NOTFOUND
)
1065 static struct __grstate_nis _nis_state
;
1066 /* storage for non _r functions */
1067 static struct group _nis_group
;
1068 static char _nis_groupbuf
[_GETGR_R_SIZE_MAX
];
1072 _nis_setgrent(void *nsrv
, void *nscb
, va_list ap
)
1075 _nis_state
.stayopen
= 0;
1076 return __grstart_nis(&_nis_state
);
1081 _nis_setgroupent(void *nsrv
, void *nscb
, va_list ap
)
1083 int *retval
= va_arg(ap
, int *);
1084 int stayopen
= va_arg(ap
, int);
1088 _nis_state
.stayopen
= stayopen
;
1089 rv
= __grstart_nis(&_nis_state
);
1090 *retval
= (rv
== NS_SUCCESS
);
1096 _nis_endgrent(void *nsrv
, void *nscb
, va_list ap
)
1099 return __grend_nis(&_nis_state
);
1104 _nis_getgrent(void *nsrv
, void *nscb
, va_list ap
)
1106 struct group
**retval
= va_arg(ap
, struct group
**);
1110 _DIAGASSERT(retval
!= NULL
);
1113 rv
= __grscan_nis(&rerror
, &_nis_group
,
1114 _nis_groupbuf
, sizeof(_nis_groupbuf
), &_nis_state
, 0, NULL
, 0);
1115 if (rv
== NS_SUCCESS
)
1116 *retval
= &_nis_group
;
1122 _nis_getgrent_r(void *nsrv
, void *nscb
, va_list ap
)
1124 int *retval
= va_arg(ap
, int *);
1125 struct group
*grp
= va_arg(ap
, struct group
*);
1126 char *buffer
= va_arg(ap
, char *);
1127 size_t buflen
= va_arg(ap
, size_t);
1128 struct group
**result
= va_arg(ap
, struct group
**);
1132 _DIAGASSERT(retval
!= NULL
);
1133 _DIAGASSERT(grp
!= NULL
);
1134 _DIAGASSERT(buffer
!= NULL
);
1135 _DIAGASSERT(result
!= NULL
);
1137 rv
= __grscan_nis(retval
, grp
, buffer
, buflen
,
1138 &_nis_state
, 0, NULL
, 0);
1139 if (rv
== NS_SUCCESS
)
1148 _nis_getgrgid(void *nsrv
, void *nscb
, va_list ap
)
1150 struct group
**retval
= va_arg(ap
, struct group
**);
1151 gid_t gid
= va_arg(ap
, gid_t
);
1155 _DIAGASSERT(retval
!= NULL
);
1158 rv
= __grstart_nis(&_nis_state
);
1159 if (rv
!= NS_SUCCESS
)
1161 rv
= __grscan_nis(&rerror
, &_nis_group
,
1162 _nis_groupbuf
, sizeof(_nis_groupbuf
), &_nis_state
, 1, NULL
, gid
);
1163 if (!_nis_state
.stayopen
)
1164 __grend_nis(&_nis_state
);
1165 if (rv
== NS_SUCCESS
)
1166 *retval
= &_nis_group
;
1172 _nis_getgrgid_r(void *nsrv
, void *nscb
, va_list ap
)
1174 int *retval
= va_arg(ap
, int *);
1175 gid_t gid
= va_arg(ap
, gid_t
);
1176 struct group
*grp
= va_arg(ap
, struct group
*);
1177 char *buffer
= va_arg(ap
, char *);
1178 size_t buflen
= va_arg(ap
, size_t);
1179 struct group
**result
= va_arg(ap
, struct group
**);
1181 struct __grstate_nis state
;
1184 _DIAGASSERT(retval
!= NULL
);
1185 _DIAGASSERT(grp
!= NULL
);
1186 _DIAGASSERT(buffer
!= NULL
);
1187 _DIAGASSERT(result
!= NULL
);
1190 memset(&state
, 0, sizeof(state
));
1191 rv
= __grscan_nis(retval
, grp
, buffer
, buflen
, &state
, 1, NULL
, gid
);
1192 __grend_nis(&state
);
1193 if (rv
== NS_SUCCESS
)
1200 _nis_getgrnam(void *nsrv
, void *nscb
, va_list ap
)
1202 struct group
**retval
= va_arg(ap
, struct group
**);
1203 const char *name
= va_arg(ap
, const char *);
1207 _DIAGASSERT(retval
!= NULL
);
1210 rv
= __grstart_nis(&_nis_state
);
1211 if (rv
!= NS_SUCCESS
)
1213 rv
= __grscan_nis(&rerror
, &_nis_group
,
1214 _nis_groupbuf
, sizeof(_nis_groupbuf
), &_nis_state
, 1, name
, 0);
1215 if (!_nis_state
.stayopen
)
1216 __grend_nis(&_nis_state
);
1217 if (rv
== NS_SUCCESS
)
1218 *retval
= &_nis_group
;
1224 _nis_getgrnam_r(void *nsrv
, void *nscb
, va_list ap
)
1226 int *retval
= va_arg(ap
, int *);
1227 const char *name
= va_arg(ap
, const char *);
1228 struct group
*grp
= va_arg(ap
, struct group
*);
1229 char *buffer
= va_arg(ap
, char *);
1230 size_t buflen
= va_arg(ap
, size_t);
1231 struct group
**result
= va_arg(ap
, struct group
**);
1233 struct __grstate_nis state
;
1236 _DIAGASSERT(retval
!= NULL
);
1237 _DIAGASSERT(grp
!= NULL
);
1238 _DIAGASSERT(buffer
!= NULL
);
1239 _DIAGASSERT(result
!= NULL
);
1242 memset(&state
, 0, sizeof(state
));
1243 rv
= __grscan_nis(retval
, grp
, buffer
, buflen
, &state
, 1, name
, 0);
1244 __grend_nis(&state
);
1245 if (rv
== NS_SUCCESS
)
1253 #ifdef _GROUP_COMPAT
1259 __grstart_compat(struct __grstate_compat
*state
)
1262 _DIAGASSERT(state
!= NULL
);
1264 if (state
->fp
== NULL
) {
1265 state
->fp
= fopen(_PATH_GROUP
, "r");
1266 if (state
->fp
== NULL
)
1275 __grend_compat(struct __grstate_compat
*state
)
1278 _DIAGASSERT(state
!= NULL
);
1285 (void) fclose(state
->fp
);
1294 * log an error if "files" or "compat" is specified in
1295 * group_compat database
1299 __grbad_compat(void *nsrv
, void *nscb
, va_list ap
)
1303 _DIAGASSERT(nsrv
!= NULL
);
1304 _DIAGASSERT(nscb
!= NULL
);
1308 "nsswitch.conf group_compat database can't use '%s'",
1309 (const char *)nscb
);
1317 * Scan state->fp for the next desired entry.
1318 * If search is zero, return the next entry.
1319 * If search is non-zero, look for a specific name (if name != NULL),
1320 * or a specific gid (if name == NULL).
1321 * Sets *retval to the errno if the result is not NS_SUCCESS or
1324 * searchfunc is invoked when a compat "+" lookup is required;
1325 * searchcookie is passed as the first argument to searchfunc,
1326 * the second argument is the group result.
1327 * This should return NS_NOTFOUND when "no more groups" from compat src.
1328 * If searchfunc is NULL then nsdispatch of getgrent is used.
1329 * This is primarily intended for getgroupmembership(3)'s compat backend.
1332 __grscan_compat(int *retval
, struct group
*grp
, char *buffer
, size_t buflen
,
1333 struct __grstate_compat
*state
, int search
, const char *name
, gid_t gid
,
1334 int (*searchfunc
)(void *, struct group
**), void *searchcookie
)
1337 char filebuf
[_GETGR_R_SIZE_MAX
], *ep
;
1339 static const ns_dtab compatentdtab
[] = {
1340 NS_FILES_CB(__grbad_compat
, "files")
1341 NS_DNS_CB(_dns_getgrent_r
, NULL
)
1342 NS_NIS_CB(_nis_getgrent_r
, NULL
)
1343 NS_COMPAT_CB(__grbad_compat
, "compat")
1346 static const ns_dtab compatgiddtab
[] = {
1347 NS_FILES_CB(__grbad_compat
, "files")
1348 NS_DNS_CB(_dns_getgrgid_r
, NULL
)
1349 NS_NIS_CB(_nis_getgrgid_r
, NULL
)
1350 NS_COMPAT_CB(__grbad_compat
, "compat")
1353 static const ns_dtab compatnamdtab
[] = {
1354 NS_FILES_CB(__grbad_compat
, "files")
1355 NS_DNS_CB(_dns_getgrnam_r
, NULL
)
1356 NS_NIS_CB(_nis_getgrnam_r
, NULL
)
1357 NS_COMPAT_CB(__grbad_compat
, "compat")
1361 _DIAGASSERT(retval
!= NULL
);
1362 _DIAGASSERT(grp
!= NULL
);
1363 _DIAGASSERT(buffer
!= NULL
);
1364 _DIAGASSERT(state
!= NULL
);
1365 /* name is NULL to indicate searching for gid */
1369 if (state
->fp
== NULL
) { /* only start if file not open yet */
1370 rv
= __grstart_compat(state
);
1371 if (rv
!= NS_SUCCESS
)
1372 goto compatgrscan_out
;
1376 for (;;) { /* loop through file */
1377 if (state
->name
!= NULL
) {
1378 /* processing compat entry */
1380 struct group cgrp
, *cgrpres
;
1382 if (state
->name
[0]) { /* specific +group: */
1383 crv
= nsdispatch(NULL
, compatnamdtab
,
1384 NSDB_GROUP_COMPAT
, "getgrnam_r",
1386 &cretval
, state
->name
,
1387 &cgrp
, filebuf
, sizeof(filebuf
), &cgrpres
);
1388 free(state
->name
); /* (only check 1 grp) */
1390 } else if (!search
) { /* any group */
1392 crv
= searchfunc(searchcookie
,
1395 crv
= nsdispatch(NULL
, compatentdtab
,
1396 NSDB_GROUP_COMPAT
, "getgrent_r",
1398 &cretval
, &cgrp
, filebuf
,
1399 sizeof(filebuf
), &cgrpres
);
1401 } else if (name
) { /* specific group */
1402 crv
= nsdispatch(NULL
, compatnamdtab
,
1403 NSDB_GROUP_COMPAT
, "getgrnam_r",
1406 &cgrp
, filebuf
, sizeof(filebuf
), &cgrpres
);
1407 } else { /* specific gid */
1408 crv
= nsdispatch(NULL
, compatgiddtab
,
1409 NSDB_GROUP_COMPAT
, "getgrgid_r",
1412 &cgrp
, filebuf
, sizeof(filebuf
), &cgrpres
);
1414 if (crv
!= NS_SUCCESS
) { /* not found */
1417 continue; /* try next line */
1419 if (!_gr_copy(cgrpres
, grp
, buffer
, buflen
)) {
1423 goto compatgrscan_cmpgrp
; /* skip to grp test */
1426 /* get next file line */
1427 if (fgets(filebuf
, sizeof(filebuf
), state
->fp
) == NULL
)
1430 ep
= strchr(filebuf
, '\n');
1431 if (ep
== NULL
) { /* skip lines that are too big */
1434 while ((ch
= getc(state
->fp
)) != '\n' && ch
!= EOF
)
1438 *ep
= '\0'; /* clear trailing \n */
1440 if (filebuf
[0] == '+') { /* parse compat line */
1444 switch(filebuf
[1]) {
1447 state
->name
= strdup("");
1450 ep
= strchr(filebuf
+ 1, ':');
1454 state
->name
= strdup(filebuf
+ 1);
1457 if (state
->name
== NULL
) {
1465 if (! _gr_parse(filebuf
, grp
, buffer
, buflen
)) {
1466 continue; /* skip bad lines */
1469 compatgrscan_cmpgrp
:
1470 if (! search
) { /* just want this one */
1475 if ((name
&& strcmp(name
, grp
->gr_name
) == 0) ||
1476 (!name
&& gid
== grp
->gr_gid
)) {
1484 if (rv
!= NS_SUCCESS
&& rv
!= NS_NOTFOUND
)
1489 static struct __grstate_compat _compat_state
;
1490 /* storage for non _r functions */
1491 static struct group _compat_group
;
1492 static char _compat_groupbuf
[_GETGR_R_SIZE_MAX
];
1496 _compat_setgrent(void *nsrv
, void *nscb
, va_list ap
)
1498 static const ns_dtab dtab
[] = {
1499 NS_FILES_CB(__grbad_compat
, "files")
1500 NS_DNS_CB(_dns_setgrent
, NULL
)
1501 NS_NIS_CB(_nis_setgrent
, NULL
)
1502 NS_COMPAT_CB(__grbad_compat
, "compat")
1506 /* force group_compat setgrent() */
1507 (void) nsdispatch(NULL
, dtab
, NSDB_GROUP_COMPAT
, "setgrent",
1508 __nsdefaultnis_forceall
);
1510 /* reset state, keep fp open */
1511 _compat_state
.stayopen
= 0;
1512 return __grstart_compat(&_compat_state
);
1517 _compat_setgroupent(void *nsrv
, void *nscb
, va_list ap
)
1519 int *retval
= va_arg(ap
, int *);
1520 int stayopen
= va_arg(ap
, int);
1524 static const ns_dtab dtab
[] = {
1525 NS_FILES_CB(__grbad_compat
, "files")
1526 NS_DNS_CB(_dns_setgroupent
, NULL
)
1527 NS_NIS_CB(_nis_setgroupent
, NULL
)
1528 NS_COMPAT_CB(__grbad_compat
, "compat")
1532 /* force group_compat setgroupent() */
1533 (void) nsdispatch(NULL
, dtab
, NSDB_GROUP_COMPAT
, "setgroupent",
1534 __nsdefaultnis_forceall
, &rv
, stayopen
);
1536 _compat_state
.stayopen
= stayopen
;
1537 rv
= __grstart_compat(&_compat_state
);
1538 *retval
= (rv
== NS_SUCCESS
);
1544 _compat_endgrent(void *nsrv
, void *nscb
, va_list ap
)
1546 static const ns_dtab dtab
[] = {
1547 NS_FILES_CB(__grbad_compat
, "files")
1548 NS_DNS_CB(_dns_endgrent
, NULL
)
1549 NS_NIS_CB(_nis_endgrent
, NULL
)
1550 NS_COMPAT_CB(__grbad_compat
, "compat")
1554 /* force group_compat endgrent() */
1555 (void) nsdispatch(NULL
, dtab
, NSDB_GROUP_COMPAT
, "endgrent",
1556 __nsdefaultnis_forceall
);
1558 /* reset state, close fp */
1559 _compat_state
.stayopen
= 0;
1560 return __grend_compat(&_compat_state
);
1565 _compat_getgrent(void *nsrv
, void *nscb
, va_list ap
)
1567 struct group
**retval
= va_arg(ap
, struct group
**);
1571 _DIAGASSERT(retval
!= NULL
);
1574 rv
= __grscan_compat(&rerror
, &_compat_group
,
1575 _compat_groupbuf
, sizeof(_compat_groupbuf
),
1576 &_compat_state
, 0, NULL
, 0, NULL
, NULL
);
1577 if (rv
== NS_SUCCESS
)
1578 *retval
= &_compat_group
;
1584 _compat_getgrent_r(void *nsrv
, void *nscb
, va_list ap
)
1586 int *retval
= va_arg(ap
, int *);
1587 struct group
*grp
= va_arg(ap
, struct group
*);
1588 char *buffer
= va_arg(ap
, char *);
1589 size_t buflen
= va_arg(ap
, size_t);
1590 struct group
**result
= va_arg(ap
, struct group
**);
1594 _DIAGASSERT(retval
!= NULL
);
1595 _DIAGASSERT(grp
!= NULL
);
1596 _DIAGASSERT(buffer
!= NULL
);
1597 _DIAGASSERT(result
!= NULL
);
1599 rv
= __grscan_compat(retval
, grp
, buffer
, buflen
,
1600 &_compat_state
, 0, NULL
, 0, NULL
, NULL
);
1601 if (rv
== NS_SUCCESS
)
1610 _compat_getgrgid(void *nsrv
, void *nscb
, va_list ap
)
1612 struct group
**retval
= va_arg(ap
, struct group
**);
1613 gid_t gid
= va_arg(ap
, gid_t
);
1617 _DIAGASSERT(retval
!= NULL
);
1620 rv
= __grstart_compat(&_compat_state
);
1621 if (rv
!= NS_SUCCESS
)
1623 rv
= __grscan_compat(&rerror
, &_compat_group
,
1624 _compat_groupbuf
, sizeof(_compat_groupbuf
),
1625 &_compat_state
, 1, NULL
, gid
, NULL
, NULL
);
1626 if (!_compat_state
.stayopen
)
1627 __grend_compat(&_compat_state
);
1628 if (rv
== NS_SUCCESS
)
1629 *retval
= &_compat_group
;
1635 _compat_getgrgid_r(void *nsrv
, void *nscb
, va_list ap
)
1637 int *retval
= va_arg(ap
, int *);
1638 gid_t gid
= va_arg(ap
, gid_t
);
1639 struct group
*grp
= va_arg(ap
, struct group
*);
1640 char *buffer
= va_arg(ap
, char *);
1641 size_t buflen
= va_arg(ap
, size_t);
1642 struct group
**result
= va_arg(ap
, struct group
**);
1644 struct __grstate_compat state
;
1647 _DIAGASSERT(retval
!= NULL
);
1648 _DIAGASSERT(grp
!= NULL
);
1649 _DIAGASSERT(buffer
!= NULL
);
1650 _DIAGASSERT(result
!= NULL
);
1653 memset(&state
, 0, sizeof(state
));
1654 rv
= __grscan_compat(retval
, grp
, buffer
, buflen
, &state
,
1655 1, NULL
, gid
, NULL
, NULL
);
1656 __grend_compat(&state
);
1657 if (rv
== NS_SUCCESS
)
1664 _compat_getgrnam(void *nsrv
, void *nscb
, va_list ap
)
1666 struct group
**retval
= va_arg(ap
, struct group
**);
1667 const char *name
= va_arg(ap
, const char *);
1671 _DIAGASSERT(retval
!= NULL
);
1674 rv
= __grstart_compat(&_compat_state
);
1675 if (rv
!= NS_SUCCESS
)
1677 rv
= __grscan_compat(&rerror
, &_compat_group
,
1678 _compat_groupbuf
, sizeof(_compat_groupbuf
),
1679 &_compat_state
, 1, name
, 0, NULL
, NULL
);
1680 if (!_compat_state
.stayopen
)
1681 __grend_compat(&_compat_state
);
1682 if (rv
== NS_SUCCESS
)
1683 *retval
= &_compat_group
;
1689 _compat_getgrnam_r(void *nsrv
, void *nscb
, va_list ap
)
1691 int *retval
= va_arg(ap
, int *);
1692 const char *name
= va_arg(ap
, const char *);
1693 struct group
*grp
= va_arg(ap
, struct group
*);
1694 char *buffer
= va_arg(ap
, char *);
1695 size_t buflen
= va_arg(ap
, size_t);
1696 struct group
**result
= va_arg(ap
, struct group
**);
1698 struct __grstate_compat state
;
1701 _DIAGASSERT(retval
!= NULL
);
1702 _DIAGASSERT(grp
!= NULL
);
1703 _DIAGASSERT(buffer
!= NULL
);
1704 _DIAGASSERT(result
!= NULL
);
1707 memset(&state
, 0, sizeof(state
));
1708 rv
= __grscan_compat(retval
, grp
, buffer
, buflen
, &state
,
1709 1, name
, 0, NULL
, NULL
);
1710 __grend_compat(&state
);
1711 if (rv
== NS_SUCCESS
)
1716 #endif /* _GROUP_COMPAT */
1727 struct group
*retval
;
1729 static const ns_dtab dtab
[] = {
1730 NS_FILES_CB(_files_getgrent
, NULL
)
1731 NS_DNS_CB(_dns_getgrent
, NULL
)
1732 NS_NIS_CB(_nis_getgrent
, NULL
)
1733 NS_COMPAT_CB(_compat_getgrent
, NULL
)
1737 mutex_lock(&__grmutex
);
1738 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "getgrent", __nsdefaultcompat
,
1740 mutex_unlock(&__grmutex
);
1741 return (rv
== NS_SUCCESS
) ? retval
: NULL
;
1745 getgrent_r(struct group
*grp
, char *buffer
, size_t buflen
,
1746 struct group
**result
)
1750 static const ns_dtab dtab
[] = {
1751 NS_FILES_CB(_files_getgrent_r
, NULL
)
1752 NS_DNS_CB(_dns_getgrent_r
, NULL
)
1753 NS_NIS_CB(_nis_getgrent_r
, NULL
)
1754 NS_COMPAT_CB(_compat_getgrent_r
, NULL
)
1758 mutex_lock(&__grmutex
);
1759 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "getgrent_r", __nsdefaultcompat
,
1760 &retval
, grp
, buffer
, buflen
, result
);
1761 mutex_unlock(&__grmutex
);
1776 struct group
*retval
;
1778 static const ns_dtab dtab
[] = {
1779 NS_FILES_CB(_files_getgrgid
, NULL
)
1780 NS_DNS_CB(_dns_getgrgid
, NULL
)
1781 NS_NIS_CB(_nis_getgrgid
, NULL
)
1782 NS_COMPAT_CB(_compat_getgrgid
, NULL
)
1786 mutex_lock(&__grmutex
);
1787 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "getgrgid", __nsdefaultcompat
,
1789 mutex_unlock(&__grmutex
);
1790 return (rv
== NS_SUCCESS
) ? retval
: NULL
;
1794 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t buflen
,
1795 struct group
**result
)
1799 static const ns_dtab dtab
[] = {
1800 NS_FILES_CB(_files_getgrgid_r
, NULL
)
1801 NS_DNS_CB(_dns_getgrgid_r
, NULL
)
1802 NS_NIS_CB(_nis_getgrgid_r
, NULL
)
1803 NS_COMPAT_CB(_compat_getgrgid_r
, NULL
)
1807 _DIAGASSERT(grp
!= NULL
);
1808 _DIAGASSERT(buffer
!= NULL
);
1809 _DIAGASSERT(result
!= NULL
);
1813 mutex_lock(&__grmutex
);
1814 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "getgrgid_r", __nsdefaultcompat
,
1815 &retval
, gid
, grp
, buffer
, buflen
, result
);
1816 mutex_unlock(&__grmutex
);
1827 getgrnam(const char *name
)
1830 struct group
*retval
;
1832 static const ns_dtab dtab
[] = {
1833 NS_FILES_CB(_files_getgrnam
, NULL
)
1834 NS_DNS_CB(_dns_getgrnam
, NULL
)
1835 NS_NIS_CB(_nis_getgrnam
, NULL
)
1836 NS_COMPAT_CB(_compat_getgrnam
, NULL
)
1840 mutex_lock(&__grmutex
);
1841 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "getgrnam", __nsdefaultcompat
,
1843 mutex_unlock(&__grmutex
);
1844 return (rv
== NS_SUCCESS
) ? retval
: NULL
;
1848 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t buflen
,
1849 struct group
**result
)
1853 static const ns_dtab dtab
[] = {
1854 NS_FILES_CB(_files_getgrnam_r
, NULL
)
1855 NS_DNS_CB(_dns_getgrnam_r
, NULL
)
1856 NS_NIS_CB(_nis_getgrnam_r
, NULL
)
1857 NS_COMPAT_CB(_compat_getgrnam_r
, NULL
)
1861 _DIAGASSERT(name
!= NULL
);
1862 _DIAGASSERT(grp
!= NULL
);
1863 _DIAGASSERT(buffer
!= NULL
);
1864 _DIAGASSERT(result
!= NULL
);
1868 mutex_lock(&__grmutex
);
1869 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "getgrnam_r", __nsdefaultcompat
,
1870 &retval
, name
, grp
, buffer
, buflen
, result
);
1871 mutex_unlock(&__grmutex
);
1884 static const ns_dtab dtab
[] = {
1885 NS_FILES_CB(_files_endgrent
, NULL
)
1886 NS_DNS_CB(_dns_endgrent
, NULL
)
1887 NS_NIS_CB(_nis_endgrent
, NULL
)
1888 NS_COMPAT_CB(_compat_endgrent
, NULL
)
1892 mutex_lock(&__grmutex
);
1893 /* force all endgrent() methods */
1894 (void) nsdispatch(NULL
, dtab
, NSDB_GROUP
, "endgrent",
1895 __nsdefaultcompat_forceall
);
1896 mutex_unlock(&__grmutex
);
1900 setgroupent(int stayopen
)
1902 static const ns_dtab dtab
[] = {
1903 NS_FILES_CB(_files_setgroupent
, NULL
)
1904 NS_DNS_CB(_dns_setgroupent
, NULL
)
1905 NS_NIS_CB(_nis_setgroupent
, NULL
)
1906 NS_COMPAT_CB(_compat_setgroupent
, NULL
)
1911 mutex_lock(&__grmutex
);
1912 /* force all setgroupent() methods */
1913 rv
= nsdispatch(NULL
, dtab
, NSDB_GROUP
, "setgroupent",
1914 __nsdefaultcompat_forceall
, &retval
, stayopen
);
1915 mutex_unlock(&__grmutex
);
1916 return (rv
== NS_SUCCESS
) ? retval
: 0;
1922 static const ns_dtab dtab
[] = {
1923 NS_FILES_CB(_files_setgrent
, NULL
)
1924 NS_DNS_CB(_dns_setgrent
, NULL
)
1925 NS_NIS_CB(_nis_setgrent
, NULL
)
1926 NS_COMPAT_CB(_compat_setgrent
, NULL
)
1930 mutex_lock(&__grmutex
);
1931 /* force all setgrent() methods */
1932 (void) nsdispatch(NULL
, dtab
, NSDB_GROUP
, "setgrent",
1933 __nsdefaultcompat_forceall
);
1934 mutex_unlock(&__grmutex
);