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$"; 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]", 94106811Smaxim " [-n 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 114106811Smaxim domain = NULL; 11524349Simp while ((ch = getopt(argc, argv, "g:p:h:n:d:q")) != -1) { 11616728Swpaul switch(ch) { 11716728Swpaul case 'g': 11816728Swpaul groupfile = optarg; 11916728Swpaul break; 12016728Swpaul case 'p': 12116728Swpaul passfile = optarg; 12216728Swpaul break; 12316728Swpaul case 'h': 12416728Swpaul hostsfile = optarg; 12516728Swpaul break; 12616728Swpaul case 'n': 12716728Swpaul netidfile = optarg; 12816728Swpaul break; 12916728Swpaul case 'd': 13016728Swpaul domain = optarg; 13116728Swpaul break; 13216728Swpaul case 'q': 13316728Swpaul quiet++; 13416728Swpaul break; 13516728Swpaul default: 13631385Scharnier usage(); 13716728Swpaul break; 13816728Swpaul } 13916728Swpaul } 14016728Swpaul 14116728Swpaul if (domain == NULL) { 14216728Swpaul if (yp_get_default_domain(&domain)) 14316728Swpaul errx(1, "no domain name specified and default \ 14416728Swpauldomain not set"); 14516728Swpaul } 14616728Swpaul 14716728Swpaul if ((gfp = fopen(groupfile, "r")) == NULL) { 14816728Swpaul err(1, "%s", groupfile); 14916728Swpaul } 15016728Swpaul 15116728Swpaul if ((pfp = fopen(passfile, "r")) == NULL) { 15216728Swpaul err(1, "%s", passfile); 15316728Swpaul } 15416728Swpaul 15516728Swpaul if ((hfp = fopen(hostsfile, "r")) == NULL) { 15616728Swpaul err(1, "%s", hostsfile); 15716728Swpaul } 15816728Swpaul 15916728Swpaul if ((nfp = fopen(netidfile, "r")) == NULL) { 16016728Swpaul /* netid is optional -- just continue */ 16116728Swpaul nfp = NULL; 16216728Swpaul } 16316728Swpaul 16416728Swpaul _gr_fp = gfp; 16516728Swpaul 16616728Swpaul /* Load all the group membership info into a hash table. */ 16716728Swpaul 16816728Swpaul _setgrent(); 16916728Swpaul while((gr = _getgrent()) != NULL) { 17016728Swpaul while(*gr->gr_mem) { 17116728Swpaul mstore(mtable, *gr->gr_mem, gr->gr_gid, 0); 17216728Swpaul gr->gr_mem++; 17316728Swpaul } 17416728Swpaul } 17516728Swpaul 17616728Swpaul fclose(gfp); 17716728Swpaul _endgrent(); 17816728Swpaul 17916728Swpaul /* 18016728Swpaul * Now parse the passwd database, spewing out the extra 18116728Swpaul * group information we just stored if necessary. 18216728Swpaul */ 18316728Swpaul while(fgets(readbuf, LINSIZ, pfp)) { 184106811Smaxim /* Ignore comments: ^[ \t]*# */ 185106811Smaxim for (ptr = readbuf; *ptr != '\0'; ptr++) 186106811Smaxim if (*ptr != ' ' && *ptr != '\t') 187106811Smaxim break; 188106811Smaxim if (*ptr == '#' || *ptr == '\0') 189106811Smaxim continue; 190106811Smaxim if ((ptr = strchr(readbuf, ':')) == NULL) { 19116728Swpaul warnx("bad passwd file entry: %s", readbuf); 192106811Smaxim continue; 193106811Smaxim } 19416728Swpaul *ptr = '\0'; 19516728Swpaul ptr++; 196106811Smaxim if ((ptr = strchr(ptr, ':')) == NULL) { 19716728Swpaul warnx("bad passwd file entry: %s", readbuf); 198106811Smaxim continue; 199106811Smaxim } 20016728Swpaul *ptr = '\0'; 20116728Swpaul ptr++; 20216728Swpaul pidptr = ptr; 203106811Smaxim if ((ptr = strchr(ptr, ':')) == NULL) { 20416728Swpaul warnx("bad passwd file entry: %s", readbuf); 205106811Smaxim continue; 206106811Smaxim } 20716728Swpaul *ptr = '\0'; 20816728Swpaul ptr++; 20916728Swpaul gidptr = ptr; 210106811Smaxim if ((ptr = strchr(ptr, ':')) == NULL) { 21116728Swpaul warnx("bad passwd file entry: %s", readbuf); 212106811Smaxim continue; 213106811Smaxim } 21416728Swpaul *ptr = '\0'; 21516728Swpaul i = atol(gidptr); 21616728Swpaul 21716728Swpaul snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS, 21816728Swpaul pidptr, domain); 21916728Swpaul 22016728Swpaul if (lookup(dtable, writebuf)) { 22116728Swpaul if (!quiet) 22216728Swpaul warnx("duplicate netid '%s.%s@%s' -- skipping", 22316728Swpaul OPSYS, pidptr, domain); 22416728Swpaul continue; 22516728Swpaul } else { 22616728Swpaul mstore(dtable, writebuf, 0, 1); 22716728Swpaul } 22816793Swpaul printf("%s.%s@%s %s:%s", OPSYS, pidptr, domain, pidptr, gidptr); 22916728Swpaul if ((glist = lookup(mtable, (char *)&readbuf)) != NULL) { 23016728Swpaul while(glist) { 23116728Swpaul if (glist->groupid != i) 23237297Sbde printf(",%lu", (u_long)glist->groupid); 23316728Swpaul glist = glist->next; 23416728Swpaul } 23516728Swpaul } 23616728Swpaul printf ("\n"); 23716728Swpaul } 23816728Swpaul 23916728Swpaul fclose(pfp); 24016728Swpaul 24116728Swpaul /* 24216728Swpaul * Now parse the hosts database (this part sucks). 24316728Swpaul */ 24416728Swpaul 24516728Swpaul while ((ptr = fgets(readbuf, LINSIZ, hfp))) { 24616728Swpaul if (*ptr == '#') 24716728Swpaul continue; 24816728Swpaul if (!(hptr = strpbrk(ptr, "#\n"))) 24916728Swpaul continue; 25016728Swpaul *hptr = '\0'; 25116728Swpaul if (!(hptr = strpbrk(ptr, " \t"))) 25216728Swpaul continue; 25316728Swpaul *hptr++ = '\0'; 25416728Swpaul ptr = hptr; 25516728Swpaul while (*ptr == ' ' || *ptr == '\t') 25616728Swpaul ptr++; 25716728Swpaul if (!(hptr = strpbrk(ptr, " \t"))) 25816728Swpaul continue; 25916728Swpaul *hptr++ = '\0'; 26016728Swpaul snprintf(writebuf, sizeof(writebuf), "%s.%s@%s", OPSYS, 26116728Swpaul ptr, domain); 26216728Swpaul if (lookup(dtable, (char *)&writebuf)) { 26316728Swpaul if (!quiet) 26416728Swpaul warnx("duplicate netid '%s' -- skipping", 26516728Swpaul writebuf); 26616728Swpaul continue; 26716728Swpaul } else { 26816728Swpaul mstore(dtable, (char *)&writebuf, 0, 1); 26916728Swpaul } 27016793Swpaul printf ("%s.%s@%s 0:%s\n", OPSYS, ptr, domain, ptr); 27116728Swpaul } 27216728Swpaul 27316728Swpaul fclose(hfp); 27416728Swpaul 27516728Swpaul /* 27616728Swpaul * Lastly, copy out any extra information in the netid 27716728Swpaul * file. If it's not open, just ignore it: it's optional anyway. 27816728Swpaul */ 27916728Swpaul 28016728Swpaul if (nfp != NULL) { 28116728Swpaul while(fgets(readbuf, LINSIZ, nfp)) { 28216728Swpaul if (readbuf[0] == '#') 28316728Swpaul continue; 28416728Swpaul if ((ptr = strpbrk((char*)&readbuf, " \t")) == NULL) { 28516728Swpaul warnx("bad netid entry: '%s'", readbuf); 28616728Swpaul continue; 28716728Swpaul } 28816728Swpaul 28916728Swpaul writebuf[0] = *ptr; 29016728Swpaul *ptr = '\0'; 29116728Swpaul if (lookup(dtable, (char *)&readbuf)) { 29216728Swpaul if (!quiet) 29316728Swpaul warnx("duplicate netid '%s' -- skipping", 29416728Swpaul readbuf); 29516728Swpaul continue; 29616728Swpaul } else { 29716728Swpaul mstore(dtable, (char *)&readbuf, 0, 1); 29816728Swpaul } 29916728Swpaul *ptr = writebuf[0]; 30016728Swpaul printf("%s",readbuf); 30116728Swpaul } 30216728Swpaul fclose(nfp); 30316728Swpaul } 30416728Swpaul 30516728Swpaul exit(0); 30616728Swpaul} 307