Home | History | Annotate | Line # | Download | only in gen
getnetgrent.c revision 1.1.1.2
      1      1.1  mycroft /*
      2      1.1  mycroft  * Copyright (c) 1992, 1993
      3      1.1  mycroft  *	The Regents of the University of California.  All rights reserved.
      4      1.1  mycroft  *
      5      1.1  mycroft  * This code is derived from software contributed to Berkeley by
      6      1.1  mycroft  * Rick Macklem at The University of Guelph.
      7      1.1  mycroft  *
      8      1.1  mycroft  * Redistribution and use in source and binary forms, with or without
      9      1.1  mycroft  * modification, are permitted provided that the following conditions
     10      1.1  mycroft  * are met:
     11      1.1  mycroft  * 1. Redistributions of source code must retain the above copyright
     12      1.1  mycroft  *    notice, this list of conditions and the following disclaimer.
     13      1.1  mycroft  * 2. Redistributions in binary form must reproduce the above copyright
     14      1.1  mycroft  *    notice, this list of conditions and the following disclaimer in the
     15      1.1  mycroft  *    documentation and/or other materials provided with the distribution.
     16      1.1  mycroft  * 3. All advertising materials mentioning features or use of this software
     17      1.1  mycroft  *    must display the following acknowledgement:
     18      1.1  mycroft  *	This product includes software developed by the University of
     19      1.1  mycroft  *	California, Berkeley and its contributors.
     20      1.1  mycroft  * 4. Neither the name of the University nor the names of its contributors
     21      1.1  mycroft  *    may be used to endorse or promote products derived from this software
     22      1.1  mycroft  *    without specific prior written permission.
     23      1.1  mycroft  *
     24      1.1  mycroft  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25      1.1  mycroft  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26      1.1  mycroft  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27      1.1  mycroft  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28      1.1  mycroft  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29      1.1  mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30      1.1  mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31      1.1  mycroft  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32      1.1  mycroft  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33      1.1  mycroft  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34      1.1  mycroft  * SUCH DAMAGE.
     35      1.1  mycroft  */
     36      1.1  mycroft 
     37      1.1  mycroft #if defined(LIBC_SCCS) && !defined(lint)
     38  1.1.1.2    perry static char sccsid[] = "@(#)getnetgrent.c	8.2 (Berkeley) 4/27/95";
     39      1.1  mycroft #endif /* LIBC_SCCS and not lint */
     40      1.1  mycroft 
     41      1.1  mycroft #include <stdio.h>
     42      1.1  mycroft #include <strings.h>
     43      1.1  mycroft 
     44      1.1  mycroft #define _PATH_NETGROUP "/etc/netgroup"
     45      1.1  mycroft 
     46      1.1  mycroft /*
     47      1.1  mycroft  * Static Variables and functions used by setnetgrent(), getnetgrent() and
     48      1.1  mycroft  * endnetgrent().
     49      1.1  mycroft  * There are two linked lists:
     50      1.1  mycroft  * - linelist is just used by setnetgrent() to parse the net group file via.
     51      1.1  mycroft  *   parse_netgrp()
     52      1.1  mycroft  * - netgrp is the list of entries for the current netgroup
     53      1.1  mycroft  */
     54      1.1  mycroft struct linelist {
     55      1.1  mycroft 	struct linelist	*l_next;	/* Chain ptr. */
     56      1.1  mycroft 	int		l_parsed;	/* Flag for cycles */
     57      1.1  mycroft 	char		*l_groupname;	/* Name of netgroup */
     58      1.1  mycroft 	char		*l_line;	/* Netgroup entrie(s) to be parsed */
     59      1.1  mycroft };
     60      1.1  mycroft 
     61      1.1  mycroft struct netgrp {
     62      1.1  mycroft 	struct netgrp	*ng_next;	/* Chain ptr */
     63      1.1  mycroft 	char		*ng_str[3];	/* Field pointers, see below */
     64      1.1  mycroft };
     65      1.1  mycroft #define NG_HOST		0	/* Host name */
     66      1.1  mycroft #define NG_USER		1	/* User name */
     67      1.1  mycroft #define NG_DOM		2	/* and Domain name */
     68      1.1  mycroft 
     69      1.1  mycroft static struct linelist	*linehead = (struct linelist *)0;
     70      1.1  mycroft static struct netgrp	*nextgrp = (struct netgrp *)0;
     71      1.1  mycroft static struct {
     72      1.1  mycroft 	struct netgrp	*gr;
     73      1.1  mycroft 	char		*grname;
     74      1.1  mycroft } grouphead = {
     75      1.1  mycroft 	(struct netgrp *)0,
     76      1.1  mycroft 	(char *)0,
     77      1.1  mycroft };
     78      1.1  mycroft static FILE *netf = (FILE *)0;
     79      1.1  mycroft static int parse_netgrp();
     80      1.1  mycroft static struct linelist *read_for_group();
     81      1.1  mycroft void setnetgrent(), endnetgrent();
     82      1.1  mycroft int getnetgrent(), innetgr();
     83      1.1  mycroft 
     84      1.1  mycroft #define	LINSIZ	1024	/* Length of netgroup file line */
     85      1.1  mycroft 
     86      1.1  mycroft /*
     87      1.1  mycroft  * setnetgrent()
     88      1.1  mycroft  * Parse the netgroup file looking for the netgroup and build the list
     89      1.1  mycroft  * of netgrp structures. Let parse_netgrp() and read_for_group() do
     90      1.1  mycroft  * most of the work.
     91      1.1  mycroft  */
     92      1.1  mycroft void
     93      1.1  mycroft setnetgrent(group)
     94      1.1  mycroft 	char *group;
     95      1.1  mycroft {
     96      1.1  mycroft 
     97      1.1  mycroft 	if (grouphead.gr == (struct netgrp *)0 ||
     98      1.1  mycroft 		strcmp(group, grouphead.grname)) {
     99      1.1  mycroft 		endnetgrent();
    100      1.1  mycroft 		if (netf = fopen(_PATH_NETGROUP, "r")) {
    101      1.1  mycroft 			if (parse_netgrp(group))
    102      1.1  mycroft 				endnetgrent();
    103      1.1  mycroft 			else {
    104      1.1  mycroft 				grouphead.grname = (char *)
    105      1.1  mycroft 					malloc(strlen(group) + 1);
    106      1.1  mycroft 				strcpy(grouphead.grname, group);
    107      1.1  mycroft 			}
    108      1.1  mycroft 			fclose(netf);
    109      1.1  mycroft 		}
    110      1.1  mycroft 	}
    111      1.1  mycroft 	nextgrp = grouphead.gr;
    112      1.1  mycroft }
    113      1.1  mycroft 
    114      1.1  mycroft /*
    115      1.1  mycroft  * Get the next netgroup off the list.
    116      1.1  mycroft  */
    117      1.1  mycroft int
    118      1.1  mycroft getnetgrent(hostp, userp, domp)
    119      1.1  mycroft 	char **hostp, **userp, **domp;
    120      1.1  mycroft {
    121      1.1  mycroft 
    122      1.1  mycroft 	if (nextgrp) {
    123      1.1  mycroft 		*hostp = nextgrp->ng_str[NG_HOST];
    124      1.1  mycroft 		*userp = nextgrp->ng_str[NG_USER];
    125      1.1  mycroft 		*domp = nextgrp->ng_str[NG_DOM];
    126      1.1  mycroft 		nextgrp = nextgrp->ng_next;
    127      1.1  mycroft 		return (1);
    128      1.1  mycroft 	}
    129      1.1  mycroft 	return (0);
    130      1.1  mycroft }
    131      1.1  mycroft 
    132      1.1  mycroft /*
    133      1.1  mycroft  * endnetgrent() - cleanup
    134      1.1  mycroft  */
    135      1.1  mycroft void
    136      1.1  mycroft endnetgrent()
    137      1.1  mycroft {
    138      1.1  mycroft 	register struct linelist *lp, *olp;
    139      1.1  mycroft 	register struct netgrp *gp, *ogp;
    140      1.1  mycroft 
    141      1.1  mycroft 	lp = linehead;
    142      1.1  mycroft 	while (lp) {
    143      1.1  mycroft 		olp = lp;
    144      1.1  mycroft 		lp = lp->l_next;
    145      1.1  mycroft 		free(olp->l_groupname);
    146      1.1  mycroft 		free(olp->l_line);
    147      1.1  mycroft 		free((char *)olp);
    148      1.1  mycroft 	}
    149      1.1  mycroft 	linehead = (struct linelist *)0;
    150      1.1  mycroft 	if (grouphead.grname) {
    151      1.1  mycroft 		free(grouphead.grname);
    152      1.1  mycroft 		grouphead.grname = (char *)0;
    153      1.1  mycroft 	}
    154      1.1  mycroft 	gp = grouphead.gr;
    155      1.1  mycroft 	while (gp) {
    156      1.1  mycroft 		ogp = gp;
    157      1.1  mycroft 		gp = gp->ng_next;
    158      1.1  mycroft 		if (ogp->ng_str[NG_HOST])
    159      1.1  mycroft 			free(ogp->ng_str[NG_HOST]);
    160      1.1  mycroft 		if (ogp->ng_str[NG_USER])
    161      1.1  mycroft 			free(ogp->ng_str[NG_USER]);
    162      1.1  mycroft 		if (ogp->ng_str[NG_DOM])
    163      1.1  mycroft 			free(ogp->ng_str[NG_DOM]);
    164      1.1  mycroft 		free((char *)ogp);
    165      1.1  mycroft 	}
    166      1.1  mycroft 	grouphead.gr = (struct netgrp *)0;
    167      1.1  mycroft }
    168      1.1  mycroft 
    169      1.1  mycroft /*
    170      1.1  mycroft  * Search for a match in a netgroup.
    171      1.1  mycroft  */
    172      1.1  mycroft int
    173      1.1  mycroft innetgr(group, host, user, dom)
    174      1.1  mycroft 	char *group, *host, *user, *dom;
    175      1.1  mycroft {
    176      1.1  mycroft 	char *hst, *usr, *dm;
    177      1.1  mycroft 
    178      1.1  mycroft 	setnetgrent(group);
    179      1.1  mycroft 	while (getnetgrent(&hst, &usr, &dm))
    180      1.1  mycroft 		if ((host == (char *)0 || !strcmp(host, hst)) &&
    181      1.1  mycroft 		    (user == (char *)0 || !strcmp(user, usr)) &&
    182      1.1  mycroft 		    (dom == (char *)0 || !strcmp(dom, dm))) {
    183      1.1  mycroft 			endnetgrent();
    184      1.1  mycroft 			return (1);
    185      1.1  mycroft 		}
    186      1.1  mycroft 	endnetgrent();
    187      1.1  mycroft 	return (0);
    188      1.1  mycroft }
    189      1.1  mycroft 
    190      1.1  mycroft /*
    191      1.1  mycroft  * Parse the netgroup file setting up the linked lists.
    192      1.1  mycroft  */
    193      1.1  mycroft static int
    194      1.1  mycroft parse_netgrp(group)
    195      1.1  mycroft 	char *group;
    196      1.1  mycroft {
    197      1.1  mycroft 	register char *spos, *epos;
    198      1.1  mycroft 	register int len, strpos;
    199      1.1  mycroft 	char *pos, *gpos;
    200      1.1  mycroft 	struct netgrp *grp;
    201      1.1  mycroft 	struct linelist *lp = linehead;
    202      1.1  mycroft 
    203      1.1  mycroft 	/*
    204      1.1  mycroft 	 * First, see if the line has already been read in.
    205      1.1  mycroft 	 */
    206      1.1  mycroft 	while (lp) {
    207      1.1  mycroft 		if (!strcmp(group, lp->l_groupname))
    208      1.1  mycroft 			break;
    209      1.1  mycroft 		lp = lp->l_next;
    210      1.1  mycroft 	}
    211      1.1  mycroft 	if (lp == (struct linelist *)0 &&
    212      1.1  mycroft 	    (lp = read_for_group(group)) == (struct linelist *)0)
    213      1.1  mycroft 		return (1);
    214      1.1  mycroft 	if (lp->l_parsed) {
    215      1.1  mycroft 		fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);
    216      1.1  mycroft 		return (1);
    217      1.1  mycroft 	} else
    218      1.1  mycroft 		lp->l_parsed = 1;
    219      1.1  mycroft 	pos = lp->l_line;
    220      1.1  mycroft 	while (*pos != '\0') {
    221      1.1  mycroft 		if (*pos == '(') {
    222      1.1  mycroft 			grp = (struct netgrp *)malloc(sizeof (struct netgrp));
    223      1.1  mycroft 			bzero((char *)grp, sizeof (struct netgrp));
    224      1.1  mycroft 			grp->ng_next = grouphead.gr;
    225      1.1  mycroft 			grouphead.gr = grp;
    226      1.1  mycroft 			pos++;
    227      1.1  mycroft 			gpos = strsep(&pos, ")");
    228      1.1  mycroft 			for (strpos = 0; strpos < 3; strpos++) {
    229      1.1  mycroft 				if (spos = strsep(&gpos, ",")) {
    230      1.1  mycroft 					while (*spos == ' ' || *spos == '\t')
    231      1.1  mycroft 						spos++;
    232      1.1  mycroft 					if (epos = strpbrk(spos, " \t")) {
    233      1.1  mycroft 						*epos = '\0';
    234      1.1  mycroft 						len = epos - spos;
    235      1.1  mycroft 					} else
    236      1.1  mycroft 						len = strlen(spos);
    237      1.1  mycroft 					if (len > 0) {
    238      1.1  mycroft 						grp->ng_str[strpos] =  (char *)
    239      1.1  mycroft 							malloc(len + 1);
    240      1.1  mycroft 						bcopy(spos, grp->ng_str[strpos],
    241      1.1  mycroft 							len + 1);
    242      1.1  mycroft 					}
    243      1.1  mycroft 				} else
    244      1.1  mycroft 					goto errout;
    245      1.1  mycroft 			}
    246      1.1  mycroft 		} else {
    247      1.1  mycroft 			spos = strsep(&pos, ", \t");
    248      1.1  mycroft 			if (parse_netgrp(spos))
    249      1.1  mycroft 				return (1);
    250      1.1  mycroft 		}
    251  1.1.1.2    perry 		if (pos == NULL)
    252  1.1.1.2    perry 			break;
    253      1.1  mycroft 		while (*pos == ' ' || *pos == ',' || *pos == '\t')
    254      1.1  mycroft 			pos++;
    255      1.1  mycroft 	}
    256      1.1  mycroft 	return (0);
    257      1.1  mycroft errout:
    258      1.1  mycroft 	fprintf(stderr, "Bad netgroup %s at ..%s\n", lp->l_groupname,
    259      1.1  mycroft 		spos);
    260      1.1  mycroft 	return (1);
    261      1.1  mycroft }
    262      1.1  mycroft 
    263      1.1  mycroft /*
    264      1.1  mycroft  * Read the netgroup file and save lines until the line for the netgroup
    265      1.1  mycroft  * is found. Return 1 if eof is encountered.
    266      1.1  mycroft  */
    267      1.1  mycroft static struct linelist *
    268      1.1  mycroft read_for_group(group)
    269      1.1  mycroft 	char *group;
    270      1.1  mycroft {
    271      1.1  mycroft 	register char *pos, *spos, *linep, *olinep;
    272      1.1  mycroft 	register int len, olen;
    273      1.1  mycroft 	int cont;
    274      1.1  mycroft 	struct linelist *lp;
    275      1.1  mycroft 	char line[LINSIZ + 1];
    276      1.1  mycroft 
    277      1.1  mycroft 	while (fgets(line, LINSIZ, netf) != NULL) {
    278      1.1  mycroft 		pos = line;
    279      1.1  mycroft 		if (*pos == '#')
    280      1.1  mycroft 			continue;
    281      1.1  mycroft 		while (*pos == ' ' || *pos == '\t')
    282      1.1  mycroft 			pos++;
    283      1.1  mycroft 		spos = pos;
    284      1.1  mycroft 		while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
    285      1.1  mycroft 			*pos != '\0')
    286      1.1  mycroft 			pos++;
    287      1.1  mycroft 		len = pos - spos;
    288      1.1  mycroft 		while (*pos == ' ' || *pos == '\t')
    289      1.1  mycroft 			pos++;
    290      1.1  mycroft 		if (*pos != '\n' && *pos != '\0') {
    291      1.1  mycroft 			lp = (struct linelist *)malloc(sizeof (*lp));
    292      1.1  mycroft 			lp->l_parsed = 0;
    293      1.1  mycroft 			lp->l_groupname = (char *)malloc(len + 1);
    294      1.1  mycroft 			bcopy(spos, lp->l_groupname, len);
    295      1.1  mycroft 			*(lp->l_groupname + len) = '\0';
    296      1.1  mycroft 			len = strlen(pos);
    297      1.1  mycroft 			olen = 0;
    298      1.1  mycroft 
    299      1.1  mycroft 			/*
    300      1.1  mycroft 			 * Loop around handling line continuations.
    301      1.1  mycroft 			 */
    302      1.1  mycroft 			do {
    303      1.1  mycroft 				if (*(pos + len - 1) == '\n')
    304      1.1  mycroft 					len--;
    305      1.1  mycroft 				if (*(pos + len - 1) == '\\') {
    306      1.1  mycroft 					len--;
    307      1.1  mycroft 					cont = 1;
    308      1.1  mycroft 				} else
    309      1.1  mycroft 					cont = 0;
    310      1.1  mycroft 				if (len > 0) {
    311      1.1  mycroft 					linep = (char *)malloc(olen + len + 1);
    312      1.1  mycroft 					if (olen > 0) {
    313      1.1  mycroft 						bcopy(olinep, linep, olen);
    314      1.1  mycroft 						free(olinep);
    315      1.1  mycroft 					}
    316      1.1  mycroft 					bcopy(pos, linep + olen, len);
    317      1.1  mycroft 					olen += len;
    318      1.1  mycroft 					*(linep + olen) = '\0';
    319      1.1  mycroft 					olinep = linep;
    320      1.1  mycroft 				}
    321      1.1  mycroft 				if (cont) {
    322      1.1  mycroft 					if (fgets(line, LINSIZ, netf)) {
    323      1.1  mycroft 						pos = line;
    324      1.1  mycroft 						len = strlen(pos);
    325      1.1  mycroft 					} else
    326      1.1  mycroft 						cont = 0;
    327      1.1  mycroft 				}
    328      1.1  mycroft 			} while (cont);
    329      1.1  mycroft 			lp->l_line = linep;
    330      1.1  mycroft 			lp->l_next = linehead;
    331      1.1  mycroft 			linehead = lp;
    332      1.1  mycroft 
    333      1.1  mycroft 			/*
    334      1.1  mycroft 			 * If this is the one we wanted, we are done.
    335      1.1  mycroft 			 */
    336      1.1  mycroft 			if (!strcmp(lp->l_groupname, group))
    337      1.1  mycroft 				return (lp);
    338      1.1  mycroft 		}
    339      1.1  mycroft 	}
    340      1.1  mycroft 	return ((struct linelist *)0);
    341      1.1  mycroft }
    342