Annotation of src/lib/libc/gen/getgrent.c, Revision 1.54.2.4
1.54.2.4! tron 1: /* $NetBSD: getgrent.c,v 1.54.2.3 2005/07/11 21:25:27 tron Exp $ */
1.49 lukem 2:
3: /*-
1.54 lukem 4: * Copyright (c) 1999-2000, 2004-2005 The NetBSD Foundation, Inc.
1.49 lukem 5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Luke Mewburn.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the NetBSD
21: * Foundation, Inc. and its contributors.
22: * 4. Neither the name of The NetBSD Foundation nor the names of its
23: * contributors may be used to endorse or promote products derived
24: * from this software without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36: * POSSIBILITY OF SUCH DAMAGE.
37: */
1.11 cgd 38:
1.1 cgd 39: /*
1.11 cgd 40: * Copyright (c) 1989, 1993
41: * The Regents of the University of California. All rights reserved.
1.47 agc 42: *
43: * Redistribution and use in source and binary forms, with or without
44: * modification, are permitted provided that the following conditions
45: * are met:
46: * 1. Redistributions of source code must retain the above copyright
47: * notice, this list of conditions and the following disclaimer.
48: * 2. Redistributions in binary form must reproduce the above copyright
49: * notice, this list of conditions and the following disclaimer in the
50: * documentation and/or other materials provided with the distribution.
51: * 3. Neither the name of the University nor the names of its contributors
52: * may be used to endorse or promote products derived from this software
53: * without specific prior written permission.
54: *
55: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
56: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
59: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
60: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
61: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
62: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65: * SUCH DAMAGE.
66: */
67:
68: /*
1.13 phil 69: * Portions Copyright (c) 1994, Jason Downs. All Rights Reserved.
1.1 cgd 70: *
71: * Redistribution and use in source and binary forms, with or without
72: * modification, are permitted provided that the following conditions
73: * are met:
74: * 1. Redistributions of source code must retain the above copyright
75: * notice, this list of conditions and the following disclaimer.
76: * 2. Redistributions in binary form must reproduce the above copyright
77: * notice, this list of conditions and the following disclaimer in the
78: * documentation and/or other materials provided with the distribution.
79: *
1.48 agc 80: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS
81: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
82: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
83: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT,
84: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
85: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
86: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
87: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.1 cgd 88: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
89: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
90: * SUCH DAMAGE.
91: */
92:
1.20 christos 93: #include <sys/cdefs.h>
1.1 cgd 94: #if defined(LIBC_SCCS) && !defined(lint)
1.11 cgd 95: #if 0
96: static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
97: #else
1.54.2.4! tron 98: __RCSID("$NetBSD: getgrent.c,v 1.54.2.3 2005/07/11 21:25:27 tron Exp $");
1.11 cgd 99: #endif
1.1 cgd 100: #endif /* LIBC_SCCS and not lint */
101:
1.21 jtc 102: #include "namespace.h"
1.51 lukem 103: #include "reentrant.h"
1.33 lukem 104:
1.49 lukem 105: #include <sys/param.h>
1.33 lukem 106:
1.37 lukem 107: #include <assert.h>
1.33 lukem 108: #include <errno.h>
1.27 lukem 109: #include <grp.h>
1.18 lukem 110: #include <limits.h>
1.27 lukem 111: #include <nsswitch.h>
1.50 lukem 112: #include <stdarg.h>
1.1 cgd 113: #include <stdio.h>
114: #include <stdlib.h>
1.2 deraadt 115: #include <string.h>
1.27 lukem 116: #include <syslog.h>
1.33 lukem 117:
1.27 lukem 118: #ifdef HESIOD
119: #include <hesiod.h>
120: #endif
1.49 lukem 121:
1.2 deraadt 122: #ifdef YP
123: #include <rpc/rpc.h>
124: #include <rpcsvc/yp_prot.h>
125: #include <rpcsvc/ypclnt.h>
1.21 jtc 126: #endif
127:
1.54 lukem 128: #include "gr_private.h"
1.34 lukem 129:
1.21 jtc 130: #ifdef __weak_alias
1.39 mycroft 131: __weak_alias(endgrent,_endgrent)
132: __weak_alias(getgrent,_getgrent)
1.54.2.2 tron 133: __weak_alias(getgrent_r,_getgrent_r)
1.39 mycroft 134: __weak_alias(getgrgid,_getgrgid)
1.49 lukem 135: __weak_alias(getgrgid_r,_getgrgid_r)
1.39 mycroft 136: __weak_alias(getgrnam,_getgrnam)
1.49 lukem 137: __weak_alias(getgrnam_r,_getgrnam_r)
1.39 mycroft 138: __weak_alias(setgrent,_setgrent)
139: __weak_alias(setgroupent,_setgroupent)
1.2 deraadt 140: #endif
1.54 lukem 141:
1.50 lukem 142: #ifdef _REENTRANT
1.54 lukem 143: mutex_t __grmutex = MUTEX_INITIALIZER;
1.50 lukem 144: #endif
1.1 cgd 145:
1.49 lukem 146: /*
147: * _gr_memfrombuf
148: * Obtain want bytes from buffer (of size buflen) and return a pointer
149: * to the available memory after adjusting buffer/buflen.
150: * Returns NULL if there is insufficient space.
151: */
152: static char *
153: _gr_memfrombuf(size_t want, char **buffer, size_t *buflen)
154: {
155: char *rv;
156:
157: if (want > *buflen) {
158: errno = ERANGE;
159: return NULL;
160: }
161: rv = *buffer;
162: *buffer += want;
163: *buflen -= want;
164: return rv;
165: }
1.27 lukem 166:
1.49 lukem 167: /*
168: * _gr_parse
169: * Parses entry as a line per group(5) (without the trailing \n)
170: * and fills in grp with corresponding values; memory for strings
171: * and arrays will be allocated from buf (of size buflen).
172: * Returns 1 if parsed successfully, 0 on parse failure.
173: */
174: static int
175: _gr_parse(const char *entry, struct group *grp, char *buf, size_t buflen)
176: {
177: unsigned long id;
178: const char *bp;
179: char *ep;
180: size_t count;
181: int memc;
182:
183: _DIAGASSERT(entry != NULL);
184: _DIAGASSERT(grp != NULL);
185: _DIAGASSERT(buf != NULL);
186:
187: #define COPYTOBUF(to) \
188: do { \
189: (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
190: if ((to) == NULL) \
191: return 0; \
192: memmove((to), entry, count); \
193: to[count] = '\0'; \
194: } while (0) /* LINTED */
1.1 cgd 195:
1.49 lukem 196: #if 0
197: if (*entry == '+') /* fail on compat `+' token */
198: return 0;
1.27 lukem 199: #endif
200:
1.49 lukem 201: count = strcspn(entry, ":"); /* parse gr_name */
202: if (entry[count] == '\0')
203: return 0;
204: COPYTOBUF(grp->gr_name);
205: entry += count + 1;
206:
207: count = strcspn(entry, ":"); /* parse gr_passwd */
208: if (entry[count] == '\0')
209: return 0;
210: COPYTOBUF(grp->gr_passwd);
211: entry += count + 1;
212:
213: count = strcspn(entry, ":"); /* parse gr_gid */
214: if (entry[count] == '\0')
215: return 0;
216: id = strtoul(entry, &ep, 10);
217: if (id > GID_MAX || *ep != ':')
218: return 0;
219: grp->gr_gid = (gid_t)id;
220: entry += count + 1;
221:
222: memc = 1; /* for final NULL */
223: if (*entry != '\0')
224: memc++; /* for first item */
225: for (bp = entry; *bp != '\0'; bp++) {
226: if (*bp == ',')
227: memc++;
228: }
229: /* grab ALIGNed char **gr_mem from buf */
230: ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
231: grp->gr_mem = (char **)ALIGN(ep);
232: if (grp->gr_mem == NULL)
233: return 0;
1.2 deraadt 234:
1.49 lukem 235: for (memc = 0; *entry != '\0'; memc++) {
236: count = strcspn(entry, ","); /* parse member */
237: COPYTOBUF(grp->gr_mem[memc]);
238: entry += count;
239: if (*entry == ',')
240: entry++;
241: }
1.34 lukem 242:
1.49 lukem 243: #undef COPYTOBUF
1.41 lukem 244:
1.49 lukem 245: grp->gr_mem[memc] = NULL;
246: return 1;
1.45 elric 247: }
248:
249: /*
1.49 lukem 250: * _gr_copy
251: * Copy the contents of fromgrp to grp; memory for strings
252: * and arrays will be allocated from buf (of size buflen).
253: * Returns 1 if copied successfully, 0 on copy failure.
254: * NOTE: fromgrp must not use buf for its own pointers.
1.45 elric 255: */
1.49 lukem 256: static int
257: _gr_copy(struct group *fromgrp, struct group *grp, char *buf, size_t buflen)
258: {
259: char *ep;
260: int memc;
261:
262: _DIAGASSERT(fromgrp != NULL);
263: _DIAGASSERT(grp != NULL);
264: _DIAGASSERT(buf != NULL);
265:
266: #define COPYSTR(to, from) \
267: do { \
268: size_t count = strlen((from)); \
269: (to) = _gr_memfrombuf(count+1, &buf, &buflen); \
270: if ((to) == NULL) \
271: return 0; \
272: memmove((to), (from), count); \
273: to[count] = '\0'; \
274: } while (0) /* LINTED */
275:
276: COPYSTR(grp->gr_name, fromgrp->gr_name);
277: COPYSTR(grp->gr_passwd, fromgrp->gr_passwd);
278: grp->gr_gid = fromgrp->gr_gid;
279:
280: for (memc = 0; fromgrp->gr_mem[memc]; memc++)
281: continue;
282: memc++; /* for final NULL */
283:
284: /* grab ALIGNed char **gr_mem from buf */
285: ep = _gr_memfrombuf(memc * sizeof(char *) + ALIGNBYTES, &buf, &buflen);
286: grp->gr_mem = (char **)ALIGN(ep);
287: if (grp->gr_mem == NULL)
288: return 0;
289:
290: for (memc = 0; fromgrp->gr_mem[memc]; memc++) {
291: COPYSTR(grp->gr_mem[memc], fromgrp->gr_mem[memc]);
292: }
293:
294: #undef COPYSTR
1.45 elric 295:
1.49 lukem 296: grp->gr_mem[memc] = NULL;
297: return 1;
298: }
299:
300: /*
301: * files methods
302: */
303:
1.54 lukem 304: int
305: __grstart_files(struct __grstate_files *state)
1.45 elric 306: {
307:
1.49 lukem 308: _DIAGASSERT(state != NULL);
309:
310: if (state->fp == NULL) {
311: state->fp = fopen(_PATH_GROUP, "r");
312: if (state->fp == NULL)
313: return NS_UNAVAIL;
314: } else {
315: rewind(state->fp);
316: }
317: return NS_SUCCESS;
1.1 cgd 318: }
319:
1.54 lukem 320: int
321: __grend_files(struct __grstate_files *state)
1.1 cgd 322: {
323:
1.49 lukem 324: _DIAGASSERT(state != NULL);
1.37 lukem 325:
1.49 lukem 326: if (state->fp) {
327: (void) fclose(state->fp);
328: state->fp = NULL;
329: }
330: return NS_SUCCESS;
1.1 cgd 331: }
332:
1.49 lukem 333: /*
1.54 lukem 334: * __grscan_files
1.49 lukem 335: * Scan state->fp for the next desired entry.
336: * If search is zero, return the next entry.
337: * If search is non-zero, look for a specific name (if name != NULL),
338: * or a specific gid (if name == NULL).
1.54.2.3 tron 339: * Sets *retval to the errno if the result is not NS_SUCCESS
340: * or NS_NOTFOUND.
1.49 lukem 341: */
1.54 lukem 342: int
343: __grscan_files(int *retval, struct group *grp, char *buffer, size_t buflen,
344: struct __grstate_files *state, int search, const char *name, gid_t gid)
1.1 cgd 345: {
1.49 lukem 346: int rv;
1.52 lukem 347: char filebuf[_GETGR_R_SIZE_MAX], *ep;
1.49 lukem 348:
349: _DIAGASSERT(retval != NULL);
350: _DIAGASSERT(grp != NULL);
351: _DIAGASSERT(buffer != NULL);
352: _DIAGASSERT(state != NULL);
353: /* name is NULL to indicate searching for gid */
354:
355: *retval = 0;
356:
357: if (state->fp == NULL) { /* only start if file not open yet */
1.54 lukem 358: rv = __grstart_files(state);
1.49 lukem 359: if (rv != NS_SUCCESS)
360: goto filesgrscan_out;
361: }
362:
363: rv = NS_NOTFOUND;
364:
365: /* scan line by line */
366: while (fgets(filebuf, sizeof(filebuf), state->fp) != NULL) {
367: ep = strchr(filebuf, '\n');
1.54.2.4! tron 368: if (ep == NULL) { /* skip lines that are too big */
1.49 lukem 369: int ch;
370:
371: while ((ch = getc(state->fp)) != '\n' && ch != EOF)
372: continue;
1.54.2.4! tron 373: continue;
1.49 lukem 374: }
375: *ep = '\0'; /* clear trailing \n */
376:
377: if (filebuf[0] == '+') /* skip compat line */
378: continue;
379:
380: /* validate line */
381: if (! _gr_parse(filebuf, grp, buffer, buflen)) {
1.54.2.4! tron 382: continue; /* skip bad lines */
1.49 lukem 383: }
384: if (! search) { /* just want this one */
385: rv = NS_SUCCESS;
386: break;
387: }
388: /* want specific */
389: if ((name && strcmp(name, grp->gr_name) == 0) ||
390: (!name && gid == grp->gr_gid)) {
391: rv = NS_SUCCESS;
392: break;
393: }
394: }
1.1 cgd 395:
1.49 lukem 396: filesgrscan_out:
1.54.2.3 tron 397: if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1.49 lukem 398: *retval = errno;
399: return rv;
1.1 cgd 400: }
401:
1.54 lukem 402:
403: static struct __grstate_files _files_state;
404: /* storage for non _r functions */
405: static struct group _files_group;
406: static char _files_groupbuf[_GETGR_R_SIZE_MAX];
407:
1.49 lukem 408: /*ARGSUSED*/
409: static int
410: _files_setgrent(void *nsrv, void *nscb, va_list ap)
1.1 cgd 411: {
1.41 lukem 412:
1.49 lukem 413: _files_state.stayopen = 0;
1.54 lukem 414: return __grstart_files(&_files_state);
1.36 lukem 415: }
416:
1.49 lukem 417: /*ARGSUSED*/
1.36 lukem 418: static int
1.49 lukem 419: _files_setgroupent(void *nsrv, void *nscb, va_list ap)
1.36 lukem 420: {
1.49 lukem 421: int *retval = va_arg(ap, int *);
422: int stayopen = va_arg(ap, int);
1.41 lukem 423:
1.49 lukem 424: int rv;
425:
426: _files_state.stayopen = stayopen;
1.54 lukem 427: rv = __grstart_files(&_files_state);
1.49 lukem 428: *retval = (rv == NS_SUCCESS);
429: return rv;
1.1 cgd 430: }
431:
1.49 lukem 432: /*ARGSUSED*/
433: static int
434: _files_endgrent(void *nsrv, void *nscb, va_list ap)
1.1 cgd 435: {
1.41 lukem 436:
1.49 lukem 437: _files_state.stayopen = 0;
1.54 lukem 438: return __grend_files(&_files_state);
1.1 cgd 439: }
440:
1.49 lukem 441: /*ARGSUSED*/
442: static int
443: _files_getgrent(void *nsrv, void *nscb, va_list ap)
1.1 cgd 444: {
1.49 lukem 445: struct group **retval = va_arg(ap, struct group **);
446:
447: int rv, rerror;
448:
449: _DIAGASSERT(retval != NULL);
1.41 lukem 450:
1.49 lukem 451: *retval = NULL;
1.54 lukem 452: rv = __grscan_files(&rerror, &_files_group,
1.49 lukem 453: _files_groupbuf, sizeof(_files_groupbuf),
454: &_files_state, 0, NULL, 0);
455: if (rv == NS_SUCCESS)
456: *retval = &_files_group;
457: return rv;
1.1 cgd 458: }
459:
1.49 lukem 460: /*ARGSUSED*/
461: static int
1.54.2.2 tron 462: _files_getgrent_r(void *nsrv, void *nscb, va_list ap)
463: {
464: int *retval = va_arg(ap, int *);
465: struct group *grp = va_arg(ap, struct group *);
466: char *buffer = va_arg(ap, char *);
467: size_t buflen = va_arg(ap, size_t);
468: struct group **result = va_arg(ap, struct group **);
469:
470: int rv;
471:
472: _DIAGASSERT(retval != NULL);
473: _DIAGASSERT(grp != NULL);
474: _DIAGASSERT(buffer != NULL);
475: _DIAGASSERT(result != NULL);
476:
477: rv = __grscan_files(retval, grp, buffer, buflen,
478: &_files_state, 0, NULL, 0);
479: if (rv == NS_SUCCESS)
480: *result = grp;
481: else
482: *result = NULL;
483: return rv;
484: }
485:
486: /*ARGSUSED*/
487: static int
1.49 lukem 488: _files_getgrgid(void *nsrv, void *nscb, va_list ap)
1.1 cgd 489: {
1.49 lukem 490: struct group **retval = va_arg(ap, struct group **);
491: gid_t gid = va_arg(ap, gid_t);
492:
493: int rv, rerror;
494:
495: _DIAGASSERT(retval != NULL);
1.41 lukem 496:
1.49 lukem 497: *retval = NULL;
1.54 lukem 498: rv = __grstart_files(&_files_state);
1.49 lukem 499: if (rv != NS_SUCCESS)
500: return rv;
1.54 lukem 501: rv = __grscan_files(&rerror, &_files_group,
1.49 lukem 502: _files_groupbuf, sizeof(_files_groupbuf),
503: &_files_state, 1, NULL, gid);
504: if (!_files_state.stayopen)
1.54 lukem 505: __grend_files(&_files_state);
1.49 lukem 506: if (rv == NS_SUCCESS)
507: *retval = &_files_group;
508: return rv;
1.1 cgd 509: }
510:
1.49 lukem 511: /*ARGSUSED*/
512: static int
513: _files_getgrgid_r(void *nsrv, void *nscb, va_list ap)
514: {
515: int *retval = va_arg(ap, int *);
516: gid_t gid = va_arg(ap, gid_t);
517: struct group *grp = va_arg(ap, struct group *);
518: char *buffer = va_arg(ap, char *);
519: size_t buflen = va_arg(ap, size_t);
520: struct group **result = va_arg(ap, struct group **);
521:
1.54 lukem 522: struct __grstate_files state;
1.49 lukem 523: int rv;
524:
525: _DIAGASSERT(retval != NULL);
526: _DIAGASSERT(grp != NULL);
527: _DIAGASSERT(buffer != NULL);
528: _DIAGASSERT(result != NULL);
529:
530: *result = NULL;
531: memset(&state, 0, sizeof(state));
1.54 lukem 532: rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, NULL, gid);
533: __grend_files(&state);
1.49 lukem 534: if (rv == NS_SUCCESS)
535: *result = grp;
536: return rv;
537: }
1.27 lukem 538:
1.29 christos 539: /*ARGSUSED*/
1.27 lukem 540: static int
1.49 lukem 541: _files_getgrnam(void *nsrv, void *nscb, va_list ap)
1.27 lukem 542: {
1.49 lukem 543: struct group **retval = va_arg(ap, struct group **);
544: const char *name = va_arg(ap, const char *);
545:
546: int rv, rerror;
547:
548: _DIAGASSERT(retval != NULL);
1.27 lukem 549:
1.49 lukem 550: *retval = NULL;
1.54 lukem 551: rv = __grstart_files(&_files_state);
1.49 lukem 552: if (rv != NS_SUCCESS)
553: return rv;
1.54 lukem 554: rv = __grscan_files(&rerror, &_files_group,
1.49 lukem 555: _files_groupbuf, sizeof(_files_groupbuf),
556: &_files_state, 1, name, 0);
557: if (!_files_state.stayopen)
1.54 lukem 558: __grend_files(&_files_state);
1.49 lukem 559: if (rv == NS_SUCCESS)
560: *retval = &_files_group;
561: return rv;
562: }
1.27 lukem 563:
1.49 lukem 564: /*ARGSUSED*/
565: static int
566: _files_getgrnam_r(void *nsrv, void *nscb, va_list ap)
567: {
568: int *retval = va_arg(ap, int *);
569: const char *name = va_arg(ap, const char *);
570: struct group *grp = va_arg(ap, struct group *);
571: char *buffer = va_arg(ap, char *);
572: size_t buflen = va_arg(ap, size_t);
573: struct group **result = va_arg(ap, struct group **);
574:
1.54 lukem 575: struct __grstate_files state;
1.49 lukem 576: int rv;
577:
578: _DIAGASSERT(retval != NULL);
579: _DIAGASSERT(grp != NULL);
580: _DIAGASSERT(buffer != NULL);
581: _DIAGASSERT(result != NULL);
582:
583: *result = NULL;
584: memset(&state, 0, sizeof(state));
1.54 lukem 585: rv = __grscan_files(retval, grp, buffer, buflen, &state, 1, name, 0);
586: __grend_files(&state);
1.49 lukem 587: if (rv == NS_SUCCESS)
588: *result = grp;
589: return rv;
1.27 lukem 590: }
591:
1.49 lukem 592:
1.27 lukem 593: #ifdef HESIOD
1.49 lukem 594: /*
595: * dns methods
596: */
597:
1.54 lukem 598: int
599: __grstart_dns(struct __grstate_dns *state)
1.1 cgd 600: {
601:
1.49 lukem 602: _DIAGASSERT(state != NULL);
1.27 lukem 603:
1.49 lukem 604: state->num = 0;
605: if (state->context == NULL) { /* setup Hesiod */
606: if (hesiod_init(&state->context) == -1)
607: return NS_UNAVAIL;
1.27 lukem 608: }
1.49 lukem 609:
610: return NS_SUCCESS;
1.27 lukem 611: }
1.45 elric 612:
1.54 lukem 613: int
614: __grend_dns(struct __grstate_dns *state)
1.45 elric 615: {
616:
1.49 lukem 617: _DIAGASSERT(state != NULL);
1.45 elric 618:
1.49 lukem 619: state->num = 0;
620: if (state->context) {
621: hesiod_end(state->context);
622: state->context = NULL;
623: }
624: return NS_SUCCESS;
625: }
1.45 elric 626:
1.49 lukem 627: /*
1.54 lukem 628: * __grscan_dns
629: * Search Hesiod for the next desired entry.
630: * If search is zero, return the next entry.
631: * If search is non-zero, look for a specific name (if name != NULL),
632: * or a specific gid (if name == NULL).
1.49 lukem 633: */
1.54 lukem 634: int
635: __grscan_dns(int *retval, struct group *grp, char *buffer, size_t buflen,
636: struct __grstate_dns *state, int search, const char *name, gid_t gid)
1.49 lukem 637: {
638: const char **curzone;
639: char **hp, *ep;
640: int rv;
641:
1.54 lukem 642: static const char *zones_gid_group[] = {
643: "gid",
644: "group",
645: NULL
646: };
647:
648: static const char *zones_group[] = {
649: "group",
650: NULL
651: };
652:
1.49 lukem 653: _DIAGASSERT(retval != NULL);
654: _DIAGASSERT(grp != NULL);
655: _DIAGASSERT(buffer != NULL);
656: _DIAGASSERT(state != NULL);
1.54 lukem 657: /* name is NULL to indicate searching for gid */
1.49 lukem 658:
659: *retval = 0;
660:
661: if (state->context == NULL) { /* only start if Hesiod not setup */
1.54 lukem 662: rv = __grstart_dns(state);
1.49 lukem 663: if (rv != NS_SUCCESS)
664: return rv;
665: }
1.45 elric 666:
1.54.2.4! tron 667: next_dns_entry:
1.49 lukem 668: hp = NULL;
669: rv = NS_NOTFOUND;
1.45 elric 670:
1.54 lukem 671: if (! search) { /* find next entry */
672: if (state->num == -1) /* exhausted search */
673: return NS_NOTFOUND;
674: /* find group-NNN */
675: snprintf(buffer, buflen, "group-%u", state->num);
676: state->num++;
677: curzone = zones_group;
678: } else if (name) { /* find group name */
679: snprintf(buffer, buflen, "%s", name);
680: curzone = zones_group;
681: } else { /* find gid */
682: snprintf(buffer, buflen, "%u", (unsigned int)gid);
683: curzone = zones_gid_group;
684: }
685:
686: for (; *curzone; curzone++) { /* search zones */
1.49 lukem 687: hp = hesiod_resolve(state->context, buffer, *curzone);
688: if (hp != NULL)
689: break;
690: if (errno != ENOENT) {
691: rv = NS_UNAVAIL;
692: goto dnsgrscan_out;
1.45 elric 693: }
1.49 lukem 694: }
1.54 lukem 695: if (*curzone == NULL) {
696: if (! search)
697: state->num = -1;
1.49 lukem 698: goto dnsgrscan_out;
1.54 lukem 699: }
1.45 elric 700:
1.49 lukem 701: if ((ep = strchr(hp[0], '\n')) != NULL)
702: *ep = '\0'; /* clear trailing \n */
1.54 lukem 703: if (_gr_parse(hp[0], grp, buffer, buflen)) { /* validate line */
704: if (! search) { /* just want this one */
705: rv = NS_SUCCESS;
706: } else if ((name && strcmp(name, grp->gr_name) == 0) ||
707: (!name && gid == grp->gr_gid)) { /* want specific */
708: rv = NS_SUCCESS;
709: }
1.54.2.4! tron 710: } else { /* dodgy entry */
! 711: if (!search) { /* try again if ! searching */
! 712: hesiod_free_list(state->context, hp);
! 713: goto next_dns_entry;
! 714: }
! 715: }
1.49 lukem 716:
717: dnsgrscan_out:
1.54.2.3 tron 718: if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1.49 lukem 719: *retval = errno;
720: if (hp)
721: hesiod_free_list(state->context, hp);
722: return rv;
723: }
1.45 elric 724:
1.54 lukem 725: static struct __grstate_dns _dns_state;
726: /* storage for non _r functions */
727: static struct group _dns_group;
728: static char _dns_groupbuf[_GETGR_R_SIZE_MAX];
729:
1.49 lukem 730: /*ARGSUSED*/
731: static int
732: _dns_setgrent(void *nsrv, void *nscb, va_list ap)
733: {
1.45 elric 734:
1.49 lukem 735: _dns_state.stayopen = 0;
1.54 lukem 736: return __grstart_dns(&_dns_state);
1.49 lukem 737: }
1.45 elric 738:
1.49 lukem 739: /*ARGSUSED*/
740: static int
741: _dns_setgroupent(void *nsrv, void *nscb, va_list ap)
742: {
743: int *retval = va_arg(ap, int *);
744: int stayopen = va_arg(ap, int);
1.45 elric 745:
1.49 lukem 746: int rv;
1.45 elric 747:
1.49 lukem 748: _dns_state.stayopen = stayopen;
1.54 lukem 749: rv = __grstart_dns(&_dns_state);
1.49 lukem 750: *retval = (rv == NS_SUCCESS);
751: return rv;
1.45 elric 752: }
1.27 lukem 753:
1.49 lukem 754: /*ARGSUSED*/
755: static int
756: _dns_endgrent(void *nsrv, void *nscb, va_list ap)
757: {
758:
759: _dns_state.stayopen = 0;
1.54 lukem 760: return __grend_dns(&_dns_state);
1.49 lukem 761: }
1.27 lukem 762:
1.29 christos 763: /*ARGSUSED*/
1.27 lukem 764: static int
1.49 lukem 765: _dns_getgrent(void *nsrv, void *nscb, va_list ap)
1.27 lukem 766: {
1.49 lukem 767: struct group **retval = va_arg(ap, struct group **);
768:
1.54 lukem 769: int rv, rerror;
1.49 lukem 770:
771: _DIAGASSERT(retval != NULL);
1.27 lukem 772:
1.49 lukem 773: *retval = NULL;
1.54 lukem 774: rv = __grscan_dns(&rerror, &_dns_group,
775: _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 0, NULL, 0);
1.49 lukem 776: if (rv == NS_SUCCESS)
777: *retval = &_dns_group;
778: return rv;
1.27 lukem 779: }
780:
1.29 christos 781: /*ARGSUSED*/
1.27 lukem 782: static int
1.54.2.2 tron 783: _dns_getgrent_r(void *nsrv, void *nscb, va_list ap)
784: {
785: int *retval = va_arg(ap, int *);
786: struct group *grp = va_arg(ap, struct group *);
787: char *buffer = va_arg(ap, char *);
788: size_t buflen = va_arg(ap, size_t);
789: struct group **result = va_arg(ap, struct group **);
790:
791: int rv;
792:
793: _DIAGASSERT(retval != NULL);
794: _DIAGASSERT(grp != NULL);
795: _DIAGASSERT(buffer != NULL);
796: _DIAGASSERT(result != NULL);
797:
798: rv = __grscan_dns(retval, grp, buffer, buflen,
799: &_dns_state, 0, NULL, 0);
800: if (rv == NS_SUCCESS)
801: *result = grp;
802: else
803: *result = NULL;
804: return rv;
805: }
806: /*ARGSUSED*/
807: static int
1.49 lukem 808: _dns_getgrgid(void *nsrv, void *nscb, va_list ap)
1.27 lukem 809: {
1.49 lukem 810: struct group **retval = va_arg(ap, struct group **);
811: gid_t gid = va_arg(ap, gid_t);
812:
813: int rv, rerror;
1.27 lukem 814:
1.49 lukem 815: _DIAGASSERT(retval != NULL);
1.37 lukem 816:
1.49 lukem 817: *retval = NULL;
1.54 lukem 818: rv = __grstart_dns(&_dns_state);
1.49 lukem 819: if (rv != NS_SUCCESS)
820: return rv;
1.54 lukem 821: rv = __grscan_dns(&rerror, &_dns_group,
822: _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, NULL, gid);
1.49 lukem 823: if (!_dns_state.stayopen)
1.54 lukem 824: __grend_dns(&_dns_state);
825: if (rv == NS_SUCCESS)
1.49 lukem 826: *retval = &_dns_group;
827: return rv;
1.27 lukem 828: }
829:
1.49 lukem 830: /*ARGSUSED*/
831: static int
832: _dns_getgrgid_r(void *nsrv, void *nscb, va_list ap)
833: {
834: int *retval = va_arg(ap, int *);
835: gid_t gid = va_arg(ap, gid_t);
836: struct group *grp = va_arg(ap, struct group *);
837: char *buffer = va_arg(ap, char *);
838: size_t buflen = va_arg(ap, size_t);
839: struct group **result = va_arg(ap, struct group **);
840:
1.54 lukem 841: struct __grstate_dns state;
1.49 lukem 842: int rv;
843:
844: _DIAGASSERT(retval != NULL);
845: _DIAGASSERT(grp != NULL);
846: _DIAGASSERT(buffer != NULL);
847: _DIAGASSERT(result != NULL);
848:
849: *result = NULL;
850: memset(&state, 0, sizeof(state));
1.54 lukem 851: rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, NULL, gid);
852: __grend_dns(&state);
853: if (rv == NS_SUCCESS)
1.49 lukem 854: *result = grp;
1.54 lukem 855: return rv;
1.49 lukem 856: }
1.27 lukem 857:
1.49 lukem 858: /*ARGSUSED*/
1.27 lukem 859: static int
1.49 lukem 860: _dns_getgrnam(void *nsrv, void *nscb, va_list ap)
1.27 lukem 861: {
1.49 lukem 862: struct group **retval = va_arg(ap, struct group **);
863: const char *name = va_arg(ap, const char *);
864:
865: int rv, rerror;
1.27 lukem 866:
1.49 lukem 867: _DIAGASSERT(retval != NULL);
1.37 lukem 868:
1.49 lukem 869: *retval = NULL;
1.54 lukem 870: rv = __grstart_dns(&_dns_state);
1.49 lukem 871: if (rv != NS_SUCCESS)
872: return rv;
1.54 lukem 873: rv = __grscan_dns(&rerror, &_dns_group,
874: _dns_groupbuf, sizeof(_dns_groupbuf), &_dns_state, 1, name, 0);
1.49 lukem 875: if (!_dns_state.stayopen)
1.54 lukem 876: __grend_dns(&_dns_state);
877: if (rv == NS_SUCCESS)
1.49 lukem 878: *retval = &_dns_group;
879: return rv;
1.27 lukem 880: }
881:
1.29 christos 882: /*ARGSUSED*/
1.27 lukem 883: static int
1.49 lukem 884: _dns_getgrnam_r(void *nsrv, void *nscb, va_list ap)
1.27 lukem 885: {
1.49 lukem 886: int *retval = va_arg(ap, int *);
887: const char *name = va_arg(ap, const char *);
888: struct group *grp = va_arg(ap, struct group *);
889: char *buffer = va_arg(ap, char *);
890: size_t buflen = va_arg(ap, size_t);
891: struct group **result = va_arg(ap, struct group **);
892:
1.54 lukem 893: struct __grstate_dns state;
1.49 lukem 894: int rv;
895:
896: _DIAGASSERT(retval != NULL);
897: _DIAGASSERT(grp != NULL);
898: _DIAGASSERT(buffer != NULL);
899: _DIAGASSERT(result != NULL);
900:
901: *result = NULL;
902: memset(&state, 0, sizeof(state));
1.54 lukem 903: rv = __grscan_dns(retval, grp, buffer, buflen, &state, 1, name, 0);
904: __grend_dns(&state);
905: if (rv == NS_SUCCESS)
1.49 lukem 906: *result = grp;
1.54 lukem 907: return rv;
1.49 lukem 908: }
909:
910: #endif /* HESIOD */
911:
912:
913: #ifdef YP
914: /*
915: * nis methods
916: */
917:
1.54 lukem 918: int
919: __grstart_nis(struct __grstate_nis *state)
1.49 lukem 920: {
921:
922: _DIAGASSERT(state != NULL);
923:
924: state->done = 0;
925: if (state->current) {
926: free(state->current);
927: state->current = NULL;
928: }
929: if (state->domain == NULL) { /* setup NIS */
930: switch (yp_get_default_domain(&state->domain)) {
931: case 0:
932: break;
933: case YPERR_RESRC:
934: return NS_TRYAGAIN;
935: default:
936: return NS_UNAVAIL;
937: }
938: }
939: return NS_SUCCESS;
940: }
941:
1.54 lukem 942: int
943: __grend_nis(struct __grstate_nis *state)
1.49 lukem 944: {
945:
946: _DIAGASSERT(state != NULL);
947:
948: if (state->domain) {
949: state->domain = NULL;
950: }
951: state->done = 0;
952: if (state->current) {
953: free(state->current);
954: state->current = NULL;
955: }
956: return NS_SUCCESS;
957: }
958:
959: /*
1.54 lukem 960: * __grscan_nis
961: * Search NIS for the next desired entry.
962: * If search is zero, return the next entry.
963: * If search is non-zero, look for a specific name (if name != NULL),
964: * or a specific gid (if name == NULL).
1.49 lukem 965: */
1.54 lukem 966: int
967: __grscan_nis(int *retval, struct group *grp, char *buffer, size_t buflen,
968: struct __grstate_nis *state, int search, const char *name, gid_t gid)
1.49 lukem 969: {
1.54 lukem 970: const char *map;
971: char *key, *data;
972: int nisr, rv, keylen, datalen;
1.49 lukem 973:
974: _DIAGASSERT(retval != NULL);
975: _DIAGASSERT(grp != NULL);
976: _DIAGASSERT(buffer != NULL);
977: _DIAGASSERT(state != NULL);
1.54 lukem 978: /* name is NULL to indicate searching for gid */
1.49 lukem 979:
980: *retval = 0;
981:
982: if (state->domain == NULL) { /* only start if NIS not setup */
1.54 lukem 983: rv = __grstart_nis(state);
1.49 lukem 984: if (rv != NS_SUCCESS)
985: return rv;
986: }
987:
1.54.2.4! tron 988: next_nis_entry:
1.54 lukem 989: key = NULL;
1.49 lukem 990: data = NULL;
1.54 lukem 991: rv = NS_SUCCESS;
1.49 lukem 992:
1.54 lukem 993: if (! search) { /* find next entry */
994: if (state->done) /* exhausted search */
995: return NS_NOTFOUND;
996: map = "group.byname";
997: if (state->current) { /* already searching */
998: nisr = yp_next(state->domain, map,
999: state->current, state->currentlen,
1000: &key, &keylen, &data, &datalen);
1001: free(state->current);
1002: state->current = NULL;
1003: switch (nisr) {
1004: case 0:
1005: state->current = key;
1006: state->currentlen = keylen;
1007: key = NULL;
1008: break;
1009: case YPERR_NOMORE:
1010: rv = NS_NOTFOUND;
1011: state->done = 1;
1012: break;
1013: default:
1014: rv = NS_UNAVAIL;
1015: break;
1016: }
1017: } else { /* new search */
1018: if (yp_first(state->domain, map,
1019: &state->current, &state->currentlen,
1020: &data, &datalen)) {
1021: rv = NS_UNAVAIL;
1022: }
1023: }
1024: } else { /* search for specific item */
1025: if (name) { /* find group name */
1026: snprintf(buffer, buflen, "%s", name);
1027: map = "group.byname";
1028: } else { /* find gid */
1029: snprintf(buffer, buflen, "%u", (unsigned int)gid);
1030: map = "group.bygid";
1031: }
1032: nisr = yp_match(state->domain, map, buffer, (int)strlen(buffer),
1033: &data, &datalen);
1034: switch (nisr) {
1035: case 0:
1036: break;
1037: case YPERR_KEY:
1038: rv = NS_NOTFOUND;
1039: break;
1040: default:
1041: rv = NS_UNAVAIL;
1042: break;
1043: }
1044: }
1045: if (rv == NS_SUCCESS) { /* validate data */
1.49 lukem 1046: data[datalen] = '\0'; /* clear trailing \n */
1.54 lukem 1047: if (_gr_parse(data, grp, buffer, buflen)) {
1048: if (! search) { /* just want this one */
1049: rv = NS_SUCCESS;
1050: } else if ((name && strcmp(name, grp->gr_name) == 0) ||
1051: (!name && gid == grp->gr_gid)) {
1052: /* want specific */
1053: rv = NS_SUCCESS;
1054: }
1.54.2.4! tron 1055: } else { /* dodgy entry */
! 1056: if (!search) { /* try again if ! searching */
! 1057: if (key)
! 1058: free(key);
! 1059: free(data);
! 1060: goto next_nis_entry;
! 1061: }
! 1062: }
1.49 lukem 1063: }
1064:
1.54.2.3 tron 1065: if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1.49 lukem 1066: *retval = errno;
1.54 lukem 1067: if (key)
1068: free(key);
1.49 lukem 1069: if (data)
1070: free(data);
1071: return rv;
1072: }
1073:
1.54 lukem 1074: static struct __grstate_nis _nis_state;
1075: /* storage for non _r functions */
1076: static struct group _nis_group;
1077: static char _nis_groupbuf[_GETGR_R_SIZE_MAX];
1078:
1.49 lukem 1079: /*ARGSUSED*/
1080: static int
1081: _nis_setgrent(void *nsrv, void *nscb, va_list ap)
1082: {
1083:
1084: _nis_state.stayopen = 0;
1.54 lukem 1085: return __grstart_nis(&_nis_state);
1.49 lukem 1086: }
1087:
1088: /*ARGSUSED*/
1089: static int
1090: _nis_setgroupent(void *nsrv, void *nscb, va_list ap)
1091: {
1092: int *retval = va_arg(ap, int *);
1093: int stayopen = va_arg(ap, int);
1094:
1095: int rv;
1096:
1097: _nis_state.stayopen = stayopen;
1.54 lukem 1098: rv = __grstart_nis(&_nis_state);
1.49 lukem 1099: *retval = (rv == NS_SUCCESS);
1100: return rv;
1101: }
1102:
1103: /*ARGSUSED*/
1104: static int
1105: _nis_endgrent(void *nsrv, void *nscb, va_list ap)
1106: {
1107:
1.54 lukem 1108: return __grend_nis(&_nis_state);
1.49 lukem 1109: }
1110:
1111: /*ARGSUSED*/
1112: static int
1113: _nis_getgrent(void *nsrv, void *nscb, va_list ap)
1114: {
1115: struct group **retval = va_arg(ap, struct group **);
1116:
1.54 lukem 1117: int rv, rerror;
1.49 lukem 1118:
1119: _DIAGASSERT(retval != NULL);
1120:
1121: *retval = NULL;
1.54 lukem 1122: rv = __grscan_nis(&rerror, &_nis_group,
1123: _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 0, NULL, 0);
1.49 lukem 1124: if (rv == NS_SUCCESS)
1125: *retval = &_nis_group;
1126: return rv;
1127: }
1128:
1129: /*ARGSUSED*/
1130: static int
1.54.2.2 tron 1131: _nis_getgrent_r(void *nsrv, void *nscb, va_list ap)
1132: {
1133: int *retval = va_arg(ap, int *);
1134: struct group *grp = va_arg(ap, struct group *);
1135: char *buffer = va_arg(ap, char *);
1136: size_t buflen = va_arg(ap, size_t);
1137: struct group **result = va_arg(ap, struct group **);
1138:
1139: int rv;
1140:
1141: _DIAGASSERT(retval != NULL);
1142: _DIAGASSERT(grp != NULL);
1143: _DIAGASSERT(buffer != NULL);
1144: _DIAGASSERT(result != NULL);
1145:
1146: rv = __grscan_nis(retval, grp, buffer, buflen,
1147: &_nis_state, 0, NULL, 0);
1148: if (rv == NS_SUCCESS)
1149: *result = grp;
1150: else
1151: *result = NULL;
1152: return rv;
1153: }
1154:
1155: /*ARGSUSED*/
1156: static int
1.49 lukem 1157: _nis_getgrgid(void *nsrv, void *nscb, va_list ap)
1158: {
1159: struct group **retval = va_arg(ap, struct group **);
1160: gid_t gid = va_arg(ap, gid_t);
1161:
1162: int rv, rerror;
1163:
1164: _DIAGASSERT(retval != NULL);
1165:
1166: *retval = NULL;
1.54 lukem 1167: rv = __grstart_nis(&_nis_state);
1.49 lukem 1168: if (rv != NS_SUCCESS)
1169: return rv;
1.54 lukem 1170: rv = __grscan_nis(&rerror, &_nis_group,
1171: _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, NULL, gid);
1.49 lukem 1172: if (!_nis_state.stayopen)
1.54 lukem 1173: __grend_nis(&_nis_state);
1174: if (rv == NS_SUCCESS)
1.49 lukem 1175: *retval = &_nis_group;
1176: return rv;
1177: }
1178:
1179: /*ARGSUSED*/
1180: static int
1181: _nis_getgrgid_r(void *nsrv, void *nscb, va_list ap)
1182: {
1183: int *retval = va_arg(ap, int *);
1184: gid_t gid = va_arg(ap, gid_t);
1185: struct group *grp = va_arg(ap, struct group *);
1186: char *buffer = va_arg(ap, char *);
1187: size_t buflen = va_arg(ap, size_t);
1188: struct group **result = va_arg(ap, struct group **);
1189:
1.54 lukem 1190: struct __grstate_nis state;
1.49 lukem 1191: int rv;
1192:
1193: _DIAGASSERT(retval != NULL);
1194: _DIAGASSERT(grp != NULL);
1195: _DIAGASSERT(buffer != NULL);
1196: _DIAGASSERT(result != NULL);
1197:
1198: *result = NULL;
1199: memset(&state, 0, sizeof(state));
1.54 lukem 1200: rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, NULL, gid);
1201: __grend_nis(&state);
1202: if (rv == NS_SUCCESS)
1.49 lukem 1203: *result = grp;
1.54 lukem 1204: return rv;
1.49 lukem 1205: }
1206:
1207: /*ARGSUSED*/
1208: static int
1209: _nis_getgrnam(void *nsrv, void *nscb, va_list ap)
1210: {
1211: struct group **retval = va_arg(ap, struct group **);
1212: const char *name = va_arg(ap, const char *);
1213:
1214: int rv, rerror;
1215:
1216: _DIAGASSERT(retval != NULL);
1217:
1218: *retval = NULL;
1.54 lukem 1219: rv = __grstart_nis(&_nis_state);
1.49 lukem 1220: if (rv != NS_SUCCESS)
1221: return rv;
1.54 lukem 1222: rv = __grscan_nis(&rerror, &_nis_group,
1223: _nis_groupbuf, sizeof(_nis_groupbuf), &_nis_state, 1, name, 0);
1.49 lukem 1224: if (!_nis_state.stayopen)
1.54 lukem 1225: __grend_nis(&_nis_state);
1226: if (rv == NS_SUCCESS)
1.49 lukem 1227: *retval = &_nis_group;
1228: return rv;
1229: }
1230:
1231: /*ARGSUSED*/
1232: static int
1233: _nis_getgrnam_r(void *nsrv, void *nscb, va_list ap)
1234: {
1235: int *retval = va_arg(ap, int *);
1236: const char *name = va_arg(ap, const char *);
1237: struct group *grp = va_arg(ap, struct group *);
1238: char *buffer = va_arg(ap, char *);
1239: size_t buflen = va_arg(ap, size_t);
1240: struct group **result = va_arg(ap, struct group **);
1241:
1.54 lukem 1242: struct __grstate_nis state;
1.49 lukem 1243: int rv;
1244:
1245: _DIAGASSERT(retval != NULL);
1246: _DIAGASSERT(grp != NULL);
1247: _DIAGASSERT(buffer != NULL);
1248: _DIAGASSERT(result != NULL);
1249:
1250: *result = NULL;
1251: memset(&state, 0, sizeof(state));
1.54 lukem 1252: rv = __grscan_nis(retval, grp, buffer, buflen, &state, 1, name, 0);
1253: __grend_nis(&state);
1254: if (rv == NS_SUCCESS)
1.49 lukem 1255: *result = grp;
1.54 lukem 1256: return rv;
1.49 lukem 1257: }
1258:
1259: #endif /* YP */
1260:
1.27 lukem 1261:
1.34 lukem 1262: #ifdef _GROUP_COMPAT
1.49 lukem 1263: /*
1264: * compat methods
1265: */
1266:
1.54 lukem 1267: int
1268: __grstart_compat(struct __grstate_compat *state)
1.49 lukem 1269: {
1270:
1271: _DIAGASSERT(state != NULL);
1272:
1273: if (state->fp == NULL) {
1274: state->fp = fopen(_PATH_GROUP, "r");
1275: if (state->fp == NULL)
1276: return NS_UNAVAIL;
1277: } else {
1278: rewind(state->fp);
1279: }
1280: return NS_SUCCESS;
1281: }
1282:
1.54 lukem 1283: int
1284: __grend_compat(struct __grstate_compat *state)
1.49 lukem 1285: {
1286:
1287: _DIAGASSERT(state != NULL);
1288:
1289: if (state->name) {
1290: free(state->name);
1291: state->name = NULL;
1292: }
1293: if (state->fp) {
1294: (void) fclose(state->fp);
1295: state->fp = NULL;
1296: }
1297: return NS_SUCCESS;
1298: }
1299:
1300:
1301: /*
1.54 lukem 1302: * __grbad_compat
1.49 lukem 1303: * log an error if "files" or "compat" is specified in
1304: * group_compat database
1305: */
1306: /*ARGSUSED*/
1.54 lukem 1307: int
1308: __grbad_compat(void *nsrv, void *nscb, va_list ap)
1.49 lukem 1309: {
1310: static int warned;
1311:
1312: _DIAGASSERT(cb_data != NULL);
1313:
1314: if (!warned) {
1315: syslog(LOG_ERR,
1316: "nsswitch.conf group_compat database can't use '%s'",
1.54 lukem 1317: (const char *)nscb);
1.49 lukem 1318: }
1319: warned = 1;
1320: return NS_UNAVAIL;
1321: }
1322:
1323: /*
1.54 lukem 1324: * __grscan_compat
1.49 lukem 1325: * Scan state->fp for the next desired entry.
1326: * If search is zero, return the next entry.
1327: * If search is non-zero, look for a specific name (if name != NULL),
1328: * or a specific gid (if name == NULL).
1.54.2.3 tron 1329: * Sets *retval to the errno if the result is not NS_SUCCESS or
1330: * NS_NOTFOUND.
1.54 lukem 1331: *
1332: * searchfunc is invoked when a compat "+" lookup is required;
1333: * searchcookie is passed as the first argument to searchfunc,
1334: * the second argument is the group result.
1335: * This should return NS_NOTFOUND when "no more groups" from compat src.
1336: * If searchfunc is NULL then nsdispatch of getgrent is used.
1337: * This is primarily intended for getgroupmembership(3)'s compat backend.
1.49 lukem 1338: */
1.54 lukem 1339: int
1340: __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen,
1341: struct __grstate_compat *state, int search, const char *name, gid_t gid,
1342: int (*searchfunc)(void *, struct group **), void *searchcookie)
1.49 lukem 1343: {
1344: int rv;
1.52 lukem 1345: char filebuf[_GETGR_R_SIZE_MAX], *ep;
1.49 lukem 1346:
1347: static const ns_dtab compatentdtab[] = {
1.54 lukem 1348: NS_FILES_CB(__grbad_compat, "files")
1.54.2.2 tron 1349: NS_DNS_CB(_dns_getgrent_r, NULL)
1350: NS_NIS_CB(_nis_getgrent_r, NULL)
1.54 lukem 1351: NS_COMPAT_CB(__grbad_compat, "compat")
1.49 lukem 1352: { 0 }
1353: };
1354: static const ns_dtab compatgiddtab[] = {
1.54 lukem 1355: NS_FILES_CB(__grbad_compat, "files")
1.49 lukem 1356: NS_DNS_CB(_dns_getgrgid_r, NULL)
1357: NS_NIS_CB(_nis_getgrgid_r, NULL)
1.54 lukem 1358: NS_COMPAT_CB(__grbad_compat, "compat")
1.49 lukem 1359: { 0 }
1360: };
1361: static const ns_dtab compatnamdtab[] = {
1.54 lukem 1362: NS_FILES_CB(__grbad_compat, "files")
1.49 lukem 1363: NS_DNS_CB(_dns_getgrnam_r, NULL)
1364: NS_NIS_CB(_nis_getgrnam_r, NULL)
1.54 lukem 1365: NS_COMPAT_CB(__grbad_compat, "compat")
1.49 lukem 1366: { 0 }
1367: };
1.27 lukem 1368:
1.49 lukem 1369: _DIAGASSERT(retval != NULL);
1370: _DIAGASSERT(grp != NULL);
1371: _DIAGASSERT(buffer != NULL);
1372: _DIAGASSERT(state != NULL);
1373: /* name is NULL to indicate searching for gid */
1374:
1375: *retval = 0;
1376:
1377: if (state->fp == NULL) { /* only start if file not open yet */
1.54 lukem 1378: rv = __grstart_compat(state);
1.49 lukem 1379: if (rv != NS_SUCCESS)
1380: goto compatgrscan_out;
1381: }
1382: rv = NS_NOTFOUND;
1.27 lukem 1383:
1.49 lukem 1384: for (;;) { /* loop through file */
1385: if (state->name != NULL) {
1386: /* processing compat entry */
1387: int crv, cretval;
1388: struct group cgrp, *cgrpres;
1389:
1390: if (state->name[0]) { /* specific +group: */
1391: crv = nsdispatch(NULL, compatnamdtab,
1.53 lukem 1392: NSDB_GROUP_COMPAT, "getgrnam_r",
1393: __nsdefaultnis,
1.49 lukem 1394: &cretval, state->name,
1395: &cgrp, filebuf, sizeof(filebuf), &cgrpres);
1396: free(state->name); /* (only check 1 grp) */
1397: state->name = NULL;
1398: } else if (!search) { /* any group */
1.54 lukem 1399: if (searchfunc) {
1400: crv = searchfunc(searchcookie,
1401: &cgrpres);
1402: } else {
1403: crv = nsdispatch(NULL, compatentdtab,
1.54.2.2 tron 1404: NSDB_GROUP_COMPAT, "getgrent_r",
1.54 lukem 1405: __nsdefaultnis,
1.54.2.2 tron 1406: &cretval, &cgrp, filebuf,
1407: sizeof(filebuf), &cgrpres);
1.54 lukem 1408: }
1.49 lukem 1409: } else if (name) { /* specific group */
1410: crv = nsdispatch(NULL, compatnamdtab,
1.53 lukem 1411: NSDB_GROUP_COMPAT, "getgrnam_r",
1412: __nsdefaultnis,
1.49 lukem 1413: &cretval, name,
1414: &cgrp, filebuf, sizeof(filebuf), &cgrpres);
1415: } else { /* specific gid */
1416: crv = nsdispatch(NULL, compatgiddtab,
1.53 lukem 1417: NSDB_GROUP_COMPAT, "getgrgid_r",
1418: __nsdefaultnis,
1.49 lukem 1419: &cretval, gid,
1420: &cgrp, filebuf, sizeof(filebuf), &cgrpres);
1421: }
1422: if (crv != NS_SUCCESS) { /* not found */
1423: free(state->name);
1424: state->name = NULL;
1425: continue; /* try next line */
1426: }
1427: if (!_gr_copy(cgrpres, grp, buffer, buflen)) {
1428: rv = NS_UNAVAIL;
1.20 christos 1429: break;
1.2 deraadt 1430: }
1.49 lukem 1431: goto compatgrscan_cmpgrp; /* skip to grp test */
1.2 deraadt 1432: }
1.27 lukem 1433:
1.49 lukem 1434: /* get next file line */
1435: if (fgets(filebuf, sizeof(filebuf), state->fp) == NULL)
1436: break;
1437:
1438: ep = strchr(filebuf, '\n');
1.54.2.4! tron 1439: if (ep == NULL) { /* skip lines that are too big */
1.1 cgd 1440: int ch;
1441:
1.49 lukem 1442: while ((ch = getc(state->fp)) != '\n' && ch != EOF)
1443: continue;
1.54.2.4! tron 1444: continue;
1.1 cgd 1445: }
1.49 lukem 1446: *ep = '\0'; /* clear trailing \n */
1.27 lukem 1447:
1.49 lukem 1448: if (filebuf[0] == '+') { /* parse compat line */
1449: if (state->name)
1450: free(state->name);
1451: state->name = NULL;
1452: switch(filebuf[1]) {
1.13 phil 1453: case ':':
1454: case '\0':
1.49 lukem 1455: state->name = strdup("");
1.13 phil 1456: break;
1457: default:
1.49 lukem 1458: ep = strchr(filebuf + 1, ':');
1459: if (ep == NULL)
1460: break;
1461: *ep = '\0';
1462: state->name = strdup(filebuf + 1);
1463: break;
1464: }
1465: if (state->name == NULL) {
1466: rv = NS_UNAVAIL;
1.13 phil 1467: break;
1.2 deraadt 1468: }
1.9 deraadt 1469: continue;
1.1 cgd 1470: }
1.49 lukem 1471:
1472: /* validate line */
1473: if (! _gr_parse(filebuf, grp, buffer, buflen)) {
1.54.2.4! tron 1474: continue; /* skip bad lines */
1.49 lukem 1475: }
1476:
1477: compatgrscan_cmpgrp:
1478: if (! search) { /* just want this one */
1479: rv = NS_SUCCESS;
1480: break;
1481: }
1482: /* want specific */
1483: if ((name && strcmp(name, grp->gr_name) == 0) ||
1484: (!name && gid == grp->gr_gid)) {
1485: rv = NS_SUCCESS;
1486: break;
1487: }
1488:
1.1 cgd 1489: }
1.49 lukem 1490:
1491: compatgrscan_out:
1.54.2.3 tron 1492: if (rv != NS_SUCCESS && rv != NS_NOTFOUND)
1.49 lukem 1493: *retval = errno;
1494: return rv;
1.27 lukem 1495: }
1496:
1.54 lukem 1497: static struct __grstate_compat _compat_state;
1498: /* storage for non _r functions */
1499: static struct group _compat_group;
1500: static char _compat_groupbuf[_GETGR_R_SIZE_MAX];
1501:
1.49 lukem 1502: /*ARGSUSED*/
1.27 lukem 1503: static int
1.49 lukem 1504: _compat_setgrent(void *nsrv, void *nscb, va_list ap)
1.27 lukem 1505: {
1.31 lukem 1506: static const ns_dtab dtab[] = {
1.54 lukem 1507: NS_FILES_CB(__grbad_compat, "files")
1.49 lukem 1508: NS_DNS_CB(_dns_setgrent, NULL)
1509: NS_NIS_CB(_nis_setgrent, NULL)
1.54 lukem 1510: NS_COMPAT_CB(__grbad_compat, "compat")
1.27 lukem 1511: { 0 }
1512: };
1.49 lukem 1513:
1514: /* force group_compat setgrent() */
1515: (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgrent",
1.53 lukem 1516: __nsdefaultnis_forceall);
1.49 lukem 1517:
1518: /* reset state, keep fp open */
1519: _compat_state.stayopen = 0;
1.54 lukem 1520: return __grstart_compat(&_compat_state);
1.49 lukem 1521: }
1522:
1523: /*ARGSUSED*/
1524: static int
1525: _compat_setgroupent(void *nsrv, void *nscb, va_list ap)
1526: {
1527: int *retval = va_arg(ap, int *);
1528: int stayopen = va_arg(ap, int);
1529:
1530: int rv;
1531:
1532: static const ns_dtab dtab[] = {
1.54 lukem 1533: NS_FILES_CB(__grbad_compat, "files")
1.49 lukem 1534: NS_DNS_CB(_dns_setgroupent, NULL)
1535: NS_NIS_CB(_nis_setgroupent, NULL)
1.54 lukem 1536: NS_COMPAT_CB(__grbad_compat, "compat")
1.32 lukem 1537: { 0 }
1538: };
1.27 lukem 1539:
1.49 lukem 1540: /* force group_compat setgroupent() */
1541: (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgroupent",
1.53 lukem 1542: __nsdefaultnis_forceall, &rv, stayopen);
1.49 lukem 1543:
1544: _compat_state.stayopen = stayopen;
1.54 lukem 1545: rv = __grstart_compat(&_compat_state);
1.49 lukem 1546: *retval = (rv == NS_SUCCESS);
1547: return rv;
1548: }
1.37 lukem 1549:
1.49 lukem 1550: /*ARGSUSED*/
1551: static int
1552: _compat_endgrent(void *nsrv, void *nscb, va_list ap)
1553: {
1554: static const ns_dtab dtab[] = {
1.54 lukem 1555: NS_FILES_CB(__grbad_compat, "files")
1.49 lukem 1556: NS_DNS_CB(_dns_endgrent, NULL)
1557: NS_NIS_CB(_nis_endgrent, NULL)
1.54 lukem 1558: NS_COMPAT_CB(__grbad_compat, "compat")
1.49 lukem 1559: { 0 }
1560: };
1561:
1562: /* force group_compat endgrent() */
1563: (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "endgrent",
1.53 lukem 1564: __nsdefaultnis_forceall);
1.49 lukem 1565:
1566: /* reset state, close fp */
1567: _compat_state.stayopen = 0;
1.54 lukem 1568: return __grend_compat(&_compat_state);
1.27 lukem 1569: }
1570:
1.49 lukem 1571: /*ARGSUSED*/
1572: static int
1573: _compat_getgrent(void *nsrv, void *nscb, va_list ap)
1574: {
1575: struct group **retval = va_arg(ap, struct group **);
1576:
1577: int rv, rerror;
1578:
1579: _DIAGASSERT(retval != NULL);
1580:
1581: *retval = NULL;
1.54 lukem 1582: rv = __grscan_compat(&rerror, &_compat_group,
1.49 lukem 1583: _compat_groupbuf, sizeof(_compat_groupbuf),
1.54 lukem 1584: &_compat_state, 0, NULL, 0, NULL, NULL);
1.49 lukem 1585: if (rv == NS_SUCCESS)
1586: *retval = &_compat_group;
1587: return rv;
1588: }
1589:
1590: /*ARGSUSED*/
1.27 lukem 1591: static int
1.54.2.2 tron 1592: _compat_getgrent_r(void *nsrv, void *nscb, va_list ap)
1593: {
1594: int *retval = va_arg(ap, int *);
1595: struct group *grp = va_arg(ap, struct group *);
1596: char *buffer = va_arg(ap, char *);
1597: size_t buflen = va_arg(ap, size_t);
1598: struct group **result = va_arg(ap, struct group **);
1599:
1600: int rv;
1601:
1602: _DIAGASSERT(retval != NULL);
1603: _DIAGASSERT(grp != NULL);
1604: _DIAGASSERT(buffer != NULL);
1605: _DIAGASSERT(result != NULL);
1606:
1607: rv = __grscan_compat(retval, grp, buffer, buflen,
1608: &_compat_state, 0, NULL, 0, NULL, NULL);
1609: if (rv == NS_SUCCESS)
1610: *result = grp;
1611: else
1612: *result = NULL;
1613: return rv;
1614: }
1615:
1616: /*ARGSUSED*/
1617: static int
1.49 lukem 1618: _compat_getgrgid(void *nsrv, void *nscb, va_list ap)
1619: {
1620: struct group **retval = va_arg(ap, struct group **);
1621: gid_t gid = va_arg(ap, gid_t);
1622:
1623: int rv, rerror;
1624:
1625: _DIAGASSERT(retval != NULL);
1626:
1627: *retval = NULL;
1.54 lukem 1628: rv = __grstart_compat(&_compat_state);
1.49 lukem 1629: if (rv != NS_SUCCESS)
1630: return rv;
1.54 lukem 1631: rv = __grscan_compat(&rerror, &_compat_group,
1.49 lukem 1632: _compat_groupbuf, sizeof(_compat_groupbuf),
1.54 lukem 1633: &_compat_state, 1, NULL, gid, NULL, NULL);
1.49 lukem 1634: if (!_compat_state.stayopen)
1.54 lukem 1635: __grend_compat(&_compat_state);
1.49 lukem 1636: if (rv == NS_SUCCESS)
1637: *retval = &_compat_group;
1638: return rv;
1639: }
1640:
1641: /*ARGSUSED*/
1642: static int
1643: _compat_getgrgid_r(void *nsrv, void *nscb, va_list ap)
1644: {
1645: int *retval = va_arg(ap, int *);
1646: gid_t gid = va_arg(ap, gid_t);
1647: struct group *grp = va_arg(ap, struct group *);
1648: char *buffer = va_arg(ap, char *);
1649: size_t buflen = va_arg(ap, size_t);
1650: struct group **result = va_arg(ap, struct group **);
1651:
1.54 lukem 1652: struct __grstate_compat state;
1.49 lukem 1653: int rv;
1654:
1655: _DIAGASSERT(retval != NULL);
1656: _DIAGASSERT(grp != NULL);
1657: _DIAGASSERT(buffer != NULL);
1658: _DIAGASSERT(result != NULL);
1659:
1660: *result = NULL;
1661: memset(&state, 0, sizeof(state));
1.54 lukem 1662: rv = __grscan_compat(retval, grp, buffer, buflen, &state,
1663: 1, NULL, gid, NULL, NULL);
1664: __grend_compat(&state);
1.49 lukem 1665: if (rv == NS_SUCCESS)
1666: *result = grp;
1667: return rv;
1668: }
1669:
1670: /*ARGSUSED*/
1671: static int
1672: _compat_getgrnam(void *nsrv, void *nscb, va_list ap)
1673: {
1674: struct group **retval = va_arg(ap, struct group **);
1675: const char *name = va_arg(ap, const char *);
1676:
1677: int rv, rerror;
1678:
1679: _DIAGASSERT(retval != NULL);
1680:
1681: *retval = NULL;
1.54 lukem 1682: rv = __grstart_compat(&_compat_state);
1.49 lukem 1683: if (rv != NS_SUCCESS)
1684: return rv;
1.54 lukem 1685: rv = __grscan_compat(&rerror, &_compat_group,
1.49 lukem 1686: _compat_groupbuf, sizeof(_compat_groupbuf),
1.54 lukem 1687: &_compat_state, 1, name, 0, NULL, NULL);
1.49 lukem 1688: if (!_compat_state.stayopen)
1.54 lukem 1689: __grend_compat(&_compat_state);
1.49 lukem 1690: if (rv == NS_SUCCESS)
1691: *retval = &_compat_group;
1692: return rv;
1693: }
1694:
1695: /*ARGSUSED*/
1696: static int
1697: _compat_getgrnam_r(void *nsrv, void *nscb, va_list ap)
1698: {
1699: int *retval = va_arg(ap, int *);
1700: const char *name = va_arg(ap, const char *);
1701: struct group *grp = va_arg(ap, struct group *);
1702: char *buffer = va_arg(ap, char *);
1703: size_t buflen = va_arg(ap, size_t);
1704: struct group **result = va_arg(ap, struct group **);
1705:
1.54 lukem 1706: struct __grstate_compat state;
1.49 lukem 1707: int rv;
1708:
1709: _DIAGASSERT(retval != NULL);
1710: _DIAGASSERT(grp != NULL);
1711: _DIAGASSERT(buffer != NULL);
1712: _DIAGASSERT(result != NULL);
1713:
1714: *result = NULL;
1715: memset(&state, 0, sizeof(state));
1.54 lukem 1716: rv = __grscan_compat(retval, grp, buffer, buflen, &state,
1717: 1, name, 0, NULL, NULL);
1718: __grend_compat(&state);
1.49 lukem 1719: if (rv == NS_SUCCESS)
1720: *result = grp;
1721: return rv;
1722: }
1723:
1724: #endif /* _GROUP_COMPAT */
1725:
1726:
1727: /*
1728: * public functions
1729: */
1730:
1731: struct group *
1732: getgrent(void)
1.27 lukem 1733: {
1.49 lukem 1734: int rv;
1735: struct group *retval;
1736:
1737: static const ns_dtab dtab[] = {
1738: NS_FILES_CB(_files_getgrent, NULL)
1739: NS_DNS_CB(_dns_getgrent, NULL)
1740: NS_NIS_CB(_nis_getgrent, NULL)
1741: NS_COMPAT_CB(_compat_getgrent, NULL)
1742: { 0 }
1743: };
1744:
1.54 lukem 1745: mutex_lock(&__grmutex);
1.53 lukem 1746: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent", __nsdefaultcompat,
1.49 lukem 1747: &retval);
1.54 lukem 1748: mutex_unlock(&__grmutex);
1.54.2.3 tron 1749: return (rv == NS_SUCCESS) ? retval : NULL;
1.49 lukem 1750: }
1751:
1.54.2.2 tron 1752: int
1753: getgrent_r(struct group *grp, char *buffer, size_t buflen,
1754: struct group **result)
1755: {
1756: int rv, retval;
1757:
1758: static const ns_dtab dtab[] = {
1759: NS_FILES_CB(_files_getgrent_r, NULL)
1760: NS_DNS_CB(_dns_getgrent_r, NULL)
1761: NS_NIS_CB(_nis_getgrent_r, NULL)
1762: NS_COMPAT_CB(_compat_getgrent_r, NULL)
1763: { 0 }
1764: };
1765:
1766: mutex_lock(&__grmutex);
1767: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrent_r", __nsdefaultcompat,
1768: &retval, grp, buffer, buflen, result);
1769: mutex_unlock(&__grmutex);
1.54.2.3 tron 1770: switch (rv) {
1771: case NS_SUCCESS:
1772: case NS_NOTFOUND:
1773: return 0;
1774: default:
1775: return retval;
1776: }
1.54.2.2 tron 1777: }
1778:
1779:
1.49 lukem 1780: struct group *
1781: getgrgid(gid_t gid)
1782: {
1783: int rv;
1784: struct group *retval;
1785:
1786: static const ns_dtab dtab[] = {
1787: NS_FILES_CB(_files_getgrgid, NULL)
1788: NS_DNS_CB(_dns_getgrgid, NULL)
1789: NS_NIS_CB(_nis_getgrgid, NULL)
1790: NS_COMPAT_CB(_compat_getgrgid, NULL)
1791: { 0 }
1792: };
1793:
1.54 lukem 1794: mutex_lock(&__grmutex);
1.53 lukem 1795: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid", __nsdefaultcompat,
1.49 lukem 1796: &retval, gid);
1.54 lukem 1797: mutex_unlock(&__grmutex);
1.49 lukem 1798: return (rv == NS_SUCCESS) ? retval : NULL;
1799: }
1800:
1801: int
1802: getgrgid_r(gid_t gid, struct group *grp, char *buffer, size_t buflen,
1803: struct group **result)
1804: {
1805: int rv, retval;
1806:
1807: static const ns_dtab dtab[] = {
1808: NS_FILES_CB(_files_getgrgid_r, NULL)
1809: NS_DNS_CB(_dns_getgrgid_r, NULL)
1810: NS_NIS_CB(_nis_getgrgid_r, NULL)
1811: NS_COMPAT_CB(_compat_getgrgid_r, NULL)
1812: { 0 }
1813: };
1814:
1815: _DIAGASSERT(grp != NULL);
1816: _DIAGASSERT(buffer != NULL);
1817: _DIAGASSERT(result != NULL);
1818:
1819: *result = NULL;
1820: retval = 0;
1.54 lukem 1821: mutex_lock(&__grmutex);
1.53 lukem 1822: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrgid_r", __nsdefaultcompat,
1.49 lukem 1823: &retval, gid, grp, buffer, buflen, result);
1.54 lukem 1824: mutex_unlock(&__grmutex);
1.54.2.3 tron 1825: switch (rv) {
1826: case NS_SUCCESS:
1827: case NS_NOTFOUND:
1828: return 0;
1829: default:
1830: return retval;
1831: }
1.49 lukem 1832: }
1833:
1834: struct group *
1835: getgrnam(const char *name)
1836: {
1837: int rv;
1838: struct group *retval;
1839:
1840: static const ns_dtab dtab[] = {
1841: NS_FILES_CB(_files_getgrnam, NULL)
1842: NS_DNS_CB(_dns_getgrnam, NULL)
1843: NS_NIS_CB(_nis_getgrnam, NULL)
1844: NS_COMPAT_CB(_compat_getgrnam, NULL)
1845: { 0 }
1846: };
1847:
1.54 lukem 1848: mutex_lock(&__grmutex);
1.53 lukem 1849: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam", __nsdefaultcompat,
1.49 lukem 1850: &retval, name);
1.54 lukem 1851: mutex_unlock(&__grmutex);
1.49 lukem 1852: return (rv == NS_SUCCESS) ? retval : NULL;
1853: }
1854:
1855: int
1856: getgrnam_r(const char *name, struct group *grp, char *buffer, size_t buflen,
1857: struct group **result)
1858: {
1859: int rv, retval;
1860:
1861: static const ns_dtab dtab[] = {
1862: NS_FILES_CB(_files_getgrnam_r, NULL)
1863: NS_DNS_CB(_dns_getgrnam_r, NULL)
1864: NS_NIS_CB(_nis_getgrnam_r, NULL)
1865: NS_COMPAT_CB(_compat_getgrnam_r, NULL)
1866: { 0 }
1867: };
1868:
1869: _DIAGASSERT(name != NULL);
1870: _DIAGASSERT(grp != NULL);
1871: _DIAGASSERT(buffer != NULL);
1872: _DIAGASSERT(result != NULL);
1873:
1874: *result = NULL;
1875: retval = 0;
1.54 lukem 1876: mutex_lock(&__grmutex);
1.53 lukem 1877: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam_r", __nsdefaultcompat,
1.49 lukem 1878: &retval, name, grp, buffer, buflen, result);
1.54 lukem 1879: mutex_unlock(&__grmutex);
1.54.2.3 tron 1880: switch (rv) {
1881: case NS_SUCCESS:
1882: case NS_NOTFOUND:
1883: return 0;
1884: default:
1885: return retval;
1886: }
1.49 lukem 1887: }
1888:
1889: void
1890: endgrent(void)
1891: {
1892: static const ns_dtab dtab[] = {
1893: NS_FILES_CB(_files_endgrent, NULL)
1894: NS_DNS_CB(_dns_endgrent, NULL)
1895: NS_NIS_CB(_nis_endgrent, NULL)
1896: NS_COMPAT_CB(_compat_endgrent, NULL)
1897: { 0 }
1898: };
1899:
1.54 lukem 1900: mutex_lock(&__grmutex);
1.49 lukem 1901: /* force all endgrent() methods */
1902: (void) nsdispatch(NULL, dtab, NSDB_GROUP, "endgrent",
1.53 lukem 1903: __nsdefaultcompat_forceall);
1.54 lukem 1904: mutex_unlock(&__grmutex);
1.49 lukem 1905: }
1906:
1907: int
1908: setgroupent(int stayopen)
1909: {
1910: static const ns_dtab dtab[] = {
1911: NS_FILES_CB(_files_setgroupent, NULL)
1912: NS_DNS_CB(_dns_setgroupent, NULL)
1913: NS_NIS_CB(_nis_setgroupent, NULL)
1914: NS_COMPAT_CB(_compat_setgroupent, NULL)
1915: { 0 }
1916: };
1917: int rv, retval;
1918:
1.54 lukem 1919: mutex_lock(&__grmutex);
1.49 lukem 1920: /* force all setgroupent() methods */
1921: rv = nsdispatch(NULL, dtab, NSDB_GROUP, "setgroupent",
1.53 lukem 1922: __nsdefaultcompat_forceall, &retval, stayopen);
1.54 lukem 1923: mutex_unlock(&__grmutex);
1.49 lukem 1924: return (rv == NS_SUCCESS) ? retval : 0;
1925: }
1.37 lukem 1926:
1.49 lukem 1927: void
1928: setgrent(void)
1929: {
1930: static const ns_dtab dtab[] = {
1931: NS_FILES_CB(_files_setgrent, NULL)
1932: NS_DNS_CB(_dns_setgrent, NULL)
1933: NS_NIS_CB(_nis_setgrent, NULL)
1934: NS_COMPAT_CB(_compat_setgrent, NULL)
1935: { 0 }
1936: };
1.27 lukem 1937:
1.54 lukem 1938: mutex_lock(&__grmutex);
1.49 lukem 1939: /* force all setgrent() methods */
1940: (void) nsdispatch(NULL, dtab, NSDB_GROUP, "setgrent",
1.53 lukem 1941: __nsdefaultcompat_forceall);
1.54 lukem 1942: mutex_unlock(&__grmutex);
1.1 cgd 1943: }
CVSweb <webmaster@jp.NetBSD.org>