[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.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>