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