mknetid.c revision 90779
116728Swpaul/*
216728Swpaul * Copyright (c) 1995, 1996
316728Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
416728Swpaul *
516728Swpaul * Redistribution and use in source and binary forms, with or without
616728Swpaul * modification, are permitted provided that the following conditions
716728Swpaul * are met:
816728Swpaul * 1. Redistributions of source code must retain the above copyright
916728Swpaul *    notice, this list of conditions and the following disclaimer.
1016728Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1116728Swpaul *    notice, this list of conditions and the following disclaimer in the
1216728Swpaul *    documentation and/or other materials provided with the distribution.
1316728Swpaul * 3. All advertising materials mentioning features or use of this software
1416728Swpaul *    must display the following acknowledgement:
1516728Swpaul *	This product includes software developed by Bill Paul.
1616728Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1716728Swpaul *    may be used to endorse or promote products derived from this software
1816728Swpaul *    without specific prior written permission.
1916728Swpaul *
2016728Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2116728Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2216728Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2316728Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2416728Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2516728Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2616728Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2716728Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2816728Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2916728Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3016728Swpaul * SUCH DAMAGE.
3116728Swpaul *
3216728Swpaul * netid map generator program
3316728Swpaul *
3416728Swpaul * Written by Bill Paul <wpaul@ctr.columbia.edu>
3516728Swpaul * Center for Telecommunications Research
3616728Swpaul * Columbia University, New York City
3716728Swpaul */
3816728Swpaul
3917115Sbde#include <sys/types.h>
4017115Sbde
4117115Sbde#include <rpc/rpc.h>
4217115Sbde#include <rpcsvc/yp_prot.h>
4317115Sbde#include <rpcsvc/ypclnt.h>
4417115Sbde
4517115Sbde#include <err.h>
4617115Sbde#include <grp.h>
4731385Scharnier#include <netdb.h>
4817115Sbde#include <pwd.h>
4916728Swpaul#include <stdio.h>
5016728Swpaul#include <stdlib.h>
5116728Swpaul#include <string.h>
5231385Scharnier#include <unistd.h>
5317115Sbde
5416728Swpaul#include "hash.h"
5516728Swpaul
5616728Swpaul#ifndef lint
5731385Scharnierstatic const char rcsid[] =
5850476Speter  "$FreeBSD: head/libexec/mknetid/mknetid.c 90779 2002-02-17 19:09:20Z imp $";
5931385Scharnier#endif /* not lint */
6016728Swpaul
6116728Swpaul#define LINSIZ 1024
6216728Swpaul#define OPSYS "unix"
6316728Swpaul
6416728Swpaul/* Default location of group file. */
6516728Swpaulchar *groupfile = _PATH_GROUP;
6616728Swpaul/* Default location of master.passwd file. */
6716728Swpaulchar *passfile = _PATH_PASSWD;
6816728Swpaul/* Default location of hosts file. */
6916728Swpaulchar *hostsfile = _PATH_HOSTS;
7016728Swpaul/* Default location of netid file */
7116728Swpaulchar *netidfile = "/etc/netid";
7216728Swpaul
7316728Swpaul/*
7416728Swpaul * Stored hash table of 'reverse' group member database
7516728Swpaul * which we will construct.
7616728Swpaul */
7716728Swpaulstruct member_entry *mtable[TABLESIZE];
7816728Swpaul
7916728Swpaul/*
8016728Swpaul * Dupe table: used to keep track of entries so we don't
8116728Swpaul * print the same thing twice.
8216728Swpaul */
8316728Swpaulstruct member_entry *dtable[TABLESIZE];
8416728Swpaul
8590779Simpextern struct group *_getgrent(void);
8690779Simpextern int _setgrent(void);
8790779Simpextern void _endgrent(void);
8831385Scharnier
8931385Scharnierstatic void
9090779Simpusage(void)
9116728Swpaul{
9231385Scharnier	fprintf (stderr, "%s\n%s\n",
9331385Scharnier	"usage: mknetid [-q] [-g group_file] [-p passwd_file] [-h hosts_file]",
9431737Scharnier	"               [-d netid_file] [-d domain]");
9516728Swpaul	exit(1);
9616728Swpaul}
9716728Swpaul
9816728Swpaulextern FILE *_gr_fp;
9916728Swpaul
10031385Scharnierint
10190779Simpmain(int argc, char *argv[])
10216728Swpaul{
10316728Swpaul	FILE *gfp, *pfp, *hfp, *nfp;
10416728Swpaul	char readbuf[LINSIZ];
10516728Swpaul	char writebuf[LINSIZ];
10616728Swpaul	struct group *gr;
10716728Swpaul	struct grouplist *glist;
10816728Swpaul	char *domain;
10916728Swpaul	int ch;
11016728Swpaul	gid_t i;
11116728Swpaul	char *ptr, *pidptr, *gidptr, *hptr;
11216728Swpaul	int quiet = 0;
11316728Swpaul
11424349Simp	while ((ch = getopt(argc, argv, "g:p:h:n:d:q")) != -1) {
11516728Swpaul		switch(ch) {
11616728Swpaul		case 'g':
11716728Swpaul			groupfile = optarg;
11816728Swpaul			break;
11916728Swpaul		case 'p':
12016728Swpaul			passfile = optarg;
12116728Swpaul			break;
12216728Swpaul		case 'h':
12316728Swpaul			hostsfile = optarg;
12416728Swpaul			break;
12516728Swpaul		case 'n':
12616728Swpaul			netidfile = optarg;
12716728Swpaul			break;
12816728Swpaul		case 'd':
12916728Swpaul			domain = optarg;
13016728Swpaul			break;
13116728Swpaul		case 'q':
13216728Swpaul			quiet++;
13316728Swpaul			break;
13416728Swpaul		default:
13531385Scharnier			usage();
13616728Swpaul			break;
13716728Swpaul		}
13816728Swpaul	}
13916728Swpaul
14016728Swpaul	if (domain == NULL) {
14116728Swpaul		if (yp_get_default_domain(&domain))
14216728Swpaul			errx(1, "no domain name specified and default \
14316728Swpauldomain not set");
14416728Swpaul	}
14516728Swpaul
14616728Swpaul	if ((gfp = fopen(groupfile, "r")) == NULL) {
14716728Swpaul		err(1, "%s", groupfile);
14816728Swpaul	}
14916728Swpaul
15016728Swpaul	if ((pfp = fopen(passfile, "r")) == NULL) {
15116728Swpaul		err(1, "%s", passfile);
15216728Swpaul	}
15316728Swpaul
15416728Swpaul	if ((hfp = fopen(hostsfile, "r")) == NULL) {
15516728Swpaul		err(1, "%s", hostsfile);
15616728Swpaul	}
15716728Swpaul
15816728Swpaul	if ((nfp = fopen(netidfile, "r")) == NULL) {
15916728Swpaul		/* netid is optional -- just continue */
16016728Swpaul		nfp = NULL;
16116728Swpaul	}
16216728Swpaul
16316728Swpaul	_gr_fp = gfp;
16416728Swpaul
16516728Swpaul	/* Load all the group membership info into a hash table. */
16616728Swpaul
16716728Swpaul	_setgrent();
16816728Swpaul	while((gr = _getgrent()) != NULL) {
16916728Swpaul		while(*gr->gr_mem) {
17016728Swpaul			mstore(mtable, *gr->gr_mem, gr->gr_gid, 0);
17116728Swpaul			gr->gr_mem++;
17216728Swpaul		}
17316728Swpaul	}
17416728Swpaul
17516728Swpaul	fclose(gfp);
17616728Swpaul	_endgrent();
17716728Swpaul
17816728Swpaul	/*
17916728Swpaul	 * Now parse the passwd database, spewing out the extra
18016728Swpaul	 * group information we just stored if necessary.
18116728Swpaul	 */
18216728Swpaul	while(fgets(readbuf, LINSIZ, pfp)) {
18316728Swpaul		if ((ptr = strchr(readbuf, ':')) == NULL)
18416728Swpaul			warnx("bad passwd file entry: %s", readbuf);
18516728Swpaul		*ptr = '\0';
18616728Swpaul		ptr++;
18716728Swpaul		if ((ptr = strchr(ptr, ':')) == NULL)
18816728Swpaul			warnx("bad passwd file entry: %s", readbuf);
18916728Swpaul		*ptr = '\0';
19016728Swpaul		ptr++;
19116728Swpaul		pidptr = ptr;
19216728Swpaul		if ((ptr = strchr(ptr, ':')) == NULL)
19316728Swpaul			warnx("bad passwd file entry: %s", readbuf);
19416728Swpaul		*ptr = '\0';
19516728Swpaul		ptr++;
19616728Swpaul		gidptr = ptr;
19716728Swpaul		if ((ptr = strchr(ptr, ':')) == NULL)
19816728Swpaul			warnx("bad passwd file entry: %s", readbuf);
19916728Swpaul		*ptr = '\0';
20016728Swpaul		i = atol(gidptr);
20116728Swpaul
20216728Swpaul		snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS,
20316728Swpaul							pidptr, domain);
20416728Swpaul
20516728Swpaul		if (lookup(dtable, writebuf)) {
20616728Swpaul			if (!quiet)
20716728Swpaul				warnx("duplicate netid '%s.%s@%s' -- skipping",
20816728Swpaul						OPSYS, pidptr, domain);
20916728Swpaul			continue;
21016728Swpaul		} else {
21116728Swpaul			mstore(dtable, writebuf, 0, 1);
21216728Swpaul		}
21316793Swpaul		printf("%s.%s@%s %s:%s", OPSYS, pidptr, domain, pidptr, gidptr);
21416728Swpaul		if ((glist = lookup(mtable, (char *)&readbuf)) != NULL) {
21516728Swpaul			while(glist) {
21616728Swpaul				if (glist->groupid != i)
21737297Sbde					printf(",%lu", (u_long)glist->groupid);
21816728Swpaul				glist = glist->next;
21916728Swpaul			}
22016728Swpaul		}
22116728Swpaul		printf ("\n");
22216728Swpaul	}
22316728Swpaul
22416728Swpaul	fclose(pfp);
22516728Swpaul
22616728Swpaul	/*
22716728Swpaul	 * Now parse the hosts database (this part sucks).
22816728Swpaul	 */
22916728Swpaul
23016728Swpaul	while ((ptr = fgets(readbuf, LINSIZ, hfp))) {
23116728Swpaul		if (*ptr == '#')
23216728Swpaul			continue;
23316728Swpaul		if (!(hptr = strpbrk(ptr, "#\n")))
23416728Swpaul			continue;
23516728Swpaul		*hptr = '\0';
23616728Swpaul		if (!(hptr = strpbrk(ptr, " \t")))
23716728Swpaul			continue;
23816728Swpaul		*hptr++ = '\0';
23916728Swpaul		ptr = hptr;
24016728Swpaul		while (*ptr == ' ' || *ptr == '\t')
24116728Swpaul			ptr++;
24216728Swpaul		if (!(hptr = strpbrk(ptr, " \t")))
24316728Swpaul			continue;
24416728Swpaul		*hptr++ = '\0';
24516728Swpaul		snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS,
24616728Swpaul								ptr, domain);
24716728Swpaul		if (lookup(dtable, (char *)&writebuf)) {
24816728Swpaul			if (!quiet)
24916728Swpaul				warnx("duplicate netid '%s' -- skipping",
25016728Swpaul								writebuf);
25116728Swpaul			continue;
25216728Swpaul		} else {
25316728Swpaul			mstore(dtable, (char *)&writebuf, 0, 1);
25416728Swpaul		}
25516793Swpaul		printf ("%s.%s@%s 0:%s\n", OPSYS, ptr, domain, ptr);
25616728Swpaul	}
25716728Swpaul
25816728Swpaul	fclose(hfp);
25916728Swpaul
26016728Swpaul	/*
26116728Swpaul	 * Lastly, copy out any extra information in the netid
26216728Swpaul	 * file. If it's not open, just ignore it: it's optional anyway.
26316728Swpaul	 */
26416728Swpaul
26516728Swpaul	if (nfp != NULL) {
26616728Swpaul		while(fgets(readbuf, LINSIZ, nfp)) {
26716728Swpaul			if (readbuf[0] == '#')
26816728Swpaul				continue;
26916728Swpaul			if ((ptr = strpbrk((char*)&readbuf, " \t")) == NULL) {
27016728Swpaul				warnx("bad netid entry: '%s'", readbuf);
27116728Swpaul				continue;
27216728Swpaul			}
27316728Swpaul
27416728Swpaul			writebuf[0] = *ptr;
27516728Swpaul			*ptr = '\0';
27616728Swpaul			if (lookup(dtable, (char *)&readbuf)) {
27716728Swpaul				if (!quiet)
27816728Swpaul					warnx("duplicate netid '%s' -- skipping",
27916728Swpaul								readbuf);
28016728Swpaul				continue;
28116728Swpaul			} else {
28216728Swpaul				mstore(dtable, (char *)&readbuf, 0, 1);
28316728Swpaul			}
28416728Swpaul			*ptr = writebuf[0];
28516728Swpaul			printf("%s",readbuf);
28616728Swpaul		}
28716728Swpaul		fclose(nfp);
28816728Swpaul	}
28916728Swpaul
29016728Swpaul	exit(0);
29116728Swpaul}
292