1178825Sdfr/*
2233294Sstas * Copyright (c) 1995
3233294Sstas *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4233294Sstas *
5178825Sdfr * Redistribution and use in source and binary forms, with or without
6233294Sstas * modification, are permitted provided that the following conditions
7178825Sdfr * are met:
8233294Sstas * 1. Redistributions of source code must retain the above copyright
9233294Sstas *    notice, this list of conditions and the following disclaimer.
10233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
11178825Sdfr *    notice, this list of conditions and the following disclaimer in the
12233294Sstas *    documentation and/or other materials provided with the distribution.
13233294Sstas * 3. All advertising materials mentioning features or use of this software
14178825Sdfr *    must display the following acknowledgement:
15233294Sstas *	This product includes software developed by Bill Paul.
16233294Sstas * 4. Neither the name of the author nor the names of any co-contributors
17233294Sstas *    may be used to endorse or promote products derived from this software
18178825Sdfr *    without specific prior written permission.
19233294Sstas *
20233294Sstas * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23233294Sstas * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30233294Sstas * SUCH DAMAGE.
31233294Sstas *
32233294Sstas * reverse netgroup map generator program
33233294Sstas *
34178825Sdfr * Written by Bill Paul <wpaul@ctr.columbia.edu>
35178825Sdfr * Center for Telecommunications Research
36178825Sdfr * Columbia University, New York City
37178825Sdfr */
38233294Sstas
39233294Sstas#ifndef lint
40233294Sstasstatic const char rcsid[] =
41233294Sstas  "$FreeBSD$";
42233294Sstas#endif /* not lint */
43233294Sstas
44233294Sstas#include <err.h>
45233294Sstas#include <stdio.h>
46233294Sstas#include <stdlib.h>
47178825Sdfr#include <string.h>
48178825Sdfr#include <unistd.h>
49178825Sdfr#include "hash.h"
50233294Sstas
51178825Sdfr/* Default location of netgroup file. */
52233294Sstaschar *netgroup = "/etc/netgroup";
53233294Sstas
54233294Sstas/* Stored hash table version of 'forward' netgroup database. */
55233294Sstasstruct group_entry *gtable[TABLESIZE];
56178825Sdfr
57233294Sstas/*
58233294Sstas * Stored hash table of 'reverse' netgroup member database
59233294Sstas * which we will construct.
60233294Sstas */
61178825Sdfrstruct member_entry *mtable[TABLESIZE];
62178825Sdfr
63178825Sdfrstatic void
64233294Sstasusage(void)
65233294Sstas{
66178825Sdfr	fprintf (stderr,"usage: revnetgroup -u | -h [-f netgroup_file]\n");
67178825Sdfr	exit(1);
68178825Sdfr}
69178825Sdfr
70233294Sstasint
71233294Sstasmain(int argc, char *argv[])
72233294Sstas{
73178825Sdfr	FILE *fp;
74178825Sdfr	char readbuf[LINSIZ];
75233294Sstas	struct group_entry *gcur;
76233294Sstas	struct member_entry *mcur;
77178825Sdfr	char *host, *user, *domain;
78178825Sdfr	int ch;
79178825Sdfr	char *key = NULL, *data = NULL;
80233294Sstas	int hosts = -1, i;
81178825Sdfr
82233294Sstas	if (argc < 2)
83233294Sstas		usage();
84178825Sdfr
85	while ((ch = getopt(argc, argv, "uhf:")) != -1) {
86		switch(ch) {
87		case 'u':
88			if (hosts != -1) {
89				warnx("please use only one of -u or -h");
90				usage();
91			}
92			hosts = 0;
93			break;
94		case 'h':
95			if (hosts != -1) {
96				warnx("please use only one of -u or -h");
97				usage();
98			}
99			hosts = 1;
100			break;
101		case 'f':
102			netgroup = optarg;
103			break;
104		default:
105			usage();
106			break;
107		}
108	}
109
110	if (hosts == -1)
111		usage();
112
113	if (strcmp(netgroup, "-")) {
114		if ((fp = fopen(netgroup, "r")) == NULL) {
115			err(1, "%s", netgroup);
116		}
117	} else {
118		fp = stdin;
119	}
120
121	/* Stuff all the netgroup names and members into a hash table. */
122	while (fgets(readbuf, LINSIZ, fp)) {
123		if (readbuf[0] == '#')
124			continue;
125		/* handle backslash line continuations */
126		while(readbuf[strlen(readbuf) - 2] == '\\') {
127			fgets((char *)&readbuf[strlen(readbuf) - 2],
128					sizeof(readbuf) - strlen(readbuf), fp);
129		}
130		data = NULL;
131		if ((data = (char *)(strpbrk(readbuf, " \t") + 1)) < (char *)2)
132			continue;
133		key = (char *)&readbuf;
134		*(data - 1) = '\0';
135		store(gtable, key, data);
136	}
137
138	fclose(fp);
139
140	/*
141	 * Find all members of each netgroup and keep track of which
142	 * group they belong to.
143	 */
144	for (i = 0; i < TABLESIZE; i++) {
145		gcur = gtable[i];
146		while(gcur) {
147			__setnetgrent(gcur->key);
148			while(__getnetgrent(&host, &user, &domain) != 0) {
149				if (hosts ? host && strcmp(host,"-") : user && strcmp(user, "-"))
150					mstore(mtable, hosts ? host : user, gcur->key, domain);
151			}
152			gcur = gcur->next;
153		}
154	}
155
156	/* Release resources used by the netgroup parser code. */
157	__endnetgrent();
158
159	/* Spew out the results. */
160	for (i = 0; i < TABLESIZE; i++) {
161		mcur = mtable[i];
162		while(mcur) {
163			struct grouplist *tmp;
164			printf ("%s.%s\t", mcur->key, mcur->domain);
165			tmp = mcur->groups;
166			while(tmp) {
167				printf ("%s", tmp->groupname);
168				tmp = tmp->next;
169				if (tmp)
170					printf(",");
171			}
172			mcur = mcur->next;
173			printf ("\n");
174		}
175	}
176
177	/* Let the OS free all our resources. */
178	exit(0);
179}
180