getnetgrent.c revision 1.39 1 /* $NetBSD: getnetgrent.c,v 1.39 2007/02/07 19:12:44 oster Exp $ */
2
3 /*
4 * Copyright (c) 1994 Christos Zoulas
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Christos Zoulas.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 #if defined(LIBC_SCCS) && !defined(lint)
36 __RCSID("$NetBSD: getnetgrent.c,v 1.39 2007/02/07 19:12:44 oster Exp $");
37 #endif /* LIBC_SCCS and not lint */
38
39 #include "namespace.h"
40 #include <sys/types.h>
41
42 #include <assert.h>
43 #include <ctype.h>
44 #include <db.h>
45 #include <err.h>
46 #include <fcntl.h>
47 #define _NETGROUP_PRIVATE
48 #include <stringlist.h>
49 #include <netgroup.h>
50 #include <nsswitch.h>
51 #include <stdarg.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55
56 #ifdef YP
57 #include <rpc/rpc.h>
58 #include <rpcsvc/ypclnt.h>
59 #include <rpcsvc/yp_prot.h>
60 #endif
61
62 #ifdef __weak_alias
63 __weak_alias(endnetgrent,_endnetgrent)
64 __weak_alias(getnetgrent,_getnetgrent)
65 __weak_alias(innetgr,_innetgr)
66 __weak_alias(setnetgrent,_setnetgrent)
67 #endif
68
69 #define _NG_STAR(s) (((s) == NULL || *(s) == '\0') ? _ngstar : s)
70 #define _NG_EMPTY(s) ((s) == NULL ? "" : s)
71 #define _NG_ISSPACE(p) (isspace((unsigned char) (p)) || (p) == '\n')
72
73 static const char _ngstar[] = "*";
74 static struct netgroup *_nghead = NULL;
75 static struct netgroup *_nglist = NULL;
76 static DB *_ng_db;
77
78 static int getstring(char **, int, __aconst char **);
79 static struct netgroup *getnetgroup(char **);
80 static int lookup(char *, char **, int);
81 static int addgroup(StringList *, char *);
82 static int in_check(const char *, const char *, const char *,
83 struct netgroup *);
84 static int in_find(StringList *, char *, const char *, const char *,
85 const char *);
86 static char *in_lookup1(const char *, const char *, int);
87 static int in_lookup(const char *, const char *, const char *, int);
88
89 #ifdef NSSRC_FILES
90 static const ns_src default_files_nis[] = {
91 { NSSRC_FILES, NS_SUCCESS | NS_NOTFOUND },
92 #ifdef YP
93 { NSSRC_NIS, NS_SUCCESS },
94 #endif
95 { 0, 0 },
96 };
97 #endif
98
99 /*
100 * getstring(): Get a string delimited by the character, skipping leading and
101 * trailing blanks and advancing the pointer
102 */
103 static int
104 getstring(char **pp, int del, char __aconst **str)
105 {
106 size_t len;
107 char *sp, *ep, *dp;
108
109 _DIAGASSERT(pp != NULL);
110 _DIAGASSERT(str != NULL);
111
112 /* skip leading blanks */
113 for (sp = *pp; *sp && _NG_ISSPACE(*sp); sp++)
114 continue;
115
116 /* accumulate till delimiter or space */
117 for (ep = sp; *ep && *ep != del && !_NG_ISSPACE(*ep); ep++)
118 continue;
119
120 /* hunt for the delimiter */
121 for (dp = ep; *dp && *dp != del && _NG_ISSPACE(*dp); dp++)
122 continue;
123
124 if (*dp != del) {
125 *str = NULL;
126 return 0;
127 }
128
129 *pp = ++dp;
130
131 len = (ep - sp) + 1;
132 if (len > 1) {
133 dp = malloc(len);
134 if (dp == NULL)
135 return 0;
136 (void)memcpy(dp, sp, len);
137 dp[len - 1] = '\0';
138 } else
139 dp = NULL;
140
141 *str = dp;
142 return 1;
143 }
144
145
146 /*
147 * getnetgroup(): Parse a netgroup, and advance the pointer
148 */
149 static struct netgroup *
150 getnetgroup(pp)
151 char **pp;
152 {
153 struct netgroup *ng;
154
155 _DIAGASSERT(pp != NULL);
156 _DIAGASSERT(*pp != NULL);
157
158 ng = malloc(sizeof(struct netgroup));
159 if (ng == NULL)
160 return NULL;
161
162 (*pp)++; /* skip '(' */
163 if (!getstring(pp, ',', &ng->ng_host))
164 goto badhost;
165
166 if (!getstring(pp, ',', &ng->ng_user))
167 goto baduser;
168
169 if (!getstring(pp, ')', &ng->ng_domain))
170 goto baddomain;
171
172 #ifdef DEBUG_NG
173 {
174 char buf[1024];
175 (void) fprintf(stderr, "netgroup %s\n",
176 _ng_print(buf, sizeof(buf), ng));
177 }
178 #endif
179 return ng;
180
181 baddomain:
182 if (ng->ng_user)
183 free(ng->ng_user);
184 baduser:
185 if (ng->ng_host)
186 free(ng->ng_host);
187 badhost:
188 free(ng);
189 return NULL;
190 }
191
192 void
193 _ng_cycle(const char *grp, const StringList *sl)
194 {
195 size_t i;
196 warnx("netgroup: Cycle in group `%s'", grp);
197 (void)fprintf(stderr, "groups: ");
198 for (i = 0; i < sl->sl_cur; i++)
199 (void)fprintf(stderr, "%s ", sl->sl_str[i]);
200 (void)fprintf(stderr, "\n");
201 }
202
203 static int _local_lookup(void *, void *, va_list);
204
205 /*ARGSUSED*/
206 static int
207 _local_lookup(void *rv, void *cb_data, va_list ap)
208 {
209 char *name = va_arg(ap, char *);
210 char **line = va_arg(ap, char **);
211 int bywhat = va_arg(ap, int);
212
213 DBT key, data;
214 size_t len;
215 char *ks;
216 int r;
217
218 if (_ng_db == NULL)
219 return NS_UNAVAIL;
220
221 len = strlen(name) + 2;
222 ks = malloc(len);
223 if (ks == NULL)
224 return NS_UNAVAIL;
225
226 ks[0] = bywhat;
227 (void)memcpy(&ks[1], name, len - 1);
228
229 key.data = (u_char *)ks;
230 key.size = len;
231
232 r = (*_ng_db->get)(_ng_db, &key, &data, 0);
233 free(ks);
234 switch (r) {
235 case 0:
236 break;
237 case 1:
238 return NS_NOTFOUND;
239 case -1:
240 /* XXX: call endnetgrent() here ? */
241 return NS_UNAVAIL;
242 }
243
244 *line = strdup(data.data);
245 if (*line == NULL)
246 return NS_UNAVAIL;
247 return NS_SUCCESS;
248 }
249
250 #ifdef YP
251 static int _nis_lookup(void *, void *, va_list);
252
253 /*ARGSUSED*/
254 static int
255 _nis_lookup(void *rv, void *cb_data, va_list ap)
256 {
257 char *name = va_arg(ap, char *);
258 char **line = va_arg(ap, char **);
259 int bywhat = va_arg(ap, int);
260
261 static char *__ypdomain;
262 int i;
263 const char *map = NULL;
264
265 if(__ypdomain == NULL) {
266 switch (yp_get_default_domain(&__ypdomain)) {
267 case 0:
268 break;
269 case YPERR_RESRC:
270 return NS_TRYAGAIN;
271 default:
272 return NS_UNAVAIL;
273 }
274 }
275
276 switch (bywhat) {
277 case _NG_KEYBYNAME:
278 map = "netgroup";
279 break;
280
281 case _NG_KEYBYUSER:
282 map = "netgroup.byuser";
283 break;
284
285 case _NG_KEYBYHOST:
286 map = "netgroup.byhost";
287 break;
288
289 default:
290 abort();
291 }
292
293 *line = NULL;
294 switch (yp_match(__ypdomain, map, name, (int)strlen(name), line, &i)) {
295 case 0:
296 return NS_SUCCESS;
297 case YPERR_KEY:
298 if (*line)
299 free(*line);
300 return NS_NOTFOUND;
301 default:
302 if (*line)
303 free(*line);
304 return NS_UNAVAIL;
305 }
306 /* NOTREACHED */
307 }
308 #endif
309
310 #ifdef NSSRC_FILES
311 /*
312 * lookup(): Find the given key in the database or yp, and return its value
313 * in *line; returns 1 if key was found, 0 otherwise
314 */
315 static int
316 lookup(char *name, char **line, int bywhat)
317 {
318 int r;
319 static const ns_dtab dtab[] = {
320 NS_FILES_CB(_local_lookup, NULL)
321 NS_NIS_CB(_nis_lookup, NULL)
322 NS_NULL_CB
323 };
324
325 _DIAGASSERT(name != NULL);
326 _DIAGASSERT(line != NULL);
327
328 r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "lookup", default_files_nis,
329 name, line, bywhat);
330 return (r == NS_SUCCESS) ? 1 : 0;
331 }
332 #else
333 static int
334 _local_lookupv(int *rv, void *cbdata, ...)
335 {
336 int e;
337 va_list ap;
338 va_start(ap, cbdata);
339 e = _local_lookup(rv, cbdata, ap);
340 va_end(ap);
341 return e;
342 }
343
344 static int
345 lookup(name, line, bywhat)
346 char *name;
347 char **line;
348 int bywhat;
349 {
350 return _local_lookupv(NULL, NULL, name, line, bywhat) == NS_SUCCESS;
351 }
352 #endif
353
354 /*
355 * _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE:
356 * line was empty or a comment _NG_GROUP: line had a netgroup definition,
357 * returned in ng _NG_NAME: line had a netgroup name, returned in name
358 *
359 * Public since used by netgroup_mkdb
360 */
361 int
362 _ng_parse(char **p, char **name, struct netgroup **ng)
363 {
364
365 _DIAGASSERT(p != NULL);
366 _DIAGASSERT(*p != NULL);
367 _DIAGASSERT(name != NULL);
368 _DIAGASSERT(ng != NULL);
369
370 while (**p) {
371 if (**p == '#')
372 /* comment */
373 return _NG_NONE;
374
375 while (**p && _NG_ISSPACE(**p))
376 /* skipblank */
377 (*p)++;
378
379 if (**p == '(') {
380 if ((*ng = getnetgroup(p)) == NULL)
381 return _NG_ERROR;
382 return _NG_GROUP;
383 } else {
384 char *np;
385 size_t i;
386
387 for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++)
388 continue;
389 if (np != *p) {
390 i = (*p - np) + 1;
391 *name = malloc(i);
392 if (*name == NULL)
393 return _NG_ERROR;
394 (void)memcpy(*name, np, i);
395 (*name)[i - 1] = '\0';
396 return _NG_NAME;
397 }
398 }
399 }
400 return _NG_NONE;
401 }
402
403
404 /*
405 * addgroup(): Recursively add all the members of the netgroup to this group.
406 * returns 0 upon failure, nonzero upon success.
407 * grp is not a valid pointer after return (either free(3)ed or allocated
408 * to a stringlist). in either case, it shouldn't be used again.
409 */
410 static int
411 addgroup(StringList *sl, char *grp)
412 {
413 char *line, *p;
414 struct netgroup *ng;
415 char *name;
416
417 _DIAGASSERT(sl != NULL);
418 _DIAGASSERT(grp != NULL);
419
420 #ifdef DEBUG_NG
421 (void)fprintf(stderr, "addgroup(%s)\n", grp);
422 #endif
423 /* check for cycles */
424 if (sl_find(sl, grp) != NULL) {
425 _ng_cycle(grp, sl);
426 free(grp);
427 return 0;
428 }
429 if (sl_add(sl, grp) == -1) {
430 free(grp);
431 return 0;
432 }
433
434 /* Lookup this netgroup */
435 line = NULL;
436 if (!lookup(grp, &line, _NG_KEYBYNAME)) {
437 if (line)
438 free(line);
439 return 0;
440 }
441
442 p = line;
443
444 for (;;) {
445 switch (_ng_parse(&p, &name, &ng)) {
446 case _NG_NONE:
447 /* Done with the line */
448 free(line);
449 return 1;
450
451 case _NG_GROUP:
452 /* new netgroup */
453 /* add to the list */
454 ng->ng_next = _nglist;
455 _nglist = ng;
456 break;
457
458 case _NG_NAME:
459 /* netgroup name */
460 if (!addgroup(sl, name))
461 return 0;
462 break;
463
464 case _NG_ERROR:
465 return 0;
466
467 default:
468 abort();
469 }
470 }
471 }
472
473
474 /*
475 * in_check(): Compare the spec with the netgroup
476 */
477 static int
478 in_check(const char *host, const char *user, const char *domain,
479 struct netgroup *ng)
480 {
481
482 /* host may be NULL */
483 /* user may be NULL */
484 /* domain may be NULL */
485 _DIAGASSERT(ng != NULL);
486
487 if ((host != NULL) && (ng->ng_host != NULL)
488 && strcmp(ng->ng_host, host) != 0)
489 return 0;
490
491 if ((user != NULL) && (ng->ng_user != NULL)
492 && strcmp(ng->ng_user, user) != 0)
493 return 0;
494
495 if ((domain != NULL) && (ng->ng_domain != NULL)
496 && strcmp(ng->ng_domain, domain) != 0)
497 return 0;
498
499 return 1;
500 }
501
502
503 /*
504 * in_find(): Find a match for the host, user, domain spec.
505 * grp is not a valid pointer after return (either free(3)ed or allocated
506 * to a stringlist). in either case, it shouldn't be used again.
507 */
508 static int
509 in_find(StringList *sl, char *grp, const char *host, const char *user,
510 const char *domain)
511 {
512 char *line, *p;
513 int i;
514 struct netgroup *ng;
515 char *name;
516
517 _DIAGASSERT(sl != NULL);
518 _DIAGASSERT(grp != NULL);
519 /* host may be NULL */
520 /* user may be NULL */
521 /* domain may be NULL */
522
523 #ifdef DEBUG_NG
524 (void)fprintf(stderr, "in_find(%s)\n", grp);
525 #endif
526 /* check for cycles */
527 if (sl_find(sl, grp) != NULL) {
528 _ng_cycle(grp, sl);
529 free(grp);
530 return 0;
531 }
532 if (sl_add(sl, grp) == -1) {
533 free(grp);
534 return 0;
535 }
536
537 /* Lookup this netgroup */
538 line = NULL;
539 if (!lookup(grp, &line, _NG_KEYBYNAME)) {
540 if (line)
541 free(line);
542 return 0;
543 }
544
545 p = line;
546
547 for (;;) {
548 switch (_ng_parse(&p, &name, &ng)) {
549 case _NG_NONE:
550 /* Done with the line */
551 free(line);
552 return 0;
553
554 case _NG_GROUP:
555 /* new netgroup */
556 i = in_check(host, user, domain, ng);
557 if (ng->ng_host != NULL)
558 free(ng->ng_host);
559 if (ng->ng_user != NULL)
560 free(ng->ng_user);
561 if (ng->ng_domain != NULL)
562 free(ng->ng_domain);
563 free(ng);
564 if (i) {
565 free(line);
566 return 1;
567 }
568 break;
569
570 case _NG_NAME:
571 /* netgroup name */
572 if (in_find(sl, name, host, user, domain)) {
573 free(line);
574 return 1;
575 }
576 break;
577
578 case _NG_ERROR:
579 free(line);
580 return 0;
581
582 default:
583 abort();
584 }
585 }
586 }
587
588 /*
589 * _ng_makekey(): Make a key from the two names given. The key is of the form
590 * <name1>.<name2> Names strings are replaced with * if they are empty;
591 * Returns NULL if there's a problem.
592 */
593 char *
594 _ng_makekey(const char *s1, const char *s2, size_t len)
595 {
596 char *buf;
597
598 /* s1 may be NULL */
599 /* s2 may be NULL */
600
601 buf = malloc(len);
602 if (buf != NULL)
603 (void)snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2));
604 return buf;
605 }
606
607 void
608 _ng_print(char *buf, size_t len, const struct netgroup *ng)
609 {
610 _DIAGASSERT(buf != NULL);
611 _DIAGASSERT(ng != NULL);
612
613 (void)snprintf(buf, len, "(%s,%s,%s)", _NG_EMPTY(ng->ng_host),
614 _NG_EMPTY(ng->ng_user), _NG_EMPTY(ng->ng_domain));
615 }
616
617
618 /*
619 * in_lookup1(): Fast lookup for a key in the appropriate map
620 */
621 static char *
622 in_lookup1(const char *key, const char *domain, int map)
623 {
624 char *line;
625 size_t len;
626 char *ptr;
627 int res;
628
629 /* key may be NULL */
630 /* domain may be NULL */
631
632 len = (key ? strlen(key) : 1) + (domain ? strlen(domain) : 1) + 2;
633 ptr = _ng_makekey(key, domain, len);
634 if (ptr == NULL)
635 return NULL;
636 res = lookup(ptr, &line, map);
637 free(ptr);
638 return res ? line : NULL;
639 }
640
641
642 /*
643 * in_lookup(): Fast lookup for a key in the appropriate map
644 */
645 static int
646 in_lookup(const char *group, const char *key, const char *domain, int map)
647 {
648 size_t len;
649 char *ptr, *line;
650
651 _DIAGASSERT(group != NULL);
652 /* key may be NULL */
653 /* domain may be NULL */
654
655 if (domain != NULL) {
656 /* Domain specified; look in "group.domain" and "*.domain" */
657 if ((line = in_lookup1(key, domain, map)) == NULL)
658 line = in_lookup1(NULL, domain, map);
659 } else
660 line = NULL;
661
662 if (line == NULL) {
663 /*
664 * domain not specified or domain lookup failed; look in
665 * "group.*" and "*.*"
666 */
667 if (((line = in_lookup1(key, NULL, map)) == NULL) &&
668 ((line = in_lookup1(NULL, NULL, map)) == NULL))
669 return 0;
670 }
671
672 len = strlen(group);
673
674 for (ptr = line; (ptr = strstr(ptr, group)) != NULL;)
675 /* Make sure we did not find a substring */
676 if ((ptr != line && ptr[-1] != ',') ||
677 (ptr[len] != '\0' && strchr("\n\t ,", ptr[len]) == NULL))
678 ptr++;
679 else {
680 free(line);
681 return 1;
682 }
683
684 free(line);
685 return 0;
686 }
687
688 /*ARGSUSED*/
689 static int
690 _local_endnetgrent(void *rv, void *cb_data, va_list ap)
691 {
692 for (_nglist = _nghead; _nglist != NULL; _nglist = _nghead) {
693 _nghead = _nglist->ng_next;
694 if (_nglist->ng_host != NULL)
695 free(_nglist->ng_host);
696 if (_nglist->ng_user != NULL)
697 free(_nglist->ng_user);
698 if (_nglist->ng_domain != NULL)
699 free(_nglist->ng_domain);
700 free(_nglist);
701 }
702
703 if (_ng_db) {
704 (void)(*_ng_db->close)(_ng_db);
705 _ng_db = NULL;
706 }
707
708 return NS_SUCCESS;
709 }
710
711 /*ARGSUSED*/
712 static int
713 _local_setnetgrent(void *rv, void *cb_data, va_list ap)
714 {
715 const char *ng = va_arg(ap, const char *);
716 StringList *sl;
717 char *ng_copy;
718
719 _DIAGASSERT(ng != NULL);
720
721 sl = sl_init();
722 if (sl == NULL)
723 return NS_TRYAGAIN;
724
725 /* Cleanup any previous storage */
726 if (_nghead != NULL)
727 endnetgrent();
728
729 if (_ng_db == NULL)
730 _ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
731
732 ng_copy = strdup(ng);
733 if (ng_copy != NULL)
734 addgroup(sl, ng_copy);
735 _nghead = _nglist;
736 sl_free(sl, 1);
737
738 return NS_SUCCESS;
739 }
740
741 /*ARGSUSED*/
742 static int
743 _local_getnetgrent(void *rv, void *cb_data, va_list ap)
744 {
745 int *retval = va_arg(ap, int *);
746 const char **host = va_arg(ap, const char **);
747 const char **user = va_arg(ap, const char **);
748 const char **domain = va_arg(ap, const char **);
749
750 _DIAGASSERT(host != NULL);
751 _DIAGASSERT(user != NULL);
752 _DIAGASSERT(domain != NULL);
753
754 *retval = 0;
755
756 if (_nglist == NULL)
757 return NS_TRYAGAIN;
758
759 *host = _nglist->ng_host;
760 *user = _nglist->ng_user;
761 *domain = _nglist->ng_domain;
762
763 _nglist = _nglist->ng_next;
764
765 *retval = 1;
766
767 return NS_SUCCESS;
768 }
769
770 /*ARGSUSED*/
771 static int
772 _local_innetgr(void *rv, void *cb_data, va_list ap)
773 {
774 int *retval = va_arg(ap, int *);
775 const char *grp = va_arg(ap, const char *);
776 const char *host = va_arg(ap, const char *);
777 const char *user = va_arg(ap, const char *);
778 const char *domain = va_arg(ap, const char *);
779
780 int found;
781 StringList *sl;
782 char *grcpy;
783
784 _DIAGASSERT(grp != NULL);
785 /* host may be NULL */
786 /* user may be NULL */
787 /* domain may be NULL */
788
789 if (_ng_db == NULL)
790 _ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
791
792 /* Try the fast lookup first */
793 if (host != NULL && user == NULL) {
794 if (in_lookup(grp, host, domain, _NG_KEYBYHOST)) {
795 *retval = 1;
796 return NS_SUCCESS;
797 }
798 } else if (host == NULL && user != NULL) {
799 if (in_lookup(grp, user, domain, _NG_KEYBYUSER)) {
800 *retval = 1;
801 return NS_SUCCESS;
802 }
803 }
804 /* If a domainname is given, we would have found a match */
805 if (domain != NULL) {
806 *retval = 0;
807 return NS_SUCCESS;
808 }
809
810 /* Too bad need the slow recursive way */
811 sl = sl_init();
812 if (sl == NULL) {
813 *retval = 0;
814 return NS_SUCCESS;
815 }
816 if ((grcpy = strdup(grp)) == NULL) {
817 sl_free(sl, 1);
818 *retval = 0;
819 return NS_SUCCESS;
820 }
821 found = in_find(sl, grcpy, host, user, domain);
822 sl_free(sl, 1);
823
824 *retval = found;
825 return NS_SUCCESS;
826 }
827
828 #ifdef YP
829
830 /*ARGSUSED*/
831 static int
832 _nis_endnetgrent(void *rv, void *cb_data, va_list ap)
833 {
834 return _local_endnetgrent(rv, cb_data, ap);
835 }
836
837 /*ARGSUSED*/
838 static int
839 _nis_setnetgrent(void *rv, void *cb_data, va_list ap)
840 {
841 return _local_setnetgrent(rv, cb_data, ap);
842 }
843
844 /*ARGSUSED*/
845 static int
846 _nis_getnetgrent(void *rv, void *cb_data, va_list ap)
847 {
848 return _local_getnetgrent(rv, cb_data, ap);
849 }
850
851 /*ARGSUSED*/
852 static int
853 _nis_innetgr(void *rv, void *cb_data, va_list ap)
854 {
855 return _local_innetgr(rv, cb_data, ap);
856 }
857
858 #endif
859
860
861 #ifdef NSSRC_FILES
862 void
863 endnetgrent(void)
864 {
865 static const ns_dtab dtab[] = {
866 NS_FILES_CB(_local_endnetgrent, NULL)
867 NS_NIS_CB(_nis_endnetgrent, NULL)
868 NS_NULL_CB
869 };
870
871 (void) nsdispatch(NULL, dtab, NSDB_NETGROUP, "endnetgrent",
872 __nsdefaultcompat);
873 }
874 #else
875 static int
876 _local_endnetgrentv(int *rv, void *cbdata, ...)
877 {
878 int e;
879 va_list ap;
880 va_start(ap, cbdata);
881 e = _local_endnetgrent(rv, cbdata, ap);
882 va_end(ap);
883 return e;
884 }
885
886 void
887 endnetgrent(void)
888 {
889 (void)_local_endnetgrentv(NULL, NULL, NULL);
890 }
891 #endif
892
893 #ifdef NSSRC_FILES
894 void
895 setnetgrent(const char *ng)
896 {
897 static const ns_dtab dtab[] = {
898 NS_FILES_CB(_local_setnetgrent, NULL)
899 NS_NIS_CB(_nis_setnetgrent, NULL)
900 NS_NULL_CB
901 };
902
903 (void ) nsdispatch(NULL, dtab, NSDB_NETGROUP, "setnetgrent",
904 __nsdefaultnis, ng);
905 }
906 #else
907 static int
908 _local_setnetgrentv(int *rv, void *cbdata, ...)
909 {
910 int e;
911 va_list ap;
912 va_start(ap, cbdata);
913 e = _local_setnetgrent(rv, cbdata, ap);
914 va_end(ap);
915 return e;
916 }
917
918 void
919 setnetgrent(const char *ng)
920 {
921 (void) _local_setnetgrentv(NULL, NULL,ng);
922 }
923
924 #endif
925
926 #ifdef NSSRC_FILES
927 int
928 getnetgrent(const char **host, const char **user, const char **domain)
929 {
930 int r, retval;
931 static const ns_dtab dtab[] = {
932 NS_FILES_CB(_local_getnetgrent, NULL)
933 NS_NIS_CB(_nis_getnetgrent, NULL)
934 NS_NULL_CB
935 };
936
937 r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "getnetgrent",
938 __nsdefaultnis, &retval, host, user, domain);
939
940 return (r == NS_SUCCESS) ? retval : 0;
941 }
942 #else
943 static int
944 _local_getnetgrentv(int *rv, void *cbdata, ...)
945 {
946 int e;
947 va_list ap;
948 va_start(ap, cbdata);
949 e = _local_getnetgrent(rv, cbdata, ap);
950 va_end(ap);
951 return e;
952 }
953
954 int
955 getnetgrent(const char **host, const char **user, const char **domain)
956 {
957 return _local_getnetgrentv(NULL, NULL, host, user, domain) == NS_SUCCESS;
958 }
959 #endif
960
961 #ifdef NSSRC_FILES
962 int
963 innetgr(const char *grp, const char *host, const char *user,
964 const char *domain)
965 {
966 int r, retval;
967 static const ns_dtab dtab[] = {
968 NS_FILES_CB(_local_innetgr, NULL)
969 NS_NIS_CB(_nis_innetgr, NULL)
970 NS_NULL_CB
971 };
972
973 r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "innetgr",
974 __nsdefaultnis, &retval, grp, host, user, domain);
975
976 return (r == NS_SUCCESS) ? retval : 0;
977 }
978 #else
979 static int
980 _local_innetgrv(int *rv, void *cbdata, ...)
981 {
982 int e;
983 va_list ap;
984 va_start(ap, cbdata);
985 e = _local_innetgr(rv, cbdata, ap);
986 va_end(ap);
987 return e;
988 }
989
990 int
991 innetgr(const char *grp, const char *host, const char *user,
992 const char *domain)
993 {
994 return _local_innetgrv(NULL, NULL, grp, host, user, domain) == NS_SUCCESS;
995 }
996 #endif
997