home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / net / getnetgrent.c next >
C/C++ Source or Header  |  1996-09-28  |  15KB  |  743 lines

  1. /*    $NetBSD: getnetgrent.c,v 1.8 1995/02/25 08:51:19 cgd Exp $    */
  2.  
  3. /*
  4.  * Copyright (c) 1994 Christos Zoulas
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *    This product includes software developed by Christos Zoulas.
  18.  * 4. The name of the author may not be used to endorse or promote products
  19.  *    derived from this software without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  22.  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  25.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #if defined(LIBC_SCCS) && !defined(lint)
  35. static char *rcsid = "$NetBSD: getnetgrent.c,v 1.8 1995/02/25 08:51:19 cgd Exp $";
  36. #endif /* LIBC_SCCS and not lint */
  37.  
  38. #include <stdio.h>
  39. #include <netgroup.h>
  40. #include <string.h>
  41. #include <fcntl.h>
  42. #include <err.h>
  43. #include <ctype.h>
  44. #include <stdlib.h>
  45. #include <db.h>
  46.  
  47. #define _NG_STAR(s)    (((s) == NULL || *(s) == '\0') ? _ngstar : s)
  48. #define _NG_ISSPACE(p)    (isspace((unsigned char) (p)) || (p) == '\n')
  49.  
  50. __dead void    _err __P((int, const char *, ...))
  51.             __attribute__((noreturn, format (printf, 2, 3)));
  52. void        _warn __P((const char *, ...))
  53.             __attribute__((format (printf, 1, 2)));
  54. void        _warnx __P((const char *, ...))
  55.             __attribute__((format (printf, 1, 2)));
  56.  
  57. static const char _ngstar[] = "*";
  58. static const char _ngoomem[] = "netgroup: %m";
  59. static struct netgroup *_nghead = (struct netgroup *)NULL;
  60. static struct netgroup *_nglist = (struct netgroup *)NULL;
  61. static DB *_ng_db;
  62.  
  63. /*
  64.  * Simple string list
  65.  */
  66. struct stringlist {
  67.     char        **sl_str;
  68.     size_t          sl_max;
  69.     size_t          sl_cur;
  70. };
  71.  
  72. static int        getstring __P((char **, int, char **));
  73. static struct netgroup    *getnetgroup __P((char **));
  74. static int         lookup __P((const char *, char *, char **, int));
  75. static void         addgroup __P((char *, struct stringlist *, char *));
  76. static int         in_check __P((const char *, const char *,
  77.                        const char *, struct netgroup *));
  78. static int         in_find __P((char *, struct stringlist *,
  79.                       char *, const char *,
  80.                       const char *, const char *));
  81. static char        *in_lookup1 __P((const char *, const char *,
  82.                      const char *, int));
  83. static int         in_lookup __P((const char *, const char *,
  84.                         const char *, const char *, int));
  85.  
  86. /*
  87.  * _ng_sl_init(): Initialize a string list
  88.  */
  89. struct stringlist *
  90. _ng_sl_init()
  91. {
  92.     struct stringlist *sl = malloc(sizeof(struct stringlist));
  93.     if (sl == NULL)
  94.         _err(1, _ngoomem);
  95.  
  96.     sl->sl_cur = 0;
  97.     sl->sl_max = 20;
  98.     sl->sl_str = malloc(sl->sl_max * sizeof(char *));
  99.     if (sl->sl_str == NULL)
  100.         _err(1, _ngoomem);
  101.     return sl;
  102. }
  103.  
  104.  
  105. /*
  106.  * _ng_sl_add(): Add an item to the string list
  107.  */
  108. void
  109. _ng_sl_add(sl, name)
  110.     struct stringlist    *sl;
  111.     char            *name;
  112. {
  113.     if (sl->sl_cur == sl->sl_max - 1) {
  114.         sl->sl_max += 20;
  115.         sl->sl_str = realloc(sl->sl_str, sl->sl_max * sizeof(char *));
  116.         if (sl->sl_str == NULL)
  117.             _err(1, _ngoomem);
  118.     }
  119.     sl->sl_str[sl->sl_cur++] = name;
  120. }
  121.  
  122.  
  123. /*
  124.  * _ng_sl_free(): Free a stringlist
  125.  */
  126. void
  127. _ng_sl_free(sl, all)
  128.     struct stringlist    *sl;
  129.     int             all;
  130. {
  131.     size_t    i;
  132.  
  133.     if (all)
  134.         for (i = 0; i < sl->sl_cur; i++)
  135.             free(sl->sl_str[i]);
  136.     free(sl->sl_str);
  137.     free(sl);
  138. }
  139.  
  140.  
  141. /*
  142.  * sl_find(): Find a name in the string list
  143.  */
  144. char *
  145. _ng_sl_find(sl, name)
  146.     struct stringlist    *sl;
  147.     char            *name;
  148. {
  149.     size_t    i;
  150.  
  151.     for (i = 0; i < sl->sl_cur; i++)
  152.         if (strcmp(sl->sl_str[i], name) == 0)
  153.             return sl->sl_str[i];
  154.  
  155.     return NULL;
  156. }
  157.  
  158.  
  159. /*
  160.  * getstring(): Get a string delimited by the character, skipping leading and
  161.  * trailing blanks and advancing the pointer
  162.  */
  163. static int
  164. getstring(pp, del, str)
  165.     char    **pp;
  166.     int      del;
  167.     char    **str;
  168. {
  169.     char *sp, *ep, *dp;
  170.  
  171.     /* skip leading blanks */
  172.     for (sp = *pp; *sp && _NG_ISSPACE(*sp); sp++)
  173.         continue;
  174.  
  175.     /* accumulate till delimiter or space */
  176.     for (ep = sp; *ep && *ep != del && !_NG_ISSPACE(*ep); ep++)
  177.         continue;
  178.  
  179.     /* hunt for the delimiter */
  180.     for (dp = ep; *dp && *dp != del && _NG_ISSPACE(*dp); dp++)
  181.         continue;
  182.  
  183.     if (*dp != del) {
  184.         *str = NULL;
  185.         return 0;
  186.     }
  187.  
  188.     *pp = ++dp;
  189.  
  190.     del = (ep - sp) + 1;
  191.     if (del > 1) {
  192.         dp = malloc(del);
  193.         if (dp == NULL)
  194.             _err(1, _ngoomem);
  195.         memcpy(dp, sp, del);
  196.         dp[del - 1] = '\0';
  197.     } else
  198.         dp = NULL;
  199.  
  200.     *str = dp;
  201.     return 1;
  202. }
  203.  
  204.  
  205. /*
  206.  * getnetgroup(): Parse a netgroup, and advance the pointer
  207.  */
  208. static struct netgroup *
  209. getnetgroup(pp)
  210.     char    **pp;
  211. {
  212.     struct netgroup *ng = malloc(sizeof(struct netgroup));
  213.  
  214.     if (ng == NULL)
  215.         _err(1, _ngoomem);
  216.  
  217.     (*pp)++;    /* skip '(' */
  218.     if (!getstring(pp, ',', &ng->ng_host))
  219.         goto badhost;
  220.  
  221.     if (!getstring(pp, ',', &ng->ng_user))
  222.         goto baduser;
  223.  
  224.     if (!getstring(pp, ')', &ng->ng_domain))
  225.         goto baddomain;
  226.  
  227. #ifdef DEBUG_NG
  228.     (void) fprintf(stderr, "netgroup(%s,%s,%s)\n", 
  229.                _NG_STAR(ng->ng_host), _NG_STAR(ng->ng_user),
  230.                _NG_STAR(ng->ng_domain));
  231. #endif
  232.     return ng;
  233.  
  234. baddomain:
  235.     if (ng->ng_user)
  236.         free(ng->ng_user);
  237. baduser:
  238.     if (ng->ng_host)
  239.         free(ng->ng_host);
  240. badhost:
  241.     free(ng);
  242.     return NULL;
  243. }
  244.  
  245.  
  246. /*
  247.  * lookup(): Find the given key in the database or yp, and return its value
  248.  * in *line; returns 1 if key was found, 0 otherwise
  249.  */
  250. static int
  251. lookup(ypdom, name, line, bywhat)
  252.     const char     *ypdom;
  253.     char         *name;
  254.     char        **line;
  255.     int          bywhat;
  256. {
  257. #ifdef YP
  258.     int             i;
  259.     char           *map = NULL;
  260. #endif
  261.  
  262.     if (_ng_db) {
  263.         DBT     key, data;
  264.         size_t     len = strlen(name) + 2;
  265.         char    *ks = malloc(len);
  266.  
  267.         ks[0] = bywhat;
  268.         memcpy(&ks[1], name, len - 1);
  269.  
  270.         key.data = (u_char *) ks;
  271.         key.size = len;
  272.  
  273.         switch ((_ng_db->get) (_ng_db, &key, &data, 0)) {
  274.         case 0:
  275.             free(ks);
  276.             *line = strdup(data.data);
  277.             if (*line == NULL)
  278.                 _err(1, _ngoomem);
  279.             return 1;
  280.  
  281.         case 1:
  282.             break;
  283.  
  284.         case -1:
  285.             _warn("netgroup: db get");
  286.             break;
  287.         }
  288.         free(ks);
  289.     }
  290. #ifdef YP
  291.     if (ypdom) {
  292.         switch (bywhat) {
  293.         case _NG_KEYBYNAME:
  294.             map = "netgroup";
  295.             break;
  296.  
  297.         case _NG_KEYBYUSER:
  298.             map = "netgroup.byuser";
  299.             break;
  300.  
  301.         case _NG_KEYBYHOST:
  302.             map = "netgroup.byhost";
  303.             break;
  304.  
  305.         default:
  306.             abort();
  307.             break;
  308.         }
  309.  
  310.  
  311.         if (yp_match(ypdom, map, name, strlen(name), line, &i) == 0)
  312.             return 1;
  313.     }
  314. #endif
  315.  
  316.     return 0;
  317. }
  318.  
  319.  
  320. /*
  321.  * _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE:
  322.  * line was empty or a comment _NG_GROUP: line had a netgroup definition,
  323.  * returned in ng _NG_NAME:  line had a netgroup name, returned in name
  324.  * 
  325.  * Public since used by netgroup_mkdb
  326.  */
  327. int
  328. _ng_parse(p, name, ng)
  329.     char        **p;
  330.     char        **name;
  331.     struct netgroup    **ng;
  332. {
  333.     while (**p) {
  334.         if (**p == '#')
  335.             /* comment */
  336.             return _NG_NONE;
  337.  
  338.         while (**p && _NG_ISSPACE(**p))
  339.             /* skipblank */
  340.             (*p)++;
  341.  
  342.         if (**p == '(') {
  343.             if ((*ng = getnetgroup(p)) == NULL) {
  344.                 _warnx("netgroup: Syntax error `%s'", *p);
  345.                 return _NG_ERROR;
  346.             }
  347.             return _NG_GROUP;
  348.         } else {
  349.             char           *np;
  350.             int             i;
  351.  
  352.             for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++)
  353.                 continue;
  354.             if (np != *p) {
  355.                 i = (*p - np) + 1;
  356.                 *name = malloc(i);
  357.                 if (*name == NULL)
  358.                     _err(1, _ngoomem);
  359.                 memcpy(*name, np, i);
  360.                 (*name)[i - 1] = '\0';
  361.                 return _NG_NAME;
  362.             }
  363.         }
  364.     }
  365.     return _NG_NONE;
  366. }
  367.  
  368.  
  369. /*
  370.  * addgroup(): Recursively add all the members of the netgroup to this group
  371.  */
  372. static void
  373. addgroup(ypdom, sl, grp)
  374.     char            *ypdom;
  375.     struct stringlist    *sl;
  376.     char            *grp;
  377. {
  378.     char        *line, *p;
  379.     struct netgroup    *ng;
  380.     char        *name;
  381.  
  382. #ifdef DEBUG_NG
  383.     (void) fprintf(stderr, "addgroup(%s)\n", grp);
  384. #endif
  385.     /* check for cycles */
  386.     if (_ng_sl_find(sl, grp) != NULL) {
  387.         free(grp);
  388.         _warnx("netgroup: Cycle in group `%s'", grp);
  389.         return;
  390.     }
  391.     _ng_sl_add(sl, grp);
  392.  
  393.     /* Lookup this netgroup */
  394.     if (!lookup(ypdom, grp, &line, _NG_KEYBYNAME))
  395.         return;
  396.  
  397.     p = line;
  398.  
  399.     for (;;) {
  400.         switch (_ng_parse(&p, &name, &ng)) {
  401.         case _NG_NONE:
  402.             /* Done with the line */
  403.             free(line);
  404.             return;
  405.  
  406.         case _NG_GROUP:
  407.             /* new netgroup */
  408.             /* add to the list */
  409.             ng->ng_next = _nglist;
  410.             _nglist = ng;
  411.             break;
  412.  
  413.         case _NG_NAME:
  414.             /* netgroup name */
  415.             addgroup(ypdom, sl, name);
  416.             break;
  417.  
  418.         case _NG_ERROR:
  419.             return;
  420.  
  421.         default:
  422.             abort();
  423.             return;
  424.         }
  425.     }
  426. }
  427.  
  428.  
  429. /*
  430.  * in_check(): Compare the spec with the netgroup
  431.  */
  432. static int
  433. in_check(host, user, domain, ng)
  434.     const char    *host;
  435.     const char    *user;
  436.     const char    *domain;
  437.     struct netgroup    *ng;
  438. {
  439.     if ((host != NULL) && (ng->ng_host != NULL)
  440.         && strcmp(ng->ng_host, host) != 0)
  441.         return 0;
  442.  
  443.     if ((user != NULL) && (ng->ng_user != NULL)
  444.         && strcmp(ng->ng_user, user) != 0)
  445.         return 0;
  446.  
  447.     if ((domain != NULL) && (ng->ng_domain != NULL)
  448.         && strcmp(ng->ng_domain, domain) != 0)
  449.         return 0;
  450.  
  451.     return 1;
  452. }
  453.  
  454.  
  455. /*
  456.  * in_find(): Find a match for the host, user, domain spec
  457.  */
  458. static int
  459. in_find(ypdom, sl, grp, host, user, domain)
  460.     char            *ypdom;
  461.     struct stringlist    *sl;
  462.     char            *grp;
  463.     const char        *host;
  464.     const char        *user;
  465.     const char        *domain;
  466. {
  467.     char        *line, *p;
  468.     int         i;
  469.     struct netgroup    *ng;
  470.     char        *name;
  471.  
  472. #ifdef DEBUG_NG
  473.     (void) fprintf(stderr, "in_find(%s)\n", grp);
  474. #endif
  475.     /* check for cycles */
  476.     if (_ng_sl_find(sl, grp) != NULL) {
  477.         free(grp);
  478.         _warnx("netgroup: Cycle in group `%s'", grp);
  479.         return 0;
  480.     }
  481.     _ng_sl_add(sl, grp);
  482.  
  483.     /* Lookup this netgroup */
  484.     if (!lookup(ypdom, grp, &line, _NG_KEYBYNAME))
  485.         return 0;
  486.  
  487.     p = line;
  488.  
  489.     for (;;) {
  490.         switch (_ng_parse(&p, &name, &ng)) {
  491.         case _NG_NONE:
  492.             /* Done with the line */
  493.             free(line);
  494.             return 0;
  495.  
  496.         case _NG_GROUP:
  497.             /* new netgroup */
  498.             i = in_check(host, user, domain, ng);
  499.             if (ng->ng_host != NULL)
  500.                 free(ng->ng_host);
  501.             if (ng->ng_user != NULL)
  502.                 free(ng->ng_user);
  503.             if (ng->ng_domain != NULL)
  504.                 free(ng->ng_domain);
  505.             free(ng);
  506.             if (i) {
  507.                 free(line);
  508.                 return 1;
  509.             }
  510.             break;
  511.  
  512.         case _NG_NAME:
  513.             /* netgroup name */
  514.             if (in_find(ypdom, sl, name, host, user, domain)) {
  515.                 free(line);
  516.                 return 1;
  517.             }
  518.             break;
  519.  
  520.         case _NG_ERROR:
  521.             free(line);
  522.             return 0;
  523.  
  524.         default:
  525.             abort();
  526.             return 0;
  527.         }
  528.     }
  529. }
  530.  
  531.  
  532. /*
  533.  * _ng_makekey(): Make a key from the two names given. The key is of the form
  534.  * <name1>.<name2> Names strings are replaced with * if they are empty;
  535.  */
  536. char *
  537. _ng_makekey(s1, s2, len)
  538.     const char    *s1, *s2;
  539.     size_t         len;
  540. {
  541.     char *buf = malloc(len);
  542.     if (buf == NULL)
  543.         _err(1, _ngoomem);
  544.     (void) snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2));
  545.     return buf;
  546. }
  547.  
  548.  
  549. /*
  550.  * in_lookup1(): Fast lookup for a key in the appropriate map
  551.  */
  552. static char *
  553. in_lookup1(ypdom, key, domain, map)
  554.     const char    *ypdom;
  555.     const char    *key;
  556.     const char    *domain;
  557.     int         map;
  558. {
  559.     char    *line;
  560.     size_t     len;
  561.     char    *ptr;
  562.     int     res;
  563.  
  564.     len = (key ? strlen(key) : 1) + (domain ? strlen(domain) : 1) + 2;
  565.     ptr = _ng_makekey(key, domain, len);
  566.     res = lookup(ypdom, ptr, &line, map);
  567.     free(ptr);
  568.     return res ? line : NULL;
  569. }
  570.  
  571.  
  572. /*
  573.  * in_lookup(): Fast lookup for a key in the appropriate map
  574.  */
  575. static int
  576. in_lookup(ypdom, group, key, domain, map)
  577.     const char    *ypdom;
  578.     const char    *group;
  579.     const char    *key;
  580.     const char    *domain;
  581.     int         map;
  582. {
  583.     size_t     len;
  584.     char    *ptr, *line;
  585.  
  586.     if (domain != NULL) {
  587.         /* Domain specified; look in "group.domain" and "*.domain" */
  588.         if ((line = in_lookup1(ypdom, key, domain, map)) == NULL)
  589.             line = in_lookup1(ypdom, NULL, domain, map);
  590.     }
  591.     else 
  592.         line = NULL;
  593.  
  594.     if (line == NULL) {
  595.         /* 
  596.          * domain not specified or domain lookup failed; look in
  597.          * "group.*" and "*.*"
  598.          */
  599.         if (((line = in_lookup1(ypdom, key, NULL, map)) == NULL) &&
  600.         ((line = in_lookup1(ypdom, NULL, NULL, map)) == NULL))
  601.         return 0;
  602.     }
  603.  
  604.     len = strlen(group);
  605.  
  606.     for (ptr = line; (ptr = strstr(ptr, group)) != NULL;)
  607.         /* Make sure we did not find a substring */
  608.         if ((ptr != line && ptr[-1] != ',') ||
  609.             (ptr[len] != '\0' && strchr("\n\t ,", ptr[len]) == NULL))
  610.             ptr++;
  611.         else {
  612.             free(line);
  613.             return 1;
  614.         }
  615.  
  616.     free(line);
  617.     return 0;
  618. }
  619.  
  620.  
  621. void
  622. endnetgrent()
  623. {
  624.     for (_nglist = _nghead; _nglist != NULL; _nglist = _nghead) {
  625.         _nghead = _nglist->ng_next;
  626.         if (_nglist->ng_host != NULL)
  627.             free(_nglist->ng_host);
  628.         if (_nglist->ng_user != NULL)
  629.             free(_nglist->ng_user);
  630.         if (_nglist->ng_domain != NULL)
  631.             free(_nglist->ng_domain);
  632.         free(_nglist);
  633.     }
  634.  
  635.     if (_ng_db) {
  636.         (void) (_ng_db->close) (_ng_db);
  637.         _ng_db = NULL;
  638.     }
  639. }
  640.  
  641.  
  642. void
  643. setnetgrent(ng)
  644.     const char    *ng;
  645. {
  646.     struct stringlist    *sl = _ng_sl_init();
  647. #ifdef YP
  648.     char            *line;
  649. #endif
  650.     char            *ng_copy, *ypdom = NULL;
  651.  
  652.     /* Cleanup any previous storage */
  653.     if (_nghead != NULL)
  654.         endnetgrent();
  655.  
  656.     if (_ng_db == NULL)
  657.         _ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
  658.  
  659. #ifdef YP
  660.     /*
  661.      * We use yp if there is a "+" in the netgroup file, or if there is
  662.      * no netgroup file at all
  663.      */
  664.     if (_ng_db == NULL || lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0)
  665.         yp_get_default_domain(&ypdom);
  666.     else
  667.         free(line);
  668. #endif
  669.     ng_copy = strdup(ng);
  670.     if (ng_copy == NULL)
  671.         _err(1, _ngoomem);
  672.     addgroup(ypdom, sl, ng_copy);
  673.     _nghead = _nglist;
  674.     _ng_sl_free(sl, 1);
  675. }
  676.  
  677.  
  678. int
  679. getnetgrent(host, user, domain)
  680.     const char    **host;
  681.     const char    **user;
  682.     const char    **domain;
  683. {
  684.     if (_nglist == NULL)
  685.         return 0;
  686.  
  687.     *host   = _nglist->ng_host;
  688.     *user   = _nglist->ng_user;
  689.     *domain = _nglist->ng_domain;
  690.  
  691.     _nglist = _nglist->ng_next;
  692.  
  693.     return 1;
  694. }
  695.  
  696.  
  697. int
  698. innetgr(grp, host, user, domain)
  699.     const char    *grp, *host, *user, *domain;
  700. {
  701.     char    *ypdom = NULL;
  702. #ifdef YP
  703.     char    *line;
  704. #endif
  705.     int     found;
  706.     struct stringlist *sl;
  707.  
  708.     if (_ng_db == NULL)
  709.         _ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
  710.  
  711. #ifdef YP
  712.     /*
  713.      * We use yp if there is a "+" in the netgroup file, or if there is
  714.      * no netgroup file at all
  715.      */
  716.     if (_ng_db == NULL)
  717.         yp_get_default_domain(&ypdom);
  718.     else if (lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) {
  719.         yp_get_default_domain(&ypdom);
  720.         free(line);
  721.     }
  722. #endif
  723.  
  724.     /* Try the fast lookup first */
  725.     if (host != NULL && user == NULL) {
  726.         if (in_lookup(ypdom, grp, host, domain, _NG_KEYBYHOST))
  727.             return 1;
  728.     } else if (host == NULL && user != NULL) {
  729.         if (in_lookup(ypdom, grp, user, domain, _NG_KEYBYUSER))
  730.             return 1;
  731.     }
  732.     /* If a domainname is given, we would have found a match */
  733.     if (domain != NULL)
  734.         return 0;
  735.  
  736.     /* Too bad need the slow recursive way */
  737.     sl = _ng_sl_init();
  738.     found = in_find(ypdom, sl, strdup(grp), host, user, domain);
  739.     _ng_sl_free(sl, 1);
  740.  
  741.     return found;
  742. }
  743.