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