xref: /minix3/lib/libc/gen/getgrent.c (revision f14fb602092e015ff630df58e17c2a9cd57d29b3)
1*f14fb602SLionel Sambuc /*	$NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $	*/
22fe8fb19SBen Gras 
32fe8fb19SBen Gras /*-
42fe8fb19SBen Gras  * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
52fe8fb19SBen Gras  * All rights reserved.
62fe8fb19SBen Gras  *
72fe8fb19SBen Gras  * This code is derived from software contributed to The NetBSD Foundation
82fe8fb19SBen Gras  * by Luke Mewburn.
92fe8fb19SBen Gras  *
102fe8fb19SBen Gras  * Redistribution and use in source and binary forms, with or without
112fe8fb19SBen Gras  * modification, are permitted provided that the following conditions
122fe8fb19SBen Gras  * are met:
132fe8fb19SBen Gras  * 1. Redistributions of source code must retain the above copyright
142fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer.
152fe8fb19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
162fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
172fe8fb19SBen Gras  *    documentation and/or other materials provided with the distribution.
182fe8fb19SBen Gras  *
192fe8fb19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
202fe8fb19SBen Gras  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
212fe8fb19SBen Gras  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
222fe8fb19SBen Gras  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
232fe8fb19SBen Gras  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
242fe8fb19SBen Gras  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
252fe8fb19SBen Gras  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
262fe8fb19SBen Gras  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
272fe8fb19SBen Gras  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
282fe8fb19SBen Gras  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
292fe8fb19SBen Gras  * POSSIBILITY OF SUCH DAMAGE.
302fe8fb19SBen Gras  */
312fe8fb19SBen Gras 
322fe8fb19SBen Gras /*
332fe8fb19SBen Gras  * Copyright (c) 1989, 1993
342fe8fb19SBen Gras  *	The Regents of the University of California.  All rights reserved.
352fe8fb19SBen Gras  *
362fe8fb19SBen Gras  * Redistribution and use in source and binary forms, with or without
372fe8fb19SBen Gras  * modification, are permitted provided that the following conditions
382fe8fb19SBen Gras  * are met:
392fe8fb19SBen Gras  * 1. Redistributions of source code must retain the above copyright
402fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer.
412fe8fb19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
422fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
432fe8fb19SBen Gras  *    documentation and/or other materials provided with the distribution.
442fe8fb19SBen Gras  * 3. Neither the name of the University nor the names of its contributors
452fe8fb19SBen Gras  *    may be used to endorse or promote products derived from this software
462fe8fb19SBen Gras  *    without specific prior written permission.
472fe8fb19SBen Gras  *
482fe8fb19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
492fe8fb19SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
502fe8fb19SBen Gras  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
512fe8fb19SBen Gras  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
522fe8fb19SBen Gras  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
532fe8fb19SBen Gras  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
542fe8fb19SBen Gras  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
552fe8fb19SBen Gras  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
562fe8fb19SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
572fe8fb19SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
582fe8fb19SBen Gras  * SUCH DAMAGE.
592fe8fb19SBen Gras  */
602fe8fb19SBen Gras 
612fe8fb19SBen Gras /*
622fe8fb19SBen Gras  * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
632fe8fb19SBen Gras  *
642fe8fb19SBen Gras  * Redistribution and use in source and binary forms, with or without
652fe8fb19SBen Gras  * modification, are permitted provided that the following conditions
662fe8fb19SBen Gras  * are met:
672fe8fb19SBen Gras  * 1. Redistributions of source code must retain the above copyright
682fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer.
692fe8fb19SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
702fe8fb19SBen Gras  *    notice, this list of conditions and the following disclaimer in the
712fe8fb19SBen Gras  *    documentation and/or other materials provided with the distribution.
722fe8fb19SBen Gras  *
732fe8fb19SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
742fe8fb19SBen Gras  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
752fe8fb19SBen Gras  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
762fe8fb19SBen Gras  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
772fe8fb19SBen Gras  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
782fe8fb19SBen Gras  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
792fe8fb19SBen Gras  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
802fe8fb19SBen Gras  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
812fe8fb19SBen Gras  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
822fe8fb19SBen Gras  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
832fe8fb19SBen Gras  * SUCH DAMAGE.
842fe8fb19SBen Gras  */
852fe8fb19SBen Gras 
862fe8fb19SBen Gras #include <sys/cdefs.h>
872fe8fb19SBen Gras #if defined(LIBC_SCCS) && !defined(lint)
882fe8fb19SBen Gras #if 0
892fe8fb19SBen Gras static char sccsid[] = "@(#)getgrent.c	8.2 (Berkeley) 3/21/94";
902fe8fb19SBen Gras #else
91*f14fb602SLionel Sambuc __RCSID("$NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $");
922fe8fb19SBen Gras #endif
932fe8fb19SBen Gras #endif /* LIBC_SCCS and not lint */
942fe8fb19SBen Gras 
952fe8fb19SBen Gras #include "namespace.h"
962fe8fb19SBen Gras #include "reentrant.h"
972fe8fb19SBen Gras 
982fe8fb19SBen Gras #include <sys/param.h>
992fe8fb19SBen Gras 
1002fe8fb19SBen Gras #include <assert.h>
1012fe8fb19SBen Gras #include <errno.h>
1022fe8fb19SBen Gras #include <grp.h>
1032fe8fb19SBen Gras #include <limits.h>
1042fe8fb19SBen Gras #include <nsswitch.h>
1052fe8fb19SBen Gras #include <stdarg.h>
1062fe8fb19SBen Gras #include <stdio.h>
1072fe8fb19SBen Gras #include <stdlib.h>
1082fe8fb19SBen Gras #include <string.h>
1092fe8fb19SBen Gras #include <syslog.h>
1102fe8fb19SBen Gras 
1112fe8fb19SBen Gras #ifdef HESIOD
1122fe8fb19SBen Gras #include <hesiod.h>
1132fe8fb19SBen Gras #endif
1142fe8fb19SBen Gras 
1152fe8fb19SBen Gras #ifdef YP
1162fe8fb19SBen Gras #include <rpc/rpc.h>
1172fe8fb19SBen Gras #include <rpcsvc/yp_prot.h>
1182fe8fb19SBen Gras #include <rpcsvc/ypclnt.h>
1192fe8fb19SBen Gras #endif
1202fe8fb19SBen Gras 
1212fe8fb19SBen Gras #include "gr_private.h"
1222fe8fb19SBen Gras 
1232fe8fb19SBen Gras #ifdef __weak_alias
1242fe8fb19SBen Gras __weak_alias(endgrent,_endgrent)
1252fe8fb19SBen Gras __weak_alias(getgrent,_getgrent)
1262fe8fb19SBen Gras __weak_alias(getgrent_r,_getgrent_r)
1272fe8fb19SBen Gras __weak_alias(getgrgid,_getgrgid)
1282fe8fb19SBen Gras __weak_alias(getgrgid_r,_getgrgid_r)
1292fe8fb19SBen Gras __weak_alias(getgrnam,_getgrnam)
1302fe8fb19SBen Gras __weak_alias(getgrnam_r,_getgrnam_r)
1312fe8fb19SBen Gras __weak_alias(setgrent,_setgrent)
1322fe8fb19SBen Gras __weak_alias(setgroupent,_setgroupent)
1332fe8fb19SBen Gras #endif
1342fe8fb19SBen Gras 
1352fe8fb19SBen Gras #ifdef _REENTRANT
1362fe8fb19SBen Gras mutex_t	__grmutex = MUTEX_INITIALIZER;
1372fe8fb19SBen Gras #endif
1382fe8fb19SBen Gras 
1392fe8fb19SBen Gras /*
1402fe8fb19SBen Gras  * _gr_memfrombuf
1412fe8fb19SBen Gras  *	Obtain want bytes from buffer (of size buflen) and return a pointer
1422fe8fb19SBen Gras  *	to the available memory after adjusting buffer/buflen.
1432fe8fb19SBen Gras  *	Returns NULL if there is insufficient space.
1442fe8fb19SBen Gras  */
1452fe8fb19SBen Gras static char *
_gr_memfrombuf(size_t want,char ** buffer,size_t * buflen)1462fe8fb19SBen Gras _gr_memfrombuf(size_t want, char **buffer, size_t *buflen)
1472fe8fb19SBen Gras {
1482fe8fb19SBen Gras 	char	*rv;
1492fe8fb19SBen Gras 
1502fe8fb19SBen Gras 	if (want > *buflen) {
1512fe8fb19SBen Gras 		errno = ERANGE;
1522fe8fb19SBen Gras 		return NULL;
1532fe8fb19SBen Gras 	}
1542fe8fb19SBen Gras 	rv = *buffer;
1552fe8fb19SBen Gras 	*buffer += want;
1562fe8fb19SBen Gras 	*buflen -= want;
1572fe8fb19SBen Gras 	return rv;
1582fe8fb19SBen Gras }
1592fe8fb19SBen Gras 
1602fe8fb19SBen Gras /*
1612fe8fb19SBen Gras  * _gr_parse
1622fe8fb19SBen Gras  *	Parses entry as a line per group(5) (without the trailing \n)
1632fe8fb19SBen Gras  *	and fills in grp with corresponding values; memory for strings
1642fe8fb19SBen Gras  *	and arrays will be allocated from buf (of size buflen).
1652fe8fb19SBen Gras  *	Returns 1 if parsed successfully, 0 on parse failure.
1662fe8fb19SBen Gras  */
1672fe8fb19SBen Gras static int
_gr_parse(const char * entry,struct group * grp,char * buf,size_t buflen)1682fe8fb19SBen Gras _gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen)
1692fe8fb19SBen Gras {
1702fe8fb19SBen Gras 	unsigned long	id;
1712fe8fb19SBen Gras 	const char	*bp;
1722fe8fb19SBen Gras 	char		*ep;
1732fe8fb19SBen Gras 	size_t		count;
1742fe8fb19SBen Gras 	int		memc;
1752fe8fb19SBen Gras 
1762fe8fb19SBen Gras 	_DIAGASSERT(entry != NULL);
1772fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
1782fe8fb19SBen Gras 	_DIAGASSERT(buf != NULL);
1792fe8fb19SBen Gras 
1802fe8fb19SBen Gras #define COPYTOBUF(to) \
1812fe8fb19SBen Gras 	do { \
1822fe8fb19SBen Gras 		(to) = _gr_memfrombuf(count+1, &buf, &buflen); \
1832fe8fb19SBen Gras 		if ((to) == NULL) \
1842fe8fb19SBen Gras 			return 0; \
1852fe8fb19SBen Gras 		memmove((to), entry, count); \
1862fe8fb19SBen Gras 		to[count] = '\0'; \
1872fe8fb19SBen Gras 	} while (0)	/* LINTED */
1882fe8fb19SBen Gras 
1892fe8fb19SBen Gras #if 0
1902fe8fb19SBen Gras 	if (*entry == '+')			/* fail on compat `+' token */
1912fe8fb19SBen Gras 		return 0;
1922fe8fb19SBen Gras #endif
1932fe8fb19SBen Gras 
1942fe8fb19SBen Gras 	count = strcspn(entry, ":");		/* parse gr_name */
1952fe8fb19SBen Gras 	if (entry[count] == '\0')
1962fe8fb19SBen Gras 		return 0;
1972fe8fb19SBen Gras 	COPYTOBUF(grp->gr_name);
1982fe8fb19SBen Gras 	entry += count + 1;
1992fe8fb19SBen Gras 
2002fe8fb19SBen Gras 	count = strcspn(entry, ":");		/* parse gr_passwd */
2012fe8fb19SBen Gras 	if (entry[count] == '\0')
2022fe8fb19SBen Gras 		return 0;
2032fe8fb19SBen Gras 	COPYTOBUF(grp->gr_passwd);
2042fe8fb19SBen Gras 	entry += count + 1;
2052fe8fb19SBen Gras 
2062fe8fb19SBen Gras 	count = strcspn(entry, ":");		/* parse gr_gid */
2072fe8fb19SBen Gras 	if (entry[count] == '\0')
2082fe8fb19SBen Gras 		return 0;
2092fe8fb19SBen Gras 	id = strtoul(entry, &ep, 10);
2102fe8fb19SBen Gras 	if (id > GID_MAX || *ep != ':')
2112fe8fb19SBen Gras 		return 0;
2122fe8fb19SBen Gras 	grp->gr_gid = (gid_t)id;
2132fe8fb19SBen Gras 	entry += count + 1;
2142fe8fb19SBen Gras 
2152fe8fb19SBen Gras 	memc = 1;				/* for final NULL */
2162fe8fb19SBen Gras 	if (*entry != '\0')
2172fe8fb19SBen Gras 		memc++;				/* for first item */
2182fe8fb19SBen Gras 	for (bp = entry; *bp != '\0'; bp++) {
2192fe8fb19SBen Gras 		if (*bp == ',')
2202fe8fb19SBen Gras 			memc++;
2212fe8fb19SBen Gras 	}
2222fe8fb19SBen Gras 				/* grab ALIGNed char **gr_mem from buf */
2232fe8fb19SBen Gras 	ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
224*f14fb602SLionel Sambuc 	if (ep == NULL)
2252fe8fb19SBen Gras 		return 0;
226*f14fb602SLionel Sambuc 	grp->gr_mem = (char **)ALIGN(ep);
2272fe8fb19SBen Gras 
2282fe8fb19SBen Gras 	for (memc = 0; *entry != '\0'; memc++) {
2292fe8fb19SBen Gras 		count = strcspn(entry, ",");	/* parse member */
2302fe8fb19SBen Gras 		COPYTOBUF(grp->gr_mem[memc]);
2312fe8fb19SBen Gras 		entry += count;
2322fe8fb19SBen Gras 		if (*entry == ',')
2332fe8fb19SBen Gras 			entry++;
2342fe8fb19SBen Gras 	}
2352fe8fb19SBen Gras 
2362fe8fb19SBen Gras #undef COPYTOBUF
2372fe8fb19SBen Gras 
2382fe8fb19SBen Gras 	grp->gr_mem[memc] = NULL;
2392fe8fb19SBen Gras 	return 1;
2402fe8fb19SBen Gras }
2412fe8fb19SBen Gras 
2422fe8fb19SBen Gras /*
2432fe8fb19SBen Gras  * _gr_copy
2442fe8fb19SBen Gras  *	Copy the contents of fromgrp to grp; memory for strings
2452fe8fb19SBen Gras  *	and arrays will be allocated from buf (of size buflen).
2462fe8fb19SBen Gras  *	Returns 1 if copied successfully, 0 on copy failure.
2472fe8fb19SBen Gras  *	NOTE: fromgrp must not use buf for its own pointers.
2482fe8fb19SBen Gras  */
2492fe8fb19SBen Gras static int
_gr_copy(struct group * fromgrp,struct group * grp,char * buf,size_t buflen)2502fe8fb19SBen Gras _gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen)
2512fe8fb19SBen Gras {
2522fe8fb19SBen Gras 	char	*ep;
2532fe8fb19SBen Gras 	int	memc;
2542fe8fb19SBen Gras 
2552fe8fb19SBen Gras 	_DIAGASSERT(fromgrp != NULL);
2562fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
2572fe8fb19SBen Gras 	_DIAGASSERT(buf != NULL);
2582fe8fb19SBen Gras 
2592fe8fb19SBen Gras #define COPYSTR(to, from) \
2602fe8fb19SBen Gras 	do { \
2612fe8fb19SBen Gras 		size_t count = strlen((from)); \
2622fe8fb19SBen Gras 		(to) = _gr_memfrombuf(count+1, &buf, &buflen); \
2632fe8fb19SBen Gras 		if ((to) == NULL) \
2642fe8fb19SBen Gras 			return 0; \
2652fe8fb19SBen Gras 		memmove((to), (from), count); \
2662fe8fb19SBen Gras 		to[count] = '\0'; \
2672fe8fb19SBen Gras 	} while (0)	/* LINTED */
2682fe8fb19SBen Gras 
2692fe8fb19SBen Gras 	COPYSTR(grp->gr_name, fromgrp->gr_name);
2702fe8fb19SBen Gras 	COPYSTR(grp->gr_passwd, fromgrp->gr_passwd);
2712fe8fb19SBen Gras 	grp->gr_gid = fromgrp->gr_gid;
2722fe8fb19SBen Gras 
273*f14fb602SLionel Sambuc 	if (fromgrp->gr_mem == NULL)
274*f14fb602SLionel Sambuc 		return 0;
275*f14fb602SLionel Sambuc 
2762fe8fb19SBen Gras 	for (memc = 0; fromgrp->gr_mem[memc]; memc++)
2772fe8fb19SBen Gras 		continue;
2782fe8fb19SBen Gras 	memc++;					/* for final NULL */
2792fe8fb19SBen Gras 
2802fe8fb19SBen Gras 				/* grab ALIGNed char **gr_mem from buf */
2812fe8fb19SBen Gras 	ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
2822fe8fb19SBen Gras 	grp->gr_mem = (char **)ALIGN(ep);
2832fe8fb19SBen Gras 	if (grp->gr_mem == NULL)
2842fe8fb19SBen Gras 		return 0;
2852fe8fb19SBen Gras 
2862fe8fb19SBen Gras 	for (memc = 0; fromgrp->gr_mem[memc]; memc++) {
2872fe8fb19SBen Gras 		COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]);
2882fe8fb19SBen Gras 	}
2892fe8fb19SBen Gras 
2902fe8fb19SBen Gras #undef COPYSTR
2912fe8fb19SBen Gras 
2922fe8fb19SBen Gras 	grp->gr_mem[memc] = NULL;
2932fe8fb19SBen Gras 	return 1;
2942fe8fb19SBen Gras }
2952fe8fb19SBen Gras 
2962fe8fb19SBen Gras 		/*
2972fe8fb19SBen Gras 		 *	files methods
2982fe8fb19SBen Gras 		 */
2992fe8fb19SBen Gras 
3002fe8fb19SBen Gras int
__grstart_files(struct __grstate_files * state)3012fe8fb19SBen Gras __grstart_files(struct __grstate_files *state)
3022fe8fb19SBen Gras {
3032fe8fb19SBen Gras 
3042fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
3052fe8fb19SBen Gras 
3062fe8fb19SBen Gras 	if (state->fp == NULL) {
307*f14fb602SLionel Sambuc 		state->fp = fopen(_PATH_GROUP, "re");
3082fe8fb19SBen Gras 		if (state->fp == NULL)
3092fe8fb19SBen Gras 			return NS_UNAVAIL;
3102fe8fb19SBen Gras 	} else {
3112fe8fb19SBen Gras 		rewind(state->fp);
3122fe8fb19SBen Gras 	}
3132fe8fb19SBen Gras 	return NS_SUCCESS;
3142fe8fb19SBen Gras }
3152fe8fb19SBen Gras 
3162fe8fb19SBen Gras int
__grend_files(struct __grstate_files * state)3172fe8fb19SBen Gras __grend_files(struct __grstate_files *state)
3182fe8fb19SBen Gras {
3192fe8fb19SBen Gras 
3202fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
3212fe8fb19SBen Gras 
3222fe8fb19SBen Gras 	if (state->fp) {
3232fe8fb19SBen Gras 		(void) fclose(state->fp);
3242fe8fb19SBen Gras 		state->fp = NULL;
3252fe8fb19SBen Gras 	}
3262fe8fb19SBen Gras 	return NS_SUCCESS;
3272fe8fb19SBen Gras }
3282fe8fb19SBen Gras 
3292fe8fb19SBen Gras /*
3302fe8fb19SBen Gras  * __grscan_files
3312fe8fb19SBen Gras  *	Scan state->fp for the next desired entry.
3322fe8fb19SBen Gras  *	If search is zero, return the next entry.
3332fe8fb19SBen Gras  *	If search is non-zero, look for a specific name (if name != NULL),
3342fe8fb19SBen Gras  *	or a specific gid (if name == NULL).
3352fe8fb19SBen Gras  *	Sets *retval to the errno if the result is not NS_SUCCESS
3362fe8fb19SBen Gras  *	or NS_NOTFOUND.
3372fe8fb19SBen Gras  */
3382fe8fb19SBen Gras int
__grscan_files(int * retval,struct group * grp,char * buffer,size_t buflen,struct __grstate_files * state,int search,const char * name,gid_t gid)3392fe8fb19SBen Gras __grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen,
3402fe8fb19SBen Gras 	struct __grstate_files *state, int search, const char *name, gid_t gid)
3412fe8fb19SBen Gras {
3422fe8fb19SBen Gras 	int	rv;
3432fe8fb19SBen Gras 	char	filebuf[_GETGR_R_SIZE_MAX], *ep;
3442fe8fb19SBen Gras 
3452fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
3462fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
3472fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
3482fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
3492fe8fb19SBen Gras 	/* name is NULL to indicate searching for gid */
3502fe8fb19SBen Gras 
3512fe8fb19SBen Gras 	*retval = 0;
3522fe8fb19SBen Gras 
3532fe8fb19SBen Gras 	if (state->fp == NULL) {	/* only start if file not open yet */
3542fe8fb19SBen Gras 		rv = __grstart_files(state);
3552fe8fb19SBen Gras 		if (rv != NS_SUCCESS)
3562fe8fb19SBen Gras 			goto filesgrscan_out;
3572fe8fb19SBen Gras 	}
3582fe8fb19SBen Gras 
3592fe8fb19SBen Gras 	rv = NS_NOTFOUND;
3602fe8fb19SBen Gras 
3612fe8fb19SBen Gras 							/* scan line by line */
362*f14fb602SLionel Sambuc 	while (fgets(filebuf, (int)sizeof(filebuf), state->fp) != NULL) {
3632fe8fb19SBen Gras 		ep = strchr(filebuf, '\n');
3642fe8fb19SBen Gras 		if (ep == NULL) {	/* skip lines that are too big */
3652fe8fb19SBen Gras 			int ch;
3662fe8fb19SBen Gras 
3672fe8fb19SBen Gras 			while ((ch = getc(state->fp)) != '\n' && ch != EOF)
3682fe8fb19SBen Gras 				continue;
3692fe8fb19SBen Gras 			continue;
3702fe8fb19SBen Gras 		}
3712fe8fb19SBen Gras 		*ep = '\0';				/* clear trailing \n */
3722fe8fb19SBen Gras 
3732fe8fb19SBen Gras 		if (filebuf[0] == '+')			/* skip compat line */
3742fe8fb19SBen Gras 			continue;
3752fe8fb19SBen Gras 
3762fe8fb19SBen Gras 							/* validate line */
3772fe8fb19SBen Gras 		if (! _gr_parse(filebuf, grp, buffer, buflen)) {
3782fe8fb19SBen Gras 			continue;			/* skip bad lines */
3792fe8fb19SBen Gras 		}
3802fe8fb19SBen Gras 		if (! search) {				/* just want this one */
3812fe8fb19SBen Gras 			rv = NS_SUCCESS;
3822fe8fb19SBen Gras 			break;
3832fe8fb19SBen Gras 		}
3842fe8fb19SBen Gras 							/* want specific */
3852fe8fb19SBen Gras 		if ((name && strcmp(name, grp->gr_name) == 0) ||
3862fe8fb19SBen Gras 		    (!name && gid == grp->gr_gid)) {
3872fe8fb19SBen Gras 			rv = NS_SUCCESS;
3882fe8fb19SBen Gras 			break;
3892fe8fb19SBen Gras 		}
3902fe8fb19SBen Gras 	}
3912fe8fb19SBen Gras 
3922fe8fb19SBen Gras  filesgrscan_out:
3932fe8fb19SBen Gras 	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
3942fe8fb19SBen Gras 		*retval = errno;
3952fe8fb19SBen Gras 	return rv;
3962fe8fb19SBen Gras }
3972fe8fb19SBen Gras 
3982fe8fb19SBen Gras 
3992fe8fb19SBen Gras static struct __grstate_files	_files_state;
4002fe8fb19SBen Gras 					/* storage for non _r functions */
4012fe8fb19SBen Gras static struct group		_files_group;
4022fe8fb19SBen Gras static char			_files_groupbuf[_GETGR_R_SIZE_MAX];
4032fe8fb19SBen Gras 
4042fe8fb19SBen Gras /*ARGSUSED*/
4052fe8fb19SBen Gras static int
_files_setgrent(void * nsrv,void * nscb,va_list ap)4062fe8fb19SBen Gras _files_setgrent(void *nsrv, void *nscb, va_list ap)
4072fe8fb19SBen Gras {
4082fe8fb19SBen Gras 
4092fe8fb19SBen Gras 	_files_state.stayopen = 0;
4102fe8fb19SBen Gras 	return __grstart_files(&_files_state);
4112fe8fb19SBen Gras }
4122fe8fb19SBen Gras 
4132fe8fb19SBen Gras /*ARGSUSED*/
4142fe8fb19SBen Gras static int
_files_setgroupent(void * nsrv,void * nscb,va_list ap)4152fe8fb19SBen Gras _files_setgroupent(void *nsrv, void *nscb, va_list ap)
4162fe8fb19SBen Gras {
4172fe8fb19SBen Gras 	int	*retval		= va_arg(ap, int *);
4182fe8fb19SBen Gras 	int	 stayopen	= va_arg(ap, int);
4192fe8fb19SBen Gras 
4202fe8fb19SBen Gras 	int	rv;
4212fe8fb19SBen Gras 
4222fe8fb19SBen Gras 	_files_state.stayopen = stayopen;
4232fe8fb19SBen Gras 	rv = __grstart_files(&_files_state);
4242fe8fb19SBen Gras 	*retval = (rv == NS_SUCCESS);
4252fe8fb19SBen Gras 	return rv;
4262fe8fb19SBen Gras }
4272fe8fb19SBen Gras 
4282fe8fb19SBen Gras /*ARGSUSED*/
4292fe8fb19SBen Gras static int
_files_endgrent(void * nsrv,void * nscb,va_list ap)4302fe8fb19SBen Gras _files_endgrent(void *nsrv, void *nscb, va_list ap)
4312fe8fb19SBen Gras {
4322fe8fb19SBen Gras 
4332fe8fb19SBen Gras 	_files_state.stayopen = 0;
4342fe8fb19SBen Gras 	return __grend_files(&_files_state);
4352fe8fb19SBen Gras }
4362fe8fb19SBen Gras 
4372fe8fb19SBen Gras /*ARGSUSED*/
4382fe8fb19SBen Gras static int
_files_getgrent(void * nsrv,void * nscb,va_list ap)4392fe8fb19SBen Gras _files_getgrent(void *nsrv, void *nscb, va_list ap)
4402fe8fb19SBen Gras {
4412fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
4422fe8fb19SBen Gras 
4432fe8fb19SBen Gras 	int	rv, rerror;
4442fe8fb19SBen Gras 
4452fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
4462fe8fb19SBen Gras 
4472fe8fb19SBen Gras 	*retval = NULL;
4482fe8fb19SBen Gras 	rv = __grscan_files(&rerror, &_files_group,
4492fe8fb19SBen Gras 	    _files_groupbuf, sizeof(_files_groupbuf),
4502fe8fb19SBen Gras 	    &_files_state, 0, NULL, 0);
4512fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
4522fe8fb19SBen Gras 		*retval = &_files_group;
4532fe8fb19SBen Gras 	return rv;
4542fe8fb19SBen Gras }
4552fe8fb19SBen Gras 
4562fe8fb19SBen Gras /*ARGSUSED*/
4572fe8fb19SBen Gras static int
_files_getgrent_r(void * nsrv,void * nscb,va_list ap)4582fe8fb19SBen Gras _files_getgrent_r(void *nsrv, void *nscb, va_list ap)
4592fe8fb19SBen Gras {
4602fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
4612fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
4622fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
4632fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
4642fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
4652fe8fb19SBen Gras 
4662fe8fb19SBen Gras 	int	rv;
4672fe8fb19SBen Gras 
4682fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
4692fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
4702fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
4712fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
4722fe8fb19SBen Gras 
4732fe8fb19SBen Gras 	rv = __grscan_files(retval, grp, buffer, buflen,
4742fe8fb19SBen Gras 	    &_files_state, 0, NULL, 0);
4752fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
4762fe8fb19SBen Gras 		*result = grp;
4772fe8fb19SBen Gras 	else
4782fe8fb19SBen Gras 		*result = NULL;
4792fe8fb19SBen Gras 	return rv;
4802fe8fb19SBen Gras }
4812fe8fb19SBen Gras 
4822fe8fb19SBen Gras /*ARGSUSED*/
4832fe8fb19SBen Gras static int
_files_getgrgid(void * nsrv,void * nscb,va_list ap)4842fe8fb19SBen Gras _files_getgrgid(void *nsrv, void *nscb, va_list ap)
4852fe8fb19SBen Gras {
4862fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
4872fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
4882fe8fb19SBen Gras 
4892fe8fb19SBen Gras 	int	rv, rerror;
4902fe8fb19SBen Gras 
4912fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
4922fe8fb19SBen Gras 
4932fe8fb19SBen Gras 	*retval = NULL;
4942fe8fb19SBen Gras 	rv = __grstart_files(&_files_state);
4952fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
4962fe8fb19SBen Gras 		return rv;
4972fe8fb19SBen Gras 	rv = __grscan_files(&rerror, &_files_group,
4982fe8fb19SBen Gras 	    _files_groupbuf, sizeof(_files_groupbuf),
4992fe8fb19SBen Gras 	    &_files_state, 1, NULL, gid);
5002fe8fb19SBen Gras 	if (!_files_state.stayopen)
5012fe8fb19SBen Gras 		__grend_files(&_files_state);
5022fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
5032fe8fb19SBen Gras 		*retval = &_files_group;
5042fe8fb19SBen Gras 	return rv;
5052fe8fb19SBen Gras }
5062fe8fb19SBen Gras 
5072fe8fb19SBen Gras /*ARGSUSED*/
5082fe8fb19SBen Gras static int
_files_getgrgid_r(void * nsrv,void * nscb,va_list ap)5092fe8fb19SBen Gras _files_getgrgid_r(void *nsrv, void *nscb, va_list ap)
5102fe8fb19SBen Gras {
5112fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
5122fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
5132fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
5142fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
5152fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
5162fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
5172fe8fb19SBen Gras 
5182fe8fb19SBen Gras 	struct __grstate_files state;
5192fe8fb19SBen Gras 	int	rv;
5202fe8fb19SBen Gras 
5212fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
5222fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
5232fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
5242fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
5252fe8fb19SBen Gras 
5262fe8fb19SBen Gras 	*result = NULL;
5272fe8fb19SBen Gras 	memset(&state, 0, sizeof(state));
5282fe8fb19SBen Gras 	rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid);
5292fe8fb19SBen Gras 	__grend_files(&state);
5302fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
5312fe8fb19SBen Gras 		*result = grp;
5322fe8fb19SBen Gras 	return rv;
5332fe8fb19SBen Gras }
5342fe8fb19SBen Gras 
5352fe8fb19SBen Gras /*ARGSUSED*/
5362fe8fb19SBen Gras static int
_files_getgrnam(void * nsrv,void * nscb,va_list ap)5372fe8fb19SBen Gras _files_getgrnam(void *nsrv, void *nscb, va_list ap)
5382fe8fb19SBen Gras {
5392fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
5402fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
5412fe8fb19SBen Gras 
5422fe8fb19SBen Gras 	int	rv, rerror;
5432fe8fb19SBen Gras 
5442fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
5452fe8fb19SBen Gras 
5462fe8fb19SBen Gras 	*retval = NULL;
5472fe8fb19SBen Gras 	rv = __grstart_files(&_files_state);
5482fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
5492fe8fb19SBen Gras 		return rv;
5502fe8fb19SBen Gras 	rv = __grscan_files(&rerror, &_files_group,
5512fe8fb19SBen Gras 	    _files_groupbuf, sizeof(_files_groupbuf),
5522fe8fb19SBen Gras 	    &_files_state, 1, name, 0);
5532fe8fb19SBen Gras 	if (!_files_state.stayopen)
5542fe8fb19SBen Gras 		__grend_files(&_files_state);
5552fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
5562fe8fb19SBen Gras 		*retval = &_files_group;
5572fe8fb19SBen Gras 	return rv;
5582fe8fb19SBen Gras }
5592fe8fb19SBen Gras 
5602fe8fb19SBen Gras /*ARGSUSED*/
5612fe8fb19SBen Gras static int
_files_getgrnam_r(void * nsrv,void * nscb,va_list ap)5622fe8fb19SBen Gras _files_getgrnam_r(void *nsrv, void *nscb, va_list ap)
5632fe8fb19SBen Gras {
5642fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
5652fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
5662fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
5672fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
5682fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
5692fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
5702fe8fb19SBen Gras 
5712fe8fb19SBen Gras 	struct __grstate_files state;
5722fe8fb19SBen Gras 	int	rv;
5732fe8fb19SBen Gras 
5742fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
5752fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
5762fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
5772fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
5782fe8fb19SBen Gras 
5792fe8fb19SBen Gras 	*result = NULL;
5802fe8fb19SBen Gras 	memset(&state, 0, sizeof(state));
5812fe8fb19SBen Gras 	rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0);
5822fe8fb19SBen Gras 	__grend_files(&state);
5832fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
5842fe8fb19SBen Gras 		*result = grp;
5852fe8fb19SBen Gras 	return rv;
5862fe8fb19SBen Gras }
5872fe8fb19SBen Gras 
5882fe8fb19SBen Gras 
5892fe8fb19SBen Gras #ifdef HESIOD
5902fe8fb19SBen Gras 		/*
5912fe8fb19SBen Gras 		 *	dns methods
5922fe8fb19SBen Gras 		 */
5932fe8fb19SBen Gras 
5942fe8fb19SBen Gras int
__grstart_dns(struct __grstate_dns * state)5952fe8fb19SBen Gras __grstart_dns(struct __grstate_dns *state)
5962fe8fb19SBen Gras {
5972fe8fb19SBen Gras 
5982fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
5992fe8fb19SBen Gras 
6002fe8fb19SBen Gras 	state->num = 0;
6012fe8fb19SBen Gras 	if (state->context == NULL) {			/* setup Hesiod */
6022fe8fb19SBen Gras 		if (hesiod_init(&state->context) == -1)
6032fe8fb19SBen Gras 			return NS_UNAVAIL;
6042fe8fb19SBen Gras 	}
6052fe8fb19SBen Gras 
6062fe8fb19SBen Gras 	return NS_SUCCESS;
6072fe8fb19SBen Gras }
6082fe8fb19SBen Gras 
6092fe8fb19SBen Gras int
__grend_dns(struct __grstate_dns * state)6102fe8fb19SBen Gras __grend_dns(struct __grstate_dns *state)
6112fe8fb19SBen Gras {
6122fe8fb19SBen Gras 
6132fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
6142fe8fb19SBen Gras 
6152fe8fb19SBen Gras 	state->num = 0;
6162fe8fb19SBen Gras 	if (state->context) {
6172fe8fb19SBen Gras 		hesiod_end(state->context);
6182fe8fb19SBen Gras 		state->context = NULL;
6192fe8fb19SBen Gras 	}
6202fe8fb19SBen Gras 	return NS_SUCCESS;
6212fe8fb19SBen Gras }
6222fe8fb19SBen Gras 
6232fe8fb19SBen Gras /*
6242fe8fb19SBen Gras  * __grscan_dns
6252fe8fb19SBen Gras  *	Search Hesiod for the next desired entry.
6262fe8fb19SBen Gras  *	If search is zero, return the next entry.
6272fe8fb19SBen Gras  *	If search is non-zero, look for a specific name (if name != NULL),
6282fe8fb19SBen Gras  *	or a specific gid (if name == NULL).
6292fe8fb19SBen Gras  */
6302fe8fb19SBen Gras int
__grscan_dns(int * retval,struct group * grp,char * buffer,size_t buflen,struct __grstate_dns * state,int search,const char * name,gid_t gid)6312fe8fb19SBen Gras __grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen,
6322fe8fb19SBen Gras 	struct __grstate_dns *state, int search, const char *name, gid_t gid)
6332fe8fb19SBen Gras {
6342fe8fb19SBen Gras 	const char	**curzone;
6352fe8fb19SBen Gras 	char		**hp, *ep;
6362fe8fb19SBen Gras 	int		rv;
6372fe8fb19SBen Gras 
6382fe8fb19SBen Gras 	static const char *zones_gid_group[] = {
6392fe8fb19SBen Gras 		"gid",
6402fe8fb19SBen Gras 		"group",
6412fe8fb19SBen Gras 		NULL
6422fe8fb19SBen Gras 	};
6432fe8fb19SBen Gras 
6442fe8fb19SBen Gras 	static const char *zones_group[] = {
6452fe8fb19SBen Gras 		"group",
6462fe8fb19SBen Gras 		NULL
6472fe8fb19SBen Gras 	};
6482fe8fb19SBen Gras 
6492fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
6502fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
6512fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
6522fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
6532fe8fb19SBen Gras 	/* name is NULL to indicate searching for gid */
6542fe8fb19SBen Gras 
6552fe8fb19SBen Gras 	*retval = 0;
6562fe8fb19SBen Gras 
6572fe8fb19SBen Gras 	if (state->context == NULL) {	/* only start if Hesiod not setup */
6582fe8fb19SBen Gras 		rv = __grstart_dns(state);
6592fe8fb19SBen Gras 		if (rv != NS_SUCCESS)
6602fe8fb19SBen Gras 			return rv;
6612fe8fb19SBen Gras 	}
6622fe8fb19SBen Gras 
6632fe8fb19SBen Gras  next_dns_entry:
6642fe8fb19SBen Gras 	hp = NULL;
6652fe8fb19SBen Gras 	rv = NS_NOTFOUND;
6662fe8fb19SBen Gras 
6672fe8fb19SBen Gras 	if (! search) {			/* find next entry */
6682fe8fb19SBen Gras 		if (state->num == -1)		/* exhausted search */
6692fe8fb19SBen Gras 			return NS_NOTFOUND;
6702fe8fb19SBen Gras 						/* find group-NNN */
6712fe8fb19SBen Gras 		snprintf(buffer, buflen, "group-%u", state->num);
6722fe8fb19SBen Gras 		state->num++;
6732fe8fb19SBen Gras 		curzone = zones_group;
6742fe8fb19SBen Gras 	} else if (name) {		/* find group name */
6752fe8fb19SBen Gras 		snprintf(buffer, buflen, "%s", name);
6762fe8fb19SBen Gras 		curzone = zones_group;
6772fe8fb19SBen Gras 	} else {			/* find gid */
6782fe8fb19SBen Gras 		snprintf(buffer, buflen, "%u", (unsigned int)gid);
6792fe8fb19SBen Gras 		curzone = zones_gid_group;
6802fe8fb19SBen Gras 	}
6812fe8fb19SBen Gras 
6822fe8fb19SBen Gras 	for (; *curzone; curzone++) {		/* search zones */
6832fe8fb19SBen Gras 		hp = hesiod_resolve(state->context, buffer, *curzone);
6842fe8fb19SBen Gras 		if (hp != NULL)
6852fe8fb19SBen Gras 			break;
6862fe8fb19SBen Gras 		if (errno != ENOENT) {
6872fe8fb19SBen Gras 			rv = NS_UNAVAIL;
6882fe8fb19SBen Gras 			goto dnsgrscan_out;
6892fe8fb19SBen Gras 		}
6902fe8fb19SBen Gras 	}
6912fe8fb19SBen Gras 	if (*curzone == NULL) {
6922fe8fb19SBen Gras 		if (! search)
6932fe8fb19SBen Gras 			state->num = -1;
6942fe8fb19SBen Gras 		goto dnsgrscan_out;
6952fe8fb19SBen Gras 	}
6962fe8fb19SBen Gras 
6972fe8fb19SBen Gras 	if ((ep = strchr(hp[0], '\n')) != NULL)
6982fe8fb19SBen Gras 		*ep = '\0';				/* clear trailing \n */
6992fe8fb19SBen Gras 	if (_gr_parse(hp[0], grp, buffer, buflen)) {	/* validate line */
7002fe8fb19SBen Gras 		if (! search) {				/* just want this one */
7012fe8fb19SBen Gras 			rv = NS_SUCCESS;
7022fe8fb19SBen Gras 		} else if ((name && strcmp(name, grp->gr_name) == 0) ||
7032fe8fb19SBen Gras 		    (!name && gid == grp->gr_gid)) {	/* want specific */
7042fe8fb19SBen Gras 			rv = NS_SUCCESS;
7052fe8fb19SBen Gras 		}
7062fe8fb19SBen Gras 	} else {					/* dodgy entry */
7072fe8fb19SBen Gras 		if (!search) {			/* try again if ! searching */
7082fe8fb19SBen Gras 			hesiod_free_list(state->context, hp);
7092fe8fb19SBen Gras 			goto next_dns_entry;
7102fe8fb19SBen Gras 		}
7112fe8fb19SBen Gras 	}
7122fe8fb19SBen Gras 
7132fe8fb19SBen Gras  dnsgrscan_out:
7142fe8fb19SBen Gras 	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
7152fe8fb19SBen Gras 		*retval = errno;
7162fe8fb19SBen Gras 	if (hp)
7172fe8fb19SBen Gras 		hesiod_free_list(state->context, hp);
7182fe8fb19SBen Gras 	return rv;
7192fe8fb19SBen Gras }
7202fe8fb19SBen Gras 
7212fe8fb19SBen Gras static struct __grstate_dns	_dns_state;
7222fe8fb19SBen Gras 					/* storage for non _r functions */
7232fe8fb19SBen Gras static struct group		_dns_group;
7242fe8fb19SBen Gras static char			_dns_groupbuf[_GETGR_R_SIZE_MAX];
7252fe8fb19SBen Gras 
7262fe8fb19SBen Gras /*ARGSUSED*/
7272fe8fb19SBen Gras static int
_dns_setgrent(void * nsrv,void * nscb,va_list ap)7282fe8fb19SBen Gras _dns_setgrent(void *nsrv, void *nscb, va_list ap)
7292fe8fb19SBen Gras {
7302fe8fb19SBen Gras 
7312fe8fb19SBen Gras 	_dns_state.stayopen = 0;
7322fe8fb19SBen Gras 	return __grstart_dns(&_dns_state);
7332fe8fb19SBen Gras }
7342fe8fb19SBen Gras 
7352fe8fb19SBen Gras /*ARGSUSED*/
7362fe8fb19SBen Gras static int
_dns_setgroupent(void * nsrv,void * nscb,va_list ap)7372fe8fb19SBen Gras _dns_setgroupent(void *nsrv, void *nscb, va_list ap)
7382fe8fb19SBen Gras {
7392fe8fb19SBen Gras 	int	*retval		= va_arg(ap, int *);
7402fe8fb19SBen Gras 	int	 stayopen	= va_arg(ap, int);
7412fe8fb19SBen Gras 
7422fe8fb19SBen Gras 	int	rv;
7432fe8fb19SBen Gras 
7442fe8fb19SBen Gras 	_dns_state.stayopen = stayopen;
7452fe8fb19SBen Gras 	rv = __grstart_dns(&_dns_state);
7462fe8fb19SBen Gras 	*retval = (rv == NS_SUCCESS);
7472fe8fb19SBen Gras 	return rv;
7482fe8fb19SBen Gras }
7492fe8fb19SBen Gras 
7502fe8fb19SBen Gras /*ARGSUSED*/
7512fe8fb19SBen Gras static int
_dns_endgrent(void * nsrv,void * nscb,va_list ap)7522fe8fb19SBen Gras _dns_endgrent(void *nsrv, void *nscb, va_list ap)
7532fe8fb19SBen Gras {
7542fe8fb19SBen Gras 
7552fe8fb19SBen Gras 	_dns_state.stayopen = 0;
7562fe8fb19SBen Gras 	return __grend_dns(&_dns_state);
7572fe8fb19SBen Gras }
7582fe8fb19SBen Gras 
7592fe8fb19SBen Gras /*ARGSUSED*/
7602fe8fb19SBen Gras static int
_dns_getgrent(void * nsrv,void * nscb,va_list ap)7612fe8fb19SBen Gras _dns_getgrent(void *nsrv, void *nscb, va_list ap)
7622fe8fb19SBen Gras {
7632fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
7642fe8fb19SBen Gras 
7652fe8fb19SBen Gras 	int	  rv, rerror;
7662fe8fb19SBen Gras 
7672fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
7682fe8fb19SBen Gras 
7692fe8fb19SBen Gras 	*retval = NULL;
7702fe8fb19SBen Gras 	rv = __grscan_dns(&rerror, &_dns_group,
7712fe8fb19SBen Gras 	    _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0);
7722fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
7732fe8fb19SBen Gras 		*retval = &_dns_group;
7742fe8fb19SBen Gras 	return rv;
7752fe8fb19SBen Gras }
7762fe8fb19SBen Gras 
7772fe8fb19SBen Gras /*ARGSUSED*/
7782fe8fb19SBen Gras static int
_dns_getgrent_r(void * nsrv,void * nscb,va_list ap)7792fe8fb19SBen Gras _dns_getgrent_r(void *nsrv, void *nscb, va_list ap)
7802fe8fb19SBen Gras {
7812fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
7822fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
7832fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
7842fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
7852fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
7862fe8fb19SBen Gras 
7872fe8fb19SBen Gras 	int	rv;
7882fe8fb19SBen Gras 
7892fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
7902fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
7912fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
7922fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
7932fe8fb19SBen Gras 
7942fe8fb19SBen Gras 	rv = __grscan_dns(retval, grp, buffer, buflen,
7952fe8fb19SBen Gras 	    &_dns_state, 0, NULL, 0);
7962fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
7972fe8fb19SBen Gras 		*result = grp;
7982fe8fb19SBen Gras 	else
7992fe8fb19SBen Gras 		*result = NULL;
8002fe8fb19SBen Gras 	return rv;
8012fe8fb19SBen Gras }
8022fe8fb19SBen Gras /*ARGSUSED*/
8032fe8fb19SBen Gras static int
_dns_getgrgid(void * nsrv,void * nscb,va_list ap)8042fe8fb19SBen Gras _dns_getgrgid(void *nsrv, void *nscb, va_list ap)
8052fe8fb19SBen Gras {
8062fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
8072fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
8082fe8fb19SBen Gras 
8092fe8fb19SBen Gras 	int	rv, rerror;
8102fe8fb19SBen Gras 
8112fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
8122fe8fb19SBen Gras 
8132fe8fb19SBen Gras 	*retval = NULL;
8142fe8fb19SBen Gras 	rv = __grstart_dns(&_dns_state);
8152fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
8162fe8fb19SBen Gras 		return rv;
8172fe8fb19SBen Gras 	rv = __grscan_dns(&rerror, &_dns_group,
8182fe8fb19SBen Gras 	    _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid);
8192fe8fb19SBen Gras 	if (!_dns_state.stayopen)
8202fe8fb19SBen Gras 		__grend_dns(&_dns_state);
8212fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
8222fe8fb19SBen Gras 		*retval = &_dns_group;
8232fe8fb19SBen Gras 	return rv;
8242fe8fb19SBen Gras }
8252fe8fb19SBen Gras 
8262fe8fb19SBen Gras /*ARGSUSED*/
8272fe8fb19SBen Gras static int
_dns_getgrgid_r(void * nsrv,void * nscb,va_list ap)8282fe8fb19SBen Gras _dns_getgrgid_r(void *nsrv, void *nscb, va_list ap)
8292fe8fb19SBen Gras {
8302fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
8312fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
8322fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
8332fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
8342fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
8352fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
8362fe8fb19SBen Gras 
8372fe8fb19SBen Gras 	struct __grstate_dns state;
8382fe8fb19SBen Gras 	int	rv;
8392fe8fb19SBen Gras 
8402fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
8412fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
8422fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
8432fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
8442fe8fb19SBen Gras 
8452fe8fb19SBen Gras 	*result = NULL;
8462fe8fb19SBen Gras 	memset(&state, 0, sizeof(state));
8472fe8fb19SBen Gras 	rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid);
8482fe8fb19SBen Gras 	__grend_dns(&state);
8492fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
8502fe8fb19SBen Gras 		*result = grp;
8512fe8fb19SBen Gras 	return rv;
8522fe8fb19SBen Gras }
8532fe8fb19SBen Gras 
8542fe8fb19SBen Gras /*ARGSUSED*/
8552fe8fb19SBen Gras static int
_dns_getgrnam(void * nsrv,void * nscb,va_list ap)8562fe8fb19SBen Gras _dns_getgrnam(void *nsrv, void *nscb, va_list ap)
8572fe8fb19SBen Gras {
8582fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
8592fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
8602fe8fb19SBen Gras 
8612fe8fb19SBen Gras 	int	rv, rerror;
8622fe8fb19SBen Gras 
8632fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
8642fe8fb19SBen Gras 
8652fe8fb19SBen Gras 	*retval = NULL;
8662fe8fb19SBen Gras 	rv = __grstart_dns(&_dns_state);
8672fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
8682fe8fb19SBen Gras 		return rv;
8692fe8fb19SBen Gras 	rv = __grscan_dns(&rerror, &_dns_group,
8702fe8fb19SBen Gras 	    _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0);
8712fe8fb19SBen Gras 	if (!_dns_state.stayopen)
8722fe8fb19SBen Gras 		__grend_dns(&_dns_state);
8732fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
8742fe8fb19SBen Gras 		*retval = &_dns_group;
8752fe8fb19SBen Gras 	return rv;
8762fe8fb19SBen Gras }
8772fe8fb19SBen Gras 
8782fe8fb19SBen Gras /*ARGSUSED*/
8792fe8fb19SBen Gras static int
_dns_getgrnam_r(void * nsrv,void * nscb,va_list ap)8802fe8fb19SBen Gras _dns_getgrnam_r(void *nsrv, void *nscb, va_list ap)
8812fe8fb19SBen Gras {
8822fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
8832fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
8842fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
8852fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
8862fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
8872fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
8882fe8fb19SBen Gras 
8892fe8fb19SBen Gras 	struct __grstate_dns state;
8902fe8fb19SBen Gras 	int	rv;
8912fe8fb19SBen Gras 
8922fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
8932fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
8942fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
8952fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
8962fe8fb19SBen Gras 
8972fe8fb19SBen Gras 	*result = NULL;
8982fe8fb19SBen Gras 	memset(&state, 0, sizeof(state));
8992fe8fb19SBen Gras 	rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0);
9002fe8fb19SBen Gras 	__grend_dns(&state);
9012fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
9022fe8fb19SBen Gras 		*result = grp;
9032fe8fb19SBen Gras 	return rv;
9042fe8fb19SBen Gras }
9052fe8fb19SBen Gras 
9062fe8fb19SBen Gras #endif /* HESIOD */
9072fe8fb19SBen Gras 
9082fe8fb19SBen Gras 
9092fe8fb19SBen Gras #ifdef YP
9102fe8fb19SBen Gras 		/*
9112fe8fb19SBen Gras 		 *	nis methods
9122fe8fb19SBen Gras 		 */
9132fe8fb19SBen Gras 
9142fe8fb19SBen Gras int
__grstart_nis(struct __grstate_nis * state)9152fe8fb19SBen Gras __grstart_nis(struct __grstate_nis *state)
9162fe8fb19SBen Gras {
9172fe8fb19SBen Gras 
9182fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
9192fe8fb19SBen Gras 
9202fe8fb19SBen Gras 	state->done = 0;
9212fe8fb19SBen Gras 	if (state->current) {
9222fe8fb19SBen Gras 		free(state->current);
9232fe8fb19SBen Gras 		state->current = NULL;
9242fe8fb19SBen Gras 	}
9252fe8fb19SBen Gras 	if (state->domain == NULL) {			/* setup NIS */
9262fe8fb19SBen Gras 		switch (yp_get_default_domain(&state->domain)) {
9272fe8fb19SBen Gras 		case 0:
9282fe8fb19SBen Gras 			break;
9292fe8fb19SBen Gras 		case YPERR_RESRC:
9302fe8fb19SBen Gras 			return NS_TRYAGAIN;
9312fe8fb19SBen Gras 		default:
9322fe8fb19SBen Gras 			return NS_UNAVAIL;
9332fe8fb19SBen Gras 		}
9342fe8fb19SBen Gras 	}
9352fe8fb19SBen Gras 	return NS_SUCCESS;
9362fe8fb19SBen Gras }
9372fe8fb19SBen Gras 
9382fe8fb19SBen Gras int
__grend_nis(struct __grstate_nis * state)9392fe8fb19SBen Gras __grend_nis(struct __grstate_nis *state)
9402fe8fb19SBen Gras {
9412fe8fb19SBen Gras 
9422fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
9432fe8fb19SBen Gras 
9442fe8fb19SBen Gras 	if (state->domain) {
9452fe8fb19SBen Gras 		state->domain = NULL;
9462fe8fb19SBen Gras 	}
9472fe8fb19SBen Gras 	state->done = 0;
9482fe8fb19SBen Gras 	if (state->current) {
9492fe8fb19SBen Gras 		free(state->current);
9502fe8fb19SBen Gras 		state->current = NULL;
9512fe8fb19SBen Gras 	}
9522fe8fb19SBen Gras 	return NS_SUCCESS;
9532fe8fb19SBen Gras }
9542fe8fb19SBen Gras 
9552fe8fb19SBen Gras /*
9562fe8fb19SBen Gras  * __grscan_nis
9572fe8fb19SBen Gras  *	Search NIS for the next desired entry.
9582fe8fb19SBen Gras  *	If search is zero, return the next entry.
9592fe8fb19SBen Gras  *	If search is non-zero, look for a specific name (if name != NULL),
9602fe8fb19SBen Gras  *	or a specific gid (if name == NULL).
9612fe8fb19SBen Gras  */
9622fe8fb19SBen Gras int
__grscan_nis(int * retval,struct group * grp,char * buffer,size_t buflen,struct __grstate_nis * state,int search,const char * name,gid_t gid)9632fe8fb19SBen Gras __grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen,
9642fe8fb19SBen Gras 	struct __grstate_nis *state, int search, const char *name, gid_t gid)
9652fe8fb19SBen Gras {
9662fe8fb19SBen Gras 	const char *map;
9672fe8fb19SBen Gras 	char	*key, *data;
9682fe8fb19SBen Gras 	int	nisr, rv, keylen, datalen;
9692fe8fb19SBen Gras 
9702fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
9712fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
9722fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
9732fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
9742fe8fb19SBen Gras 	/* name is NULL to indicate searching for gid */
9752fe8fb19SBen Gras 
9762fe8fb19SBen Gras 	*retval = 0;
9772fe8fb19SBen Gras 
9782fe8fb19SBen Gras 	if (state->domain == NULL) {	/* only start if NIS not setup */
9792fe8fb19SBen Gras 		rv = __grstart_nis(state);
9802fe8fb19SBen Gras 		if (rv != NS_SUCCESS)
9812fe8fb19SBen Gras 			return rv;
9822fe8fb19SBen Gras 	}
9832fe8fb19SBen Gras 
9842fe8fb19SBen Gras  next_nis_entry:
9852fe8fb19SBen Gras 	key = NULL;
9862fe8fb19SBen Gras 	data = NULL;
9872fe8fb19SBen Gras 	rv = NS_SUCCESS;
9882fe8fb19SBen Gras 
9892fe8fb19SBen Gras 	if (! search) 	{			/* find next entry */
9902fe8fb19SBen Gras 		if (state->done)			/* exhausted search */
9912fe8fb19SBen Gras 			return NS_NOTFOUND;
9922fe8fb19SBen Gras 		map = "group.byname";
9932fe8fb19SBen Gras 		if (state->current) {			/* already searching */
9942fe8fb19SBen Gras 			nisr = yp_next(state->domain, map,
9952fe8fb19SBen Gras 			    state->current, state->currentlen,
9962fe8fb19SBen Gras 			    &key, &keylen, &data, &datalen);
9972fe8fb19SBen Gras 			free(state->current);
9982fe8fb19SBen Gras 			state->current = NULL;
9992fe8fb19SBen Gras 			switch (nisr) {
10002fe8fb19SBen Gras 			case 0:
10012fe8fb19SBen Gras 				state->current = key;
10022fe8fb19SBen Gras 				state->currentlen = keylen;
10032fe8fb19SBen Gras 				key = NULL;
10042fe8fb19SBen Gras 				break;
10052fe8fb19SBen Gras 			case YPERR_NOMORE:
10062fe8fb19SBen Gras 				rv = NS_NOTFOUND;
10072fe8fb19SBen Gras 				state->done = 1;
10082fe8fb19SBen Gras 				break;
10092fe8fb19SBen Gras 			default:
10102fe8fb19SBen Gras 				rv = NS_UNAVAIL;
10112fe8fb19SBen Gras 				break;
10122fe8fb19SBen Gras 			}
10132fe8fb19SBen Gras 		} else {				/* new search */
10142fe8fb19SBen Gras 			if (yp_first(state->domain, map,
10152fe8fb19SBen Gras 			    &state->current, &state->currentlen,
10162fe8fb19SBen Gras 			    &data, &datalen)) {
10172fe8fb19SBen Gras 				rv = NS_UNAVAIL;
10182fe8fb19SBen Gras 			}
10192fe8fb19SBen Gras 		}
10202fe8fb19SBen Gras 	} else {				/* search for specific item */
10212fe8fb19SBen Gras 		if (name) {			/* find group name */
10222fe8fb19SBen Gras 			snprintf(buffer, buflen, "%s", name);
10232fe8fb19SBen Gras 			map = "group.byname";
10242fe8fb19SBen Gras 		} else {			/* find gid */
10252fe8fb19SBen Gras 			snprintf(buffer, buflen, "%u", (unsigned int)gid);
10262fe8fb19SBen Gras 			map = "group.bygid";
10272fe8fb19SBen Gras 		}
10282fe8fb19SBen Gras 		nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer),
10292fe8fb19SBen Gras 		    &data, &datalen);
10302fe8fb19SBen Gras 		switch (nisr) {
10312fe8fb19SBen Gras 		case 0:
10322fe8fb19SBen Gras 			break;
10332fe8fb19SBen Gras 		case YPERR_KEY:
10342fe8fb19SBen Gras 			rv = NS_NOTFOUND;
10352fe8fb19SBen Gras 			break;
10362fe8fb19SBen Gras 		default:
10372fe8fb19SBen Gras 			rv = NS_UNAVAIL;
10382fe8fb19SBen Gras 			break;
10392fe8fb19SBen Gras 		}
10402fe8fb19SBen Gras 	}
10412fe8fb19SBen Gras 	if (rv == NS_SUCCESS) {				/* validate data */
10422fe8fb19SBen Gras 		data[datalen] = '\0';			/* clear trailing \n */
10432fe8fb19SBen Gras 		if (_gr_parse(data, grp, buffer, buflen)) {
10442fe8fb19SBen Gras 			if (! search) {			/* just want this one */
10452fe8fb19SBen Gras 				rv = NS_SUCCESS;
10462fe8fb19SBen Gras 			} else if ((name && strcmp(name, grp->gr_name) == 0) ||
10472fe8fb19SBen Gras 			    (!name && gid == grp->gr_gid)) {
10482fe8fb19SBen Gras 							/* want specific */
10492fe8fb19SBen Gras 				rv = NS_SUCCESS;
10502fe8fb19SBen Gras 			}
10512fe8fb19SBen Gras 		} else {				/* dodgy entry */
10522fe8fb19SBen Gras 			if (!search) {		/* try again if ! searching */
10532fe8fb19SBen Gras 				free(data);
10542fe8fb19SBen Gras 				goto next_nis_entry;
10552fe8fb19SBen Gras 			}
10562fe8fb19SBen Gras 		}
10572fe8fb19SBen Gras 	}
10582fe8fb19SBen Gras 
10592fe8fb19SBen Gras 	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
10602fe8fb19SBen Gras 		*retval = errno;
10612fe8fb19SBen Gras 	if (key)
10622fe8fb19SBen Gras 		free(key);
10632fe8fb19SBen Gras 	if (data)
10642fe8fb19SBen Gras 		free(data);
10652fe8fb19SBen Gras 	return rv;
10662fe8fb19SBen Gras }
10672fe8fb19SBen Gras 
10682fe8fb19SBen Gras static struct __grstate_nis	_nis_state;
10692fe8fb19SBen Gras 					/* storage for non _r functions */
10702fe8fb19SBen Gras static struct group		_nis_group;
10712fe8fb19SBen Gras static char			_nis_groupbuf[_GETGR_R_SIZE_MAX];
10722fe8fb19SBen Gras 
10732fe8fb19SBen Gras /*ARGSUSED*/
10742fe8fb19SBen Gras static int
_nis_setgrent(void * nsrv,void * nscb,va_list ap)10752fe8fb19SBen Gras _nis_setgrent(void *nsrv, void *nscb, va_list ap)
10762fe8fb19SBen Gras {
10772fe8fb19SBen Gras 
10782fe8fb19SBen Gras 	_nis_state.stayopen = 0;
10792fe8fb19SBen Gras 	return __grstart_nis(&_nis_state);
10802fe8fb19SBen Gras }
10812fe8fb19SBen Gras 
10822fe8fb19SBen Gras /*ARGSUSED*/
10832fe8fb19SBen Gras static int
_nis_setgroupent(void * nsrv,void * nscb,va_list ap)10842fe8fb19SBen Gras _nis_setgroupent(void *nsrv, void *nscb, va_list ap)
10852fe8fb19SBen Gras {
10862fe8fb19SBen Gras 	int	*retval		= va_arg(ap, int *);
10872fe8fb19SBen Gras 	int	 stayopen	= va_arg(ap, int);
10882fe8fb19SBen Gras 
10892fe8fb19SBen Gras 	int	rv;
10902fe8fb19SBen Gras 
10912fe8fb19SBen Gras 	_nis_state.stayopen = stayopen;
10922fe8fb19SBen Gras 	rv = __grstart_nis(&_nis_state);
10932fe8fb19SBen Gras 	*retval = (rv == NS_SUCCESS);
10942fe8fb19SBen Gras 	return rv;
10952fe8fb19SBen Gras }
10962fe8fb19SBen Gras 
10972fe8fb19SBen Gras /*ARGSUSED*/
10982fe8fb19SBen Gras static int
_nis_endgrent(void * nsrv,void * nscb,va_list ap)10992fe8fb19SBen Gras _nis_endgrent(void *nsrv, void *nscb, va_list ap)
11002fe8fb19SBen Gras {
11012fe8fb19SBen Gras 
11022fe8fb19SBen Gras 	return __grend_nis(&_nis_state);
11032fe8fb19SBen Gras }
11042fe8fb19SBen Gras 
11052fe8fb19SBen Gras /*ARGSUSED*/
11062fe8fb19SBen Gras static int
_nis_getgrent(void * nsrv,void * nscb,va_list ap)11072fe8fb19SBen Gras _nis_getgrent(void *nsrv, void *nscb, va_list ap)
11082fe8fb19SBen Gras {
11092fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
11102fe8fb19SBen Gras 
11112fe8fb19SBen Gras 	int	rv, rerror;
11122fe8fb19SBen Gras 
11132fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
11142fe8fb19SBen Gras 
11152fe8fb19SBen Gras 	*retval = NULL;
11162fe8fb19SBen Gras 	rv = __grscan_nis(&rerror, &_nis_group,
11172fe8fb19SBen Gras 	    _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0);
11182fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
11192fe8fb19SBen Gras 		*retval = &_nis_group;
11202fe8fb19SBen Gras 	return rv;
11212fe8fb19SBen Gras }
11222fe8fb19SBen Gras 
11232fe8fb19SBen Gras /*ARGSUSED*/
11242fe8fb19SBen Gras static int
_nis_getgrent_r(void * nsrv,void * nscb,va_list ap)11252fe8fb19SBen Gras _nis_getgrent_r(void *nsrv, void *nscb, va_list ap)
11262fe8fb19SBen Gras {
11272fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
11282fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
11292fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
11302fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
11312fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
11322fe8fb19SBen Gras 
11332fe8fb19SBen Gras 	int	rv;
11342fe8fb19SBen Gras 
11352fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
11362fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
11372fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
11382fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
11392fe8fb19SBen Gras 
11402fe8fb19SBen Gras 	rv = __grscan_nis(retval, grp, buffer, buflen,
11412fe8fb19SBen Gras 	    &_nis_state, 0, NULL, 0);
11422fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
11432fe8fb19SBen Gras 		*result = grp;
11442fe8fb19SBen Gras 	else
11452fe8fb19SBen Gras 		*result = NULL;
11462fe8fb19SBen Gras 	return rv;
11472fe8fb19SBen Gras }
11482fe8fb19SBen Gras 
11492fe8fb19SBen Gras /*ARGSUSED*/
11502fe8fb19SBen Gras static int
_nis_getgrgid(void * nsrv,void * nscb,va_list ap)11512fe8fb19SBen Gras _nis_getgrgid(void *nsrv, void *nscb, va_list ap)
11522fe8fb19SBen Gras {
11532fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
11542fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
11552fe8fb19SBen Gras 
11562fe8fb19SBen Gras 	int	rv, rerror;
11572fe8fb19SBen Gras 
11582fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
11592fe8fb19SBen Gras 
11602fe8fb19SBen Gras 	*retval = NULL;
11612fe8fb19SBen Gras 	rv = __grstart_nis(&_nis_state);
11622fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
11632fe8fb19SBen Gras 		return rv;
11642fe8fb19SBen Gras 	rv = __grscan_nis(&rerror, &_nis_group,
11652fe8fb19SBen Gras 	    _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid);
11662fe8fb19SBen Gras 	if (!_nis_state.stayopen)
11672fe8fb19SBen Gras 		__grend_nis(&_nis_state);
11682fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
11692fe8fb19SBen Gras 		*retval = &_nis_group;
11702fe8fb19SBen Gras 	return rv;
11712fe8fb19SBen Gras }
11722fe8fb19SBen Gras 
11732fe8fb19SBen Gras /*ARGSUSED*/
11742fe8fb19SBen Gras static int
_nis_getgrgid_r(void * nsrv,void * nscb,va_list ap)11752fe8fb19SBen Gras _nis_getgrgid_r(void *nsrv, void *nscb, va_list ap)
11762fe8fb19SBen Gras {
11772fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
11782fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
11792fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
11802fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
11812fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
11822fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
11832fe8fb19SBen Gras 
11842fe8fb19SBen Gras 	struct __grstate_nis state;
11852fe8fb19SBen Gras 	int	rv;
11862fe8fb19SBen Gras 
11872fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
11882fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
11892fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
11902fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
11912fe8fb19SBen Gras 
11922fe8fb19SBen Gras 	*result = NULL;
1193*f14fb602SLionel Sambuc /* remark: we run under a global mutex inside of this module ... */
1194*f14fb602SLionel Sambuc 	if (_nis_state.stayopen)
1195*f14fb602SLionel Sambuc 	  { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
1196*f14fb602SLionel Sambuc 	     rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, NULL, gid);
1197*f14fb602SLionel Sambuc 	  }
1198*f14fb602SLionel Sambuc 	else
1199*f14fb602SLionel Sambuc 	  {
12002fe8fb19SBen Gras 	    memset(&state, 0, sizeof(state));
12012fe8fb19SBen Gras 	    rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
12022fe8fb19SBen Gras 	    __grend_nis(&state);
1203*f14fb602SLionel Sambuc 	  }
12042fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
12052fe8fb19SBen Gras 		*result = grp;
12062fe8fb19SBen Gras 	return rv;
12072fe8fb19SBen Gras }
12082fe8fb19SBen Gras 
12092fe8fb19SBen Gras /*ARGSUSED*/
12102fe8fb19SBen Gras static int
_nis_getgrnam(void * nsrv,void * nscb,va_list ap)12112fe8fb19SBen Gras _nis_getgrnam(void *nsrv, void *nscb, va_list ap)
12122fe8fb19SBen Gras {
12132fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
12142fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
12152fe8fb19SBen Gras 
12162fe8fb19SBen Gras 	int	rv, rerror;
12172fe8fb19SBen Gras 
12182fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
12192fe8fb19SBen Gras 
12202fe8fb19SBen Gras 	*retval = NULL;
12212fe8fb19SBen Gras 	rv = __grstart_nis(&_nis_state);
12222fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
12232fe8fb19SBen Gras 		return rv;
12242fe8fb19SBen Gras 	rv = __grscan_nis(&rerror, &_nis_group,
12252fe8fb19SBen Gras 	    _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0);
12262fe8fb19SBen Gras 	if (!_nis_state.stayopen)
12272fe8fb19SBen Gras 		__grend_nis(&_nis_state);
12282fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
12292fe8fb19SBen Gras 		*retval = &_nis_group;
12302fe8fb19SBen Gras 	return rv;
12312fe8fb19SBen Gras }
12322fe8fb19SBen Gras 
12332fe8fb19SBen Gras /*ARGSUSED*/
12342fe8fb19SBen Gras static int
_nis_getgrnam_r(void * nsrv,void * nscb,va_list ap)12352fe8fb19SBen Gras _nis_getgrnam_r(void *nsrv, void *nscb, va_list ap)
12362fe8fb19SBen Gras {
12372fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
12382fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
12392fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
12402fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
12412fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
12422fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
12432fe8fb19SBen Gras 
12442fe8fb19SBen Gras 	struct __grstate_nis state;
12452fe8fb19SBen Gras 	int	rv;
12462fe8fb19SBen Gras 
12472fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
12482fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
12492fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
12502fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
12512fe8fb19SBen Gras 
12522fe8fb19SBen Gras 	*result = NULL;
1253*f14fb602SLionel Sambuc /* remark: we run under a global mutex inside of this module ... */
1254*f14fb602SLionel Sambuc 	if (_nis_state.stayopen)
1255*f14fb602SLionel Sambuc 	  { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
1256*f14fb602SLionel Sambuc 	     rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, name, 0);
1257*f14fb602SLionel Sambuc 	  }
1258*f14fb602SLionel Sambuc 	else
1259*f14fb602SLionel Sambuc 	  {
12602fe8fb19SBen Gras 	    memset(&state, 0, sizeof(state));
12612fe8fb19SBen Gras 	    rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
12622fe8fb19SBen Gras 	    __grend_nis(&state);
1263*f14fb602SLionel Sambuc 	  }
12642fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
12652fe8fb19SBen Gras 		*result = grp;
12662fe8fb19SBen Gras 	return rv;
12672fe8fb19SBen Gras }
12682fe8fb19SBen Gras 
12692fe8fb19SBen Gras #endif /* YP */
12702fe8fb19SBen Gras 
12712fe8fb19SBen Gras 
12722fe8fb19SBen Gras #ifdef _GROUP_COMPAT
12732fe8fb19SBen Gras 		/*
12742fe8fb19SBen Gras 		 *	compat methods
12752fe8fb19SBen Gras 		 */
12762fe8fb19SBen Gras 
12772fe8fb19SBen Gras int
__grstart_compat(struct __grstate_compat * state)12782fe8fb19SBen Gras __grstart_compat(struct __grstate_compat *state)
12792fe8fb19SBen Gras {
12802fe8fb19SBen Gras 
12812fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
12822fe8fb19SBen Gras 
12832fe8fb19SBen Gras 	if (state->fp == NULL) {
1284*f14fb602SLionel Sambuc 		state->fp = fopen(_PATH_GROUP, "re");
12852fe8fb19SBen Gras 		if (state->fp == NULL)
12862fe8fb19SBen Gras 			return NS_UNAVAIL;
12872fe8fb19SBen Gras 	} else {
12882fe8fb19SBen Gras 		rewind(state->fp);
12892fe8fb19SBen Gras 	}
12902fe8fb19SBen Gras 	return NS_SUCCESS;
12912fe8fb19SBen Gras }
12922fe8fb19SBen Gras 
12932fe8fb19SBen Gras int
__grend_compat(struct __grstate_compat * state)12942fe8fb19SBen Gras __grend_compat(struct __grstate_compat *state)
12952fe8fb19SBen Gras {
12962fe8fb19SBen Gras 
12972fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
12982fe8fb19SBen Gras 
12992fe8fb19SBen Gras 	if (state->name) {
13002fe8fb19SBen Gras 		free(state->name);
13012fe8fb19SBen Gras 		state->name = NULL;
13022fe8fb19SBen Gras 	}
13032fe8fb19SBen Gras 	if (state->fp) {
13042fe8fb19SBen Gras 		(void) fclose(state->fp);
13052fe8fb19SBen Gras 		state->fp = NULL;
13062fe8fb19SBen Gras 	}
13072fe8fb19SBen Gras 	return NS_SUCCESS;
13082fe8fb19SBen Gras }
13092fe8fb19SBen Gras 
13102fe8fb19SBen Gras 
13112fe8fb19SBen Gras /*
13122fe8fb19SBen Gras  * __grbad_compat
13132fe8fb19SBen Gras  *	log an error if "files" or "compat" is specified in
13142fe8fb19SBen Gras  *	group_compat database
13152fe8fb19SBen Gras  */
13162fe8fb19SBen Gras /*ARGSUSED*/
13172fe8fb19SBen Gras int
__grbad_compat(void * nsrv,void * nscb,va_list ap)13182fe8fb19SBen Gras __grbad_compat(void *nsrv, void *nscb, va_list ap)
13192fe8fb19SBen Gras {
13202fe8fb19SBen Gras 	static int warned;
13212fe8fb19SBen Gras 
13222fe8fb19SBen Gras 	_DIAGASSERT(nsrv != NULL);
13232fe8fb19SBen Gras 	_DIAGASSERT(nscb != NULL);
13242fe8fb19SBen Gras 
13252fe8fb19SBen Gras 	if (!warned) {
13262fe8fb19SBen Gras 		syslog(LOG_ERR,
13272fe8fb19SBen Gras 			"nsswitch.conf group_compat database can't use '%s'",
13282fe8fb19SBen Gras 			(const char *)nscb);
13292fe8fb19SBen Gras 	}
13302fe8fb19SBen Gras 	warned = 1;
13312fe8fb19SBen Gras 	return NS_UNAVAIL;
13322fe8fb19SBen Gras }
13332fe8fb19SBen Gras 
13342fe8fb19SBen Gras /*
13352fe8fb19SBen Gras  * __grscan_compat
13362fe8fb19SBen Gras  *	Scan state->fp for the next desired entry.
13372fe8fb19SBen Gras  *	If search is zero, return the next entry.
13382fe8fb19SBen Gras  *	If search is non-zero, look for a specific name (if name != NULL),
13392fe8fb19SBen Gras  *	or a specific gid (if name == NULL).
13402fe8fb19SBen Gras  *	Sets *retval to the errno if the result is not NS_SUCCESS or
13412fe8fb19SBen Gras  *	NS_NOTFOUND.
13422fe8fb19SBen Gras  *
13432fe8fb19SBen Gras  *	searchfunc is invoked when a compat "+" lookup is required;
13442fe8fb19SBen Gras  *	searchcookie is passed as the first argument to searchfunc,
13452fe8fb19SBen Gras  *	the second argument is the group result.
13462fe8fb19SBen Gras  *	This should return NS_NOTFOUND when "no more groups" from compat src.
13472fe8fb19SBen Gras  *	If searchfunc is NULL then nsdispatch of getgrent is used.
13482fe8fb19SBen Gras  *	This is primarily intended for getgroupmembership(3)'s compat backend.
13492fe8fb19SBen Gras  */
13502fe8fb19SBen Gras int
__grscan_compat(int * retval,struct group * grp,char * buffer,size_t buflen,struct __grstate_compat * state,int search,const char * name,gid_t gid,int (* searchfunc)(void *,struct group **),void * searchcookie)13512fe8fb19SBen Gras __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen,
13522fe8fb19SBen Gras 	struct __grstate_compat *state, int search, const char *name, gid_t gid,
13532fe8fb19SBen Gras 	int (*searchfunc)(void *, struct group **), void *searchcookie)
13542fe8fb19SBen Gras {
13552fe8fb19SBen Gras 	int		rv;
13562fe8fb19SBen Gras 	char		filebuf[_GETGR_R_SIZE_MAX], *ep;
13572fe8fb19SBen Gras 
13582fe8fb19SBen Gras 	static const ns_dtab compatentdtab[] = {
13592fe8fb19SBen Gras 		NS_FILES_CB(__grbad_compat, "files")
13602fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrent_r, NULL)
13612fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrent_r, NULL)
13622fe8fb19SBen Gras 		NS_COMPAT_CB(__grbad_compat, "compat")
13632fe8fb19SBen Gras 		NS_NULL_CB
13642fe8fb19SBen Gras 	};
13652fe8fb19SBen Gras 	static const ns_dtab compatgiddtab[] = {
13662fe8fb19SBen Gras 		NS_FILES_CB(__grbad_compat, "files")
13672fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrgid_r, NULL)
13682fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrgid_r, NULL)
13692fe8fb19SBen Gras 		NS_COMPAT_CB(__grbad_compat, "compat")
13702fe8fb19SBen Gras 		NS_NULL_CB
13712fe8fb19SBen Gras 	};
13722fe8fb19SBen Gras 	static const ns_dtab compatnamdtab[] = {
13732fe8fb19SBen Gras 		NS_FILES_CB(__grbad_compat, "files")
13742fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrnam_r, NULL)
13752fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrnam_r, NULL)
13762fe8fb19SBen Gras 		NS_COMPAT_CB(__grbad_compat, "compat")
13772fe8fb19SBen Gras 		NS_NULL_CB
13782fe8fb19SBen Gras 	};
13792fe8fb19SBen Gras 
13802fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
13812fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
13822fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
13832fe8fb19SBen Gras 	_DIAGASSERT(state != NULL);
13842fe8fb19SBen Gras 	/* name is NULL to indicate searching for gid */
13852fe8fb19SBen Gras 
13862fe8fb19SBen Gras 	*retval = 0;
13872fe8fb19SBen Gras 
13882fe8fb19SBen Gras 	if (state->fp == NULL) {	/* only start if file not open yet */
13892fe8fb19SBen Gras 		rv = __grstart_compat(state);
13902fe8fb19SBen Gras 		if (rv != NS_SUCCESS)
13912fe8fb19SBen Gras 			goto compatgrscan_out;
13922fe8fb19SBen Gras 	}
13932fe8fb19SBen Gras 	rv = NS_NOTFOUND;
13942fe8fb19SBen Gras 
13952fe8fb19SBen Gras 	for (;;) {					/* loop through file */
13962fe8fb19SBen Gras 		if (state->name != NULL) {
13972fe8fb19SBen Gras 					/* processing compat entry */
13982fe8fb19SBen Gras 			int		crv, cretval;
13992fe8fb19SBen Gras 			struct group	cgrp, *cgrpres;
14002fe8fb19SBen Gras 
14012fe8fb19SBen Gras 			if (state->name[0]) {		/* specific +group: */
14022fe8fb19SBen Gras 				crv = nsdispatch(NULL, compatnamdtab,
14032fe8fb19SBen Gras 				    NSDB_GROUP_COMPAT, "getgrnam_r",
14042fe8fb19SBen Gras 				    __nsdefaultnis,
14052fe8fb19SBen Gras 				    &cretval, state->name,
14062fe8fb19SBen Gras 				    &cgrp, filebuf, sizeof(filebuf), &cgrpres);
14072fe8fb19SBen Gras 				free(state->name);	/* (only check 1 grp) */
14082fe8fb19SBen Gras 				state->name = NULL;
14092fe8fb19SBen Gras 			} else if (!search) {		/* any group */
14102fe8fb19SBen Gras 				if (searchfunc) {
14112fe8fb19SBen Gras 					crv = searchfunc(searchcookie,
14122fe8fb19SBen Gras 					    &cgrpres);
14132fe8fb19SBen Gras 				} else {
14142fe8fb19SBen Gras 					crv = nsdispatch(NULL, compatentdtab,
14152fe8fb19SBen Gras 					    NSDB_GROUP_COMPAT, "getgrent_r",
14162fe8fb19SBen Gras 					    __nsdefaultnis,
14172fe8fb19SBen Gras 					    &cretval, &cgrp, filebuf,
14182fe8fb19SBen Gras 					    sizeof(filebuf), &cgrpres);
14192fe8fb19SBen Gras 				}
14202fe8fb19SBen Gras 			} else if (name) {		/* specific group */
14212fe8fb19SBen Gras 				crv = nsdispatch(NULL, compatnamdtab,
14222fe8fb19SBen Gras 				    NSDB_GROUP_COMPAT, "getgrnam_r",
14232fe8fb19SBen Gras 				    __nsdefaultnis,
14242fe8fb19SBen Gras 				    &cretval, name,
14252fe8fb19SBen Gras 				    &cgrp, filebuf, sizeof(filebuf), &cgrpres);
14262fe8fb19SBen Gras 			} else {			/* specific gid */
14272fe8fb19SBen Gras 				crv = nsdispatch(NULL, compatgiddtab,
14282fe8fb19SBen Gras 				    NSDB_GROUP_COMPAT, "getgrgid_r",
14292fe8fb19SBen Gras 				    __nsdefaultnis,
14302fe8fb19SBen Gras 				    &cretval, gid,
14312fe8fb19SBen Gras 				    &cgrp, filebuf, sizeof(filebuf), &cgrpres);
14322fe8fb19SBen Gras 			}
14332fe8fb19SBen Gras 			if (crv != NS_SUCCESS) {	/* not found */
14342fe8fb19SBen Gras 				free(state->name);
14352fe8fb19SBen Gras 				state->name = NULL;
14362fe8fb19SBen Gras 				continue;		/* try next line */
14372fe8fb19SBen Gras 			}
14382fe8fb19SBen Gras 			if (!_gr_copy(cgrpres, grp, buffer, buflen)) {
14392fe8fb19SBen Gras 				rv = NS_UNAVAIL;
14402fe8fb19SBen Gras 				break;
14412fe8fb19SBen Gras 			}
14422fe8fb19SBen Gras 			goto compatgrscan_cmpgrp;	/* skip to grp test */
14432fe8fb19SBen Gras 		}
14442fe8fb19SBen Gras 
14452fe8fb19SBen Gras 							/* get next file line */
1446*f14fb602SLionel Sambuc 		if (fgets(filebuf, (int)sizeof(filebuf), state->fp) == NULL)
14472fe8fb19SBen Gras 			break;
14482fe8fb19SBen Gras 
14492fe8fb19SBen Gras 		ep = strchr(filebuf, '\n');
14502fe8fb19SBen Gras 		if (ep == NULL) {	/* skip lines that are too big */
14512fe8fb19SBen Gras 			int ch;
14522fe8fb19SBen Gras 
14532fe8fb19SBen Gras 			while ((ch = getc(state->fp)) != '\n' && ch != EOF)
14542fe8fb19SBen Gras 				continue;
14552fe8fb19SBen Gras 			continue;
14562fe8fb19SBen Gras 		}
14572fe8fb19SBen Gras 		*ep = '\0';				/* clear trailing \n */
14582fe8fb19SBen Gras 
14592fe8fb19SBen Gras 		if (filebuf[0] == '+') {		/* parse compat line */
14602fe8fb19SBen Gras 			if (state->name)
14612fe8fb19SBen Gras 				free(state->name);
14622fe8fb19SBen Gras 			state->name = NULL;
14632fe8fb19SBen Gras 			switch(filebuf[1]) {
14642fe8fb19SBen Gras 			case ':':
14652fe8fb19SBen Gras 			case '\0':
14662fe8fb19SBen Gras 				state->name = strdup("");
14672fe8fb19SBen Gras 				break;
14682fe8fb19SBen Gras 			default:
14692fe8fb19SBen Gras 				ep = strchr(filebuf + 1, ':');
14702fe8fb19SBen Gras 				if (ep == NULL)
14712fe8fb19SBen Gras 					break;
14722fe8fb19SBen Gras 				*ep = '\0';
14732fe8fb19SBen Gras 				state->name = strdup(filebuf + 1);
14742fe8fb19SBen Gras 				break;
14752fe8fb19SBen Gras 			}
14762fe8fb19SBen Gras 			if (state->name == NULL) {
14772fe8fb19SBen Gras 				rv = NS_UNAVAIL;
14782fe8fb19SBen Gras 				break;
14792fe8fb19SBen Gras 			}
14802fe8fb19SBen Gras 			continue;
14812fe8fb19SBen Gras 		}
14822fe8fb19SBen Gras 
14832fe8fb19SBen Gras 							/* validate line */
14842fe8fb19SBen Gras 		if (! _gr_parse(filebuf, grp, buffer, buflen)) {
14852fe8fb19SBen Gras 			continue;			/* skip bad lines */
14862fe8fb19SBen Gras 		}
14872fe8fb19SBen Gras 
14882fe8fb19SBen Gras  compatgrscan_cmpgrp:
14892fe8fb19SBen Gras 		if (! search) {				/* just want this one */
14902fe8fb19SBen Gras 			rv = NS_SUCCESS;
14912fe8fb19SBen Gras 			break;
14922fe8fb19SBen Gras 		}
14932fe8fb19SBen Gras 							/* want specific */
14942fe8fb19SBen Gras 		if ((name && strcmp(name, grp->gr_name) == 0) ||
14952fe8fb19SBen Gras 		    (!name && gid == grp->gr_gid)) {
14962fe8fb19SBen Gras 			rv = NS_SUCCESS;
14972fe8fb19SBen Gras 			break;
14982fe8fb19SBen Gras 		}
14992fe8fb19SBen Gras 
15002fe8fb19SBen Gras 	}
15012fe8fb19SBen Gras 
15022fe8fb19SBen Gras  compatgrscan_out:
15032fe8fb19SBen Gras 	if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
15042fe8fb19SBen Gras 		*retval = errno;
15052fe8fb19SBen Gras 	return rv;
15062fe8fb19SBen Gras }
15072fe8fb19SBen Gras 
15082fe8fb19SBen Gras static struct __grstate_compat	_compat_state;
15092fe8fb19SBen Gras 					/* storage for non _r functions */
15102fe8fb19SBen Gras static struct group		_compat_group;
15112fe8fb19SBen Gras static char			_compat_groupbuf[_GETGR_R_SIZE_MAX];
15122fe8fb19SBen Gras 
15132fe8fb19SBen Gras /*ARGSUSED*/
15142fe8fb19SBen Gras static int
_compat_setgrent(void * nsrv,void * nscb,va_list ap)15152fe8fb19SBen Gras _compat_setgrent(void *nsrv, void *nscb, va_list ap)
15162fe8fb19SBen Gras {
15172fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
15182fe8fb19SBen Gras 		NS_FILES_CB(__grbad_compat, "files")
15192fe8fb19SBen Gras 		NS_DNS_CB(_dns_setgrent, NULL)
15202fe8fb19SBen Gras 		NS_NIS_CB(_nis_setgrent, NULL)
15212fe8fb19SBen Gras 		NS_COMPAT_CB(__grbad_compat, "compat")
15222fe8fb19SBen Gras 		NS_NULL_CB
15232fe8fb19SBen Gras 	};
15242fe8fb19SBen Gras 
15252fe8fb19SBen Gras 					/* force group_compat setgrent() */
15262fe8fb19SBen Gras 	(void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgrent",
15272fe8fb19SBen Gras 	    __nsdefaultnis_forceall);
15282fe8fb19SBen Gras 
15292fe8fb19SBen Gras 					/* reset state, keep fp open */
15302fe8fb19SBen Gras 	_compat_state.stayopen = 0;
15312fe8fb19SBen Gras 	return __grstart_compat(&_compat_state);
15322fe8fb19SBen Gras }
15332fe8fb19SBen Gras 
15342fe8fb19SBen Gras /*ARGSUSED*/
15352fe8fb19SBen Gras static int
_compat_setgroupent(void * nsrv,void * nscb,va_list ap)15362fe8fb19SBen Gras _compat_setgroupent(void *nsrv, void *nscb, va_list ap)
15372fe8fb19SBen Gras {
15382fe8fb19SBen Gras 	int	*retval		= va_arg(ap, int *);
15392fe8fb19SBen Gras 	int	 stayopen	= va_arg(ap, int);
15402fe8fb19SBen Gras 
15412fe8fb19SBen Gras 	int	rv;
15422fe8fb19SBen Gras 
15432fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
15442fe8fb19SBen Gras 		NS_FILES_CB(__grbad_compat, "files")
15452fe8fb19SBen Gras 		NS_DNS_CB(_dns_setgroupent, NULL)
15462fe8fb19SBen Gras 		NS_NIS_CB(_nis_setgroupent, NULL)
15472fe8fb19SBen Gras 		NS_COMPAT_CB(__grbad_compat, "compat")
15482fe8fb19SBen Gras 		NS_NULL_CB
15492fe8fb19SBen Gras 	};
15502fe8fb19SBen Gras 
15512fe8fb19SBen Gras 					/* force group_compat setgroupent() */
15522fe8fb19SBen Gras 	(void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgroupent",
15532fe8fb19SBen Gras 	    __nsdefaultnis_forceall, &rv, stayopen);
15542fe8fb19SBen Gras 
15552fe8fb19SBen Gras 	_compat_state.stayopen = stayopen;
15562fe8fb19SBen Gras 	rv = __grstart_compat(&_compat_state);
15572fe8fb19SBen Gras 	*retval = (rv == NS_SUCCESS);
15582fe8fb19SBen Gras 	return rv;
15592fe8fb19SBen Gras }
15602fe8fb19SBen Gras 
15612fe8fb19SBen Gras /*ARGSUSED*/
15622fe8fb19SBen Gras static int
_compat_endgrent(void * nsrv,void * nscb,va_list ap)15632fe8fb19SBen Gras _compat_endgrent(void *nsrv, void *nscb, va_list ap)
15642fe8fb19SBen Gras {
15652fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
15662fe8fb19SBen Gras 		NS_FILES_CB(__grbad_compat, "files")
15672fe8fb19SBen Gras 		NS_DNS_CB(_dns_endgrent, NULL)
15682fe8fb19SBen Gras 		NS_NIS_CB(_nis_endgrent, NULL)
15692fe8fb19SBen Gras 		NS_COMPAT_CB(__grbad_compat, "compat")
15702fe8fb19SBen Gras 		NS_NULL_CB
15712fe8fb19SBen Gras 	};
15722fe8fb19SBen Gras 
15732fe8fb19SBen Gras 					/* force group_compat endgrent() */
15742fe8fb19SBen Gras 	(void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "endgrent",
15752fe8fb19SBen Gras 	    __nsdefaultnis_forceall);
15762fe8fb19SBen Gras 
15772fe8fb19SBen Gras 					/* reset state, close fp */
15782fe8fb19SBen Gras 	_compat_state.stayopen = 0;
15792fe8fb19SBen Gras 	return __grend_compat(&_compat_state);
15802fe8fb19SBen Gras }
15812fe8fb19SBen Gras 
15822fe8fb19SBen Gras /*ARGSUSED*/
15832fe8fb19SBen Gras static int
_compat_getgrent(void * nsrv,void * nscb,va_list ap)15842fe8fb19SBen Gras _compat_getgrent(void *nsrv, void *nscb, va_list ap)
15852fe8fb19SBen Gras {
15862fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
15872fe8fb19SBen Gras 
15882fe8fb19SBen Gras 	int	rv, rerror;
15892fe8fb19SBen Gras 
15902fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
15912fe8fb19SBen Gras 
15922fe8fb19SBen Gras 	*retval = NULL;
15932fe8fb19SBen Gras 	rv = __grscan_compat(&rerror, &_compat_group,
15942fe8fb19SBen Gras 	    _compat_groupbuf, sizeof(_compat_groupbuf),
15952fe8fb19SBen Gras 	    &_compat_state, 0, NULL, 0, NULL, NULL);
15962fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
15972fe8fb19SBen Gras 		*retval = &_compat_group;
15982fe8fb19SBen Gras 	return rv;
15992fe8fb19SBen Gras }
16002fe8fb19SBen Gras 
16012fe8fb19SBen Gras /*ARGSUSED*/
16022fe8fb19SBen Gras static int
_compat_getgrent_r(void * nsrv,void * nscb,va_list ap)16032fe8fb19SBen Gras _compat_getgrent_r(void *nsrv, void *nscb, va_list ap)
16042fe8fb19SBen Gras {
16052fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
16062fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
16072fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
16082fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
16092fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
16102fe8fb19SBen Gras 
16112fe8fb19SBen Gras 	int	rv;
16122fe8fb19SBen Gras 
16132fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
16142fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
16152fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
16162fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
16172fe8fb19SBen Gras 
16182fe8fb19SBen Gras 	rv = __grscan_compat(retval, grp, buffer, buflen,
16192fe8fb19SBen Gras 	    &_compat_state, 0, NULL, 0, NULL, NULL);
16202fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
16212fe8fb19SBen Gras 		*result = grp;
16222fe8fb19SBen Gras 	else
16232fe8fb19SBen Gras 		*result = NULL;
16242fe8fb19SBen Gras 	return rv;
16252fe8fb19SBen Gras }
16262fe8fb19SBen Gras 
16272fe8fb19SBen Gras /*ARGSUSED*/
16282fe8fb19SBen Gras static int
_compat_getgrgid(void * nsrv,void * nscb,va_list ap)16292fe8fb19SBen Gras _compat_getgrgid(void *nsrv, void *nscb, va_list ap)
16302fe8fb19SBen Gras {
16312fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
16322fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
16332fe8fb19SBen Gras 
16342fe8fb19SBen Gras 	int	rv, rerror;
16352fe8fb19SBen Gras 
16362fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
16372fe8fb19SBen Gras 
16382fe8fb19SBen Gras 	*retval = NULL;
16392fe8fb19SBen Gras 	rv = __grstart_compat(&_compat_state);
16402fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
16412fe8fb19SBen Gras 		return rv;
16422fe8fb19SBen Gras 	rv = __grscan_compat(&rerror, &_compat_group,
16432fe8fb19SBen Gras 	    _compat_groupbuf, sizeof(_compat_groupbuf),
16442fe8fb19SBen Gras 	    &_compat_state, 1, NULL, gid, NULL, NULL);
16452fe8fb19SBen Gras 	if (!_compat_state.stayopen)
16462fe8fb19SBen Gras 		__grend_compat(&_compat_state);
16472fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
16482fe8fb19SBen Gras 		*retval = &_compat_group;
16492fe8fb19SBen Gras 	return rv;
16502fe8fb19SBen Gras }
16512fe8fb19SBen Gras 
16522fe8fb19SBen Gras /*ARGSUSED*/
16532fe8fb19SBen Gras static int
_compat_getgrgid_r(void * nsrv,void * nscb,va_list ap)16542fe8fb19SBen Gras _compat_getgrgid_r(void *nsrv, void *nscb, va_list ap)
16552fe8fb19SBen Gras {
16562fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
16572fe8fb19SBen Gras 	gid_t		 gid	= va_arg(ap, gid_t);
16582fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
16592fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
16602fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
16612fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
16622fe8fb19SBen Gras 
16632fe8fb19SBen Gras 	struct __grstate_compat	state;
16642fe8fb19SBen Gras 	int		rv;
16652fe8fb19SBen Gras 
16662fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
16672fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
16682fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
16692fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
16702fe8fb19SBen Gras 
16712fe8fb19SBen Gras 	*result = NULL;
16722fe8fb19SBen Gras 	memset(&state, 0, sizeof(state));
16732fe8fb19SBen Gras 	rv = __grscan_compat(retval, grp, buffer, buflen, &state,
16742fe8fb19SBen Gras 	    1, NULL, gid, NULL, NULL);
16752fe8fb19SBen Gras 	__grend_compat(&state);
16762fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
16772fe8fb19SBen Gras 		*result = grp;
16782fe8fb19SBen Gras 	return rv;
16792fe8fb19SBen Gras }
16802fe8fb19SBen Gras 
16812fe8fb19SBen Gras /*ARGSUSED*/
16822fe8fb19SBen Gras static int
_compat_getgrnam(void * nsrv,void * nscb,va_list ap)16832fe8fb19SBen Gras _compat_getgrnam(void *nsrv, void *nscb, va_list ap)
16842fe8fb19SBen Gras {
16852fe8fb19SBen Gras 	struct group	**retval = va_arg(ap, struct group **);
16862fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
16872fe8fb19SBen Gras 
16882fe8fb19SBen Gras 	int	rv, rerror;
16892fe8fb19SBen Gras 
16902fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
16912fe8fb19SBen Gras 
16922fe8fb19SBen Gras 	*retval = NULL;
16932fe8fb19SBen Gras 	rv = __grstart_compat(&_compat_state);
16942fe8fb19SBen Gras 	if (rv != NS_SUCCESS)
16952fe8fb19SBen Gras 		return rv;
16962fe8fb19SBen Gras 	rv = __grscan_compat(&rerror, &_compat_group,
16972fe8fb19SBen Gras 	    _compat_groupbuf, sizeof(_compat_groupbuf),
16982fe8fb19SBen Gras 	    &_compat_state, 1, name, 0, NULL, NULL);
16992fe8fb19SBen Gras 	if (!_compat_state.stayopen)
17002fe8fb19SBen Gras 		__grend_compat(&_compat_state);
17012fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
17022fe8fb19SBen Gras 		*retval = &_compat_group;
17032fe8fb19SBen Gras 	return rv;
17042fe8fb19SBen Gras }
17052fe8fb19SBen Gras 
17062fe8fb19SBen Gras /*ARGSUSED*/
17072fe8fb19SBen Gras static int
_compat_getgrnam_r(void * nsrv,void * nscb,va_list ap)17082fe8fb19SBen Gras _compat_getgrnam_r(void *nsrv, void *nscb, va_list ap)
17092fe8fb19SBen Gras {
17102fe8fb19SBen Gras 	int		*retval	= va_arg(ap, int *);
17112fe8fb19SBen Gras 	const char	*name	= va_arg(ap, const char *);
17122fe8fb19SBen Gras 	struct group	*grp	= va_arg(ap, struct group *);
17132fe8fb19SBen Gras 	char		*buffer	= va_arg(ap, char *);
17142fe8fb19SBen Gras 	size_t		 buflen	= va_arg(ap, size_t);
17152fe8fb19SBen Gras 	struct group   **result	= va_arg(ap, struct group **);
17162fe8fb19SBen Gras 
17172fe8fb19SBen Gras 	struct __grstate_compat	state;
17182fe8fb19SBen Gras 	int		rv;
17192fe8fb19SBen Gras 
17202fe8fb19SBen Gras 	_DIAGASSERT(retval != NULL);
17212fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
17222fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
17232fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
17242fe8fb19SBen Gras 
17252fe8fb19SBen Gras 	*result = NULL;
17262fe8fb19SBen Gras 	memset(&state, 0, sizeof(state));
17272fe8fb19SBen Gras 	rv = __grscan_compat(retval, grp, buffer, buflen, &state,
17282fe8fb19SBen Gras 	    1, name, 0, NULL, NULL);
17292fe8fb19SBen Gras 	__grend_compat(&state);
17302fe8fb19SBen Gras 	if (rv == NS_SUCCESS)
17312fe8fb19SBen Gras 		*result = grp;
17322fe8fb19SBen Gras 	return rv;
17332fe8fb19SBen Gras }
17342fe8fb19SBen Gras 
17352fe8fb19SBen Gras #endif	/* _GROUP_COMPAT */
17362fe8fb19SBen Gras 
17372fe8fb19SBen Gras 
17382fe8fb19SBen Gras 		/*
17392fe8fb19SBen Gras 		 *	public functions
17402fe8fb19SBen Gras 		 */
17412fe8fb19SBen Gras 
17422fe8fb19SBen Gras struct group *
getgrent(void)17432fe8fb19SBen Gras getgrent(void)
17442fe8fb19SBen Gras {
17452fe8fb19SBen Gras 	int		rv;
17462fe8fb19SBen Gras 	struct group	*retval;
17472fe8fb19SBen Gras 
17482fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
17492fe8fb19SBen Gras 		NS_FILES_CB(_files_getgrent, NULL)
17502fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrent, NULL)
17512fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrent, NULL)
17522fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_getgrent, NULL)
17532fe8fb19SBen Gras 		NS_NULL_CB
17542fe8fb19SBen Gras 	};
17552fe8fb19SBen Gras 
17562fe8fb19SBen Gras 	mutex_lock(&__grmutex);
17572fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent", __nsdefaultcompat,
17582fe8fb19SBen Gras 	    &retval);
17592fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
17602fe8fb19SBen Gras 	return (rv == NS_SUCCESS) ? retval : NULL;
17612fe8fb19SBen Gras }
17622fe8fb19SBen Gras 
17632fe8fb19SBen Gras int
getgrent_r(struct group * grp,char * buffer,size_t buflen,struct group ** result)17642fe8fb19SBen Gras getgrent_r(struct group *grp, char *buffer, size_t buflen,
17652fe8fb19SBen Gras     struct group **result)
17662fe8fb19SBen Gras {
17672fe8fb19SBen Gras 	int		rv, retval;
17682fe8fb19SBen Gras 
17692fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
17702fe8fb19SBen Gras 		NS_FILES_CB(_files_getgrent_r, NULL)
17712fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrent_r, NULL)
17722fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrent_r, NULL)
17732fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_getgrent_r, NULL)
17742fe8fb19SBen Gras 		NS_NULL_CB
17752fe8fb19SBen Gras 	};
17762fe8fb19SBen Gras 
17772fe8fb19SBen Gras 	mutex_lock(&__grmutex);
17782fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent_r", __nsdefaultcompat,
17792fe8fb19SBen Gras 	    &retval, grp, buffer, buflen, result);
17802fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
17812fe8fb19SBen Gras 	switch (rv) {
17822fe8fb19SBen Gras 	case NS_SUCCESS:
17832fe8fb19SBen Gras 	case NS_NOTFOUND:
17842fe8fb19SBen Gras 		return 0;
17852fe8fb19SBen Gras 	default:
17862fe8fb19SBen Gras 		return retval;
17872fe8fb19SBen Gras 	}
17882fe8fb19SBen Gras }
17892fe8fb19SBen Gras 
17902fe8fb19SBen Gras 
17912fe8fb19SBen Gras struct group *
getgrgid(gid_t gid)17922fe8fb19SBen Gras getgrgid(gid_t gid)
17932fe8fb19SBen Gras {
17942fe8fb19SBen Gras 	int		rv;
17952fe8fb19SBen Gras 	struct group	*retval;
17962fe8fb19SBen Gras 
17972fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
17982fe8fb19SBen Gras 		NS_FILES_CB(_files_getgrgid, NULL)
17992fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrgid, NULL)
18002fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrgid, NULL)
18012fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_getgrgid, NULL)
18022fe8fb19SBen Gras 		NS_NULL_CB
18032fe8fb19SBen Gras 	};
18042fe8fb19SBen Gras 
18052fe8fb19SBen Gras 	mutex_lock(&__grmutex);
18062fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid", __nsdefaultcompat,
18072fe8fb19SBen Gras 	    &retval, gid);
18082fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
18092fe8fb19SBen Gras 	return (rv == NS_SUCCESS) ? retval : NULL;
18102fe8fb19SBen Gras }
18112fe8fb19SBen Gras 
18122fe8fb19SBen Gras int
getgrgid_r(gid_t gid,struct group * grp,char * buffer,size_t buflen,struct group ** result)18132fe8fb19SBen Gras getgrgid_r(gid_t gid, struct group *grp, char *buffer, size_t buflen,
18142fe8fb19SBen Gras 	struct group **result)
18152fe8fb19SBen Gras {
18162fe8fb19SBen Gras 	int	rv, retval;
18172fe8fb19SBen Gras 
18182fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
18192fe8fb19SBen Gras 		NS_FILES_CB(_files_getgrgid_r, NULL)
18202fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrgid_r, NULL)
18212fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrgid_r, NULL)
18222fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_getgrgid_r, NULL)
18232fe8fb19SBen Gras 		NS_NULL_CB
18242fe8fb19SBen Gras 	};
18252fe8fb19SBen Gras 
18262fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
18272fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
18282fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
18292fe8fb19SBen Gras 
18302fe8fb19SBen Gras 	*result = NULL;
18312fe8fb19SBen Gras 	retval = 0;
18322fe8fb19SBen Gras 	mutex_lock(&__grmutex);
18332fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid_r", __nsdefaultcompat,
18342fe8fb19SBen Gras 	    &retval, gid, grp, buffer, buflen, result);
18352fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
18362fe8fb19SBen Gras 	switch (rv) {
18372fe8fb19SBen Gras 	case NS_SUCCESS:
18382fe8fb19SBen Gras 	case NS_NOTFOUND:
18392fe8fb19SBen Gras 		return 0;
18402fe8fb19SBen Gras 	default:
18412fe8fb19SBen Gras 		return retval;
18422fe8fb19SBen Gras 	}
18432fe8fb19SBen Gras }
18442fe8fb19SBen Gras 
18452fe8fb19SBen Gras struct group *
getgrnam(const char * name)18462fe8fb19SBen Gras getgrnam(const char *name)
18472fe8fb19SBen Gras {
18482fe8fb19SBen Gras 	int		rv;
18492fe8fb19SBen Gras 	struct group	*retval;
18502fe8fb19SBen Gras 
18512fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
18522fe8fb19SBen Gras 		NS_FILES_CB(_files_getgrnam, NULL)
18532fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrnam, NULL)
18542fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrnam, NULL)
18552fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_getgrnam, NULL)
18562fe8fb19SBen Gras 		NS_NULL_CB
18572fe8fb19SBen Gras 	};
18582fe8fb19SBen Gras 
18592fe8fb19SBen Gras 	mutex_lock(&__grmutex);
18602fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam", __nsdefaultcompat,
18612fe8fb19SBen Gras 	    &retval, name);
18622fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
18632fe8fb19SBen Gras 	return (rv == NS_SUCCESS) ? retval : NULL;
18642fe8fb19SBen Gras }
18652fe8fb19SBen Gras 
18662fe8fb19SBen Gras int
getgrnam_r(const char * name,struct group * grp,char * buffer,size_t buflen,struct group ** result)18672fe8fb19SBen Gras getgrnam_r(const char *name, struct group *grp, char *buffer, size_t buflen,
18682fe8fb19SBen Gras 	struct group **result)
18692fe8fb19SBen Gras {
18702fe8fb19SBen Gras 	int	rv, retval;
18712fe8fb19SBen Gras 
18722fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
18732fe8fb19SBen Gras 		NS_FILES_CB(_files_getgrnam_r, NULL)
18742fe8fb19SBen Gras 		NS_DNS_CB(_dns_getgrnam_r, NULL)
18752fe8fb19SBen Gras 		NS_NIS_CB(_nis_getgrnam_r, NULL)
18762fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_getgrnam_r, NULL)
18772fe8fb19SBen Gras 		NS_NULL_CB
18782fe8fb19SBen Gras 	};
18792fe8fb19SBen Gras 
18802fe8fb19SBen Gras 	_DIAGASSERT(name != NULL);
18812fe8fb19SBen Gras 	_DIAGASSERT(grp != NULL);
18822fe8fb19SBen Gras 	_DIAGASSERT(buffer != NULL);
18832fe8fb19SBen Gras 	_DIAGASSERT(result != NULL);
18842fe8fb19SBen Gras 
18852fe8fb19SBen Gras 	*result = NULL;
18862fe8fb19SBen Gras 	retval = 0;
18872fe8fb19SBen Gras 	mutex_lock(&__grmutex);
18882fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam_r", __nsdefaultcompat,
18892fe8fb19SBen Gras 	    &retval, name, grp, buffer, buflen, result);
18902fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
18912fe8fb19SBen Gras 	switch (rv) {
18922fe8fb19SBen Gras 	case NS_SUCCESS:
18932fe8fb19SBen Gras 	case NS_NOTFOUND:
18942fe8fb19SBen Gras 		return 0;
18952fe8fb19SBen Gras 	default:
18962fe8fb19SBen Gras 		return retval;
18972fe8fb19SBen Gras 	}
18982fe8fb19SBen Gras }
18992fe8fb19SBen Gras 
19002fe8fb19SBen Gras void
endgrent(void)19012fe8fb19SBen Gras endgrent(void)
19022fe8fb19SBen Gras {
19032fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
19042fe8fb19SBen Gras 		NS_FILES_CB(_files_endgrent, NULL)
19052fe8fb19SBen Gras 		NS_DNS_CB(_dns_endgrent, NULL)
19062fe8fb19SBen Gras 		NS_NIS_CB(_nis_endgrent, NULL)
19072fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_endgrent, NULL)
19082fe8fb19SBen Gras 		NS_NULL_CB
19092fe8fb19SBen Gras 	};
19102fe8fb19SBen Gras 
19112fe8fb19SBen Gras 	mutex_lock(&__grmutex);
19122fe8fb19SBen Gras 					/* force all endgrent() methods */
19132fe8fb19SBen Gras 	(void) nsdispatch(NULL, dtab, NSDB_GROUP, "endgrent",
19142fe8fb19SBen Gras 	    __nsdefaultcompat_forceall);
19152fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
19162fe8fb19SBen Gras }
19172fe8fb19SBen Gras 
19182fe8fb19SBen Gras int
setgroupent(int stayopen)19192fe8fb19SBen Gras setgroupent(int stayopen)
19202fe8fb19SBen Gras {
19212fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
19222fe8fb19SBen Gras 		NS_FILES_CB(_files_setgroupent, NULL)
19232fe8fb19SBen Gras 		NS_DNS_CB(_dns_setgroupent, NULL)
19242fe8fb19SBen Gras 		NS_NIS_CB(_nis_setgroupent, NULL)
19252fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_setgroupent, NULL)
19262fe8fb19SBen Gras 		NS_NULL_CB
19272fe8fb19SBen Gras 	};
19282fe8fb19SBen Gras 	int	rv, retval;
19292fe8fb19SBen Gras 
19302fe8fb19SBen Gras 	mutex_lock(&__grmutex);
19312fe8fb19SBen Gras 					/* force all setgroupent() methods */
19322fe8fb19SBen Gras 	rv = nsdispatch(NULL, dtab, NSDB_GROUP, "setgroupent",
19332fe8fb19SBen Gras 	    __nsdefaultcompat_forceall, &retval, stayopen);
19342fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
19352fe8fb19SBen Gras 	return (rv == NS_SUCCESS) ? retval : 0;
19362fe8fb19SBen Gras }
19372fe8fb19SBen Gras 
19382fe8fb19SBen Gras void
setgrent(void)19392fe8fb19SBen Gras setgrent(void)
19402fe8fb19SBen Gras {
19412fe8fb19SBen Gras 	static const ns_dtab dtab[] = {
19422fe8fb19SBen Gras 		NS_FILES_CB(_files_setgrent, NULL)
19432fe8fb19SBen Gras 		NS_DNS_CB(_dns_setgrent, NULL)
19442fe8fb19SBen Gras 		NS_NIS_CB(_nis_setgrent, NULL)
19452fe8fb19SBen Gras 		NS_COMPAT_CB(_compat_setgrent, NULL)
19462fe8fb19SBen Gras 		NS_NULL_CB
19472fe8fb19SBen Gras 	};
19482fe8fb19SBen Gras 
19492fe8fb19SBen Gras 	mutex_lock(&__grmutex);
19502fe8fb19SBen Gras 					/* force all setgrent() methods */
19512fe8fb19SBen Gras 	(void) nsdispatch(NULL, dtab, NSDB_GROUP, "setgrent",
19522fe8fb19SBen Gras 	    __nsdefaultcompat_forceall);
19532fe8fb19SBen Gras 	mutex_unlock(&__grmutex);
19542fe8fb19SBen Gras }
1955