1*8c41afe6Sdholland /* $NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $ */
2c54f283eSlukem
3c54f283eSlukem /*-
4337d8d73Slukem * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
5c54f283eSlukem * All rights reserved.
6c54f283eSlukem *
7c54f283eSlukem * This code is derived from software contributed to The NetBSD Foundation
8c54f283eSlukem * by Luke Mewburn.
9c54f283eSlukem *
10c54f283eSlukem * Redistribution and use in source and binary forms, with or without
11c54f283eSlukem * modification, are permitted provided that the following conditions
12c54f283eSlukem * are met:
13c54f283eSlukem * 1. Redistributions of source code must retain the above copyright
14c54f283eSlukem * notice, this list of conditions and the following disclaimer.
15c54f283eSlukem * 2. Redistributions in binary form must reproduce the above copyright
16c54f283eSlukem * notice, this list of conditions and the following disclaimer in the
17c54f283eSlukem * documentation and/or other materials provided with the distribution.
18c54f283eSlukem *
19c54f283eSlukem * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20c54f283eSlukem * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21c54f283eSlukem * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22c54f283eSlukem * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23c54f283eSlukem * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24c54f283eSlukem * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25c54f283eSlukem * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26c54f283eSlukem * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27c54f283eSlukem * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28c54f283eSlukem * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29c54f283eSlukem * POSSIBILITY OF SUCH DAMAGE.
30c54f283eSlukem */
31b585e843Scgd
3261f28255Scgd /*
33b585e843Scgd * Copyright (c) 1989, 1993
34b585e843Scgd * The Regents of the University of California. All rights reserved.
35eb7c1594Sagc *
36eb7c1594Sagc * Redistribution and use in source and binary forms, with or without
37eb7c1594Sagc * modification, are permitted provided that the following conditions
38eb7c1594Sagc * are met:
39eb7c1594Sagc * 1. Redistributions of source code must retain the above copyright
40eb7c1594Sagc * notice, this list of conditions and the following disclaimer.
41eb7c1594Sagc * 2. Redistributions in binary form must reproduce the above copyright
42eb7c1594Sagc * notice, this list of conditions and the following disclaimer in the
43eb7c1594Sagc * documentation and/or other materials provided with the distribution.
44eb7c1594Sagc * 3. Neither the name of the University nor the names of its contributors
45eb7c1594Sagc * may be used to endorse or promote products derived from this software
46eb7c1594Sagc * without specific prior written permission.
47eb7c1594Sagc *
48eb7c1594Sagc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49eb7c1594Sagc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50eb7c1594Sagc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51eb7c1594Sagc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52eb7c1594Sagc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53eb7c1594Sagc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54eb7c1594Sagc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55eb7c1594Sagc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56eb7c1594Sagc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57eb7c1594Sagc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58eb7c1594Sagc * SUCH DAMAGE.
59eb7c1594Sagc */
60eb7c1594Sagc
61eb7c1594Sagc /*
62e69d4136Sphil * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
6361f28255Scgd *
6461f28255Scgd * Redistribution and use in source and binary forms, with or without
6561f28255Scgd * modification, are permitted provided that the following conditions
6661f28255Scgd * are met:
6761f28255Scgd * 1. Redistributions of source code must retain the above copyright
6861f28255Scgd * notice, this list of conditions and the following disclaimer.
6961f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
7061f28255Scgd * notice, this list of conditions and the following disclaimer in the
7161f28255Scgd * documentation and/or other materials provided with the distribution.
7261f28255Scgd *
739f1aac5bSagc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
749f1aac5bSagc * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
759f1aac5bSagc * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
769f1aac5bSagc * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
779f1aac5bSagc * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
789f1aac5bSagc * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
799f1aac5bSagc * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
809f1aac5bSagc * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
8161f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
8261f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
8361f28255Scgd * SUCH DAMAGE.
8461f28255Scgd */
8561f28255Scgd
8611cac208Schristos #include <sys/cdefs.h>
8761f28255Scgd #if defined(LIBC_SCCS) && !defined(lint)
88b585e843Scgd #if 0
89b585e843Scgd static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
90b585e843Scgd #else
91*8c41afe6Sdholland __RCSID("$NetBSD: getgrent.c,v 1.67 2012/08/29 18:50:35 dholland Exp $");
92b585e843Scgd #endif
9361f28255Scgd #endif /* LIBC_SCCS and not lint */
9461f28255Scgd
9543fa6fe3Sjtc #include "namespace.h"
96c49e8087Slukem #include "reentrant.h"
97147dea10Slukem
98c54f283eSlukem #include <sys/param.h>
99147dea10Slukem
100b48252f3Slukem #include <assert.h>
101147dea10Slukem #include <errno.h>
1020eb8645eSlukem #include <grp.h>
10350820e9bSlukem #include <limits.h>
1040eb8645eSlukem #include <nsswitch.h>
105feb92219Slukem #include <stdarg.h>
10661f28255Scgd #include <stdio.h>
10761f28255Scgd #include <stdlib.h>
1083cbc24e4Sderaadt #include <string.h>
1090eb8645eSlukem #include <syslog.h>
11073e9ef01Slukem
1110eb8645eSlukem #ifdef HESIOD
1120eb8645eSlukem #include <hesiod.h>
1130eb8645eSlukem #endif
114c54f283eSlukem
1153cbc24e4Sderaadt #ifdef YP
1163cbc24e4Sderaadt #include <rpc/rpc.h>
1173cbc24e4Sderaadt #include <rpcsvc/yp_prot.h>
1183cbc24e4Sderaadt #include <rpcsvc/ypclnt.h>
1193cbc24e4Sderaadt #endif
12061f28255Scgd
121337d8d73Slukem #include "gr_private.h"
1227f1c203cSlukem
12343fa6fe3Sjtc #ifdef __weak_alias
12460549036Smycroft __weak_alias(endgrent,_endgrent)
12560549036Smycroft __weak_alias(getgrent,_getgrent)
126184974e0Schristos __weak_alias(getgrent_r,_getgrent_r)
12760549036Smycroft __weak_alias(getgrgid,_getgrgid)
128c54f283eSlukem __weak_alias(getgrgid_r,_getgrgid_r)
12960549036Smycroft __weak_alias(getgrnam,_getgrnam)
130c54f283eSlukem __weak_alias(getgrnam_r,_getgrnam_r)
13160549036Smycroft __weak_alias(setgrent,_setgrent)
13260549036Smycroft __weak_alias(setgroupent,_setgroupent)
13343fa6fe3Sjtc #endif
13443fa6fe3Sjtc
135feb92219Slukem #ifdef _REENTRANT
136337d8d73Slukem mutex_t __grmutex = MUTEX_INITIALIZER;
137feb92219Slukem #endif
138feb92219Slukem
139c54f283eSlukem /*
140c54f283eSlukem * _gr_memfrombuf
141c54f283eSlukem * Obtain want bytes from buffer (of size buflen) and return a pointer
142c54f283eSlukem * to the available memory after adjusting buffer/buflen.
143c54f283eSlukem * Returns NULL if there is insufficient space.
144c54f283eSlukem */
145c54f283eSlukem static char *
_gr_memfrombuf(size_t want,char ** buffer,size_t * buflen)146c54f283eSlukem _gr_memfrombuf(size_t want, char **buffer, size_t *buflen)
14761f28255Scgd {
148c54f283eSlukem char *rv;
1493792c586Slukem
150c54f283eSlukem if (want > *buflen) {
151c54f283eSlukem errno = ERANGE;
152c54f283eSlukem return NULL;
153c54f283eSlukem }
154c54f283eSlukem rv = *buffer;
155c54f283eSlukem *buffer += want;
156c54f283eSlukem *buflen -= want;
157c54f283eSlukem return rv;
15816c5a7ddSelric }
15916c5a7ddSelric
16016c5a7ddSelric /*
161c54f283eSlukem * _gr_parse
162c54f283eSlukem * Parses entry as a line per group(5) (without the trailing \n)
163c54f283eSlukem * and fills in grp with corresponding values; memory for strings
164c54f283eSlukem * and arrays will be allocated from buf (of size buflen).
165c54f283eSlukem * Returns 1 if parsed successfully, 0 on parse failure.
166c54f283eSlukem */
167c54f283eSlukem static int
_gr_parse(const char * entry,struct group * grp,char * buf,size_t buflen)168c54f283eSlukem _gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen)
169c54f283eSlukem {
170c54f283eSlukem unsigned long id;
171c54f283eSlukem const char *bp;
172c54f283eSlukem char *ep;
173c54f283eSlukem size_t count;
174c54f283eSlukem int memc;
175c54f283eSlukem
176c54f283eSlukem _DIAGASSERT(entry != NULL);
177c54f283eSlukem _DIAGASSERT(grp != NULL);
178c54f283eSlukem _DIAGASSERT(buf != NULL);
179c54f283eSlukem
180c54f283eSlukem #define COPYTOBUF(to) \
181c54f283eSlukem do { \
182c54f283eSlukem (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
183c54f283eSlukem if ((to) == NULL) \
184c54f283eSlukem return 0; \
185c54f283eSlukem memmove((to), entry, count); \
186c54f283eSlukem to[count] = '\0'; \
187c54f283eSlukem } while (0) /* LINTED */
188c54f283eSlukem
189c54f283eSlukem #if 0
190c54f283eSlukem if (*entry == '+') /* fail on compat `+' token */
191c54f283eSlukem return 0;
192c54f283eSlukem #endif
193c54f283eSlukem
194c54f283eSlukem count = strcspn(entry, ":"); /* parse gr_name */
195c54f283eSlukem if (entry[count] == '\0')
196c54f283eSlukem return 0;
197c54f283eSlukem COPYTOBUF(grp->gr_name);
198c54f283eSlukem entry += count + 1;
199c54f283eSlukem
200c54f283eSlukem count = strcspn(entry, ":"); /* parse gr_passwd */
201c54f283eSlukem if (entry[count] == '\0')
202c54f283eSlukem return 0;
203c54f283eSlukem COPYTOBUF(grp->gr_passwd);
204c54f283eSlukem entry += count + 1;
205c54f283eSlukem
206c54f283eSlukem count = strcspn(entry, ":"); /* parse gr_gid */
207c54f283eSlukem if (entry[count] == '\0')
208c54f283eSlukem return 0;
209c54f283eSlukem id = strtoul(entry, &ep, 10);
210c54f283eSlukem if (id > GID_MAX || *ep != ':')
211c54f283eSlukem return 0;
212c54f283eSlukem grp->gr_gid = (gid_t)id;
213c54f283eSlukem entry += count + 1;
214c54f283eSlukem
215c54f283eSlukem memc = 1; /* for final NULL */
216c54f283eSlukem if (*entry != '\0')
217c54f283eSlukem memc++; /* for first item */
218c54f283eSlukem for (bp = entry; *bp != '\0'; bp++) {
219c54f283eSlukem if (*bp == ',')
220c54f283eSlukem memc++;
221c54f283eSlukem }
222c54f283eSlukem /* grab ALIGNed char **gr_mem from buf */
223c54f283eSlukem ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
224*8c41afe6Sdholland if (ep == NULL)
225c54f283eSlukem return 0;
226*8c41afe6Sdholland grp->gr_mem = (char **)ALIGN(ep);
227c54f283eSlukem
228c54f283eSlukem for (memc = 0; *entry != '\0'; memc++) {
229c54f283eSlukem count = strcspn(entry, ","); /* parse member */
230c54f283eSlukem COPYTOBUF(grp->gr_mem[memc]);
231c54f283eSlukem entry += count;
232c54f283eSlukem if (*entry == ',')
233c54f283eSlukem entry++;
234c54f283eSlukem }
235c54f283eSlukem
236c54f283eSlukem #undef COPYTOBUF
237c54f283eSlukem
238c54f283eSlukem grp->gr_mem[memc] = NULL;
239c54f283eSlukem return 1;
240c54f283eSlukem }
241c54f283eSlukem
242c54f283eSlukem /*
243c54f283eSlukem * _gr_copy
244c54f283eSlukem * Copy the contents of fromgrp to grp; memory for strings
245c54f283eSlukem * and arrays will be allocated from buf (of size buflen).
246c54f283eSlukem * Returns 1 if copied successfully, 0 on copy failure.
247c54f283eSlukem * NOTE: fromgrp must not use buf for its own pointers.
248c54f283eSlukem */
249c54f283eSlukem static int
_gr_copy(struct group * fromgrp,struct group * grp,char * buf,size_t buflen)250c54f283eSlukem _gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen)
251c54f283eSlukem {
252c54f283eSlukem char *ep;
253c54f283eSlukem int memc;
254c54f283eSlukem
255c54f283eSlukem _DIAGASSERT(fromgrp != NULL);
256c54f283eSlukem _DIAGASSERT(grp != NULL);
257c54f283eSlukem _DIAGASSERT(buf != NULL);
258c54f283eSlukem
259c54f283eSlukem #define COPYSTR(to, from) \
260c54f283eSlukem do { \
261c54f283eSlukem size_t count = strlen((from)); \
262c54f283eSlukem (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
263c54f283eSlukem if ((to) == NULL) \
264c54f283eSlukem return 0; \
265c54f283eSlukem memmove((to), (from), count); \
266c54f283eSlukem to[count] = '\0'; \
267c54f283eSlukem } while (0) /* LINTED */
268c54f283eSlukem
269c54f283eSlukem COPYSTR(grp->gr_name, fromgrp->gr_name);
270c54f283eSlukem COPYSTR(grp->gr_passwd, fromgrp->gr_passwd);
271c54f283eSlukem grp->gr_gid = fromgrp->gr_gid;
272c54f283eSlukem
27382f4eed5Ssjg if (fromgrp->gr_mem == NULL)
27482f4eed5Ssjg return 0;
27582f4eed5Ssjg
276c54f283eSlukem for (memc = 0; fromgrp->gr_mem[memc]; memc++)
277c54f283eSlukem continue;
278c54f283eSlukem memc++; /* for final NULL */
279c54f283eSlukem
280c54f283eSlukem /* grab ALIGNed char **gr_mem from buf */
281c54f283eSlukem ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
282c54f283eSlukem grp->gr_mem = (char **)ALIGN(ep);
283c54f283eSlukem if (grp->gr_mem == NULL)
284c54f283eSlukem return 0;
285c54f283eSlukem
286c54f283eSlukem for (memc = 0; fromgrp->gr_mem[memc]; memc++) {
287c54f283eSlukem COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]);
288c54f283eSlukem }
289c54f283eSlukem
290c54f283eSlukem #undef COPYSTR
291c54f283eSlukem
292c54f283eSlukem grp->gr_mem[memc] = NULL;
293c54f283eSlukem return 1;
294c54f283eSlukem }
295c54f283eSlukem
296c54f283eSlukem /*
297c54f283eSlukem * files methods
29816c5a7ddSelric */
29916c5a7ddSelric
300337d8d73Slukem int
__grstart_files(struct __grstate_files * state)301337d8d73Slukem __grstart_files(struct __grstate_files *state)
302326483c4Slukem {
3033792c586Slukem
304c54f283eSlukem _DIAGASSERT(state != NULL);
305c54f283eSlukem
306c54f283eSlukem if (state->fp == NULL) {
3079292cfb2Schristos state->fp = fopen(_PATH_GROUP, "re");
308c54f283eSlukem if (state->fp == NULL)
309c54f283eSlukem return NS_UNAVAIL;
310c54f283eSlukem } else {
311c54f283eSlukem rewind(state->fp);
31261f28255Scgd }
3130eb8645eSlukem return NS_SUCCESS;
3140eb8645eSlukem }
315c54f283eSlukem
316337d8d73Slukem int
__grend_files(struct __grstate_files * state)317337d8d73Slukem __grend_files(struct __grstate_files *state)
318c54f283eSlukem {
319c54f283eSlukem
320c54f283eSlukem _DIAGASSERT(state != NULL);
321c54f283eSlukem
322c54f283eSlukem if (state->fp) {
323c54f283eSlukem (void) fclose(state->fp);
324c54f283eSlukem state->fp = NULL;
325c54f283eSlukem }
326c54f283eSlukem return NS_SUCCESS;
3270eb8645eSlukem }
3280eb8645eSlukem
329c54f283eSlukem /*
330337d8d73Slukem * __grscan_files
331c54f283eSlukem * Scan state->fp for the next desired entry.
332c54f283eSlukem * If search is zero, return the next entry.
333c54f283eSlukem * If search is non-zero, look for a specific name (if name != NULL),
334c54f283eSlukem * or a specific gid (if name == NULL).
335d0388cffSlukem * Sets *retval to the errno if the result is not NS_SUCCESS
336d0388cffSlukem * or NS_NOTFOUND.
337c54f283eSlukem */
338337d8d73Slukem 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)339337d8d73Slukem __grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen,
340337d8d73Slukem struct __grstate_files *state, int search, const char *name, gid_t gid)
341c54f283eSlukem {
342c54f283eSlukem int rv;
3432ffe6b72Slukem char filebuf[_GETGR_R_SIZE_MAX], *ep;
344c54f283eSlukem
345c54f283eSlukem _DIAGASSERT(retval != NULL);
346c54f283eSlukem _DIAGASSERT(grp != NULL);
347c54f283eSlukem _DIAGASSERT(buffer != NULL);
348c54f283eSlukem _DIAGASSERT(state != NULL);
349c54f283eSlukem /* name is NULL to indicate searching for gid */
350c54f283eSlukem
351c54f283eSlukem *retval = 0;
352c54f283eSlukem
353c54f283eSlukem if (state->fp == NULL) { /* only start if file not open yet */
354337d8d73Slukem rv = __grstart_files(state);
355c54f283eSlukem if (rv != NS_SUCCESS)
356c54f283eSlukem goto filesgrscan_out;
357c54f283eSlukem }
358c54f283eSlukem
359c54f283eSlukem rv = NS_NOTFOUND;
360c54f283eSlukem
361c54f283eSlukem /* scan line by line */
362c5e820caSchristos while (fgets(filebuf, (int)sizeof(filebuf), state->fp) != NULL) {
363c54f283eSlukem ep = strchr(filebuf, '\n');
3649fcbc803Slukem if (ep == NULL) { /* skip lines that are too big */
365c54f283eSlukem int ch;
366c54f283eSlukem
367c54f283eSlukem while ((ch = getc(state->fp)) != '\n' && ch != EOF)
368c54f283eSlukem continue;
3699fcbc803Slukem continue;
370c54f283eSlukem }
371c54f283eSlukem *ep = '\0'; /* clear trailing \n */
372c54f283eSlukem
373c54f283eSlukem if (filebuf[0] == '+') /* skip compat line */
374c54f283eSlukem continue;
375c54f283eSlukem
376c54f283eSlukem /* validate line */
377c54f283eSlukem if (! _gr_parse(filebuf, grp, buffer, buflen)) {
3789fcbc803Slukem continue; /* skip bad lines */
379c54f283eSlukem }
380c54f283eSlukem if (! search) { /* just want this one */
381c54f283eSlukem rv = NS_SUCCESS;
382c54f283eSlukem break;
383c54f283eSlukem }
384c54f283eSlukem /* want specific */
385c54f283eSlukem if ((name && strcmp(name, grp->gr_name) == 0) ||
386c54f283eSlukem (!name && gid == grp->gr_gid)) {
387c54f283eSlukem rv = NS_SUCCESS;
388c54f283eSlukem break;
389c54f283eSlukem }
390c54f283eSlukem }
391c54f283eSlukem
392c54f283eSlukem filesgrscan_out:
393d0388cffSlukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
394c54f283eSlukem *retval = errno;
395c54f283eSlukem return rv;
396c54f283eSlukem }
3970eb8645eSlukem
398337d8d73Slukem
399337d8d73Slukem static struct __grstate_files _files_state;
400337d8d73Slukem /* storage for non _r functions */
401337d8d73Slukem static struct group _files_group;
402337d8d73Slukem static char _files_groupbuf[_GETGR_R_SIZE_MAX];
403337d8d73Slukem
4046304dadcSchristos /*ARGSUSED*/
4050eb8645eSlukem static int
_files_setgrent(void * nsrv,void * nscb,va_list ap)406c54f283eSlukem _files_setgrent(void *nsrv, void *nscb, va_list ap)
4070eb8645eSlukem {
408c54f283eSlukem
409c54f283eSlukem _files_state.stayopen = 0;
410337d8d73Slukem return __grstart_files(&_files_state);
411c54f283eSlukem }
412c54f283eSlukem
413c54f283eSlukem /*ARGSUSED*/
414c54f283eSlukem static int
_files_setgroupent(void * nsrv,void * nscb,va_list ap)415c54f283eSlukem _files_setgroupent(void *nsrv, void *nscb, va_list ap)
416c54f283eSlukem {
417c54f283eSlukem int *retval = va_arg(ap, int *);
418c54f283eSlukem int stayopen = va_arg(ap, int);
419c54f283eSlukem
420c54f283eSlukem int rv;
421c54f283eSlukem
422c54f283eSlukem _files_state.stayopen = stayopen;
423337d8d73Slukem rv = __grstart_files(&_files_state);
424c54f283eSlukem *retval = (rv == NS_SUCCESS);
425c54f283eSlukem return rv;
426c54f283eSlukem }
427c54f283eSlukem
428c54f283eSlukem /*ARGSUSED*/
429c54f283eSlukem static int
_files_endgrent(void * nsrv,void * nscb,va_list ap)430c54f283eSlukem _files_endgrent(void *nsrv, void *nscb, va_list ap)
431c54f283eSlukem {
432c54f283eSlukem
433c54f283eSlukem _files_state.stayopen = 0;
434337d8d73Slukem return __grend_files(&_files_state);
435c54f283eSlukem }
436c54f283eSlukem
437c54f283eSlukem /*ARGSUSED*/
438c54f283eSlukem static int
_files_getgrent(void * nsrv,void * nscb,va_list ap)439c54f283eSlukem _files_getgrent(void *nsrv, void *nscb, va_list ap)
440c54f283eSlukem {
441c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
442c54f283eSlukem
443c54f283eSlukem int rv, rerror;
444c54f283eSlukem
445c54f283eSlukem _DIAGASSERT(retval != NULL);
446c54f283eSlukem
447c54f283eSlukem *retval = NULL;
448337d8d73Slukem rv = __grscan_files(&rerror, &_files_group,
449c54f283eSlukem _files_groupbuf, sizeof(_files_groupbuf),
450c54f283eSlukem &_files_state, 0, NULL, 0);
451c54f283eSlukem if (rv == NS_SUCCESS)
452c54f283eSlukem *retval = &_files_group;
453c54f283eSlukem return rv;
454c54f283eSlukem }
455c54f283eSlukem
456c54f283eSlukem /*ARGSUSED*/
457c54f283eSlukem static int
_files_getgrent_r(void * nsrv,void * nscb,va_list ap)458184974e0Schristos _files_getgrent_r(void *nsrv, void *nscb, va_list ap)
459184974e0Schristos {
460184974e0Schristos int *retval = va_arg(ap, int *);
461184974e0Schristos struct group *grp = va_arg(ap, struct group *);
462184974e0Schristos char *buffer = va_arg(ap, char *);
463184974e0Schristos size_t buflen = va_arg(ap, size_t);
464184974e0Schristos struct group **result = va_arg(ap, struct group **);
465184974e0Schristos
466184974e0Schristos int rv;
467184974e0Schristos
468184974e0Schristos _DIAGASSERT(retval != NULL);
469184974e0Schristos _DIAGASSERT(grp != NULL);
470184974e0Schristos _DIAGASSERT(buffer != NULL);
471184974e0Schristos _DIAGASSERT(result != NULL);
472184974e0Schristos
473184974e0Schristos rv = __grscan_files(retval, grp, buffer, buflen,
474184974e0Schristos &_files_state, 0, NULL, 0);
475184974e0Schristos if (rv == NS_SUCCESS)
476184974e0Schristos *result = grp;
477184974e0Schristos else
478184974e0Schristos *result = NULL;
479184974e0Schristos return rv;
480184974e0Schristos }
481184974e0Schristos
482184974e0Schristos /*ARGSUSED*/
483184974e0Schristos static int
_files_getgrgid(void * nsrv,void * nscb,va_list ap)484c54f283eSlukem _files_getgrgid(void *nsrv, void *nscb, va_list ap)
485c54f283eSlukem {
486c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
4870eb8645eSlukem gid_t gid = va_arg(ap, gid_t);
488c54f283eSlukem
489c54f283eSlukem int rv, rerror;
490c54f283eSlukem
491c54f283eSlukem _DIAGASSERT(retval != NULL);
492c54f283eSlukem
493c54f283eSlukem *retval = NULL;
494337d8d73Slukem rv = __grstart_files(&_files_state);
495c54f283eSlukem if (rv != NS_SUCCESS)
496c54f283eSlukem return rv;
497337d8d73Slukem rv = __grscan_files(&rerror, &_files_group,
498c54f283eSlukem _files_groupbuf, sizeof(_files_groupbuf),
499c54f283eSlukem &_files_state, 1, NULL, gid);
500c54f283eSlukem if (!_files_state.stayopen)
501337d8d73Slukem __grend_files(&_files_state);
502c54f283eSlukem if (rv == NS_SUCCESS)
503c54f283eSlukem *retval = &_files_group;
504c54f283eSlukem return rv;
505c54f283eSlukem }
506c54f283eSlukem
507c54f283eSlukem /*ARGSUSED*/
508c54f283eSlukem static int
_files_getgrgid_r(void * nsrv,void * nscb,va_list ap)509c54f283eSlukem _files_getgrgid_r(void *nsrv, void *nscb, va_list ap)
510c54f283eSlukem {
511c54f283eSlukem int *retval = va_arg(ap, int *);
512c54f283eSlukem gid_t gid = va_arg(ap, gid_t);
513c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
514c54f283eSlukem char *buffer = va_arg(ap, char *);
515c54f283eSlukem size_t buflen = va_arg(ap, size_t);
516c54f283eSlukem struct group **result = va_arg(ap, struct group **);
517c54f283eSlukem
518337d8d73Slukem struct __grstate_files state;
519c54f283eSlukem int rv;
520c54f283eSlukem
521c54f283eSlukem _DIAGASSERT(retval != NULL);
522c54f283eSlukem _DIAGASSERT(grp != NULL);
523c54f283eSlukem _DIAGASSERT(buffer != NULL);
524c54f283eSlukem _DIAGASSERT(result != NULL);
525c54f283eSlukem
526c54f283eSlukem *result = NULL;
527c54f283eSlukem memset(&state, 0, sizeof(state));
528337d8d73Slukem rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid);
529337d8d73Slukem __grend_files(&state);
530c54f283eSlukem if (rv == NS_SUCCESS)
531c54f283eSlukem *result = grp;
532c54f283eSlukem return rv;
533c54f283eSlukem }
534c54f283eSlukem
535c54f283eSlukem /*ARGSUSED*/
536c54f283eSlukem static int
_files_getgrnam(void * nsrv,void * nscb,va_list ap)537c54f283eSlukem _files_getgrnam(void *nsrv, void *nscb, va_list ap)
538c54f283eSlukem {
539c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
5400eb8645eSlukem const char *name = va_arg(ap, const char *);
5410eb8645eSlukem
542c54f283eSlukem int rv, rerror;
543147dea10Slukem
544c54f283eSlukem _DIAGASSERT(retval != NULL);
5450eb8645eSlukem
546c54f283eSlukem *retval = NULL;
547337d8d73Slukem rv = __grstart_files(&_files_state);
548c54f283eSlukem if (rv != NS_SUCCESS)
549c54f283eSlukem return rv;
550337d8d73Slukem rv = __grscan_files(&rerror, &_files_group,
551c54f283eSlukem _files_groupbuf, sizeof(_files_groupbuf),
552c54f283eSlukem &_files_state, 1, name, 0);
553c54f283eSlukem if (!_files_state.stayopen)
554337d8d73Slukem __grend_files(&_files_state);
555c54f283eSlukem if (rv == NS_SUCCESS)
556c54f283eSlukem *retval = &_files_group;
557c54f283eSlukem return rv;
5580eb8645eSlukem }
5590eb8645eSlukem
560c54f283eSlukem /*ARGSUSED*/
561c54f283eSlukem static int
_files_getgrnam_r(void * nsrv,void * nscb,va_list ap)562c54f283eSlukem _files_getgrnam_r(void *nsrv, void *nscb, va_list ap)
563c54f283eSlukem {
564c54f283eSlukem int *retval = va_arg(ap, int *);
565c54f283eSlukem const char *name = va_arg(ap, const char *);
566c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
567c54f283eSlukem char *buffer = va_arg(ap, char *);
568c54f283eSlukem size_t buflen = va_arg(ap, size_t);
569c54f283eSlukem struct group **result = va_arg(ap, struct group **);
570c54f283eSlukem
571337d8d73Slukem struct __grstate_files state;
572c54f283eSlukem int rv;
573c54f283eSlukem
574c54f283eSlukem _DIAGASSERT(retval != NULL);
575c54f283eSlukem _DIAGASSERT(grp != NULL);
576c54f283eSlukem _DIAGASSERT(buffer != NULL);
577c54f283eSlukem _DIAGASSERT(result != NULL);
578c54f283eSlukem
579c54f283eSlukem *result = NULL;
580c54f283eSlukem memset(&state, 0, sizeof(state));
581337d8d73Slukem rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0);
582337d8d73Slukem __grend_files(&state);
583c54f283eSlukem if (rv == NS_SUCCESS)
584c54f283eSlukem *result = grp;
585c54f283eSlukem return rv;
5860eb8645eSlukem }
5870eb8645eSlukem
588c54f283eSlukem
589c54f283eSlukem #ifdef HESIOD
590c54f283eSlukem /*
591c54f283eSlukem * dns methods
592c54f283eSlukem */
593c54f283eSlukem
594337d8d73Slukem int
__grstart_dns(struct __grstate_dns * state)595337d8d73Slukem __grstart_dns(struct __grstate_dns *state)
59616c5a7ddSelric {
59716c5a7ddSelric
598c54f283eSlukem _DIAGASSERT(state != NULL);
59916c5a7ddSelric
600c54f283eSlukem state->num = 0;
601c54f283eSlukem if (state->context == NULL) { /* setup Hesiod */
602c54f283eSlukem if (hesiod_init(&state->context) == -1)
60316c5a7ddSelric return NS_UNAVAIL;
60416c5a7ddSelric }
60516c5a7ddSelric
60616c5a7ddSelric return NS_SUCCESS;
60716c5a7ddSelric }
6080eb8645eSlukem
609337d8d73Slukem int
__grend_dns(struct __grstate_dns * state)610337d8d73Slukem __grend_dns(struct __grstate_dns *state)
611c54f283eSlukem {
612c54f283eSlukem
613c54f283eSlukem _DIAGASSERT(state != NULL);
614c54f283eSlukem
615c54f283eSlukem state->num = 0;
616c54f283eSlukem if (state->context) {
617c54f283eSlukem hesiod_end(state->context);
618c54f283eSlukem state->context = NULL;
619c54f283eSlukem }
620c54f283eSlukem return NS_SUCCESS;
621c54f283eSlukem }
622c54f283eSlukem
623c54f283eSlukem /*
624337d8d73Slukem * __grscan_dns
625337d8d73Slukem * Search Hesiod for the next desired entry.
626337d8d73Slukem * If search is zero, return the next entry.
627337d8d73Slukem * If search is non-zero, look for a specific name (if name != NULL),
628337d8d73Slukem * or a specific gid (if name == NULL).
629c54f283eSlukem */
630337d8d73Slukem 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)631337d8d73Slukem __grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen,
632337d8d73Slukem struct __grstate_dns *state, int search, const char *name, gid_t gid)
633c54f283eSlukem {
634c54f283eSlukem const char **curzone;
635c54f283eSlukem char **hp, *ep;
636c54f283eSlukem int rv;
637c54f283eSlukem
638337d8d73Slukem static const char *zones_gid_group[] = {
639337d8d73Slukem "gid",
640337d8d73Slukem "group",
641337d8d73Slukem NULL
642337d8d73Slukem };
643337d8d73Slukem
644337d8d73Slukem static const char *zones_group[] = {
645337d8d73Slukem "group",
646337d8d73Slukem NULL
647337d8d73Slukem };
648337d8d73Slukem
649c54f283eSlukem _DIAGASSERT(retval != NULL);
650c54f283eSlukem _DIAGASSERT(grp != NULL);
651c54f283eSlukem _DIAGASSERT(buffer != NULL);
652c54f283eSlukem _DIAGASSERT(state != NULL);
653337d8d73Slukem /* name is NULL to indicate searching for gid */
654c54f283eSlukem
655c54f283eSlukem *retval = 0;
656c54f283eSlukem
657c54f283eSlukem if (state->context == NULL) { /* only start if Hesiod not setup */
658337d8d73Slukem rv = __grstart_dns(state);
659c54f283eSlukem if (rv != NS_SUCCESS)
660c54f283eSlukem return rv;
661c54f283eSlukem }
662c54f283eSlukem
6639fcbc803Slukem next_dns_entry:
664c54f283eSlukem hp = NULL;
665c54f283eSlukem rv = NS_NOTFOUND;
666c54f283eSlukem
667337d8d73Slukem if (! search) { /* find next entry */
668337d8d73Slukem if (state->num == -1) /* exhausted search */
669337d8d73Slukem return NS_NOTFOUND;
670337d8d73Slukem /* find group-NNN */
671337d8d73Slukem snprintf(buffer, buflen, "group-%u", state->num);
672337d8d73Slukem state->num++;
673337d8d73Slukem curzone = zones_group;
674337d8d73Slukem } else if (name) { /* find group name */
675337d8d73Slukem snprintf(buffer, buflen, "%s", name);
676337d8d73Slukem curzone = zones_group;
677337d8d73Slukem } else { /* find gid */
678337d8d73Slukem snprintf(buffer, buflen, "%u", (unsigned int)gid);
679337d8d73Slukem curzone = zones_gid_group;
680337d8d73Slukem }
681337d8d73Slukem
682337d8d73Slukem for (; *curzone; curzone++) { /* search zones */
683c54f283eSlukem hp = hesiod_resolve(state->context, buffer, *curzone);
684c54f283eSlukem if (hp != NULL)
685c54f283eSlukem break;
686c54f283eSlukem if (errno != ENOENT) {
687c54f283eSlukem rv = NS_UNAVAIL;
688c54f283eSlukem goto dnsgrscan_out;
689c54f283eSlukem }
690c54f283eSlukem }
691337d8d73Slukem if (*curzone == NULL) {
692337d8d73Slukem if (! search)
693337d8d73Slukem state->num = -1;
694c54f283eSlukem goto dnsgrscan_out;
695337d8d73Slukem }
696c54f283eSlukem
697c54f283eSlukem if ((ep = strchr(hp[0], '\n')) != NULL)
698c54f283eSlukem *ep = '\0'; /* clear trailing \n */
699337d8d73Slukem if (_gr_parse(hp[0], grp, buffer, buflen)) { /* validate line */
700337d8d73Slukem if (! search) { /* just want this one */
701c54f283eSlukem rv = NS_SUCCESS;
702337d8d73Slukem } else if ((name && strcmp(name, grp->gr_name) == 0) ||
703337d8d73Slukem (!name && gid == grp->gr_gid)) { /* want specific */
704337d8d73Slukem rv = NS_SUCCESS;
705337d8d73Slukem }
7069fcbc803Slukem } else { /* dodgy entry */
7079fcbc803Slukem if (!search) { /* try again if ! searching */
7089fcbc803Slukem hesiod_free_list(state->context, hp);
7099fcbc803Slukem goto next_dns_entry;
7109fcbc803Slukem }
7119fcbc803Slukem }
712c54f283eSlukem
713c54f283eSlukem dnsgrscan_out:
714d0388cffSlukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
715c54f283eSlukem *retval = errno;
716c54f283eSlukem if (hp)
717c54f283eSlukem hesiod_free_list(state->context, hp);
718c54f283eSlukem return rv;
719c54f283eSlukem }
7200eb8645eSlukem
721337d8d73Slukem static struct __grstate_dns _dns_state;
722337d8d73Slukem /* storage for non _r functions */
723337d8d73Slukem static struct group _dns_group;
724337d8d73Slukem static char _dns_groupbuf[_GETGR_R_SIZE_MAX];
725337d8d73Slukem
7266304dadcSchristos /*ARGSUSED*/
7270eb8645eSlukem static int
_dns_setgrent(void * nsrv,void * nscb,va_list ap)728c54f283eSlukem _dns_setgrent(void *nsrv, void *nscb, va_list ap)
7290eb8645eSlukem {
730c54f283eSlukem
731c54f283eSlukem _dns_state.stayopen = 0;
732337d8d73Slukem return __grstart_dns(&_dns_state);
733c54f283eSlukem }
734c54f283eSlukem
735c54f283eSlukem /*ARGSUSED*/
736c54f283eSlukem static int
_dns_setgroupent(void * nsrv,void * nscb,va_list ap)737c54f283eSlukem _dns_setgroupent(void *nsrv, void *nscb, va_list ap)
738c54f283eSlukem {
739c54f283eSlukem int *retval = va_arg(ap, int *);
740c54f283eSlukem int stayopen = va_arg(ap, int);
741c54f283eSlukem
742c54f283eSlukem int rv;
743c54f283eSlukem
744c54f283eSlukem _dns_state.stayopen = stayopen;
745337d8d73Slukem rv = __grstart_dns(&_dns_state);
746c54f283eSlukem *retval = (rv == NS_SUCCESS);
747c54f283eSlukem return rv;
748c54f283eSlukem }
749c54f283eSlukem
750c54f283eSlukem /*ARGSUSED*/
751c54f283eSlukem static int
_dns_endgrent(void * nsrv,void * nscb,va_list ap)752c54f283eSlukem _dns_endgrent(void *nsrv, void *nscb, va_list ap)
753c54f283eSlukem {
754c54f283eSlukem
755c54f283eSlukem _dns_state.stayopen = 0;
756337d8d73Slukem return __grend_dns(&_dns_state);
757c54f283eSlukem }
758c54f283eSlukem
759c54f283eSlukem /*ARGSUSED*/
760c54f283eSlukem static int
_dns_getgrent(void * nsrv,void * nscb,va_list ap)761c54f283eSlukem _dns_getgrent(void *nsrv, void *nscb, va_list ap)
762c54f283eSlukem {
763c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
764c54f283eSlukem
765337d8d73Slukem int rv, rerror;
766c54f283eSlukem
767c54f283eSlukem _DIAGASSERT(retval != NULL);
768c54f283eSlukem
769c54f283eSlukem *retval = NULL;
770337d8d73Slukem rv = __grscan_dns(&rerror, &_dns_group,
771337d8d73Slukem _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0);
772c54f283eSlukem if (rv == NS_SUCCESS)
773c54f283eSlukem *retval = &_dns_group;
774c54f283eSlukem return rv;
775c54f283eSlukem }
776c54f283eSlukem
777c54f283eSlukem /*ARGSUSED*/
778c54f283eSlukem static int
_dns_getgrent_r(void * nsrv,void * nscb,va_list ap)779184974e0Schristos _dns_getgrent_r(void *nsrv, void *nscb, va_list ap)
780184974e0Schristos {
781184974e0Schristos int *retval = va_arg(ap, int *);
782184974e0Schristos struct group *grp = va_arg(ap, struct group *);
783184974e0Schristos char *buffer = va_arg(ap, char *);
784184974e0Schristos size_t buflen = va_arg(ap, size_t);
785184974e0Schristos struct group **result = va_arg(ap, struct group **);
786184974e0Schristos
787184974e0Schristos int rv;
788184974e0Schristos
789184974e0Schristos _DIAGASSERT(retval != NULL);
790184974e0Schristos _DIAGASSERT(grp != NULL);
791184974e0Schristos _DIAGASSERT(buffer != NULL);
792184974e0Schristos _DIAGASSERT(result != NULL);
793184974e0Schristos
794184974e0Schristos rv = __grscan_dns(retval, grp, buffer, buflen,
795184974e0Schristos &_dns_state, 0, NULL, 0);
796184974e0Schristos if (rv == NS_SUCCESS)
797184974e0Schristos *result = grp;
798184974e0Schristos else
799184974e0Schristos *result = NULL;
800184974e0Schristos return rv;
801184974e0Schristos }
802184974e0Schristos /*ARGSUSED*/
803184974e0Schristos static int
_dns_getgrgid(void * nsrv,void * nscb,va_list ap)804c54f283eSlukem _dns_getgrgid(void *nsrv, void *nscb, va_list ap)
805c54f283eSlukem {
806c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
8070eb8645eSlukem gid_t gid = va_arg(ap, gid_t);
808c54f283eSlukem
809c54f283eSlukem int rv, rerror;
810c54f283eSlukem
811c54f283eSlukem _DIAGASSERT(retval != NULL);
812c54f283eSlukem
813c54f283eSlukem *retval = NULL;
814337d8d73Slukem rv = __grstart_dns(&_dns_state);
815c54f283eSlukem if (rv != NS_SUCCESS)
816c54f283eSlukem return rv;
817337d8d73Slukem rv = __grscan_dns(&rerror, &_dns_group,
818337d8d73Slukem _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid);
819c54f283eSlukem if (!_dns_state.stayopen)
820337d8d73Slukem __grend_dns(&_dns_state);
821337d8d73Slukem if (rv == NS_SUCCESS)
822c54f283eSlukem *retval = &_dns_group;
823c54f283eSlukem return rv;
824c54f283eSlukem }
825c54f283eSlukem
826c54f283eSlukem /*ARGSUSED*/
827c54f283eSlukem static int
_dns_getgrgid_r(void * nsrv,void * nscb,va_list ap)828c54f283eSlukem _dns_getgrgid_r(void *nsrv, void *nscb, va_list ap)
829c54f283eSlukem {
830c54f283eSlukem int *retval = va_arg(ap, int *);
831c54f283eSlukem gid_t gid = va_arg(ap, gid_t);
832c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
833c54f283eSlukem char *buffer = va_arg(ap, char *);
834c54f283eSlukem size_t buflen = va_arg(ap, size_t);
835c54f283eSlukem struct group **result = va_arg(ap, struct group **);
836c54f283eSlukem
837337d8d73Slukem struct __grstate_dns state;
838c54f283eSlukem int rv;
839c54f283eSlukem
840c54f283eSlukem _DIAGASSERT(retval != NULL);
841c54f283eSlukem _DIAGASSERT(grp != NULL);
842c54f283eSlukem _DIAGASSERT(buffer != NULL);
843c54f283eSlukem _DIAGASSERT(result != NULL);
844c54f283eSlukem
845c54f283eSlukem *result = NULL;
846c54f283eSlukem memset(&state, 0, sizeof(state));
847337d8d73Slukem rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid);
848337d8d73Slukem __grend_dns(&state);
849337d8d73Slukem if (rv == NS_SUCCESS)
850c54f283eSlukem *result = grp;
851337d8d73Slukem return rv;
852c54f283eSlukem }
853c54f283eSlukem
854c54f283eSlukem /*ARGSUSED*/
855c54f283eSlukem static int
_dns_getgrnam(void * nsrv,void * nscb,va_list ap)856c54f283eSlukem _dns_getgrnam(void *nsrv, void *nscb, va_list ap)
857c54f283eSlukem {
858c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
8590eb8645eSlukem const char *name = va_arg(ap, const char *);
8600eb8645eSlukem
861c54f283eSlukem int rv, rerror;
8620eb8645eSlukem
863c54f283eSlukem _DIAGASSERT(retval != NULL);
864c54f283eSlukem
865c54f283eSlukem *retval = NULL;
866337d8d73Slukem rv = __grstart_dns(&_dns_state);
867c54f283eSlukem if (rv != NS_SUCCESS)
868c54f283eSlukem return rv;
869337d8d73Slukem rv = __grscan_dns(&rerror, &_dns_group,
870337d8d73Slukem _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0);
871c54f283eSlukem if (!_dns_state.stayopen)
872337d8d73Slukem __grend_dns(&_dns_state);
873337d8d73Slukem if (rv == NS_SUCCESS)
874c54f283eSlukem *retval = &_dns_group;
875c54f283eSlukem return rv;
876c54f283eSlukem }
877c54f283eSlukem
878c54f283eSlukem /*ARGSUSED*/
879c54f283eSlukem static int
_dns_getgrnam_r(void * nsrv,void * nscb,va_list ap)880c54f283eSlukem _dns_getgrnam_r(void *nsrv, void *nscb, va_list ap)
881c54f283eSlukem {
882c54f283eSlukem int *retval = va_arg(ap, int *);
883c54f283eSlukem const char *name = va_arg(ap, const char *);
884c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
885c54f283eSlukem char *buffer = va_arg(ap, char *);
886c54f283eSlukem size_t buflen = va_arg(ap, size_t);
887c54f283eSlukem struct group **result = va_arg(ap, struct group **);
888c54f283eSlukem
889337d8d73Slukem struct __grstate_dns state;
890c54f283eSlukem int rv;
891c54f283eSlukem
892c54f283eSlukem _DIAGASSERT(retval != NULL);
893c54f283eSlukem _DIAGASSERT(grp != NULL);
894c54f283eSlukem _DIAGASSERT(buffer != NULL);
895c54f283eSlukem _DIAGASSERT(result != NULL);
896c54f283eSlukem
897c54f283eSlukem *result = NULL;
898c54f283eSlukem memset(&state, 0, sizeof(state));
899337d8d73Slukem rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0);
900337d8d73Slukem __grend_dns(&state);
901337d8d73Slukem if (rv == NS_SUCCESS)
902c54f283eSlukem *result = grp;
903337d8d73Slukem return rv;
904c54f283eSlukem }
905c54f283eSlukem
906c54f283eSlukem #endif /* HESIOD */
907c54f283eSlukem
908c54f283eSlukem
909c54f283eSlukem #ifdef YP
910c54f283eSlukem /*
911c54f283eSlukem * nis methods
912c54f283eSlukem */
913c54f283eSlukem
914337d8d73Slukem int
__grstart_nis(struct __grstate_nis * state)915337d8d73Slukem __grstart_nis(struct __grstate_nis *state)
916c54f283eSlukem {
917c54f283eSlukem
918c54f283eSlukem _DIAGASSERT(state != NULL);
919c54f283eSlukem
920c54f283eSlukem state->done = 0;
921c54f283eSlukem if (state->current) {
922c54f283eSlukem free(state->current);
923c54f283eSlukem state->current = NULL;
924c54f283eSlukem }
925c54f283eSlukem if (state->domain == NULL) { /* setup NIS */
926c54f283eSlukem switch (yp_get_default_domain(&state->domain)) {
9270eb8645eSlukem case 0:
9280eb8645eSlukem break;
9290eb8645eSlukem case YPERR_RESRC:
9300eb8645eSlukem return NS_TRYAGAIN;
9310eb8645eSlukem default:
9320eb8645eSlukem return NS_UNAVAIL;
9330eb8645eSlukem }
9340eb8645eSlukem }
935c54f283eSlukem return NS_SUCCESS;
936c54f283eSlukem }
9370eb8645eSlukem
938337d8d73Slukem int
__grend_nis(struct __grstate_nis * state)939337d8d73Slukem __grend_nis(struct __grstate_nis *state)
940c54f283eSlukem {
941c54f283eSlukem
942c54f283eSlukem _DIAGASSERT(state != NULL);
943c54f283eSlukem
944c54f283eSlukem if (state->domain) {
945c54f283eSlukem state->domain = NULL;
946c54f283eSlukem }
947c54f283eSlukem state->done = 0;
948c54f283eSlukem if (state->current) {
949c54f283eSlukem free(state->current);
950c54f283eSlukem state->current = NULL;
951c54f283eSlukem }
952c54f283eSlukem return NS_SUCCESS;
953c54f283eSlukem }
954c54f283eSlukem
955c54f283eSlukem /*
956337d8d73Slukem * __grscan_nis
957337d8d73Slukem * Search NIS for the next desired entry.
958337d8d73Slukem * If search is zero, return the next entry.
959337d8d73Slukem * If search is non-zero, look for a specific name (if name != NULL),
960337d8d73Slukem * or a specific gid (if name == NULL).
961c54f283eSlukem */
962337d8d73Slukem 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)963337d8d73Slukem __grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen,
964337d8d73Slukem struct __grstate_nis *state, int search, const char *name, gid_t gid)
965c54f283eSlukem {
966337d8d73Slukem const char *map;
967337d8d73Slukem char *key, *data;
968337d8d73Slukem int nisr, rv, keylen, datalen;
969c54f283eSlukem
970c54f283eSlukem _DIAGASSERT(retval != NULL);
971c54f283eSlukem _DIAGASSERT(grp != NULL);
972c54f283eSlukem _DIAGASSERT(buffer != NULL);
973c54f283eSlukem _DIAGASSERT(state != NULL);
974337d8d73Slukem /* name is NULL to indicate searching for gid */
975c54f283eSlukem
976c54f283eSlukem *retval = 0;
977c54f283eSlukem
978c54f283eSlukem if (state->domain == NULL) { /* only start if NIS not setup */
979337d8d73Slukem rv = __grstart_nis(state);
980c54f283eSlukem if (rv != NS_SUCCESS)
981c54f283eSlukem return rv;
982c54f283eSlukem }
983c54f283eSlukem
9849fcbc803Slukem next_nis_entry:
985337d8d73Slukem key = NULL;
9860eb8645eSlukem data = NULL;
987337d8d73Slukem rv = NS_SUCCESS;
988c54f283eSlukem
989337d8d73Slukem if (! search) { /* find next entry */
990337d8d73Slukem if (state->done) /* exhausted search */
991337d8d73Slukem return NS_NOTFOUND;
992337d8d73Slukem map = "group.byname";
993337d8d73Slukem if (state->current) { /* already searching */
994337d8d73Slukem nisr = yp_next(state->domain, map,
995337d8d73Slukem state->current, state->currentlen,
996337d8d73Slukem &key, &keylen, &data, &datalen);
997337d8d73Slukem free(state->current);
998337d8d73Slukem state->current = NULL;
999c54f283eSlukem switch (nisr) {
10000eb8645eSlukem case 0:
1001337d8d73Slukem state->current = key;
1002337d8d73Slukem state->currentlen = keylen;
1003337d8d73Slukem key = NULL;
10040eb8645eSlukem break;
1005337d8d73Slukem case YPERR_NOMORE:
1006337d8d73Slukem rv = NS_NOTFOUND;
1007337d8d73Slukem state->done = 1;
10080eb8645eSlukem break;
10090eb8645eSlukem default:
1010c54f283eSlukem rv = NS_UNAVAIL;
1011c54f283eSlukem break;
10120eb8645eSlukem }
1013337d8d73Slukem } else { /* new search */
1014337d8d73Slukem if (yp_first(state->domain, map,
1015337d8d73Slukem &state->current, &state->currentlen,
1016337d8d73Slukem &data, &datalen)) {
1017337d8d73Slukem rv = NS_UNAVAIL;
1018337d8d73Slukem }
1019337d8d73Slukem }
1020337d8d73Slukem } else { /* search for specific item */
1021337d8d73Slukem if (name) { /* find group name */
1022337d8d73Slukem snprintf(buffer, buflen, "%s", name);
1023337d8d73Slukem map = "group.byname";
1024337d8d73Slukem } else { /* find gid */
1025337d8d73Slukem snprintf(buffer, buflen, "%u", (unsigned int)gid);
1026337d8d73Slukem map = "group.bygid";
1027337d8d73Slukem }
1028337d8d73Slukem nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer),
1029337d8d73Slukem &data, &datalen);
1030337d8d73Slukem switch (nisr) {
1031337d8d73Slukem case 0:
1032337d8d73Slukem break;
1033337d8d73Slukem case YPERR_KEY:
1034337d8d73Slukem rv = NS_NOTFOUND;
1035337d8d73Slukem break;
1036337d8d73Slukem default:
1037337d8d73Slukem rv = NS_UNAVAIL;
1038337d8d73Slukem break;
1039337d8d73Slukem }
1040337d8d73Slukem }
1041337d8d73Slukem if (rv == NS_SUCCESS) { /* validate data */
1042337d8d73Slukem data[datalen] = '\0'; /* clear trailing \n */
1043337d8d73Slukem if (_gr_parse(data, grp, buffer, buflen)) {
1044337d8d73Slukem if (! search) { /* just want this one */
1045337d8d73Slukem rv = NS_SUCCESS;
1046337d8d73Slukem } else if ((name && strcmp(name, grp->gr_name) == 0) ||
1047337d8d73Slukem (!name && gid == grp->gr_gid)) {
1048337d8d73Slukem /* want specific */
1049337d8d73Slukem rv = NS_SUCCESS;
1050337d8d73Slukem }
10519fcbc803Slukem } else { /* dodgy entry */
10529fcbc803Slukem if (!search) { /* try again if ! searching */
10539fcbc803Slukem free(data);
10549fcbc803Slukem goto next_nis_entry;
10559fcbc803Slukem }
10569fcbc803Slukem }
1057337d8d73Slukem }
10580eb8645eSlukem
1059d0388cffSlukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1060c54f283eSlukem *retval = errno;
1061337d8d73Slukem if (key)
1062337d8d73Slukem free(key);
1063c54f283eSlukem if (data)
1064c54f283eSlukem free(data);
1065c54f283eSlukem return rv;
1066c54f283eSlukem }
10670eb8645eSlukem
1068337d8d73Slukem static struct __grstate_nis _nis_state;
1069337d8d73Slukem /* storage for non _r functions */
1070337d8d73Slukem static struct group _nis_group;
1071337d8d73Slukem static char _nis_groupbuf[_GETGR_R_SIZE_MAX];
1072337d8d73Slukem
10736304dadcSchristos /*ARGSUSED*/
10740eb8645eSlukem static int
_nis_setgrent(void * nsrv,void * nscb,va_list ap)1075c54f283eSlukem _nis_setgrent(void *nsrv, void *nscb, va_list ap)
1076c54f283eSlukem {
1077c54f283eSlukem
1078c54f283eSlukem _nis_state.stayopen = 0;
1079337d8d73Slukem return __grstart_nis(&_nis_state);
1080c54f283eSlukem }
1081c54f283eSlukem
1082c54f283eSlukem /*ARGSUSED*/
1083c54f283eSlukem static int
_nis_setgroupent(void * nsrv,void * nscb,va_list ap)1084c54f283eSlukem _nis_setgroupent(void *nsrv, void *nscb, va_list ap)
1085c54f283eSlukem {
1086c54f283eSlukem int *retval = va_arg(ap, int *);
1087c54f283eSlukem int stayopen = va_arg(ap, int);
1088c54f283eSlukem
1089c54f283eSlukem int rv;
1090c54f283eSlukem
1091c54f283eSlukem _nis_state.stayopen = stayopen;
1092337d8d73Slukem rv = __grstart_nis(&_nis_state);
1093c54f283eSlukem *retval = (rv == NS_SUCCESS);
1094c54f283eSlukem return rv;
1095c54f283eSlukem }
1096c54f283eSlukem
1097c54f283eSlukem /*ARGSUSED*/
1098c54f283eSlukem static int
_nis_endgrent(void * nsrv,void * nscb,va_list ap)1099c54f283eSlukem _nis_endgrent(void *nsrv, void *nscb, va_list ap)
1100c54f283eSlukem {
1101c54f283eSlukem
1102337d8d73Slukem return __grend_nis(&_nis_state);
1103c54f283eSlukem }
1104c54f283eSlukem
1105c54f283eSlukem /*ARGSUSED*/
1106c54f283eSlukem static int
_nis_getgrent(void * nsrv,void * nscb,va_list ap)1107c54f283eSlukem _nis_getgrent(void *nsrv, void *nscb, va_list ap)
1108c54f283eSlukem {
1109c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
1110c54f283eSlukem
1111337d8d73Slukem int rv, rerror;
1112c54f283eSlukem
1113c54f283eSlukem _DIAGASSERT(retval != NULL);
1114c54f283eSlukem
1115c54f283eSlukem *retval = NULL;
1116337d8d73Slukem rv = __grscan_nis(&rerror, &_nis_group,
1117337d8d73Slukem _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0);
1118c54f283eSlukem if (rv == NS_SUCCESS)
1119c54f283eSlukem *retval = &_nis_group;
1120c54f283eSlukem return rv;
1121c54f283eSlukem }
1122c54f283eSlukem
1123c54f283eSlukem /*ARGSUSED*/
1124c54f283eSlukem static int
_nis_getgrent_r(void * nsrv,void * nscb,va_list ap)1125184974e0Schristos _nis_getgrent_r(void *nsrv, void *nscb, va_list ap)
1126184974e0Schristos {
1127184974e0Schristos int *retval = va_arg(ap, int *);
1128184974e0Schristos struct group *grp = va_arg(ap, struct group *);
1129184974e0Schristos char *buffer = va_arg(ap, char *);
1130184974e0Schristos size_t buflen = va_arg(ap, size_t);
1131184974e0Schristos struct group **result = va_arg(ap, struct group **);
1132184974e0Schristos
1133184974e0Schristos int rv;
1134184974e0Schristos
1135184974e0Schristos _DIAGASSERT(retval != NULL);
1136184974e0Schristos _DIAGASSERT(grp != NULL);
1137184974e0Schristos _DIAGASSERT(buffer != NULL);
1138184974e0Schristos _DIAGASSERT(result != NULL);
1139184974e0Schristos
1140184974e0Schristos rv = __grscan_nis(retval, grp, buffer, buflen,
1141184974e0Schristos &_nis_state, 0, NULL, 0);
1142184974e0Schristos if (rv == NS_SUCCESS)
1143184974e0Schristos *result = grp;
1144184974e0Schristos else
1145184974e0Schristos *result = NULL;
1146184974e0Schristos return rv;
1147184974e0Schristos }
1148184974e0Schristos
1149184974e0Schristos /*ARGSUSED*/
1150184974e0Schristos static int
_nis_getgrgid(void * nsrv,void * nscb,va_list ap)1151c54f283eSlukem _nis_getgrgid(void *nsrv, void *nscb, va_list ap)
1152c54f283eSlukem {
1153c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
1154c54f283eSlukem gid_t gid = va_arg(ap, gid_t);
1155c54f283eSlukem
1156c54f283eSlukem int rv, rerror;
1157c54f283eSlukem
1158c54f283eSlukem _DIAGASSERT(retval != NULL);
1159c54f283eSlukem
1160c54f283eSlukem *retval = NULL;
1161337d8d73Slukem rv = __grstart_nis(&_nis_state);
1162c54f283eSlukem if (rv != NS_SUCCESS)
1163c54f283eSlukem return rv;
1164337d8d73Slukem rv = __grscan_nis(&rerror, &_nis_group,
1165337d8d73Slukem _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid);
1166c54f283eSlukem if (!_nis_state.stayopen)
1167337d8d73Slukem __grend_nis(&_nis_state);
1168337d8d73Slukem if (rv == NS_SUCCESS)
1169c54f283eSlukem *retval = &_nis_group;
1170c54f283eSlukem return rv;
1171c54f283eSlukem }
1172c54f283eSlukem
1173c54f283eSlukem /*ARGSUSED*/
1174c54f283eSlukem static int
_nis_getgrgid_r(void * nsrv,void * nscb,va_list ap)1175c54f283eSlukem _nis_getgrgid_r(void *nsrv, void *nscb, va_list ap)
1176c54f283eSlukem {
1177c54f283eSlukem int *retval = va_arg(ap, int *);
1178c54f283eSlukem gid_t gid = va_arg(ap, gid_t);
1179c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
1180c54f283eSlukem char *buffer = va_arg(ap, char *);
1181c54f283eSlukem size_t buflen = va_arg(ap, size_t);
1182c54f283eSlukem struct group **result = va_arg(ap, struct group **);
1183c54f283eSlukem
1184337d8d73Slukem struct __grstate_nis state;
1185c54f283eSlukem int rv;
1186c54f283eSlukem
1187c54f283eSlukem _DIAGASSERT(retval != NULL);
1188c54f283eSlukem _DIAGASSERT(grp != NULL);
1189c54f283eSlukem _DIAGASSERT(buffer != NULL);
1190c54f283eSlukem _DIAGASSERT(result != NULL);
1191c54f283eSlukem
1192c54f283eSlukem *result = NULL;
11932ad3ddd6Schristos /* remark: we run under a global mutex inside of this module ... */
11942ad3ddd6Schristos if (_nis_state.stayopen)
11952ad3ddd6Schristos { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
11962ad3ddd6Schristos rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, NULL, gid);
11972ad3ddd6Schristos }
11982ad3ddd6Schristos else
11992ad3ddd6Schristos {
1200c54f283eSlukem memset(&state, 0, sizeof(state));
1201337d8d73Slukem rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
1202337d8d73Slukem __grend_nis(&state);
12032ad3ddd6Schristos }
1204337d8d73Slukem if (rv == NS_SUCCESS)
1205c54f283eSlukem *result = grp;
1206337d8d73Slukem return rv;
1207c54f283eSlukem }
1208c54f283eSlukem
1209c54f283eSlukem /*ARGSUSED*/
1210c54f283eSlukem static int
_nis_getgrnam(void * nsrv,void * nscb,va_list ap)1211c54f283eSlukem _nis_getgrnam(void *nsrv, void *nscb, va_list ap)
1212c54f283eSlukem {
1213c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
1214c54f283eSlukem const char *name = va_arg(ap, const char *);
1215c54f283eSlukem
1216c54f283eSlukem int rv, rerror;
1217c54f283eSlukem
1218c54f283eSlukem _DIAGASSERT(retval != NULL);
1219c54f283eSlukem
1220c54f283eSlukem *retval = NULL;
1221337d8d73Slukem rv = __grstart_nis(&_nis_state);
1222c54f283eSlukem if (rv != NS_SUCCESS)
1223c54f283eSlukem return rv;
1224337d8d73Slukem rv = __grscan_nis(&rerror, &_nis_group,
1225337d8d73Slukem _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0);
1226c54f283eSlukem if (!_nis_state.stayopen)
1227337d8d73Slukem __grend_nis(&_nis_state);
1228337d8d73Slukem if (rv == NS_SUCCESS)
1229c54f283eSlukem *retval = &_nis_group;
1230c54f283eSlukem return rv;
1231c54f283eSlukem }
1232c54f283eSlukem
1233c54f283eSlukem /*ARGSUSED*/
1234c54f283eSlukem static int
_nis_getgrnam_r(void * nsrv,void * nscb,va_list ap)1235c54f283eSlukem _nis_getgrnam_r(void *nsrv, void *nscb, va_list ap)
1236c54f283eSlukem {
1237c54f283eSlukem int *retval = va_arg(ap, int *);
1238c54f283eSlukem const char *name = va_arg(ap, const char *);
1239c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
1240c54f283eSlukem char *buffer = va_arg(ap, char *);
1241c54f283eSlukem size_t buflen = va_arg(ap, size_t);
1242c54f283eSlukem struct group **result = va_arg(ap, struct group **);
1243c54f283eSlukem
1244337d8d73Slukem struct __grstate_nis state;
1245c54f283eSlukem int rv;
1246c54f283eSlukem
1247c54f283eSlukem _DIAGASSERT(retval != NULL);
1248c54f283eSlukem _DIAGASSERT(grp != NULL);
1249c54f283eSlukem _DIAGASSERT(buffer != NULL);
1250c54f283eSlukem _DIAGASSERT(result != NULL);
1251c54f283eSlukem
1252c54f283eSlukem *result = NULL;
12532ad3ddd6Schristos /* remark: we run under a global mutex inside of this module ... */
12542ad3ddd6Schristos if (_nis_state.stayopen)
12552ad3ddd6Schristos { /* use global state only if stayopen is set - otherwiese we would blow up getgrent_r() ... */
12562ad3ddd6Schristos rv = __grscan_nis(retval, grp, buffer, buflen, &_nis_state, 1, name, 0);
12572ad3ddd6Schristos }
12582ad3ddd6Schristos else
12592ad3ddd6Schristos {
1260c54f283eSlukem memset(&state, 0, sizeof(state));
1261337d8d73Slukem rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
1262337d8d73Slukem __grend_nis(&state);
12632ad3ddd6Schristos }
1264337d8d73Slukem if (rv == NS_SUCCESS)
1265c54f283eSlukem *result = grp;
1266337d8d73Slukem return rv;
1267c54f283eSlukem }
1268c54f283eSlukem
1269c54f283eSlukem #endif /* YP */
1270c54f283eSlukem
1271c54f283eSlukem
1272c54f283eSlukem #ifdef _GROUP_COMPAT
1273c54f283eSlukem /*
1274c54f283eSlukem * compat methods
1275c54f283eSlukem */
1276c54f283eSlukem
1277337d8d73Slukem int
__grstart_compat(struct __grstate_compat * state)1278337d8d73Slukem __grstart_compat(struct __grstate_compat *state)
1279c54f283eSlukem {
1280c54f283eSlukem
1281c54f283eSlukem _DIAGASSERT(state != NULL);
1282c54f283eSlukem
1283c54f283eSlukem if (state->fp == NULL) {
12849292cfb2Schristos state->fp = fopen(_PATH_GROUP, "re");
1285c54f283eSlukem if (state->fp == NULL)
1286c54f283eSlukem return NS_UNAVAIL;
1287c54f283eSlukem } else {
1288c54f283eSlukem rewind(state->fp);
1289c54f283eSlukem }
1290c54f283eSlukem return NS_SUCCESS;
1291c54f283eSlukem }
1292c54f283eSlukem
1293337d8d73Slukem int
__grend_compat(struct __grstate_compat * state)1294337d8d73Slukem __grend_compat(struct __grstate_compat *state)
1295c54f283eSlukem {
1296c54f283eSlukem
1297c54f283eSlukem _DIAGASSERT(state != NULL);
1298c54f283eSlukem
1299c54f283eSlukem if (state->name) {
1300c54f283eSlukem free(state->name);
1301c54f283eSlukem state->name = NULL;
1302c54f283eSlukem }
1303c54f283eSlukem if (state->fp) {
1304c54f283eSlukem (void) fclose(state->fp);
1305c54f283eSlukem state->fp = NULL;
1306c54f283eSlukem }
1307c54f283eSlukem return NS_SUCCESS;
1308c54f283eSlukem }
1309c54f283eSlukem
1310c54f283eSlukem
1311c54f283eSlukem /*
1312337d8d73Slukem * __grbad_compat
1313c54f283eSlukem * log an error if "files" or "compat" is specified in
1314c54f283eSlukem * group_compat database
1315c54f283eSlukem */
1316c54f283eSlukem /*ARGSUSED*/
1317337d8d73Slukem int
__grbad_compat(void * nsrv,void * nscb,va_list ap)1318337d8d73Slukem __grbad_compat(void *nsrv, void *nscb, va_list ap)
13190eb8645eSlukem {
13200eb8645eSlukem static int warned;
13210eb8645eSlukem
1322b513fb7cSchristos _DIAGASSERT(nsrv != NULL);
1323b513fb7cSchristos _DIAGASSERT(nscb != NULL);
1324b48252f3Slukem
13250eb8645eSlukem if (!warned) {
13260eb8645eSlukem syslog(LOG_ERR,
13270eb8645eSlukem "nsswitch.conf group_compat database can't use '%s'",
1328337d8d73Slukem (const char *)nscb);
13290eb8645eSlukem }
13300eb8645eSlukem warned = 1;
13310eb8645eSlukem return NS_UNAVAIL;
13320eb8645eSlukem }
13330eb8645eSlukem
13340eb8645eSlukem /*
1335337d8d73Slukem * __grscan_compat
1336c54f283eSlukem * Scan state->fp for the next desired entry.
1337c54f283eSlukem * If search is zero, return the next entry.
1338c54f283eSlukem * If search is non-zero, look for a specific name (if name != NULL),
1339c54f283eSlukem * or a specific gid (if name == NULL).
1340d0388cffSlukem * Sets *retval to the errno if the result is not NS_SUCCESS or
1341d0388cffSlukem * NS_NOTFOUND.
1342337d8d73Slukem *
1343337d8d73Slukem * searchfunc is invoked when a compat "+" lookup is required;
1344337d8d73Slukem * searchcookie is passed as the first argument to searchfunc,
1345337d8d73Slukem * the second argument is the group result.
1346337d8d73Slukem * This should return NS_NOTFOUND when "no more groups" from compat src.
1347337d8d73Slukem * If searchfunc is NULL then nsdispatch of getgrent is used.
1348337d8d73Slukem * This is primarily intended for getgroupmembership(3)'s compat backend.
13490eb8645eSlukem */
1350337d8d73Slukem 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)1351337d8d73Slukem __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen,
1352337d8d73Slukem struct __grstate_compat *state, int search, const char *name, gid_t gid,
1353337d8d73Slukem int (*searchfunc)(void *, struct group **), void *searchcookie)
13540eb8645eSlukem {
1355c54f283eSlukem int rv;
13562ffe6b72Slukem char filebuf[_GETGR_R_SIZE_MAX], *ep;
1357c54f283eSlukem
1358c54f283eSlukem static const ns_dtab compatentdtab[] = {
1359337d8d73Slukem NS_FILES_CB(__grbad_compat, "files")
1360184974e0Schristos NS_DNS_CB(_dns_getgrent_r, NULL)
1361184974e0Schristos NS_NIS_CB(_nis_getgrent_r, NULL)
1362337d8d73Slukem NS_COMPAT_CB(__grbad_compat, "compat")
1363ce2c90c7Schristos NS_NULL_CB
13640eb8645eSlukem };
1365c54f283eSlukem static const ns_dtab compatgiddtab[] = {
1366337d8d73Slukem NS_FILES_CB(__grbad_compat, "files")
1367c54f283eSlukem NS_DNS_CB(_dns_getgrgid_r, NULL)
1368c54f283eSlukem NS_NIS_CB(_nis_getgrgid_r, NULL)
1369337d8d73Slukem NS_COMPAT_CB(__grbad_compat, "compat")
1370ce2c90c7Schristos NS_NULL_CB
1371c54f283eSlukem };
1372c54f283eSlukem static const ns_dtab compatnamdtab[] = {
1373337d8d73Slukem NS_FILES_CB(__grbad_compat, "files")
1374c54f283eSlukem NS_DNS_CB(_dns_getgrnam_r, NULL)
1375c54f283eSlukem NS_NIS_CB(_nis_getgrnam_r, NULL)
1376337d8d73Slukem NS_COMPAT_CB(__grbad_compat, "compat")
1377ce2c90c7Schristos NS_NULL_CB
1378c54f283eSlukem };
1379c54f283eSlukem
1380c54f283eSlukem _DIAGASSERT(retval != NULL);
1381c54f283eSlukem _DIAGASSERT(grp != NULL);
1382c54f283eSlukem _DIAGASSERT(buffer != NULL);
1383c54f283eSlukem _DIAGASSERT(state != NULL);
1384c54f283eSlukem /* name is NULL to indicate searching for gid */
1385c54f283eSlukem
1386c54f283eSlukem *retval = 0;
1387c54f283eSlukem
1388c54f283eSlukem if (state->fp == NULL) { /* only start if file not open yet */
1389337d8d73Slukem rv = __grstart_compat(state);
1390c54f283eSlukem if (rv != NS_SUCCESS)
1391c54f283eSlukem goto compatgrscan_out;
1392c54f283eSlukem }
1393c54f283eSlukem rv = NS_NOTFOUND;
1394c54f283eSlukem
1395c54f283eSlukem for (;;) { /* loop through file */
1396c54f283eSlukem if (state->name != NULL) {
1397c54f283eSlukem /* processing compat entry */
1398c54f283eSlukem int crv, cretval;
1399c54f283eSlukem struct group cgrp, *cgrpres;
1400c54f283eSlukem
1401c54f283eSlukem if (state->name[0]) { /* specific +group: */
1402c54f283eSlukem crv = nsdispatch(NULL, compatnamdtab,
1403c873ad0dSlukem NSDB_GROUP_COMPAT, "getgrnam_r",
1404c873ad0dSlukem __nsdefaultnis,
1405c54f283eSlukem &cretval, state->name,
1406c54f283eSlukem &cgrp, filebuf, sizeof(filebuf), &cgrpres);
1407c54f283eSlukem free(state->name); /* (only check 1 grp) */
1408c54f283eSlukem state->name = NULL;
1409c54f283eSlukem } else if (!search) { /* any group */
1410337d8d73Slukem if (searchfunc) {
1411337d8d73Slukem crv = searchfunc(searchcookie,
1412337d8d73Slukem &cgrpres);
1413337d8d73Slukem } else {
1414c54f283eSlukem crv = nsdispatch(NULL, compatentdtab,
1415184974e0Schristos NSDB_GROUP_COMPAT, "getgrent_r",
1416c873ad0dSlukem __nsdefaultnis,
1417184974e0Schristos &cretval, &cgrp, filebuf,
1418184974e0Schristos sizeof(filebuf), &cgrpres);
1419337d8d73Slukem }
1420c54f283eSlukem } else if (name) { /* specific group */
1421c54f283eSlukem crv = nsdispatch(NULL, compatnamdtab,
1422c873ad0dSlukem NSDB_GROUP_COMPAT, "getgrnam_r",
1423c873ad0dSlukem __nsdefaultnis,
1424c54f283eSlukem &cretval, name,
1425c54f283eSlukem &cgrp, filebuf, sizeof(filebuf), &cgrpres);
1426c54f283eSlukem } else { /* specific gid */
1427c54f283eSlukem crv = nsdispatch(NULL, compatgiddtab,
1428c873ad0dSlukem NSDB_GROUP_COMPAT, "getgrgid_r",
1429c873ad0dSlukem __nsdefaultnis,
1430c54f283eSlukem &cretval, gid,
1431c54f283eSlukem &cgrp, filebuf, sizeof(filebuf), &cgrpres);
1432c54f283eSlukem }
1433c54f283eSlukem if (crv != NS_SUCCESS) { /* not found */
1434c54f283eSlukem free(state->name);
1435c54f283eSlukem state->name = NULL;
1436c54f283eSlukem continue; /* try next line */
1437c54f283eSlukem }
1438c54f283eSlukem if (!_gr_copy(cgrpres, grp, buffer, buflen)) {
1439c54f283eSlukem rv = NS_UNAVAIL;
1440c54f283eSlukem break;
1441c54f283eSlukem }
1442c54f283eSlukem goto compatgrscan_cmpgrp; /* skip to grp test */
1443c54f283eSlukem }
1444c54f283eSlukem
1445c54f283eSlukem /* get next file line */
1446c5e820caSchristos if (fgets(filebuf, (int)sizeof(filebuf), state->fp) == NULL)
1447c54f283eSlukem break;
1448c54f283eSlukem
1449c54f283eSlukem ep = strchr(filebuf, '\n');
14509fcbc803Slukem if (ep == NULL) { /* skip lines that are too big */
1451c54f283eSlukem int ch;
1452c54f283eSlukem
1453c54f283eSlukem while ((ch = getc(state->fp)) != '\n' && ch != EOF)
1454c54f283eSlukem continue;
14559fcbc803Slukem continue;
1456c54f283eSlukem }
1457c54f283eSlukem *ep = '\0'; /* clear trailing \n */
1458c54f283eSlukem
1459c54f283eSlukem if (filebuf[0] == '+') { /* parse compat line */
1460c54f283eSlukem if (state->name)
1461c54f283eSlukem free(state->name);
1462c54f283eSlukem state->name = NULL;
1463c54f283eSlukem switch(filebuf[1]) {
1464c54f283eSlukem case ':':
1465c54f283eSlukem case '\0':
1466c54f283eSlukem state->name = strdup("");
1467c54f283eSlukem break;
1468c54f283eSlukem default:
1469c54f283eSlukem ep = strchr(filebuf + 1, ':');
1470c54f283eSlukem if (ep == NULL)
1471c54f283eSlukem break;
1472c54f283eSlukem *ep = '\0';
1473c54f283eSlukem state->name = strdup(filebuf + 1);
1474c54f283eSlukem break;
1475c54f283eSlukem }
1476c54f283eSlukem if (state->name == NULL) {
1477c54f283eSlukem rv = NS_UNAVAIL;
1478c54f283eSlukem break;
1479c54f283eSlukem }
1480c54f283eSlukem continue;
1481c54f283eSlukem }
1482c54f283eSlukem
1483c54f283eSlukem /* validate line */
1484c54f283eSlukem if (! _gr_parse(filebuf, grp, buffer, buflen)) {
14859fcbc803Slukem continue; /* skip bad lines */
1486c54f283eSlukem }
1487c54f283eSlukem
1488c54f283eSlukem compatgrscan_cmpgrp:
1489c54f283eSlukem if (! search) { /* just want this one */
1490c54f283eSlukem rv = NS_SUCCESS;
1491c54f283eSlukem break;
1492c54f283eSlukem }
1493c54f283eSlukem /* want specific */
1494c54f283eSlukem if ((name && strcmp(name, grp->gr_name) == 0) ||
1495c54f283eSlukem (!name && gid == grp->gr_gid)) {
1496c54f283eSlukem rv = NS_SUCCESS;
1497c54f283eSlukem break;
1498c54f283eSlukem }
1499c54f283eSlukem
1500c54f283eSlukem }
1501c54f283eSlukem
1502c54f283eSlukem compatgrscan_out:
1503d0388cffSlukem if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1504c54f283eSlukem *retval = errno;
1505c54f283eSlukem return rv;
1506c54f283eSlukem }
1507c54f283eSlukem
1508337d8d73Slukem static struct __grstate_compat _compat_state;
1509337d8d73Slukem /* storage for non _r functions */
1510337d8d73Slukem static struct group _compat_group;
1511337d8d73Slukem static char _compat_groupbuf[_GETGR_R_SIZE_MAX];
1512337d8d73Slukem
1513c54f283eSlukem /*ARGSUSED*/
1514c54f283eSlukem static int
_compat_setgrent(void * nsrv,void * nscb,va_list ap)1515c54f283eSlukem _compat_setgrent(void *nsrv, void *nscb, va_list ap)
1516c54f283eSlukem {
1517c54f283eSlukem static const ns_dtab dtab[] = {
1518337d8d73Slukem NS_FILES_CB(__grbad_compat, "files")
1519c54f283eSlukem NS_DNS_CB(_dns_setgrent, NULL)
1520c54f283eSlukem NS_NIS_CB(_nis_setgrent, NULL)
1521337d8d73Slukem NS_COMPAT_CB(__grbad_compat, "compat")
1522ce2c90c7Schristos NS_NULL_CB
1523c54f283eSlukem };
1524c54f283eSlukem
1525c54f283eSlukem /* force group_compat setgrent() */
1526c54f283eSlukem (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgrent",
1527c873ad0dSlukem __nsdefaultnis_forceall);
1528c54f283eSlukem
1529c54f283eSlukem /* reset state, keep fp open */
1530c54f283eSlukem _compat_state.stayopen = 0;
1531337d8d73Slukem return __grstart_compat(&_compat_state);
1532c54f283eSlukem }
1533c54f283eSlukem
1534c54f283eSlukem /*ARGSUSED*/
1535c54f283eSlukem static int
_compat_setgroupent(void * nsrv,void * nscb,va_list ap)1536c54f283eSlukem _compat_setgroupent(void *nsrv, void *nscb, va_list ap)
1537c54f283eSlukem {
1538c54f283eSlukem int *retval = va_arg(ap, int *);
1539c54f283eSlukem int stayopen = va_arg(ap, int);
1540c54f283eSlukem
1541c54f283eSlukem int rv;
1542c54f283eSlukem
1543c54f283eSlukem static const ns_dtab dtab[] = {
1544337d8d73Slukem NS_FILES_CB(__grbad_compat, "files")
1545c54f283eSlukem NS_DNS_CB(_dns_setgroupent, NULL)
1546c54f283eSlukem NS_NIS_CB(_nis_setgroupent, NULL)
1547337d8d73Slukem NS_COMPAT_CB(__grbad_compat, "compat")
1548ce2c90c7Schristos NS_NULL_CB
1549c54f283eSlukem };
1550c54f283eSlukem
1551c54f283eSlukem /* force group_compat setgroupent() */
1552c54f283eSlukem (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgroupent",
1553c873ad0dSlukem __nsdefaultnis_forceall, &rv, stayopen);
1554c54f283eSlukem
1555c54f283eSlukem _compat_state.stayopen = stayopen;
1556337d8d73Slukem rv = __grstart_compat(&_compat_state);
1557c54f283eSlukem *retval = (rv == NS_SUCCESS);
1558c54f283eSlukem return rv;
1559c54f283eSlukem }
1560c54f283eSlukem
1561c54f283eSlukem /*ARGSUSED*/
1562c54f283eSlukem static int
_compat_endgrent(void * nsrv,void * nscb,va_list ap)1563c54f283eSlukem _compat_endgrent(void *nsrv, void *nscb, va_list ap)
1564c54f283eSlukem {
1565c54f283eSlukem static const ns_dtab dtab[] = {
1566337d8d73Slukem NS_FILES_CB(__grbad_compat, "files")
1567c54f283eSlukem NS_DNS_CB(_dns_endgrent, NULL)
1568c54f283eSlukem NS_NIS_CB(_nis_endgrent, NULL)
1569337d8d73Slukem NS_COMPAT_CB(__grbad_compat, "compat")
1570ce2c90c7Schristos NS_NULL_CB
1571c54f283eSlukem };
1572c54f283eSlukem
1573c54f283eSlukem /* force group_compat endgrent() */
1574c54f283eSlukem (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "endgrent",
1575c873ad0dSlukem __nsdefaultnis_forceall);
1576c54f283eSlukem
1577c54f283eSlukem /* reset state, close fp */
1578c54f283eSlukem _compat_state.stayopen = 0;
1579337d8d73Slukem return __grend_compat(&_compat_state);
1580c54f283eSlukem }
1581c54f283eSlukem
1582c54f283eSlukem /*ARGSUSED*/
1583c54f283eSlukem static int
_compat_getgrent(void * nsrv,void * nscb,va_list ap)1584c54f283eSlukem _compat_getgrent(void *nsrv, void *nscb, va_list ap)
1585c54f283eSlukem {
1586c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
1587c54f283eSlukem
1588c54f283eSlukem int rv, rerror;
1589c54f283eSlukem
1590c54f283eSlukem _DIAGASSERT(retval != NULL);
1591c54f283eSlukem
1592c54f283eSlukem *retval = NULL;
1593337d8d73Slukem rv = __grscan_compat(&rerror, &_compat_group,
1594c54f283eSlukem _compat_groupbuf, sizeof(_compat_groupbuf),
1595337d8d73Slukem &_compat_state, 0, NULL, 0, NULL, NULL);
1596c54f283eSlukem if (rv == NS_SUCCESS)
1597c54f283eSlukem *retval = &_compat_group;
1598c54f283eSlukem return rv;
1599c54f283eSlukem }
1600c54f283eSlukem
1601c54f283eSlukem /*ARGSUSED*/
1602c54f283eSlukem static int
_compat_getgrent_r(void * nsrv,void * nscb,va_list ap)1603184974e0Schristos _compat_getgrent_r(void *nsrv, void *nscb, va_list ap)
1604184974e0Schristos {
1605184974e0Schristos int *retval = va_arg(ap, int *);
1606184974e0Schristos struct group *grp = va_arg(ap, struct group *);
1607184974e0Schristos char *buffer = va_arg(ap, char *);
1608184974e0Schristos size_t buflen = va_arg(ap, size_t);
1609184974e0Schristos struct group **result = va_arg(ap, struct group **);
1610184974e0Schristos
1611184974e0Schristos int rv;
1612184974e0Schristos
1613184974e0Schristos _DIAGASSERT(retval != NULL);
1614184974e0Schristos _DIAGASSERT(grp != NULL);
1615184974e0Schristos _DIAGASSERT(buffer != NULL);
1616184974e0Schristos _DIAGASSERT(result != NULL);
1617184974e0Schristos
1618184974e0Schristos rv = __grscan_compat(retval, grp, buffer, buflen,
1619184974e0Schristos &_compat_state, 0, NULL, 0, NULL, NULL);
1620184974e0Schristos if (rv == NS_SUCCESS)
1621184974e0Schristos *result = grp;
1622184974e0Schristos else
1623184974e0Schristos *result = NULL;
1624184974e0Schristos return rv;
1625184974e0Schristos }
1626184974e0Schristos
1627184974e0Schristos /*ARGSUSED*/
1628184974e0Schristos static int
_compat_getgrgid(void * nsrv,void * nscb,va_list ap)1629c54f283eSlukem _compat_getgrgid(void *nsrv, void *nscb, va_list ap)
1630c54f283eSlukem {
1631c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
1632c54f283eSlukem gid_t gid = va_arg(ap, gid_t);
1633c54f283eSlukem
1634c54f283eSlukem int rv, rerror;
1635c54f283eSlukem
1636c54f283eSlukem _DIAGASSERT(retval != NULL);
1637c54f283eSlukem
1638c54f283eSlukem *retval = NULL;
1639337d8d73Slukem rv = __grstart_compat(&_compat_state);
1640c54f283eSlukem if (rv != NS_SUCCESS)
1641c54f283eSlukem return rv;
1642337d8d73Slukem rv = __grscan_compat(&rerror, &_compat_group,
1643c54f283eSlukem _compat_groupbuf, sizeof(_compat_groupbuf),
1644337d8d73Slukem &_compat_state, 1, NULL, gid, NULL, NULL);
1645c54f283eSlukem if (!_compat_state.stayopen)
1646337d8d73Slukem __grend_compat(&_compat_state);
1647c54f283eSlukem if (rv == NS_SUCCESS)
1648c54f283eSlukem *retval = &_compat_group;
1649c54f283eSlukem return rv;
1650c54f283eSlukem }
1651c54f283eSlukem
1652c54f283eSlukem /*ARGSUSED*/
1653c54f283eSlukem static int
_compat_getgrgid_r(void * nsrv,void * nscb,va_list ap)1654c54f283eSlukem _compat_getgrgid_r(void *nsrv, void *nscb, va_list ap)
1655c54f283eSlukem {
1656c54f283eSlukem int *retval = va_arg(ap, int *);
1657c54f283eSlukem gid_t gid = va_arg(ap, gid_t);
1658c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
1659c54f283eSlukem char *buffer = va_arg(ap, char *);
1660c54f283eSlukem size_t buflen = va_arg(ap, size_t);
1661c54f283eSlukem struct group **result = va_arg(ap, struct group **);
1662c54f283eSlukem
1663337d8d73Slukem struct __grstate_compat state;
1664c54f283eSlukem int rv;
1665c54f283eSlukem
1666c54f283eSlukem _DIAGASSERT(retval != NULL);
1667c54f283eSlukem _DIAGASSERT(grp != NULL);
1668c54f283eSlukem _DIAGASSERT(buffer != NULL);
1669c54f283eSlukem _DIAGASSERT(result != NULL);
1670c54f283eSlukem
1671c54f283eSlukem *result = NULL;
1672c54f283eSlukem memset(&state, 0, sizeof(state));
1673337d8d73Slukem rv = __grscan_compat(retval, grp, buffer, buflen, &state,
1674337d8d73Slukem 1, NULL, gid, NULL, NULL);
1675337d8d73Slukem __grend_compat(&state);
1676c54f283eSlukem if (rv == NS_SUCCESS)
1677c54f283eSlukem *result = grp;
1678c54f283eSlukem return rv;
1679c54f283eSlukem }
1680c54f283eSlukem
1681c54f283eSlukem /*ARGSUSED*/
1682c54f283eSlukem static int
_compat_getgrnam(void * nsrv,void * nscb,va_list ap)1683c54f283eSlukem _compat_getgrnam(void *nsrv, void *nscb, va_list ap)
1684c54f283eSlukem {
1685c54f283eSlukem struct group **retval = va_arg(ap, struct group **);
1686c54f283eSlukem const char *name = va_arg(ap, const char *);
1687c54f283eSlukem
1688c54f283eSlukem int rv, rerror;
1689c54f283eSlukem
1690c54f283eSlukem _DIAGASSERT(retval != NULL);
1691c54f283eSlukem
1692c54f283eSlukem *retval = NULL;
1693337d8d73Slukem rv = __grstart_compat(&_compat_state);
1694c54f283eSlukem if (rv != NS_SUCCESS)
1695c54f283eSlukem return rv;
1696337d8d73Slukem rv = __grscan_compat(&rerror, &_compat_group,
1697c54f283eSlukem _compat_groupbuf, sizeof(_compat_groupbuf),
1698337d8d73Slukem &_compat_state, 1, name, 0, NULL, NULL);
1699c54f283eSlukem if (!_compat_state.stayopen)
1700337d8d73Slukem __grend_compat(&_compat_state);
1701c54f283eSlukem if (rv == NS_SUCCESS)
1702c54f283eSlukem *retval = &_compat_group;
1703c54f283eSlukem return rv;
1704c54f283eSlukem }
1705c54f283eSlukem
1706c54f283eSlukem /*ARGSUSED*/
1707c54f283eSlukem static int
_compat_getgrnam_r(void * nsrv,void * nscb,va_list ap)1708c54f283eSlukem _compat_getgrnam_r(void *nsrv, void *nscb, va_list ap)
1709c54f283eSlukem {
1710c54f283eSlukem int *retval = va_arg(ap, int *);
1711c54f283eSlukem const char *name = va_arg(ap, const char *);
1712c54f283eSlukem struct group *grp = va_arg(ap, struct group *);
1713c54f283eSlukem char *buffer = va_arg(ap, char *);
1714c54f283eSlukem size_t buflen = va_arg(ap, size_t);
1715c54f283eSlukem struct group **result = va_arg(ap, struct group **);
1716c54f283eSlukem
1717337d8d73Slukem struct __grstate_compat state;
1718c54f283eSlukem int rv;
1719c54f283eSlukem
1720c54f283eSlukem _DIAGASSERT(retval != NULL);
1721c54f283eSlukem _DIAGASSERT(grp != NULL);
1722c54f283eSlukem _DIAGASSERT(buffer != NULL);
1723c54f283eSlukem _DIAGASSERT(result != NULL);
1724c54f283eSlukem
1725c54f283eSlukem *result = NULL;
1726c54f283eSlukem memset(&state, 0, sizeof(state));
1727337d8d73Slukem rv = __grscan_compat(retval, grp, buffer, buflen, &state,
1728337d8d73Slukem 1, name, 0, NULL, NULL);
1729337d8d73Slukem __grend_compat(&state);
1730c54f283eSlukem if (rv == NS_SUCCESS)
1731c54f283eSlukem *result = grp;
1732c54f283eSlukem return rv;
1733c54f283eSlukem }
1734c54f283eSlukem
1735c54f283eSlukem #endif /* _GROUP_COMPAT */
1736c54f283eSlukem
1737c54f283eSlukem
1738c54f283eSlukem /*
1739c54f283eSlukem * public functions
1740c54f283eSlukem */
1741c54f283eSlukem
1742c54f283eSlukem struct group *
getgrent(void)1743c54f283eSlukem getgrent(void)
1744c54f283eSlukem {
1745c54f283eSlukem int rv;
1746c54f283eSlukem struct group *retval;
1747c54f283eSlukem
1748c54f283eSlukem static const ns_dtab dtab[] = {
1749c54f283eSlukem NS_FILES_CB(_files_getgrent, NULL)
1750c54f283eSlukem NS_DNS_CB(_dns_getgrent, NULL)
1751c54f283eSlukem NS_NIS_CB(_nis_getgrent, NULL)
1752c54f283eSlukem NS_COMPAT_CB(_compat_getgrent, NULL)
1753ce2c90c7Schristos NS_NULL_CB
1754c54f283eSlukem };
1755c54f283eSlukem
1756337d8d73Slukem mutex_lock(&__grmutex);
1757c873ad0dSlukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent", __nsdefaultcompat,
1758c54f283eSlukem &retval);
1759337d8d73Slukem mutex_unlock(&__grmutex);
1760d0388cffSlukem return (rv == NS_SUCCESS) ? retval : NULL;
1761c54f283eSlukem }
1762c54f283eSlukem
1763184974e0Schristos int
getgrent_r(struct group * grp,char * buffer,size_t buflen,struct group ** result)1764184974e0Schristos getgrent_r(struct group *grp, char *buffer, size_t buflen,
1765184974e0Schristos struct group **result)
1766184974e0Schristos {
1767184974e0Schristos int rv, retval;
1768184974e0Schristos
1769184974e0Schristos static const ns_dtab dtab[] = {
1770184974e0Schristos NS_FILES_CB(_files_getgrent_r, NULL)
1771184974e0Schristos NS_DNS_CB(_dns_getgrent_r, NULL)
1772184974e0Schristos NS_NIS_CB(_nis_getgrent_r, NULL)
1773184974e0Schristos NS_COMPAT_CB(_compat_getgrent_r, NULL)
1774ce2c90c7Schristos NS_NULL_CB
1775184974e0Schristos };
1776184974e0Schristos
1777184974e0Schristos mutex_lock(&__grmutex);
1778184974e0Schristos rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent_r", __nsdefaultcompat,
1779184974e0Schristos &retval, grp, buffer, buflen, result);
1780184974e0Schristos mutex_unlock(&__grmutex);
1781d0388cffSlukem switch (rv) {
1782d0388cffSlukem case NS_SUCCESS:
1783d0388cffSlukem case NS_NOTFOUND:
1784d0388cffSlukem return 0;
1785d0388cffSlukem default:
1786d0388cffSlukem return retval;
1787d0388cffSlukem }
1788184974e0Schristos }
1789184974e0Schristos
1790184974e0Schristos
1791c54f283eSlukem struct group *
getgrgid(gid_t gid)1792c54f283eSlukem getgrgid(gid_t gid)
1793c54f283eSlukem {
1794c54f283eSlukem int rv;
1795c54f283eSlukem struct group *retval;
1796c54f283eSlukem
1797c54f283eSlukem static const ns_dtab dtab[] = {
1798c54f283eSlukem NS_FILES_CB(_files_getgrgid, NULL)
1799c54f283eSlukem NS_DNS_CB(_dns_getgrgid, NULL)
1800c54f283eSlukem NS_NIS_CB(_nis_getgrgid, NULL)
1801c54f283eSlukem NS_COMPAT_CB(_compat_getgrgid, NULL)
1802ce2c90c7Schristos NS_NULL_CB
1803c54f283eSlukem };
1804c54f283eSlukem
1805337d8d73Slukem mutex_lock(&__grmutex);
1806c873ad0dSlukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid", __nsdefaultcompat,
1807c54f283eSlukem &retval, gid);
1808337d8d73Slukem mutex_unlock(&__grmutex);
1809c54f283eSlukem return (rv == NS_SUCCESS) ? retval : NULL;
1810c54f283eSlukem }
1811c54f283eSlukem
1812c54f283eSlukem int
getgrgid_r(gid_t gid,struct group * grp,char * buffer,size_t buflen,struct group ** result)1813c54f283eSlukem getgrgid_r(gid_t gid, struct group *grp, char *buffer, size_t buflen,
1814c54f283eSlukem struct group **result)
1815c54f283eSlukem {
1816c54f283eSlukem int rv, retval;
1817c54f283eSlukem
1818c54f283eSlukem static const ns_dtab dtab[] = {
1819c54f283eSlukem NS_FILES_CB(_files_getgrgid_r, NULL)
1820c54f283eSlukem NS_DNS_CB(_dns_getgrgid_r, NULL)
1821c54f283eSlukem NS_NIS_CB(_nis_getgrgid_r, NULL)
1822c54f283eSlukem NS_COMPAT_CB(_compat_getgrgid_r, NULL)
1823ce2c90c7Schristos NS_NULL_CB
1824c54f283eSlukem };
1825c54f283eSlukem
1826c54f283eSlukem _DIAGASSERT(grp != NULL);
1827c54f283eSlukem _DIAGASSERT(buffer != NULL);
1828c54f283eSlukem _DIAGASSERT(result != NULL);
1829c54f283eSlukem
1830c54f283eSlukem *result = NULL;
1831c54f283eSlukem retval = 0;
1832337d8d73Slukem mutex_lock(&__grmutex);
1833c873ad0dSlukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid_r", __nsdefaultcompat,
1834c54f283eSlukem &retval, gid, grp, buffer, buflen, result);
1835337d8d73Slukem mutex_unlock(&__grmutex);
1836d0388cffSlukem switch (rv) {
1837d0388cffSlukem case NS_SUCCESS:
1838d0388cffSlukem case NS_NOTFOUND:
1839d0388cffSlukem return 0;
1840d0388cffSlukem default:
1841d0388cffSlukem return retval;
1842d0388cffSlukem }
1843c54f283eSlukem }
1844c54f283eSlukem
1845c54f283eSlukem struct group *
getgrnam(const char * name)1846c54f283eSlukem getgrnam(const char *name)
1847c54f283eSlukem {
1848c54f283eSlukem int rv;
1849c54f283eSlukem struct group *retval;
1850c54f283eSlukem
1851c54f283eSlukem static const ns_dtab dtab[] = {
1852c54f283eSlukem NS_FILES_CB(_files_getgrnam, NULL)
1853c54f283eSlukem NS_DNS_CB(_dns_getgrnam, NULL)
1854c54f283eSlukem NS_NIS_CB(_nis_getgrnam, NULL)
1855c54f283eSlukem NS_COMPAT_CB(_compat_getgrnam, NULL)
1856ce2c90c7Schristos NS_NULL_CB
1857c54f283eSlukem };
1858c54f283eSlukem
1859337d8d73Slukem mutex_lock(&__grmutex);
1860c873ad0dSlukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam", __nsdefaultcompat,
1861c54f283eSlukem &retval, name);
1862337d8d73Slukem mutex_unlock(&__grmutex);
1863c54f283eSlukem return (rv == NS_SUCCESS) ? retval : NULL;
1864c54f283eSlukem }
1865c54f283eSlukem
1866c54f283eSlukem int
getgrnam_r(const char * name,struct group * grp,char * buffer,size_t buflen,struct group ** result)1867c54f283eSlukem getgrnam_r(const char *name, struct group *grp, char *buffer, size_t buflen,
1868c54f283eSlukem struct group **result)
1869c54f283eSlukem {
1870c54f283eSlukem int rv, retval;
1871c54f283eSlukem
1872c54f283eSlukem static const ns_dtab dtab[] = {
1873c54f283eSlukem NS_FILES_CB(_files_getgrnam_r, NULL)
1874c54f283eSlukem NS_DNS_CB(_dns_getgrnam_r, NULL)
1875c54f283eSlukem NS_NIS_CB(_nis_getgrnam_r, NULL)
1876c54f283eSlukem NS_COMPAT_CB(_compat_getgrnam_r, NULL)
1877ce2c90c7Schristos NS_NULL_CB
187840901ecdSlukem };
18790eb8645eSlukem
1880b48252f3Slukem _DIAGASSERT(name != NULL);
1881c54f283eSlukem _DIAGASSERT(grp != NULL);
1882c54f283eSlukem _DIAGASSERT(buffer != NULL);
1883c54f283eSlukem _DIAGASSERT(result != NULL);
1884b48252f3Slukem
1885c54f283eSlukem *result = NULL;
1886c54f283eSlukem retval = 0;
1887337d8d73Slukem mutex_lock(&__grmutex);
1888c873ad0dSlukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam_r", __nsdefaultcompat,
1889c54f283eSlukem &retval, name, grp, buffer, buflen, result);
1890337d8d73Slukem mutex_unlock(&__grmutex);
1891d0388cffSlukem switch (rv) {
1892d0388cffSlukem case NS_SUCCESS:
1893d0388cffSlukem case NS_NOTFOUND:
1894d0388cffSlukem return 0;
1895d0388cffSlukem default:
1896d0388cffSlukem return retval;
1897d0388cffSlukem }
18980eb8645eSlukem }
18990eb8645eSlukem
1900c54f283eSlukem void
endgrent(void)1901c54f283eSlukem endgrent(void)
19020eb8645eSlukem {
1903b247a8ecSlukem static const ns_dtab dtab[] = {
1904c54f283eSlukem NS_FILES_CB(_files_endgrent, NULL)
1905c54f283eSlukem NS_DNS_CB(_dns_endgrent, NULL)
1906c54f283eSlukem NS_NIS_CB(_nis_endgrent, NULL)
1907c54f283eSlukem NS_COMPAT_CB(_compat_endgrent, NULL)
1908ce2c90c7Schristos NS_NULL_CB
190940901ecdSlukem };
19100eb8645eSlukem
1911337d8d73Slukem mutex_lock(&__grmutex);
1912c54f283eSlukem /* force all endgrent() methods */
1913c54f283eSlukem (void) nsdispatch(NULL, dtab, NSDB_GROUP, "endgrent",
1914c873ad0dSlukem __nsdefaultcompat_forceall);
1915337d8d73Slukem mutex_unlock(&__grmutex);
19160eb8645eSlukem }
19170eb8645eSlukem
1918c54f283eSlukem int
setgroupent(int stayopen)1919c54f283eSlukem setgroupent(int stayopen)
19200eb8645eSlukem {
1921c54f283eSlukem static const ns_dtab dtab[] = {
1922c54f283eSlukem NS_FILES_CB(_files_setgroupent, NULL)
1923c54f283eSlukem NS_DNS_CB(_dns_setgroupent, NULL)
1924c54f283eSlukem NS_NIS_CB(_nis_setgroupent, NULL)
1925c54f283eSlukem NS_COMPAT_CB(_compat_setgroupent, NULL)
1926ce2c90c7Schristos NS_NULL_CB
1927c54f283eSlukem };
1928c54f283eSlukem int rv, retval;
19290eb8645eSlukem
1930337d8d73Slukem mutex_lock(&__grmutex);
1931c54f283eSlukem /* force all setgroupent() methods */
1932c54f283eSlukem rv = nsdispatch(NULL, dtab, NSDB_GROUP, "setgroupent",
1933c873ad0dSlukem __nsdefaultcompat_forceall, &retval, stayopen);
1934337d8d73Slukem mutex_unlock(&__grmutex);
1935c54f283eSlukem return (rv == NS_SUCCESS) ? retval : 0;
1936c54f283eSlukem }
1937b48252f3Slukem
1938c54f283eSlukem void
setgrent(void)1939c54f283eSlukem setgrent(void)
1940c54f283eSlukem {
1941c54f283eSlukem static const ns_dtab dtab[] = {
1942c54f283eSlukem NS_FILES_CB(_files_setgrent, NULL)
1943c54f283eSlukem NS_DNS_CB(_dns_setgrent, NULL)
1944c54f283eSlukem NS_NIS_CB(_nis_setgrent, NULL)
1945c54f283eSlukem NS_COMPAT_CB(_compat_setgrent, NULL)
1946ce2c90c7Schristos NS_NULL_CB
1947c54f283eSlukem };
1948c54f283eSlukem
1949337d8d73Slukem mutex_lock(&__grmutex);
1950c54f283eSlukem /* force all setgrent() methods */
1951c54f283eSlukem (void) nsdispatch(NULL, dtab, NSDB_GROUP, "setgrent",
1952c873ad0dSlukem __nsdefaultcompat_forceall);
1953337d8d73Slukem mutex_unlock(&__grmutex);
195461f28255Scgd }
1955