111814Swpaul/*
211814Swpaul * Copyright (c) 1995
311814Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
411814Swpaul *
511814Swpaul * Redistribution and use in source and binary forms, with or without
611814Swpaul * modification, are permitted provided that the following conditions
711814Swpaul * are met:
811814Swpaul * 1. Redistributions of source code must retain the above copyright
911814Swpaul *    notice, this list of conditions and the following disclaimer.
1011814Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1111814Swpaul *    notice, this list of conditions and the following disclaimer in the
1211814Swpaul *    documentation and/or other materials provided with the distribution.
1311814Swpaul * 3. All advertising materials mentioning features or use of this software
1411814Swpaul *    must display the following acknowledgement:
1511814Swpaul *	This product includes software developed by Bill Paul.
1611814Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1711814Swpaul *    may be used to endorse or promote products derived from this software
1811814Swpaul *    without specific prior written permission.
1911814Swpaul *
2011814Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2111814Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2211814Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2311814Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2411814Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2511814Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2611814Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2711814Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2811814Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2911814Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3011814Swpaul * SUCH DAMAGE.
3111814Swpaul *
3211814Swpaul * reverse netgroup map generator program
3311814Swpaul *
3411814Swpaul * Written by Bill Paul <wpaul@ctr.columbia.edu>
3511814Swpaul * Center for Telecommunications Research
3611814Swpaul * Columbia University, New York City
3711814Swpaul */
3811814Swpaul
3931404Scharnier#ifndef lint
4031404Scharnierstatic const char rcsid[] =
4150476Speter  "$FreeBSD$";
4231404Scharnier#endif /* not lint */
4331404Scharnier
4431404Scharnier#include <err.h>
4511814Swpaul#include <stdio.h>
4611814Swpaul#include <stdlib.h>
4711814Swpaul#include <string.h>
4831404Scharnier#include <unistd.h>
4911814Swpaul#include "hash.h"
5011814Swpaul
5111814Swpaul/* Default location of netgroup file. */
5211814Swpaulchar *netgroup = "/etc/netgroup";
5311814Swpaul
5411814Swpaul/* Stored hash table version of 'forward' netgroup database. */
5511814Swpaulstruct group_entry *gtable[TABLESIZE];
5611814Swpaul
5711814Swpaul/*
5811814Swpaul * Stored hash table of 'reverse' netgroup member database
5911814Swpaul * which we will construct.
6011814Swpaul */
6111814Swpaulstruct member_entry *mtable[TABLESIZE];
6211814Swpaul
6331404Scharnierstatic void
6490377Simpusage(void)
6511814Swpaul{
66141589Sru	fprintf (stderr,"usage: revnetgroup -u | -h [-f netgroup_file]\n");
6711814Swpaul	exit(1);
6811814Swpaul}
6911814Swpaul
7020387Swpaulint
7190377Simpmain(int argc, char *argv[])
7211814Swpaul{
7311814Swpaul	FILE *fp;
7411814Swpaul	char readbuf[LINSIZ];
7511814Swpaul	struct group_entry *gcur;
7611814Swpaul	struct member_entry *mcur;
7711814Swpaul	char *host, *user, *domain;
7815754Swpaul	int ch;
7911814Swpaul	char *key = NULL, *data = NULL;
8015754Swpaul	int hosts = -1, i;
8111814Swpaul
8211814Swpaul	if (argc < 2)
8331404Scharnier		usage();
8411814Swpaul
8524349Simp	while ((ch = getopt(argc, argv, "uhf:")) != -1) {
8611814Swpaul		switch(ch) {
8711814Swpaul		case 'u':
8815754Swpaul			if (hosts != -1) {
8915754Swpaul				warnx("please use only one of -u or -h");
9031404Scharnier				usage();
9115754Swpaul			}
9211814Swpaul			hosts = 0;
9311814Swpaul			break;
9411814Swpaul		case 'h':
9515754Swpaul			if (hosts != -1) {
9615754Swpaul				warnx("please use only one of -u or -h");
9731404Scharnier				usage();
9815754Swpaul			}
9911814Swpaul			hosts = 1;
10011814Swpaul			break;
10111814Swpaul		case 'f':
10211814Swpaul			netgroup = optarg;
10311814Swpaul			break;
10411814Swpaul		default:
10531404Scharnier			usage();
10611814Swpaul			break;
10711814Swpaul		}
10811814Swpaul	}
10911814Swpaul
11015754Swpaul	if (hosts == -1)
11131404Scharnier		usage();
11215754Swpaul
11311814Swpaul	if (strcmp(netgroup, "-")) {
11411814Swpaul		if ((fp = fopen(netgroup, "r")) == NULL) {
11562983Skris			err(1, "%s", netgroup);
11611814Swpaul		}
11711814Swpaul	} else {
11811814Swpaul		fp = stdin;
11911814Swpaul	}
12011814Swpaul
12111814Swpaul	/* Stuff all the netgroup names and members into a hash table. */
12211814Swpaul	while (fgets(readbuf, LINSIZ, fp)) {
12311814Swpaul		if (readbuf[0] == '#')
12411814Swpaul			continue;
12520387Swpaul		/* handle backslash line continuations */
12620387Swpaul		while(readbuf[strlen(readbuf) - 2] == '\\') {
12720387Swpaul			fgets((char *)&readbuf[strlen(readbuf) - 2],
12820387Swpaul					sizeof(readbuf) - strlen(readbuf), fp);
12920387Swpaul		}
13020387Swpaul		data = NULL;
13111814Swpaul		if ((data = (char *)(strpbrk(readbuf, " \t") + 1)) < (char *)2)
13211814Swpaul			continue;
13311814Swpaul		key = (char *)&readbuf;
13411814Swpaul		*(data - 1) = '\0';
13511814Swpaul		store(gtable, key, data);
13611814Swpaul	}
13711814Swpaul
13811814Swpaul	fclose(fp);
13911814Swpaul
14011814Swpaul	/*
14111814Swpaul	 * Find all members of each netgroup and keep track of which
14211814Swpaul	 * group they belong to.
14311814Swpaul	 */
14411814Swpaul	for (i = 0; i < TABLESIZE; i++) {
14511814Swpaul		gcur = gtable[i];
14611814Swpaul		while(gcur) {
14711814Swpaul			__setnetgrent(gcur->key);
14829574Sphk			while(__getnetgrent(&host, &user, &domain) != 0) {
14911814Swpaul				if (hosts ? host && strcmp(host,"-") : user && strcmp(user, "-"))
15011814Swpaul					mstore(mtable, hosts ? host : user, gcur->key, domain);
15111814Swpaul			}
15211814Swpaul			gcur = gcur->next;
15311814Swpaul		}
15411814Swpaul	}
15511814Swpaul
15611814Swpaul	/* Release resources used by the netgroup parser code. */
15711814Swpaul	__endnetgrent();
15811814Swpaul
15911814Swpaul	/* Spew out the results. */
16011814Swpaul	for (i = 0; i < TABLESIZE; i++) {
16111814Swpaul		mcur = mtable[i];
16211814Swpaul		while(mcur) {
16311814Swpaul			struct grouplist *tmp;
16411814Swpaul			printf ("%s.%s\t", mcur->key, mcur->domain);
16511814Swpaul			tmp = mcur->groups;
16611814Swpaul			while(tmp) {
16711814Swpaul				printf ("%s", tmp->groupname);
16811814Swpaul				tmp = tmp->next;
16911814Swpaul				if (tmp)
17011814Swpaul					printf(",");
17111814Swpaul			}
17211814Swpaul			mcur = mcur->next;
17311814Swpaul			printf ("\n");
17411814Swpaul		}
17511814Swpaul	}
17611814Swpaul
17711814Swpaul	/* Let the OS free all our resources. */
17811814Swpaul	exit(0);
17911814Swpaul}
180