mknetid.c revision 16729
1/*
2 * Copyright (c) 1995, 1996
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 * netid 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: mknetid.c,v 1.5 1996/06/24 22:48:15 wpaul Exp $
39 */
40
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <grp.h>
45#include <pwd.h>
46#include <netdb.h>
47#include <err.h>
48#include <rpc/rpc.h>
49#include <rpcsvc/yp_prot.h>
50#include <rpcsvc/ypclnt.h>
51#include "hash.h"
52
53#ifndef lint
54static const char rcsid[] = "$Id: mknetid.c,v 1.5 1996/06/24 22:48:15 wpaul Exp $";
55#endif
56
57#define LINSIZ 1024
58#define OPSYS "unix"
59
60/* Default location of group file. */
61char *groupfile = _PATH_GROUP;
62/* Default location of master.passwd file. */
63char *passfile = _PATH_PASSWD;
64/* Default location of hosts file. */
65char *hostsfile = _PATH_HOSTS;
66/* Default location of netid file */
67char *netidfile = "/etc/netid";
68
69/*
70 * Stored hash table of 'reverse' group member database
71 * which we will construct.
72 */
73struct member_entry *mtable[TABLESIZE];
74
75/*
76 * Dupe table: used to keep track of entries so we don't
77 * print the same thing twice.
78 */
79struct member_entry *dtable[TABLESIZE];
80
81extern struct group *_getgrent __P(( void ));
82extern int _setgrent __P(( void ));
83extern void _endgrent __P(( void ));
84void usage(prog)
85char *prog;
86{
87	fprintf (stderr,"usage: %s [-q] [-g group file] [-p passwd file] \
88[-h hosts file]\n\t\t\t[-d netid file] [-d domain]\n",prog);
89	exit(1);
90}
91
92extern char *optarg;
93extern FILE *_gr_fp;
94
95main(argc, argv)
96	int argc;
97	char *argv[];
98{
99	FILE *gfp, *pfp, *hfp, *nfp;
100	char readbuf[LINSIZ];
101	char writebuf[LINSIZ];
102	struct group *gr;
103	struct grouplist *glist;
104	char *domain;
105	int ch;
106	gid_t i;
107	char *ptr, *pidptr, *gidptr, *hptr;
108	int quiet = 0;
109
110	while ((ch = getopt(argc, argv, "g:p:h:n:d:q")) != EOF) {
111		switch(ch) {
112		case 'g':
113			groupfile = optarg;
114			break;
115		case 'p':
116			passfile = optarg;
117			break;
118		case 'h':
119			hostsfile = optarg;
120			break;
121		case 'n':
122			netidfile = optarg;
123			break;
124		case 'd':
125			domain = optarg;
126			break;
127		case 'q':
128			quiet++;
129			break;
130		default:
131			usage(argv[0]);
132			break;
133		}
134	}
135
136	if (domain == NULL) {
137		if (yp_get_default_domain(&domain))
138			errx(1, "no domain name specified and default \
139domain not set");
140	}
141
142	if ((gfp = fopen(groupfile, "r")) == NULL) {
143		err(1, "%s", groupfile);
144	}
145
146	if ((pfp = fopen(passfile, "r")) == NULL) {
147		err(1, "%s", passfile);
148	}
149
150	if ((hfp = fopen(hostsfile, "r")) == NULL) {
151		err(1, "%s", hostsfile);
152	}
153
154	if ((nfp = fopen(netidfile, "r")) == NULL) {
155		/* netid is optional -- just continue */
156		nfp = NULL;
157	}
158
159	_gr_fp = gfp;
160
161	/* Load all the group membership info into a hash table. */
162
163	_setgrent();
164	while((gr = _getgrent()) != NULL) {
165		while(*gr->gr_mem) {
166			mstore(mtable, *gr->gr_mem, gr->gr_gid, 0);
167			gr->gr_mem++;
168		}
169	}
170
171	fclose(gfp);
172	_endgrent();
173
174	/*
175	 * Now parse the passwd database, spewing out the extra
176	 * group information we just stored if necessary.
177	 */
178	while(fgets(readbuf, LINSIZ, pfp)) {
179		if ((ptr = strchr(readbuf, ':')) == NULL)
180			warnx("bad passwd file entry: %s", readbuf);
181		*ptr = '\0';
182		ptr++;
183		if ((ptr = strchr(ptr, ':')) == NULL)
184			warnx("bad passwd file entry: %s", readbuf);
185		*ptr = '\0';
186		ptr++;
187		pidptr = ptr;
188		if ((ptr = strchr(ptr, ':')) == NULL)
189			warnx("bad passwd file entry: %s", readbuf);
190		*ptr = '\0';
191		ptr++;
192		gidptr = ptr;
193		if ((ptr = strchr(ptr, ':')) == NULL)
194			warnx("bad passwd file entry: %s", readbuf);
195		*ptr = '\0';
196		i = atol(gidptr);
197
198		snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS,
199							pidptr, domain);
200
201		if (lookup(dtable, writebuf)) {
202			if (!quiet)
203				warnx("duplicate netid '%s.%s@%s' -- skipping",
204						OPSYS, pidptr, domain);
205			continue;
206		} else {
207			mstore(dtable, writebuf, 0, 1);
208		}
209		printf("%s.%s@%s\t\t%s:%s", OPSYS, pidptr, domain, pidptr, gidptr);
210		if ((glist = lookup(mtable, (char *)&readbuf)) != NULL) {
211			while(glist) {
212				if (glist->groupid != i)
213					printf(",%lu", glist->groupid);
214				glist = glist->next;
215			}
216		}
217		printf ("\n");
218	}
219
220	fclose(pfp);
221
222	/*
223	 * Now parse the hosts database (this part sucks).
224	 */
225
226	while ((ptr = fgets(readbuf, LINSIZ, hfp))) {
227		if (*ptr == '#')
228			continue;
229		if (!(hptr = strpbrk(ptr, "#\n")))
230			continue;
231		*hptr = '\0';
232		if (!(hptr = strpbrk(ptr, " \t")))
233			continue;
234		*hptr++ = '\0';
235		ptr = hptr;
236		while (*ptr == ' ' || *ptr == '\t')
237			ptr++;
238		if (!(hptr = strpbrk(ptr, " \t")))
239			continue;
240		*hptr++ = '\0';
241		snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS,
242								ptr, domain);
243		if (lookup(dtable, (char *)&writebuf)) {
244			if (!quiet)
245				warnx("duplicate netid '%s' -- skipping",
246								writebuf);
247			continue;
248		} else {
249			mstore(dtable, (char *)&writebuf, 0, 1);
250		}
251		printf ("%s.%s@%s\t\t0:%s\n", OPSYS, ptr, domain, ptr);
252	}
253
254	fclose(hfp);
255
256	/*
257	 * Lastly, copy out any extra information in the netid
258	 * file. If it's not open, just ignore it: it's optional anyway.
259	 */
260
261	if (nfp != NULL) {
262		while(fgets(readbuf, LINSIZ, nfp)) {
263			if (readbuf[0] == '#')
264				continue;
265			if ((ptr = strpbrk((char*)&readbuf, " \t")) == NULL) {
266				warnx("bad netid entry: '%s'", readbuf);
267				continue;
268			}
269
270			writebuf[0] = *ptr;
271			*ptr = '\0';
272			snprintf(writebuf, sizeof(readbuf), "%s.%s@%s", OPSYS,
273								ptr, domain);
274			if (lookup(dtable, (char *)&readbuf)) {
275				if (!quiet)
276					warnx("duplicate netid '%s' -- skipping",
277								readbuf);
278				continue;
279			} else {
280				mstore(dtable, (char *)&readbuf, 0, 1);
281			}
282			*ptr = writebuf[0];
283			printf("%s",readbuf);
284		}
285		fclose(nfp);
286	}
287
288	exit(0);
289}
290