Annotation of src/lib/libc/gen/getnetgrent.c, Revision 1.25.4.1
1.25.4.1! wrstuden 1: /* $NetBSD: getnetgrent.c,v 1.26 1999/11/28 04:30:15 lukem Exp $ */
1.8 cgd 2:
1.1 mycroft 3: /*
1.4 christos 4: * Copyright (c) 1994 Christos Zoulas
5: * All rights reserved.
1.1 mycroft 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:
1.4 christos 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.
1.1 mycroft 20: *
1.4 christos 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
1.1 mycroft 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:
1.12 christos 34: #include <sys/cdefs.h>
1.1 mycroft 35: #if defined(LIBC_SCCS) && !defined(lint)
1.25.4.1! wrstuden 36: __RCSID("$NetBSD: getnetgrent.c,v 1.26 1999/11/28 04:30:15 lukem Exp $");
1.1 mycroft 37: #endif /* LIBC_SCCS and not lint */
38:
1.12 christos 39: #include "namespace.h"
1.9 christos 40: #include <sys/types.h>
1.24 lukem 41:
42: #include <assert.h>
43: #include <ctype.h>
44: #include <db.h>
45: #include <err.h>
46: #include <fcntl.h>
1.9 christos 47: #define _NETGROUP_PRIVATE
1.4 christos 48: #include <netgroup.h>
1.17 lukem 49: #include <nsswitch.h>
1.24 lukem 50: #include <stdio.h>
1.3 cgd 51: #include <stdlib.h>
1.24 lukem 52: #include <string.h>
1.11 lukem 53: #include <stringlist.h>
1.24 lukem 54:
1.10 cgd 55: #ifdef YP
1.17 lukem 56: #include <rpc/rpc.h>
1.10 cgd 57: #include <rpcsvc/ypclnt.h>
1.17 lukem 58: #include <rpcsvc/yp_prot.h>
1.23 lukem 59: #endif
60:
61: #ifdef __STDC__
62: #include <stdarg.h>
63: #else
64: #include <varargs.h>
1.13 jtc 65: #endif
1.17 lukem 66:
1.13 jtc 67: #ifdef __weak_alias
68: __weak_alias(endnetgrent,_endnetgrent);
69: __weak_alias(getnetgrent,_getnetgrent);
70: __weak_alias(innetgr,_innetgr);
71: __weak_alias(setnetgrent,_setnetgrent);
1.10 cgd 72: #endif
1.4 christos 73:
74: #define _NG_STAR(s) (((s) == NULL || *(s) == '\0') ? _ngstar : s)
1.9 christos 75: #define _NG_EMPTY(s) ((s) == NULL ? "" : s)
1.4 christos 76: #define _NG_ISSPACE(p) (isspace((unsigned char) (p)) || (p) == '\n')
1.1 mycroft 77:
1.4 christos 78: static const char _ngstar[] = "*";
79: static const char _ngoomem[] = "netgroup: %m";
1.6 christos 80: static struct netgroup *_nghead = (struct netgroup *)NULL;
81: static struct netgroup *_nglist = (struct netgroup *)NULL;
1.4 christos 82: static DB *_ng_db;
1.1 mycroft 83:
1.25.4.1! wrstuden 84: static int getstring __P((char **, int, __aconst char **));
1.4 christos 85: static struct netgroup *getnetgroup __P((char **));
1.17 lukem 86: static int lookup __P((char *, char **, int));
1.25.4.1! wrstuden 87: static int addgroup __P((StringList *, char *));
1.4 christos 88: static int in_check __P((const char *, const char *,
89: const char *, struct netgroup *));
1.17 lukem 90: static int in_find __P((StringList *, char *, const char *,
1.4 christos 91: const char *, const char *));
1.17 lukem 92: static char *in_lookup1 __P((const char *, const char *, int));
1.4 christos 93: static int in_lookup __P((const char *, const char *,
1.17 lukem 94: const char *, int));
1.4 christos 95:
1.21 thorpej 96: static const ns_src default_files_nis[] = {
1.22 lukem 97: { NSSRC_FILES, NS_SUCCESS | NS_NOTFOUND },
1.21 thorpej 98: #ifdef YP
99: { NSSRC_NIS, NS_SUCCESS },
100: #endif
101: { 0 }
102: };
103:
1.4 christos 104: /*
105: * getstring(): Get a string delimited by the character, skipping leading and
106: * trailing blanks and advancing the pointer
107: */
1.6 christos 108: static int
109: getstring(pp, del, str)
1.4 christos 110: char **pp;
111: int del;
1.16 mycroft 112: char __aconst **str;
1.4 christos 113: {
1.14 perry 114: size_t len;
1.4 christos 115: char *sp, *ep, *dp;
116:
1.24 lukem 117: _DIAGASSERT(pp != NULL);
118: _DIAGASSERT(str != NULL);
119:
1.4 christos 120: /* skip leading blanks */
121: for (sp = *pp; *sp && _NG_ISSPACE(*sp); sp++)
122: continue;
123:
124: /* accumulate till delimiter or space */
125: for (ep = sp; *ep && *ep != del && !_NG_ISSPACE(*ep); ep++)
126: continue;
127:
128: /* hunt for the delimiter */
129: for (dp = ep; *dp && *dp != del && _NG_ISSPACE(*dp); dp++)
130: continue;
131:
1.6 christos 132: if (*dp != del) {
133: *str = NULL;
134: return 0;
135: }
1.4 christos 136:
137: *pp = ++dp;
138:
1.14 perry 139: len = (ep - sp) + 1;
140: if (len > 1) {
141: dp = malloc(len);
1.6 christos 142: if (dp == NULL)
1.25.4.1! wrstuden 143: return 0;
1.14 perry 144: memcpy(dp, sp, len);
145: dp[len - 1] = '\0';
1.6 christos 146: } else
147: dp = NULL;
1.1 mycroft 148:
1.6 christos 149: *str = dp;
150: return 1;
1.4 christos 151: }
152:
153:
154: /*
155: * getnetgroup(): Parse a netgroup, and advance the pointer
156: */
157: static struct netgroup *
158: getnetgroup(pp)
159: char **pp;
160: {
1.24 lukem 161: struct netgroup *ng;
162:
163: _DIAGASSERT(pp != NULL);
164: _DIAGASSERT(*pp != NULL);
1.4 christos 165:
1.24 lukem 166: ng = malloc(sizeof(struct netgroup));
1.4 christos 167: if (ng == NULL)
1.25.4.1! wrstuden 168: return NULL;
1.4 christos 169:
170: (*pp)++; /* skip '(' */
1.6 christos 171: if (!getstring(pp, ',', &ng->ng_host))
1.4 christos 172: goto badhost;
173:
1.6 christos 174: if (!getstring(pp, ',', &ng->ng_user))
1.4 christos 175: goto baduser;
176:
1.6 christos 177: if (!getstring(pp, ')', &ng->ng_domain))
1.4 christos 178: goto baddomain;
179:
180: #ifdef DEBUG_NG
1.9 christos 181: {
182: char buf[1024];
183: (void) fprintf(stderr, "netgroup %s\n",
184: _ng_print(buf, sizeof(buf), ng));
185: }
1.4 christos 186: #endif
187: return ng;
188:
189: baddomain:
1.6 christos 190: if (ng->ng_user)
1.15 mycroft 191: free((char *)ng->ng_user);
1.4 christos 192: baduser:
1.6 christos 193: if (ng->ng_host)
1.15 mycroft 194: free((char *)ng->ng_host);
1.4 christos 195: badhost:
196: free(ng);
197: return NULL;
198: }
199:
200:
1.17 lukem 201: static int _local_lookup __P((void *, void *, va_list));
202:
1.18 christos 203: /*ARGSUSED*/
1.4 christos 204: static int
1.17 lukem 205: _local_lookup(rv, cb_data, ap)
206: void *rv;
207: void *cb_data;
208: va_list ap;
209: {
210: char *name = va_arg(ap, char *);
211: char **line = va_arg(ap, char **);
212: int bywhat = va_arg(ap, int);
213:
214: DBT key, data;
215: size_t len;
216: char *ks;
217: int r;
1.4 christos 218:
1.17 lukem 219: if (_ng_db == NULL)
220: return NS_UNAVAIL;
1.4 christos 221:
1.17 lukem 222: len = strlen(name) + 2;
223: ks = malloc(len);
224: if (ks == NULL)
1.25.4.1! wrstuden 225: return NS_UNAVAIL;
1.4 christos 226:
1.17 lukem 227: ks[0] = bywhat;
228: memcpy(&ks[1], name, len - 1);
1.4 christos 229:
1.17 lukem 230: key.data = (u_char *) ks;
231: key.size = len;
1.4 christos 232:
1.17 lukem 233: r = (_ng_db->get) (_ng_db, &key, &data, 0);
234: free(ks);
235: switch (r) {
236: case 0:
237: break;
238: case 1:
239: return NS_NOTFOUND;
240: case -1:
1.22 lukem 241: /* XXX: call endnetgrent() here ? */
1.17 lukem 242: return NS_UNAVAIL;
243: }
244:
245: *line = strdup(data.data);
246: if (*line == NULL)
247: return NS_UNAVAIL;
248: return NS_SUCCESS;
249: }
1.4 christos 250:
251: #ifdef YP
1.17 lukem 252: static int _nis_lookup __P((void *, void *, va_list));
1.4 christos 253:
1.18 christos 254: /*ARGSUSED*/
1.17 lukem 255: static int
256: _nis_lookup(rv, cb_data, ap)
257: void *rv;
258: void *cb_data;
259: va_list ap;
260: {
261: char *name = va_arg(ap, char *);
262: char **line = va_arg(ap, char **);
263: int bywhat = va_arg(ap, int);
264:
265: static char *__ypdomain;
266: int i;
267: char *map = NULL;
1.4 christos 268:
1.17 lukem 269: if(__ypdomain == NULL) {
270: switch (yp_get_default_domain(&__ypdomain)) {
271: case 0:
1.6 christos 272: break;
1.17 lukem 273: case YPERR_RESRC:
274: return NS_TRYAGAIN;
1.6 christos 275: default:
1.17 lukem 276: return NS_UNAVAIL;
1.6 christos 277: }
1.17 lukem 278: }
279:
280: switch (bywhat) {
281: case _NG_KEYBYNAME:
282: map = "netgroup";
283: break;
284:
285: case _NG_KEYBYUSER:
286: map = "netgroup.byuser";
287: break;
288:
289: case _NG_KEYBYHOST:
290: map = "netgroup.byhost";
291: break;
292:
293: default:
294: abort();
295: }
1.4 christos 296:
1.17 lukem 297: *line = NULL;
298: switch (yp_match(__ypdomain, map, name, (int)strlen(name), line, &i)) {
299: case 0:
300: return NS_SUCCESS;
301: case YPERR_KEY:
302: if (*line)
303: free(*line);
304: return NS_NOTFOUND;
305: default:
306: if (*line)
307: free(*line);
308: return NS_UNAVAIL;
1.6 christos 309: }
1.17 lukem 310: /* NOTREACHED */
311: }
1.4 christos 312: #endif
313:
1.25.4.1! wrstuden 314:
1.17 lukem 315: /*
316: * lookup(): Find the given key in the database or yp, and return its value
317: * in *line; returns 1 if key was found, 0 otherwise
318: */
319: static int
320: lookup(name, line, bywhat)
321: char *name;
322: char **line;
323: int bywhat;
324: {
325: int r;
1.20 lukem 326: static const ns_dtab dtab[] = {
1.19 lukem 327: NS_FILES_CB(_local_lookup, NULL)
1.21 thorpej 328: NS_NIS_CB(_nis_lookup, NULL)
1.19 lukem 329: { 0 }
1.17 lukem 330: };
331:
1.24 lukem 332: _DIAGASSERT(name != NULL);
333: _DIAGASSERT(line != NULL);
334:
1.21 thorpej 335: r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "lookup", default_files_nis,
1.19 lukem 336: name, line, bywhat);
1.17 lukem 337: return (r == NS_SUCCESS) ? 1 : 0;
1.1 mycroft 338: }
339:
340: /*
1.4 christos 341: * _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE:
342: * line was empty or a comment _NG_GROUP: line had a netgroup definition,
343: * returned in ng _NG_NAME: line had a netgroup name, returned in name
344: *
345: * Public since used by netgroup_mkdb
1.1 mycroft 346: */
347: int
1.4 christos 348: _ng_parse(p, name, ng)
349: char **p;
350: char **name;
351: struct netgroup **ng;
1.1 mycroft 352: {
1.24 lukem 353:
354: _DIAGASSERT(p != NULL);
355: _DIAGASSERT(*p != NULL);
356: _DIAGASSERT(name != NULL);
357: _DIAGASSERT(ng != NULL);
358:
1.4 christos 359: while (**p) {
360: if (**p == '#')
361: /* comment */
362: return _NG_NONE;
363:
364: while (**p && _NG_ISSPACE(**p))
365: /* skipblank */
366: (*p)++;
367:
368: if (**p == '(') {
1.25.4.1! wrstuden 369: if ((*ng = getnetgroup(p)) == NULL)
1.4 christos 370: return _NG_ERROR;
371: return _NG_GROUP;
372: } else {
1.17 lukem 373: char *np;
374: size_t i;
1.1 mycroft 375:
1.4 christos 376: for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++)
377: continue;
378: if (np != *p) {
379: i = (*p - np) + 1;
380: *name = malloc(i);
381: if (*name == NULL)
1.25.4.1! wrstuden 382: return _NG_ERROR;
1.4 christos 383: memcpy(*name, np, i);
384: (*name)[i - 1] = '\0';
385: return _NG_NAME;
386: }
387: }
1.1 mycroft 388: }
1.4 christos 389: return _NG_NONE;
1.1 mycroft 390: }
391:
1.4 christos 392:
1.1 mycroft 393: /*
1.25.4.1! wrstuden 394: * addgroup(): Recursively add all the members of the netgroup to this group.
! 395: * returns 0 upon failure, nonzero upon success.
! 396: * grp is not a valid pointer after return (either free(3)ed or allocated
! 397: * to a stringlist). in either case, it shouldn't be used again.
1.1 mycroft 398: */
1.25.4.1! wrstuden 399: static int
1.17 lukem 400: addgroup(sl, grp)
1.11 lukem 401: StringList *sl;
402: char *grp;
1.1 mycroft 403: {
1.4 christos 404: char *line, *p;
405: struct netgroup *ng;
406: char *name;
407:
1.24 lukem 408: _DIAGASSERT(sl != NULL);
409: _DIAGASSERT(grp != NULL);
410:
1.4 christos 411: #ifdef DEBUG_NG
412: (void) fprintf(stderr, "addgroup(%s)\n", grp);
413: #endif
414: /* check for cycles */
1.11 lukem 415: if (sl_find(sl, grp) != NULL) {
1.6 christos 416: free(grp);
1.12 christos 417: warnx("netgroup: Cycle in group `%s'", grp);
1.25.4.1! wrstuden 418: return 0;
! 419: }
! 420: if (sl_add(sl, grp) == -1) {
! 421: free(grp);
! 422: return 0;
1.4 christos 423: }
424:
425: /* Lookup this netgroup */
1.17 lukem 426: line = NULL;
427: if (!lookup(grp, &line, _NG_KEYBYNAME)) {
428: if (line != NULL)
429: free(line);
1.25.4.1! wrstuden 430: return 0;
1.17 lukem 431: }
1.4 christos 432:
433: p = line;
434:
435: for (;;) {
436: switch (_ng_parse(&p, &name, &ng)) {
437: case _NG_NONE:
438: /* Done with the line */
439: free(line);
1.25.4.1! wrstuden 440: return 1;
1.4 christos 441:
442: case _NG_GROUP:
443: /* new netgroup */
444: /* add to the list */
445: ng->ng_next = _nglist;
446: _nglist = ng;
447: break;
448:
449: case _NG_NAME:
450: /* netgroup name */
1.25.4.1! wrstuden 451: if (!addgroup(sl, name))
! 452: return 0;
1.4 christos 453: break;
1.1 mycroft 454:
1.4 christos 455: case _NG_ERROR:
1.25.4.1! wrstuden 456: return 0;
1.4 christos 457:
458: default:
459: abort();
460: }
1.1 mycroft 461: }
462: }
463:
1.4 christos 464:
1.1 mycroft 465: /*
1.4 christos 466: * in_check(): Compare the spec with the netgroup
1.1 mycroft 467: */
1.4 christos 468: static int
469: in_check(host, user, domain, ng)
470: const char *host;
471: const char *user;
472: const char *domain;
473: struct netgroup *ng;
1.1 mycroft 474: {
1.24 lukem 475:
476: /* host may be NULL */
477: /* user may be NULL */
478: /* domain may be NULL */
479: _DIAGASSERT(ng != NULL);
480:
1.6 christos 481: if ((host != NULL) && (ng->ng_host != NULL)
1.4 christos 482: && strcmp(ng->ng_host, host) != 0)
483: return 0;
484:
1.6 christos 485: if ((user != NULL) && (ng->ng_user != NULL)
1.4 christos 486: && strcmp(ng->ng_user, user) != 0)
487: return 0;
488:
1.6 christos 489: if ((domain != NULL) && (ng->ng_domain != NULL)
1.4 christos 490: && strcmp(ng->ng_domain, domain) != 0)
491: return 0;
1.1 mycroft 492:
1.4 christos 493: return 1;
1.1 mycroft 494: }
495:
1.4 christos 496:
1.1 mycroft 497: /*
1.25.4.1! wrstuden 498: * in_find(): Find a match for the host, user, domain spec.
! 499: * grp is not a valid pointer after return (either free(3)ed or allocated
! 500: * to a stringlist). in either case, it shouldn't be used again.
1.1 mycroft 501: */
502: static int
1.17 lukem 503: in_find(sl, grp, host, user, domain)
1.11 lukem 504: StringList *sl;
505: char *grp;
506: const char *host;
507: const char *user;
508: const char *domain;
1.1 mycroft 509: {
1.4 christos 510: char *line, *p;
511: int i;
512: struct netgroup *ng;
513: char *name;
514:
1.24 lukem 515: _DIAGASSERT(sl != NULL);
516: _DIAGASSERT(grp != NULL);
517: /* host may be NULL */
518: /* user may be NULL */
519: /* domain may be NULL */
520:
1.4 christos 521: #ifdef DEBUG_NG
522: (void) fprintf(stderr, "in_find(%s)\n", grp);
523: #endif
524: /* check for cycles */
1.11 lukem 525: if (sl_find(sl, grp) != NULL) {
1.6 christos 526: free(grp);
1.12 christos 527: warnx("netgroup: Cycle in group `%s'", grp);
1.4 christos 528: return 0;
529: }
1.25.4.1! wrstuden 530: if (sl_add(sl, grp) == -1) {
! 531: free(grp);
! 532: return 0;
! 533: }
1.1 mycroft 534:
1.4 christos 535: /* Lookup this netgroup */
1.17 lukem 536: line = NULL;
537: if (!lookup(grp, &line, _NG_KEYBYNAME)) {
538: if (line)
539: free(line);
1.4 christos 540: return 0;
1.17 lukem 541: }
1.4 christos 542:
543: p = line;
544:
545: for (;;) {
546: switch (_ng_parse(&p, &name, &ng)) {
547: case _NG_NONE:
548: /* Done with the line */
549: free(line);
550: return 0;
551:
552: case _NG_GROUP:
553: /* new netgroup */
554: i = in_check(host, user, domain, ng);
1.6 christos 555: if (ng->ng_host != NULL)
1.15 mycroft 556: free((char *)ng->ng_host);
1.6 christos 557: if (ng->ng_user != NULL)
1.15 mycroft 558: free((char *)ng->ng_user);
1.6 christos 559: if (ng->ng_domain != NULL)
1.15 mycroft 560: free((char *)ng->ng_domain);
1.4 christos 561: free(ng);
562: if (i) {
563: free(line);
564: return 1;
565: }
1.1 mycroft 566: break;
1.4 christos 567:
568: case _NG_NAME:
569: /* netgroup name */
1.17 lukem 570: if (in_find(sl, name, host, user, domain)) {
1.4 christos 571: free(line);
572: return 1;
1.1 mycroft 573: }
1.4 christos 574: break;
575:
576: case _NG_ERROR:
577: free(line);
578: return 0;
579:
580: default:
581: abort();
1.1 mycroft 582: }
583: }
1.4 christos 584: }
585:
586: /*
587: * _ng_makekey(): Make a key from the two names given. The key is of the form
588: * <name1>.<name2> Names strings are replaced with * if they are empty;
1.25.4.1! wrstuden 589: * Returns NULL if there's a problem.
1.4 christos 590: */
591: char *
592: _ng_makekey(s1, s2, len)
593: const char *s1, *s2;
594: size_t len;
595: {
1.24 lukem 596: char *buf;
597:
598: /* s1 may be NULL */
599: /* s2 may be NULL */
600:
601: buf = malloc(len);
1.25.4.1! wrstuden 602: if (buf != NULL)
! 603: (void) snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2));
1.4 christos 604: return buf;
1.9 christos 605: }
606:
607: void
608: _ng_print(buf, len, ng)
609: char *buf;
610: size_t len;
611: const struct netgroup *ng;
612: {
1.24 lukem 613: _DIAGASSERT(buf != NULL);
614: _DIAGASSERT(ng != NULL);
615:
1.9 christos 616: (void) snprintf(buf, len, "(%s,%s,%s)", _NG_EMPTY(ng->ng_host),
617: _NG_EMPTY(ng->ng_user), _NG_EMPTY(ng->ng_domain));
1.4 christos 618: }
619:
620:
621: /*
622: * in_lookup1(): Fast lookup for a key in the appropriate map
623: */
624: static char *
1.17 lukem 625: in_lookup1(key, domain, map)
1.4 christos 626: const char *key;
627: const char *domain;
628: int map;
629: {
630: char *line;
631: size_t len;
632: char *ptr;
633: int res;
634:
1.24 lukem 635: /* key may be NULL */
636: /* domain may be NULL */
637:
1.4 christos 638: len = (key ? strlen(key) : 1) + (domain ? strlen(domain) : 1) + 2;
639: ptr = _ng_makekey(key, domain, len);
1.25.4.1! wrstuden 640: if (ptr == NULL)
! 641: return NULL;
1.17 lukem 642: res = lookup(ptr, &line, map);
1.4 christos 643: free(ptr);
644: return res ? line : NULL;
645: }
646:
647:
648: /*
649: * in_lookup(): Fast lookup for a key in the appropriate map
650: */
651: static int
1.17 lukem 652: in_lookup(group, key, domain, map)
1.4 christos 653: const char *group;
654: const char *key;
655: const char *domain;
656: int map;
657: {
658: size_t len;
659: char *ptr, *line;
660:
1.24 lukem 661: _DIAGASSERT(group != NULL);
662: /* key may be NULL */
663: /* domain may be NULL */
664:
1.4 christos 665: if (domain != NULL) {
666: /* Domain specified; look in "group.domain" and "*.domain" */
1.17 lukem 667: if ((line = in_lookup1(key, domain, map)) == NULL)
668: line = in_lookup1(NULL, domain, map);
1.25.4.1! wrstuden 669: } else
1.4 christos 670: line = NULL;
671:
672: if (line == NULL) {
673: /*
674: * domain not specified or domain lookup failed; look in
675: * "group.*" and "*.*"
676: */
1.17 lukem 677: if (((line = in_lookup1(key, NULL, map)) == NULL) &&
678: ((line = in_lookup1(NULL, NULL, map)) == NULL))
1.4 christos 679: return 0;
680: }
681:
682: len = strlen(group);
683:
684: for (ptr = line; (ptr = strstr(ptr, group)) != NULL;)
685: /* Make sure we did not find a substring */
686: if ((ptr != line && ptr[-1] != ',') ||
687: (ptr[len] != '\0' && strchr("\n\t ,", ptr[len]) == NULL))
688: ptr++;
689: else {
690: free(line);
691: return 1;
1.1 mycroft 692: }
1.4 christos 693:
694: free(line);
695: return 0;
696: }
697:
698:
699: void
700: endnetgrent()
701: {
702: for (_nglist = _nghead; _nglist != NULL; _nglist = _nghead) {
703: _nghead = _nglist->ng_next;
1.6 christos 704: if (_nglist->ng_host != NULL)
1.15 mycroft 705: free((char *)_nglist->ng_host);
1.6 christos 706: if (_nglist->ng_user != NULL)
1.15 mycroft 707: free((char *)_nglist->ng_user);
1.6 christos 708: if (_nglist->ng_domain != NULL)
1.15 mycroft 709: free((char *)_nglist->ng_domain);
1.4 christos 710: free(_nglist);
711: }
712:
713: if (_ng_db) {
714: (void) (_ng_db->close) (_ng_db);
715: _ng_db = NULL;
716: }
717: }
718:
719:
720: void
721: setnetgrent(ng)
722: const char *ng;
723: {
1.25.4.1! wrstuden 724: StringList *sl;
1.17 lukem 725: char *ng_copy;
1.4 christos 726:
1.24 lukem 727: _DIAGASSERT(ng != NULL);
728:
1.25.4.1! wrstuden 729: sl = sl_init();
! 730: if (sl == NULL)
! 731: return;
! 732:
1.4 christos 733: /* Cleanup any previous storage */
734: if (_nghead != NULL)
735: endnetgrent();
736:
737: if (_ng_db == NULL)
738: _ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
739:
740: ng_copy = strdup(ng);
1.25.4.1! wrstuden 741: if (ng_copy != NULL)
! 742: addgroup(sl, ng_copy);
1.4 christos 743: _nghead = _nglist;
1.11 lukem 744: sl_free(sl, 1);
1.4 christos 745: }
746:
747:
748: int
749: getnetgrent(host, user, domain)
750: const char **host;
751: const char **user;
752: const char **domain;
753: {
1.24 lukem 754: _DIAGASSERT(host != NULL);
755: _DIAGASSERT(user != NULL);
756: _DIAGASSERT(domain != NULL);
757:
1.4 christos 758: if (_nglist == NULL)
759: return 0;
760:
761: *host = _nglist->ng_host;
762: *user = _nglist->ng_user;
763: *domain = _nglist->ng_domain;
764:
765: _nglist = _nglist->ng_next;
766:
767: return 1;
768: }
769:
770:
771: int
772: innetgr(grp, host, user, domain)
773: const char *grp, *host, *user, *domain;
774: {
775: int found;
1.11 lukem 776: StringList *sl;
1.24 lukem 777:
778: _DIAGASSERT(grp != NULL);
779: /* host may be NULL */
780: /* user may be NULL */
781: /* domain may be NULL */
1.4 christos 782:
783: if (_ng_db == NULL)
784: _ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
785:
786: /* Try the fast lookup first */
787: if (host != NULL && user == NULL) {
1.17 lukem 788: if (in_lookup(grp, host, domain, _NG_KEYBYHOST))
1.4 christos 789: return 1;
790: } else if (host == NULL && user != NULL) {
1.17 lukem 791: if (in_lookup(grp, user, domain, _NG_KEYBYUSER))
1.4 christos 792: return 1;
793: }
794: /* If a domainname is given, we would have found a match */
795: if (domain != NULL)
796: return 0;
797:
798: /* Too bad need the slow recursive way */
1.11 lukem 799: sl = sl_init();
1.25.4.1! wrstuden 800: if (sl == NULL)
! 801: return 0;
1.17 lukem 802: found = in_find(sl, strdup(grp), host, user, domain);
1.11 lukem 803: sl_free(sl, 1);
1.4 christos 804:
805: return found;
1.1 mycroft 806: }
CVSweb <webmaster@jp.NetBSD.org>