[BACK]Return to getnetgrent.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

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>