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