mknetid.c revision 22989
1179237Sjb/*
2179237Sjb * Copyright (c) 1995, 1996
3179237Sjb *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4179237Sjb *
5179237Sjb * Redistribution and use in source and binary forms, with or without
6179237Sjb * modification, are permitted provided that the following conditions
7179237Sjb * are met:
8179237Sjb * 1. Redistributions of source code must retain the above copyright
9179237Sjb *    notice, this list of conditions and the following disclaimer.
10179237Sjb * 2. Redistributions in binary form must reproduce the above copyright
11179237Sjb *    notice, this list of conditions and the following disclaimer in the
12179237Sjb *    documentation and/or other materials provided with the distribution.
13179237Sjb * 3. All advertising materials mentioning features or use of this software
14179237Sjb *    must display the following acknowledgement:
15179237Sjb *	This product includes software developed by Bill Paul.
16179237Sjb * 4. Neither the name of the author nor the names of any co-contributors
17179237Sjb *    may be used to endorse or promote products derived from this software
18179237Sjb *    without specific prior written permission.
19179237Sjb *
20179237Sjb * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21179237Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22179237Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23179237Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24179237Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25179237Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26179237Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27179237Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28179237Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29179237Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30179237Sjb * SUCH DAMAGE.
31179237Sjb *
32179237Sjb * netid map generator program
33209059Sjhb *
34209059Sjhb * Written by Bill Paul <wpaul@ctr.columbia.edu>
35179237Sjb * Center for Telecommunications Research
36179237Sjb * Columbia University, New York City
37179237Sjb *
38179237Sjb *	$Id$
39179237Sjb */
40179237Sjb
41179237Sjb#include <sys/types.h>
42179237Sjb
43179237Sjb#include <rpc/rpc.h>
44179237Sjb#include <rpcsvc/yp_prot.h>
45179237Sjb#include <rpcsvc/ypclnt.h>
46179237Sjb
47179237Sjb#include <err.h>
48179237Sjb#include <grp.h>
49179237Sjb#include <pwd.h>
50179237Sjb#include <netdb.h>
51179237Sjb#include <stdio.h>
52179237Sjb#include <stdlib.h>
53179237Sjb#include <string.h>
54179237Sjb
55179237Sjb#include "hash.h"
56179237Sjb
57179237Sjb#ifndef lint
58179237Sjbstatic const char rcsid[] = "$Id$";
59179237Sjb#endif
60179237Sjb
61179237Sjb#define LINSIZ 1024
62179237Sjb#define OPSYS "unix"
63179237Sjb
64179237Sjb/* Default location of group file. */
65179237Sjbchar *groupfile = _PATH_GROUP;
66179237Sjb/* Default location of master.passwd file. */
67179237Sjbchar *passfile = _PATH_PASSWD;
68179237Sjb/* Default location of hosts file. */
69179237Sjbchar *hostsfile = _PATH_HOSTS;
70179237Sjb/* Default location of netid file */
71179237Sjbchar *netidfile = "/etc/netid";
72179237Sjb
73179237Sjb/*
74179237Sjb * Stored hash table of 'reverse' group member database
75179237Sjb * which we will construct.
76179237Sjb */
77179237Sjbstruct member_entry *mtable[TABLESIZE];
78179237Sjb
79179237Sjb/*
80179237Sjb * Dupe table: used to keep track of entries so we don't
81179237Sjb * print the same thing twice.
82179237Sjb */
83179237Sjbstruct member_entry *dtable[TABLESIZE];
84179237Sjb
85179237Sjbextern struct group *_getgrent __P(( void ));
86179237Sjbextern int _setgrent __P(( void ));
87179237Sjbextern void _endgrent __P(( void ));
88179237Sjbvoid usage(prog)
89179237Sjbchar *prog;
90179237Sjb{
91179237Sjb	fprintf (stderr,"usage: %s [-q] [-g group file] [-p passwd file] \
92179237Sjb[-h hosts file]\n\t\t\t[-d netid file] [-d domain]\n",prog);
93179237Sjb	exit(1);
94179237Sjb}
95179237Sjb
96179237Sjbextern char *optarg;
97179237Sjbextern FILE *_gr_fp;
98179237Sjb
99179237Sjbmain(argc, argv)
100179237Sjb	int argc;
101179237Sjb	char *argv[];
102179237Sjb{
103179237Sjb	FILE *gfp, *pfp, *hfp, *nfp;
104179237Sjb	char readbuf[LINSIZ];
105179237Sjb	char writebuf[LINSIZ];
106179237Sjb	struct group *gr;
107179237Sjb	struct grouplist *glist;
108179237Sjb	char *domain;
109179237Sjb	int ch;
110179237Sjb	gid_t i;
111179237Sjb	char *ptr, *pidptr, *gidptr, *hptr;
112179237Sjb	int quiet = 0;
113179237Sjb
114179237Sjb	while ((ch = getopt(argc, argv, "g:p:h:n:d:q")) != EOF) {
115179237Sjb		switch(ch) {
116179237Sjb		case 'g':
117179237Sjb			groupfile = optarg;
118179237Sjb			break;
119179237Sjb		case 'p':
120179237Sjb			passfile = optarg;
121179237Sjb			break;
122179237Sjb		case 'h':
123179237Sjb			hostsfile = optarg;
124179237Sjb			break;
125179237Sjb		case 'n':
126179237Sjb			netidfile = optarg;
127179237Sjb			break;
128179237Sjb		case 'd':
129179237Sjb			domain = optarg;
130179237Sjb			break;
131179237Sjb		case 'q':
132179237Sjb			quiet++;
133179237Sjb			break;
134179237Sjb		default:
135179237Sjb			usage(argv[0]);
136179237Sjb			break;
137179237Sjb		}
138179237Sjb	}
139179237Sjb
140179237Sjb	if (domain == NULL) {
141179237Sjb		if (yp_get_default_domain(&domain))
142179237Sjb			errx(1, "no domain name specified and default \
143179237Sjbdomain not set");
144179237Sjb	}
145179237Sjb
146179237Sjb	if ((gfp = fopen(groupfile, "r")) == NULL) {
147179237Sjb		err(1, "%s", groupfile);
148179237Sjb	}
149179237Sjb
150179237Sjb	if ((pfp = fopen(passfile, "r")) == NULL) {
151179237Sjb		err(1, "%s", passfile);
152179237Sjb	}
153179237Sjb
154179237Sjb	if ((hfp = fopen(hostsfile, "r")) == NULL) {
155179237Sjb		err(1, "%s", hostsfile);
156179237Sjb	}
157184698Srodrigc
158179237Sjb	if ((nfp = fopen(netidfile, "r")) == NULL) {
159179237Sjb		/* netid is optional -- just continue */
160179237Sjb		nfp = NULL;
161179237Sjb	}
162179237Sjb
163184698Srodrigc	_gr_fp = gfp;
164211608Srpaulo
165211608Srpaulo	/* Load all the group membership info into a hash table. */
166212093Srpaulo
167211608Srpaulo	_setgrent();
168184698Srodrigc	while((gr = _getgrent()) != NULL) {
169179237Sjb		while(*gr->gr_mem) {
170179237Sjb			mstore(mtable, *gr->gr_mem, gr->gr_gid, 0);
171179237Sjb			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