xref: /freebsd/libexec/revnetgroup/revnetgroup.c (revision df7f5d4de4592a8948a25ce01e5bddfbb7ce39dc)
1 /*
2  * Copyright (c) 1995
3  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by Bill Paul.
16  * 4. Neither the name of the author nor the names of any co-contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  * reverse netgroup map generator program
33  *
34  * Written by Bill Paul <wpaul@ctr.columbia.edu>
35  * Center for Telecommunications Research
36  * Columbia University, New York City
37  *
38  *	$Id$
39  */
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <errno.h>
45 #include <err.h>
46 #include "hash.h"
47 
48 #ifndef lint
49 static const char rcsid[] = "$Id$";
50 #endif
51 
52 /* Default location of netgroup file. */
53 char *netgroup = "/etc/netgroup";
54 
55 /* Stored hash table version of 'forward' netgroup database. */
56 struct group_entry *gtable[TABLESIZE];
57 
58 /*
59  * Stored hash table of 'reverse' netgroup member database
60  * which we will construct.
61  */
62 struct member_entry *mtable[TABLESIZE];
63 
64 void usage(prog)
65 char *prog;
66 {
67 	fprintf (stderr,"usage: %s -u|-h [-f netgroup file]\n",prog);
68 	exit(1);
69 }
70 
71 extern char *optarg;
72 
73 int
74 main(argc, argv)
75 	int argc;
76 	char *argv[];
77 {
78 	FILE *fp;
79 	char readbuf[LINSIZ];
80 	struct group_entry *gcur;
81 	struct member_entry *mcur;
82 	char *host, *user, *domain;
83 	int ch;
84 	char *key = NULL, *data = NULL;
85 	int hosts = -1, i;
86 
87 	if (argc < 2)
88 		usage(argv[0]);
89 
90 	while ((ch = getopt(argc, argv, "uhf:")) != EOF) {
91 		switch(ch) {
92 		case 'u':
93 			if (hosts != -1) {
94 				warnx("please use only one of -u or -h");
95 				usage(argv[0]);
96 			}
97 			hosts = 0;
98 			break;
99 		case 'h':
100 			if (hosts != -1) {
101 				warnx("please use only one of -u or -h");
102 				usage(argv[0]);
103 			}
104 			hosts = 1;
105 			break;
106 		case 'f':
107 			netgroup = optarg;
108 			break;
109 		default:
110 			usage(argv[0]);
111 			break;
112 		}
113 	}
114 
115 	if (hosts == -1)
116 		usage(argv[0]);
117 
118 	if (strcmp(netgroup, "-")) {
119 		if ((fp = fopen(netgroup, "r")) == NULL) {
120 			err(1,netgroup);
121 		}
122 	} else {
123 		fp = stdin;
124 	}
125 
126 	/* Stuff all the netgroup names and members into a hash table. */
127 	while (fgets(readbuf, LINSIZ, fp)) {
128 		if (readbuf[0] == '#')
129 			continue;
130 		/* handle backslash line continuations */
131 		while(readbuf[strlen(readbuf) - 2] == '\\') {
132 			fgets((char *)&readbuf[strlen(readbuf) - 2],
133 					sizeof(readbuf) - strlen(readbuf), fp);
134 		}
135 		data = NULL;
136 		if ((data = (char *)(strpbrk(readbuf, " \t") + 1)) < (char *)2)
137 			continue;
138 		key = (char *)&readbuf;
139 		*(data - 1) = '\0';
140 		store(gtable, key, data);
141 	}
142 
143 	fclose(fp);
144 
145 	/*
146 	 * Find all members of each netgroup and keep track of which
147 	 * group they belong to.
148 	 */
149 	for (i = 0; i < TABLESIZE; i++) {
150 		gcur = gtable[i];
151 		while(gcur) {
152 			__setnetgrent(gcur->key);
153 			while(__getnetgrent(&host, &user, &domain) != NULL) {
154 				if (hosts ? host && strcmp(host,"-") : user && strcmp(user, "-"))
155 					mstore(mtable, hosts ? host : user, gcur->key, domain);
156 			}
157 			gcur = gcur->next;
158 		}
159 	}
160 
161 	/* Release resources used by the netgroup parser code. */
162 	__endnetgrent();
163 
164 	/* Spew out the results. */
165 	for (i = 0; i < TABLESIZE; i++) {
166 		mcur = mtable[i];
167 		while(mcur) {
168 			struct grouplist *tmp;
169 			printf ("%s.%s\t", mcur->key, mcur->domain);
170 			tmp = mcur->groups;
171 			while(tmp) {
172 				printf ("%s", tmp->groupname);
173 				tmp = tmp->next;
174 				if (tmp)
175 					printf(",");
176 			}
177 			mcur = mcur->next;
178 			printf ("\n");
179 		}
180 	}
181 
182 	/* Let the OS free all our resources. */
183 	exit(0);
184 }
185