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