summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/getnetgrent.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen/getnetgrent.c')
-rw-r--r--lib/libc/gen/getnetgrent.c632
1 files changed, 0 insertions, 632 deletions
diff --git a/lib/libc/gen/getnetgrent.c b/lib/libc/gen/getnetgrent.c
deleted file mode 100644
index cc04f2f..0000000
--- a/lib/libc/gen/getnetgrent.c
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Rick Macklem at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)getnetgrent.c 8.2 (Berkeley) 4/27/95";
-#endif /* LIBC_SCCS and not lint */
-
-#include <stdio.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifdef YP
-/*
- * Notes:
- * We want to be able to use NIS netgroups properly while retaining
- * the ability to use a local /etc/netgroup file. Unfortunately, you
- * can't really do both at the same time - at least, not efficiently.
- * NetBSD deals with this problem by creating a netgroup database
- * using Berkeley DB (just like the password database) that allows
- * for lookups using netgroup, netgroup.byuser or netgroup.byhost
- * searches. This is a neat idea, but I don't have time to implement
- * something like that now. (I think ultimately it would be nice
- * if we DB-fied the group and netgroup stuff all in one shot, but
- * for now I'm satisfied just to have something that works well
- * without requiring massive code changes.)
- *
- * Therefore, to still permit the use of the local file and maintain
- * optimum NIS performance, we allow for the following conditions:
- *
- * - If /etc/netgroup does not exist and NIS is turned on, we use
- * NIS netgroups only.
- *
- * - If /etc/netgroup exists but is empty, we use NIS netgroups
- * only.
- *
- * - If /etc/netgroup exists and contains _only_ a '+', we use
- * NIS netgroups only.
- *
- * - If /etc/netgroup exists, contains locally defined netgroups
- * and a '+', we use a mixture of NIS and the local entries.
- * This method should return the same NIS data as just using
- * NIS alone, but it will be slower if the NIS netgroup database
- * is large (innetgr() in particular will suffer since extra
- * processing has to be done in order to determine memberships
- * using just the raw netgroup data).
- *
- * - If /etc/netgroup exists and contains only locally defined
- * netgroup entries, we use just those local entries and ignore
- * NIS (this is the original, pre-NIS behavior).
- */
-
-#include <rpc/rpc.h>
-#include <rpcsvc/yp_prot.h>
-#include <rpcsvc/ypclnt.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/errno.h>
-static char *_netgr_yp_domain;
-int _use_only_yp;
-static int _netgr_yp_enabled;
-static int _yp_innetgr;
-#endif
-
-#ifndef _PATH_NETGROUP
-#define _PATH_NETGROUP "/etc/netgroup"
-#endif
-
-/*
- * Static Variables and functions used by setnetgrent(), getnetgrent() and
- * endnetgrent().
- * There are two linked lists:
- * - linelist is just used by setnetgrent() to parse the net group file via.
- * parse_netgrp()
- * - netgrp is the list of entries for the current netgroup
- */
-struct linelist {
- struct linelist *l_next; /* Chain ptr. */
- int l_parsed; /* Flag for cycles */
- char *l_groupname; /* Name of netgroup */
- char *l_line; /* Netgroup entrie(s) to be parsed */
-};
-
-struct netgrp {
- struct netgrp *ng_next; /* Chain ptr */
- char *ng_str[3]; /* Field pointers, see below */
-};
-#define NG_HOST 0 /* Host name */
-#define NG_USER 1 /* User name */
-#define NG_DOM 2 /* and Domain name */
-
-static struct linelist *linehead = (struct linelist *)0;
-static struct netgrp *nextgrp = (struct netgrp *)0;
-static struct {
- struct netgrp *gr;
- char *grname;
-} grouphead = {
- (struct netgrp *)0,
- (char *)0,
-};
-static FILE *netf = (FILE *)0;
-static int parse_netgrp();
-static struct linelist *read_for_group();
-void setnetgrent(), endnetgrent();
-int getnetgrent(), innetgr();
-
-#define LINSIZ 1024 /* Length of netgroup file line */
-
-/*
- * setnetgrent()
- * Parse the netgroup file looking for the netgroup and build the list
- * of netgrp structures. Let parse_netgrp() and read_for_group() do
- * most of the work.
- */
-void
-setnetgrent(group)
- char *group;
-{
-#ifdef YP
- struct stat _yp_statp;
- char _yp_plus;
-#endif
-
- /* Sanity check */
-
- if (group == NULL || !strlen(group))
- return;
-
- if (grouphead.gr == (struct netgrp *)0 ||
- strcmp(group, grouphead.grname)) {
- endnetgrent();
-#ifdef YP
- /* Presumed guilty until proven innocent. */
- _use_only_yp = 0;
- /*
- * If /etc/netgroup doesn't exist or is empty,
- * use NIS exclusively.
- */
- if (((stat(_PATH_NETGROUP, &_yp_statp) < 0) &&
- errno == ENOENT) || _yp_statp.st_size == 0)
- _use_only_yp = _netgr_yp_enabled = 1;
- if ((netf = fopen(_PATH_NETGROUP,"r")) != NULL ||_use_only_yp){
- /*
- * Icky: grab the first character of the netgroup file
- * and turn on NIS if it's a '+'. rewind the stream
- * afterwards so we don't goof up read_for_group() later.
- */
- if (netf) {
- fscanf(netf, "%c", &_yp_plus);
- rewind(netf);
- if (_yp_plus == '+')
- _use_only_yp = _netgr_yp_enabled = 1;
- }
- /*
- * If we were called specifically for an innetgr()
- * lookup and we're in NIS-only mode, short-circuit
- * parse_netgroup() and cut directly to the chase.
- */
- if (_use_only_yp && _yp_innetgr) {
- /* dohw! */
- if (netf != NULL)
- fclose(netf);
- return;
- }
-#else
- if (netf = fopen(_PATH_NETGROUP, "r")) {
-#endif
- if (parse_netgrp(group))
- endnetgrent();
- else {
- grouphead.grname = (char *)
- malloc(strlen(group) + 1);
- strcpy(grouphead.grname, group);
- }
- if (netf)
- fclose(netf);
- }
- }
- nextgrp = grouphead.gr;
-}
-
-/*
- * Get the next netgroup off the list.
- */
-int
-getnetgrent(hostp, userp, domp)
- char **hostp, **userp, **domp;
-{
-#ifdef YP
- _yp_innetgr = 0;
-#endif
-
- if (nextgrp) {
- *hostp = nextgrp->ng_str[NG_HOST];
- *userp = nextgrp->ng_str[NG_USER];
- *domp = nextgrp->ng_str[NG_DOM];
- nextgrp = nextgrp->ng_next;
- return (1);
- }
- return (0);
-}
-
-/*
- * endnetgrent() - cleanup
- */
-void
-endnetgrent()
-{
- register struct linelist *lp, *olp;
- register struct netgrp *gp, *ogp;
-
- lp = linehead;
- while (lp) {
- olp = lp;
- lp = lp->l_next;
- free(olp->l_groupname);
- free(olp->l_line);
- free((char *)olp);
- }
- linehead = (struct linelist *)0;
- if (grouphead.grname) {
- free(grouphead.grname);
- grouphead.grname = (char *)0;
- }
- gp = grouphead.gr;
- while (gp) {
- ogp = gp;
- gp = gp->ng_next;
- if (ogp->ng_str[NG_HOST])
- free(ogp->ng_str[NG_HOST]);
- if (ogp->ng_str[NG_USER])
- free(ogp->ng_str[NG_USER]);
- if (ogp->ng_str[NG_DOM])
- free(ogp->ng_str[NG_DOM]);
- free((char *)ogp);
- }
- grouphead.gr = (struct netgrp *)0;
-#ifdef YP
- _netgr_yp_enabled = 0;
-#endif
-}
-
-#ifdef YP
-static int _listmatch(list, group, len)
- char *list, *group;
- int len;
-{
- char *ptr = list, *cptr;
- int glen = strlen(group);
-
- /* skip possible leading whitespace */
- while(isspace(*ptr))
- ptr++;
-
- while (ptr < list + len) {
- cptr = ptr;
- while(*ptr != ',' && !isspace(*ptr))
- ptr++;
- if (strncmp(cptr, group, glen) == 0 && glen == (ptr - cptr))
- return(1);
- while(*ptr == ',' || isspace(*ptr))
- ptr++;
- }
-
- return(0);
-}
-
-static int _buildkey(key, str, dom, rotation)
-char *key, *str, *dom;
-int *rotation;
-{
- (*rotation)++;
- if (*rotation > 4)
- return(0);
- switch(*rotation) {
- case(1): sprintf((char *)key, "%s.%s", str, dom ? dom : "*");
- break;
- case(2): sprintf((char *)key, "%s.*", str);
- break;
- case(3): sprintf((char *)key, "*.%s", dom ? dom : "*");
- break;
- case(4): sprintf((char *)key, "*.*");
- break;
- }
- return(1);
-}
-#endif
-
-/*
- * Search for a match in a netgroup.
- */
-int
-innetgr(group, host, user, dom)
- const char *group, *host, *user, *dom;
-{
- char *hst, *usr, *dm;
-#ifdef YP
- char *result;
- int resultlen;
- int rv;
-#endif
- /* Sanity check */
-
- if (group == NULL || !strlen(group))
- return (0);
-
-#ifdef YP
- _yp_innetgr = 1;
-#endif
- setnetgrent(group);
-#ifdef YP
- _yp_innetgr = 0;
- /*
- * If we're in NIS-only mode, do the search using
- * NIS 'reverse netgroup' lookups.
- */
- if (_use_only_yp) {
- char _key[MAXHOSTNAMELEN];
- int rot = 0, y = 0;
-
- if(yp_get_default_domain(&_netgr_yp_domain))
- return(0);
- while(_buildkey(_key, user ? user : host, dom, &rot)) {
- y = yp_match(_netgr_yp_domain, user? "netgroup.byuser":
- "netgroup.byhost", _key, strlen(_key), &result,
- &resultlen);
- if (y) {
- /*
- * If we get an error other than 'no
- * such key in map' then something is
- * wrong and we should stop the search.
- */
- if (y != YPERR_KEY)
- break;
- } else {
- rv = _listmatch(result, group, resultlen);
- free(result);
- if (rv)
- return(1);
- else
- return(0);
- }
- }
- /*
- * Couldn't match using NIS-exclusive mode. If the error
- * was YPERR_MAP, then the failure happened because there
- * was no netgroup.byhost or netgroup.byuser map. The odds
- * are we are talking to an Sun NIS+ server in YP emulation
- * mode; if this is the case, then we have to do the check
- * the 'old-fashioned' way by grovelling through the netgroup
- * map and resolving memberships on the fly.
- */
- if (y != YPERR_MAP)
- return(0);
- }
-
- setnetgrent(group);
-#endif /* YP */
-
- while (getnetgrent(&hst, &usr, &dm))
- if ((host == NULL || hst == NULL || !strcmp(host, hst)) &&
- (user == NULL || usr == NULL || !strcmp(user, usr)) &&
- ( dom == NULL || dm == NULL || !strcmp(dom, dm))) {
- endnetgrent();
- return (1);
- }
- endnetgrent();
- return (0);
-}
-
-/*
- * Parse the netgroup file setting up the linked lists.
- */
-static int
-parse_netgrp(group)
- char *group;
-{
- register char *spos, *epos;
- register int len, strpos;
-#ifdef DEBUG
- register int fields;
-#endif
- char *pos, *gpos;
- struct netgrp *grp;
- struct linelist *lp = linehead;
-
- /*
- * First, see if the line has already been read in.
- */
- while (lp) {
- if (!strcmp(group, lp->l_groupname))
- break;
- lp = lp->l_next;
- }
- if (lp == (struct linelist *)0 &&
- (lp = read_for_group(group)) == (struct linelist *)0)
- return (1);
- if (lp->l_parsed) {
-#ifdef DEBUG
- /*
- * This error message is largely superflous since the
- * code handles the error condition sucessfully, and
- * spewing it out from inside libc can actually hose
- * certain programs.
- */
- fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);
-#endif
- return (1);
- } else
- lp->l_parsed = 1;
- pos = lp->l_line;
- /* Watch for null pointer dereferences, dammit! */
- while (pos != NULL && *pos != '\0') {
- if (*pos == '(') {
- grp = (struct netgrp *)malloc(sizeof (struct netgrp));
- bzero((char *)grp, sizeof (struct netgrp));
- grp->ng_next = grouphead.gr;
- grouphead.gr = grp;
- pos++;
- gpos = strsep(&pos, ")");
-#ifdef DEBUG
- fields = 0;
-#endif
- for (strpos = 0; strpos < 3; strpos++) {
- if ((spos = strsep(&gpos, ","))) {
-#ifdef DEBUG
- fields++;
-#endif
- while (*spos == ' ' || *spos == '\t')
- spos++;
- if ((epos = strpbrk(spos, " \t"))) {
- *epos = '\0';
- len = epos - spos;
- } else
- len = strlen(spos);
- if (len > 0) {
- grp->ng_str[strpos] = (char *)
- malloc(len + 1);
- bcopy(spos, grp->ng_str[strpos],
- len + 1);
- }
- } else {
- /*
- * All other systems I've tested
- * return NULL for empty netgroup
- * fields. It's up to user programs
- * to handle the NULLs appropriately.
- */
- grp->ng_str[strpos] = NULL;
- }
- }
-#ifdef DEBUG
- /*
- * Note: on other platforms, malformed netgroup
- * entries are not normally flagged. While we
- * can catch bad entries and report them, we should
- * stay silent by default for compatibility's sake.
- */
- if (fields < 3)
- fprintf(stderr, "Bad entry (%s%s%s%s%s) in netgroup \"%s\"\n",
- grp->ng_str[NG_HOST] == NULL ? "" : grp->ng_str[NG_HOST],
- grp->ng_str[NG_USER] == NULL ? "" : ",",
- grp->ng_str[NG_USER] == NULL ? "" : grp->ng_str[NG_USER],
- grp->ng_str[NG_DOM] == NULL ? "" : ",",
- grp->ng_str[NG_DOM] == NULL ? "" : grp->ng_str[NG_DOM],
- lp->l_groupname);
-#endif
- } else {
- spos = strsep(&pos, ", \t");
- if (parse_netgrp(spos))
- continue;
- }
- if (pos == NULL)
- break;
- while (*pos == ' ' || *pos == ',' || *pos == '\t')
- pos++;
- }
- return (0);
-}
-
-/*
- * Read the netgroup file and save lines until the line for the netgroup
- * is found. Return 1 if eof is encountered.
- */
-static struct linelist *
-read_for_group(group)
- char *group;
-{
- register char *pos, *spos, *linep, *olinep;
- register int len, olen;
- int cont;
- struct linelist *lp;
- char line[LINSIZ + 2];
-#ifdef YP
- char *result;
- int resultlen;
-
- while (_netgr_yp_enabled || fgets(line, LINSIZ, netf) != NULL) {
- if (_netgr_yp_enabled) {
- if(!_netgr_yp_domain)
- if(yp_get_default_domain(&_netgr_yp_domain))
- continue;
- if (yp_match(_netgr_yp_domain, "netgroup", group,
- strlen(group), &result, &resultlen)) {
- free(result);
- if (_use_only_yp)
- return ((struct linelist *)0);
- else {
- _netgr_yp_enabled = 0;
- continue;
- }
- }
- snprintf(line, LINSIZ, "%s %s", group, result);
- free(result);
- }
-#else
- while (fgets(line, LINSIZ, netf) != NULL) {
-#endif
- pos = (char *)&line;
-#ifdef YP
- if (*pos == '+') {
- _netgr_yp_enabled = 1;
- continue;
- }
-#endif
- if (*pos == '#')
- continue;
- while (*pos == ' ' || *pos == '\t')
- pos++;
- spos = pos;
- while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
- *pos != '\0')
- pos++;
- len = pos - spos;
- while (*pos == ' ' || *pos == '\t')
- pos++;
- if (*pos != '\n' && *pos != '\0') {
- lp = (struct linelist *)malloc(sizeof (*lp));
- lp->l_parsed = 0;
- lp->l_groupname = (char *)malloc(len + 1);
- bcopy(spos, lp->l_groupname, len);
- *(lp->l_groupname + len) = '\0';
- len = strlen(pos);
- olen = 0;
-
- /*
- * Loop around handling line continuations.
- */
- do {
- if (*(pos + len - 1) == '\n')
- len--;
- if (*(pos + len - 1) == '\\') {
- len--;
- cont = 1;
- } else
- cont = 0;
- if (len > 0) {
- linep = (char *)malloc(olen + len + 1);
- if (olen > 0) {
- bcopy(olinep, linep, olen);
- free(olinep);
- }
- bcopy(pos, linep + olen, len);
- olen += len;
- *(linep + olen) = '\0';
- olinep = linep;
- }
- if (cont) {
- if (fgets(line, LINSIZ, netf)) {
- pos = line;
- len = strlen(pos);
- } else
- cont = 0;
- }
- } while (cont);
- lp->l_line = linep;
- lp->l_next = linehead;
- linehead = lp;
-
- /*
- * If this is the one we wanted, we are done.
- */
- if (!strcmp(lp->l_groupname, group))
- return (lp);
- }
- }
-#ifdef YP
- /*
- * Yucky. The recursive nature of this whole mess might require
- * us to make more than one pass through the netgroup file.
- * This might be best left outside the #ifdef YP, but YP is
- * defined by default anyway, so I'll leave it like this
- * until I know better.
- */
- rewind(netf);
-#endif
- return ((struct linelist *)0);
-}
OpenPOWER on IntegriCloud