xref: /freebsd-src/libexec/mknetid/mknetid.c (revision eba230afba4932f02a1ca44efc797cf7499a5cb0)
1*df57947fSPedro F. Giffuni /*-
2*df57947fSPedro F. Giffuni  * SPDX-License-Identifier: BSD-4-Clause
3*df57947fSPedro F. Giffuni  *
4ca09eb42SBill Paul  * Copyright (c) 1995, 1996
5ca09eb42SBill Paul  *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
6ca09eb42SBill Paul  *
7ca09eb42SBill Paul  * Redistribution and use in source and binary forms, with or without
8ca09eb42SBill Paul  * modification, are permitted provided that the following conditions
9ca09eb42SBill Paul  * are met:
10ca09eb42SBill Paul  * 1. Redistributions of source code must retain the above copyright
11ca09eb42SBill Paul  *    notice, this list of conditions and the following disclaimer.
12ca09eb42SBill Paul  * 2. Redistributions in binary form must reproduce the above copyright
13ca09eb42SBill Paul  *    notice, this list of conditions and the following disclaimer in the
14ca09eb42SBill Paul  *    documentation and/or other materials provided with the distribution.
15ca09eb42SBill Paul  * 3. All advertising materials mentioning features or use of this software
16ca09eb42SBill Paul  *    must display the following acknowledgement:
17ca09eb42SBill Paul  *	This product includes software developed by Bill Paul.
18ca09eb42SBill Paul  * 4. Neither the name of the author nor the names of any co-contributors
19ca09eb42SBill Paul  *    may be used to endorse or promote products derived from this software
20ca09eb42SBill Paul  *    without specific prior written permission.
21ca09eb42SBill Paul  *
22ca09eb42SBill Paul  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
23ca09eb42SBill Paul  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24ca09eb42SBill Paul  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25ca09eb42SBill Paul  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
26ca09eb42SBill Paul  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27ca09eb42SBill Paul  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28ca09eb42SBill Paul  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29ca09eb42SBill Paul  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30ca09eb42SBill Paul  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31ca09eb42SBill Paul  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32ca09eb42SBill Paul  * SUCH DAMAGE.
33ca09eb42SBill Paul  *
34ca09eb42SBill Paul  * netid map generator program
35ca09eb42SBill Paul  *
36ca09eb42SBill Paul  * Written by Bill Paul <wpaul@ctr.columbia.edu>
37ca09eb42SBill Paul  * Center for Telecommunications Research
38ca09eb42SBill Paul  * Columbia University, New York City
39ca09eb42SBill Paul  */
40ca09eb42SBill Paul 
41884d83ffSBruce Evans #include <sys/types.h>
42884d83ffSBruce Evans 
43ca09eb42SBill Paul #include <rpc/rpc.h>
44ca09eb42SBill Paul #include <rpcsvc/yp_prot.h>
45ca09eb42SBill Paul #include <rpcsvc/ypclnt.h>
46884d83ffSBruce Evans 
47884d83ffSBruce Evans #include <err.h>
48884d83ffSBruce Evans #include <grp.h>
49884d83ffSBruce Evans #include <netdb.h>
50ad17ca10SPhilippe Charnier #include <pwd.h>
51884d83ffSBruce Evans #include <stdio.h>
52884d83ffSBruce Evans #include <stdlib.h>
53884d83ffSBruce Evans #include <string.h>
54ad17ca10SPhilippe Charnier #include <unistd.h>
55884d83ffSBruce Evans 
56ca09eb42SBill Paul #include "hash.h"
57ca09eb42SBill Paul 
58ca09eb42SBill Paul #define LINSIZ 1024
59ca09eb42SBill Paul #define OPSYS "unix"
60ca09eb42SBill Paul 
61ca09eb42SBill Paul /* Default location of group file. */
62ca09eb42SBill Paul char *groupfile = _PATH_GROUP;
63ca09eb42SBill Paul /* Default location of master.passwd file. */
64ca09eb42SBill Paul char *passfile = _PATH_PASSWD;
65ca09eb42SBill Paul /* Default location of hosts file. */
66ca09eb42SBill Paul char *hostsfile = _PATH_HOSTS;
67ca09eb42SBill Paul /* Default location of netid file */
68ca09eb42SBill Paul char *netidfile = "/etc/netid";
69ca09eb42SBill Paul 
70ca09eb42SBill Paul /*
71ca09eb42SBill Paul  * Stored hash table of 'reverse' group member database
72ca09eb42SBill Paul  * which we will construct.
73ca09eb42SBill Paul  */
74ca09eb42SBill Paul struct member_entry *mtable[TABLESIZE];
75ca09eb42SBill Paul 
76ca09eb42SBill Paul /*
77ca09eb42SBill Paul  * Dupe table: used to keep track of entries so we don't
78ca09eb42SBill Paul  * print the same thing twice.
79ca09eb42SBill Paul  */
80ca09eb42SBill Paul struct member_entry *dtable[TABLESIZE];
81ca09eb42SBill Paul 
8271233f4fSWarner Losh extern struct group *_getgrent(void);
8371233f4fSWarner Losh extern int _setgrent(void);
8471233f4fSWarner Losh extern void _endgrent(void);
85ad17ca10SPhilippe Charnier 
86ad17ca10SPhilippe Charnier static void
usage(void)8771233f4fSWarner Losh usage(void)
88ca09eb42SBill Paul {
89ad17ca10SPhilippe Charnier 	fprintf (stderr, "%s\n%s\n",
90ad17ca10SPhilippe Charnier 	"usage: mknetid [-q] [-g group_file] [-p passwd_file] [-h hosts_file]",
91e1b57f44SMaxim Konovalov 	"               [-n netid_file] [-d domain]");
92ca09eb42SBill Paul 	exit(1);
93ca09eb42SBill Paul }
94ca09eb42SBill Paul 
95ca09eb42SBill Paul extern FILE *_gr_fp;
96ca09eb42SBill Paul 
97ad17ca10SPhilippe Charnier int
main(int argc,char * argv[])9871233f4fSWarner Losh main(int argc, char *argv[])
99ca09eb42SBill Paul {
100ca09eb42SBill Paul 	FILE *gfp, *pfp, *hfp, *nfp;
101ca09eb42SBill Paul 	char readbuf[LINSIZ];
102ca09eb42SBill Paul 	char writebuf[LINSIZ];
103ca09eb42SBill Paul 	struct group *gr;
104ca09eb42SBill Paul 	struct grouplist *glist;
105ca09eb42SBill Paul 	char *domain;
106ca09eb42SBill Paul 	int ch;
107ca09eb42SBill Paul 	gid_t i;
108ca09eb42SBill Paul 	char *ptr, *pidptr, *gidptr, *hptr;
109ca09eb42SBill Paul 	int quiet = 0;
110ca09eb42SBill Paul 
111e1b57f44SMaxim Konovalov 	domain = NULL;
11291477cc4SWarner Losh 	while ((ch = getopt(argc, argv, "g:p:h:n:d:q")) != -1) {
113ca09eb42SBill Paul 		switch(ch) {
114ca09eb42SBill Paul 		case 'g':
115ca09eb42SBill Paul 			groupfile = optarg;
116ca09eb42SBill Paul 			break;
117ca09eb42SBill Paul 		case 'p':
118ca09eb42SBill Paul 			passfile = optarg;
119ca09eb42SBill Paul 			break;
120ca09eb42SBill Paul 		case 'h':
121ca09eb42SBill Paul 			hostsfile = optarg;
122ca09eb42SBill Paul 			break;
123ca09eb42SBill Paul 		case 'n':
124ca09eb42SBill Paul 			netidfile = optarg;
125ca09eb42SBill Paul 			break;
126ca09eb42SBill Paul 		case 'd':
127ca09eb42SBill Paul 			domain = optarg;
128ca09eb42SBill Paul 			break;
129ca09eb42SBill Paul 		case 'q':
130ca09eb42SBill Paul 			quiet++;
131ca09eb42SBill Paul 			break;
132ca09eb42SBill Paul 		default:
133ad17ca10SPhilippe Charnier 			usage();
134ca09eb42SBill Paul 			break;
135ca09eb42SBill Paul 		}
136ca09eb42SBill Paul 	}
137ca09eb42SBill Paul 
138ca09eb42SBill Paul 	if (domain == NULL) {
139ca09eb42SBill Paul 		if (yp_get_default_domain(&domain))
140ca09eb42SBill Paul 			errx(1, "no domain name specified and default \
141ca09eb42SBill Paul domain not set");
142ca09eb42SBill Paul 	}
143ca09eb42SBill Paul 
144ca09eb42SBill Paul 	if ((gfp = fopen(groupfile, "r")) == NULL) {
145ca09eb42SBill Paul 		err(1, "%s", groupfile);
146ca09eb42SBill Paul 	}
147ca09eb42SBill Paul 
148ca09eb42SBill Paul 	if ((pfp = fopen(passfile, "r")) == NULL) {
149ca09eb42SBill Paul 		err(1, "%s", passfile);
150ca09eb42SBill Paul 	}
151ca09eb42SBill Paul 
152ca09eb42SBill Paul 	if ((hfp = fopen(hostsfile, "r")) == NULL) {
153ca09eb42SBill Paul 		err(1, "%s", hostsfile);
154ca09eb42SBill Paul 	}
155ca09eb42SBill Paul 
156ca09eb42SBill Paul 	if ((nfp = fopen(netidfile, "r")) == NULL) {
157ca09eb42SBill Paul 		/* netid is optional -- just continue */
158ca09eb42SBill Paul 		nfp = NULL;
159ca09eb42SBill Paul 	}
160ca09eb42SBill Paul 
161ca09eb42SBill Paul 	_gr_fp = gfp;
162ca09eb42SBill Paul 
163ca09eb42SBill Paul 	/* Load all the group membership info into a hash table. */
164ca09eb42SBill Paul 
165ca09eb42SBill Paul 	_setgrent();
166ca09eb42SBill Paul 	while((gr = _getgrent()) != NULL) {
167ca09eb42SBill Paul 		while(*gr->gr_mem) {
168ca09eb42SBill Paul 			mstore(mtable, *gr->gr_mem, gr->gr_gid, 0);
169ca09eb42SBill Paul 			gr->gr_mem++;
170ca09eb42SBill Paul 		}
171ca09eb42SBill Paul 	}
172ca09eb42SBill Paul 
173ca09eb42SBill Paul 	fclose(gfp);
174ca09eb42SBill Paul 	_endgrent();
175ca09eb42SBill Paul 
176ca09eb42SBill Paul 	/*
177ca09eb42SBill Paul 	 * Now parse the passwd database, spewing out the extra
178ca09eb42SBill Paul 	 * group information we just stored if necessary.
179ca09eb42SBill Paul 	 */
180ca09eb42SBill Paul 	while(fgets(readbuf, LINSIZ, pfp)) {
181e1b57f44SMaxim Konovalov 		/* Ignore comments: ^[ \t]*# */
182e1b57f44SMaxim Konovalov 		for (ptr = readbuf; *ptr != '\0'; ptr++)
183e1b57f44SMaxim Konovalov 			if (*ptr != ' ' && *ptr != '\t')
184e1b57f44SMaxim Konovalov 				break;
185e1b57f44SMaxim Konovalov 		if (*ptr == '#' || *ptr == '\0')
186e1b57f44SMaxim Konovalov 			continue;
187e1b57f44SMaxim Konovalov 		if ((ptr = strchr(readbuf, ':')) == NULL) {
188ca09eb42SBill Paul 			warnx("bad passwd file entry: %s", readbuf);
189e1b57f44SMaxim Konovalov 			continue;
190e1b57f44SMaxim Konovalov 		}
191ca09eb42SBill Paul 		*ptr = '\0';
192ca09eb42SBill Paul 		ptr++;
193e1b57f44SMaxim Konovalov 		if ((ptr = strchr(ptr, ':')) == NULL) {
194ca09eb42SBill Paul 			warnx("bad passwd file entry: %s", readbuf);
195e1b57f44SMaxim Konovalov 			continue;
196e1b57f44SMaxim Konovalov 		}
197ca09eb42SBill Paul 		*ptr = '\0';
198ca09eb42SBill Paul 		ptr++;
199ca09eb42SBill Paul 		pidptr = ptr;
200e1b57f44SMaxim Konovalov 		if ((ptr = strchr(ptr, ':')) == NULL) {
201ca09eb42SBill Paul 			warnx("bad passwd file entry: %s", readbuf);
202e1b57f44SMaxim Konovalov 			continue;
203e1b57f44SMaxim Konovalov 		}
204ca09eb42SBill Paul 		*ptr = '\0';
205ca09eb42SBill Paul 		ptr++;
206ca09eb42SBill Paul 		gidptr = ptr;
207e1b57f44SMaxim Konovalov 		if ((ptr = strchr(ptr, ':')) == NULL) {
208ca09eb42SBill Paul 			warnx("bad passwd file entry: %s", readbuf);
209e1b57f44SMaxim Konovalov 			continue;
210e1b57f44SMaxim Konovalov 		}
211ca09eb42SBill Paul 		*ptr = '\0';
212ca09eb42SBill Paul 		i = atol(gidptr);
213ca09eb42SBill Paul 
214ca09eb42SBill Paul 		snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS,
215ca09eb42SBill Paul 							pidptr, domain);
216ca09eb42SBill Paul 
217ca09eb42SBill Paul 		if (lookup(dtable, writebuf)) {
218ca09eb42SBill Paul 			if (!quiet)
219ca09eb42SBill Paul 				warnx("duplicate netid '%s.%s@%s' -- skipping",
220ca09eb42SBill Paul 						OPSYS, pidptr, domain);
221ca09eb42SBill Paul 			continue;
222ca09eb42SBill Paul 		} else {
223ca09eb42SBill Paul 			mstore(dtable, writebuf, 0, 1);
224ca09eb42SBill Paul 		}
2254c2e2040SBill Paul 		printf("%s.%s@%s %s:%s", OPSYS, pidptr, domain, pidptr, gidptr);
226ca09eb42SBill Paul 		if ((glist = lookup(mtable, (char *)&readbuf)) != NULL) {
227ca09eb42SBill Paul 			while(glist) {
228ca09eb42SBill Paul 				if (glist->groupid != i)
2291a463b86SBruce Evans 					printf(",%lu", (u_long)glist->groupid);
230ca09eb42SBill Paul 				glist = glist->next;
231ca09eb42SBill Paul 			}
232ca09eb42SBill Paul 		}
233ca09eb42SBill Paul 		printf ("\n");
234ca09eb42SBill Paul 	}
235ca09eb42SBill Paul 
236ca09eb42SBill Paul 	fclose(pfp);
237ca09eb42SBill Paul 
238ca09eb42SBill Paul 	/*
239ca09eb42SBill Paul 	 * Now parse the hosts database (this part sucks).
240ca09eb42SBill Paul 	 */
241ca09eb42SBill Paul 
242ca09eb42SBill Paul 	while ((ptr = fgets(readbuf, LINSIZ, hfp))) {
243ca09eb42SBill Paul 		if (*ptr == '#')
244ca09eb42SBill Paul 			continue;
245ca09eb42SBill Paul 		if (!(hptr = strpbrk(ptr, "#\n")))
246ca09eb42SBill Paul 			continue;
247ca09eb42SBill Paul 		*hptr = '\0';
248ca09eb42SBill Paul 		if (!(hptr = strpbrk(ptr, " \t")))
249ca09eb42SBill Paul 			continue;
250ca09eb42SBill Paul 		*hptr++ = '\0';
251ca09eb42SBill Paul 		ptr = hptr;
252ca09eb42SBill Paul 		while (*ptr == ' ' || *ptr == '\t')
253ca09eb42SBill Paul 			ptr++;
254ca09eb42SBill Paul 		if (!(hptr = strpbrk(ptr, " \t")))
255ca09eb42SBill Paul 			continue;
256ca09eb42SBill Paul 		*hptr++ = '\0';
257ca09eb42SBill Paul 		snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS,
258ca09eb42SBill Paul 								ptr, domain);
259ca09eb42SBill Paul 		if (lookup(dtable, (char *)&writebuf)) {
260ca09eb42SBill Paul 			if (!quiet)
261ca09eb42SBill Paul 				warnx("duplicate netid '%s' -- skipping",
262ca09eb42SBill Paul 								writebuf);
263ca09eb42SBill Paul 			continue;
264ca09eb42SBill Paul 		} else {
265ca09eb42SBill Paul 			mstore(dtable, (char *)&writebuf, 0, 1);
266ca09eb42SBill Paul 		}
2674c2e2040SBill Paul 		printf ("%s.%s@%s 0:%s\n", OPSYS, ptr, domain, ptr);
268ca09eb42SBill Paul 	}
269ca09eb42SBill Paul 
270ca09eb42SBill Paul 	fclose(hfp);
271ca09eb42SBill Paul 
272ca09eb42SBill Paul 	/*
273ca09eb42SBill Paul 	 * Lastly, copy out any extra information in the netid
274ca09eb42SBill Paul 	 * file. If it's not open, just ignore it: it's optional anyway.
275ca09eb42SBill Paul 	 */
276ca09eb42SBill Paul 
277ca09eb42SBill Paul 	if (nfp != NULL) {
278ca09eb42SBill Paul 		while(fgets(readbuf, LINSIZ, nfp)) {
279ca09eb42SBill Paul 			if (readbuf[0] == '#')
280ca09eb42SBill Paul 				continue;
281ca09eb42SBill Paul 			if ((ptr = strpbrk((char*)&readbuf, " \t")) == NULL) {
282ca09eb42SBill Paul 				warnx("bad netid entry: '%s'", readbuf);
283ca09eb42SBill Paul 				continue;
284ca09eb42SBill Paul 			}
285ca09eb42SBill Paul 
286ca09eb42SBill Paul 			writebuf[0] = *ptr;
287ca09eb42SBill Paul 			*ptr = '\0';
288ca09eb42SBill Paul 			if (lookup(dtable, (char *)&readbuf)) {
289ca09eb42SBill Paul 				if (!quiet)
290ca09eb42SBill Paul 					warnx("duplicate netid '%s' -- skipping",
291ca09eb42SBill Paul 								readbuf);
292ca09eb42SBill Paul 				continue;
293ca09eb42SBill Paul 			} else {
294ca09eb42SBill Paul 				mstore(dtable, (char *)&readbuf, 0, 1);
295ca09eb42SBill Paul 			}
296ca09eb42SBill Paul 			*ptr = writebuf[0];
297ca09eb42SBill Paul 			printf("%s",readbuf);
298ca09eb42SBill Paul 		}
299ca09eb42SBill Paul 		fclose(nfp);
300ca09eb42SBill Paul 	}
301ca09eb42SBill Paul 
302ca09eb42SBill Paul 	exit(0);
303ca09eb42SBill Paul }
304