Home | History | Annotate | Line # | Download | only in mkalias
mkalias.c revision 1.15.10.1
      1  1.15.10.1     jym /*	$NetBSD: mkalias.c,v 1.15.10.1 2009/05/13 19:20:45 jym Exp $ */
      2        1.1   lukem 
      3        1.1   lukem /*
      4        1.1   lukem  * Copyright (c) 1997 Mats O Jansson <moj (at) stacken.kth.se>
      5        1.1   lukem  * All rights reserved.
      6        1.1   lukem  *
      7        1.1   lukem  * Redistribution and use in source and binary forms, with or without
      8        1.1   lukem  * modification, are permitted provided that the following conditions
      9        1.1   lukem  * are met:
     10        1.1   lukem  * 1. Redistributions of source code must retain the above copyright
     11        1.1   lukem  *    notice, this list of conditions and the following disclaimer.
     12        1.1   lukem  * 2. Redistributions in binary form must reproduce the above copyright
     13        1.1   lukem  *    notice, this list of conditions and the following disclaimer in the
     14        1.1   lukem  *    documentation and/or other materials provided with the distribution.
     15        1.1   lukem  * 3. All advertising materials mentioning features or use of this software
     16        1.1   lukem  *    must display the following acknowledgement:
     17        1.1   lukem  *	This product includes software developed by Mats O Jansson
     18        1.1   lukem  * 4. The name of the author may not be used to endorse or promote products
     19        1.1   lukem  *    derived from this software without specific prior written permission.
     20        1.1   lukem  *
     21        1.1   lukem  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     22        1.1   lukem  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     23        1.1   lukem  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24        1.1   lukem  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     25        1.1   lukem  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26        1.1   lukem  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27        1.1   lukem  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28        1.1   lukem  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29        1.1   lukem  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30        1.1   lukem  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31        1.1   lukem  * SUCH DAMAGE.
     32        1.1   lukem  */
     33        1.1   lukem 
     34        1.2   lukem #include <sys/cdefs.h>
     35        1.4   lukem #ifndef lint
     36  1.15.10.1     jym __RCSID("$NetBSD: mkalias.c,v 1.15.10.1 2009/05/13 19:20:45 jym Exp $");
     37        1.1   lukem #endif
     38        1.1   lukem 
     39        1.2   lukem #include <sys/types.h>
     40        1.2   lukem #include <sys/param.h>
     41        1.2   lukem #include <netinet/in.h>
     42        1.2   lukem #include <arpa/nameser.h>
     43        1.2   lukem 
     44        1.1   lukem #include <ctype.h>
     45        1.2   lukem #include <err.h>
     46        1.1   lukem #include <netdb.h>
     47        1.2   lukem #include <resolv.h>
     48        1.1   lukem #include <stdio.h>
     49        1.6  kleink #include <stdlib.h>
     50        1.1   lukem #include <string.h>
     51        1.7  kleink #include <time.h>
     52        1.1   lukem #include <unistd.h>
     53        1.2   lukem 
     54        1.2   lukem #include <rpc/rpc.h>
     55        1.2   lukem 
     56        1.5   lukem #include "protos.h"
     57        1.1   lukem #include "ypdb.h"
     58        1.1   lukem #include "ypdef.h"
     59        1.1   lukem 
     60       1.10     wiz void	capitalize(char *, int);
     61       1.10     wiz int	check_host(char *, char *, int, int, int);
     62       1.10     wiz int	main(int, char *[]);
     63       1.10     wiz void	split_address(char *, int, char *, char *);
     64       1.10     wiz void	usage(void);
     65        1.2   lukem 
     66        1.1   lukem void
     67       1.10     wiz split_address(char *address, int len, char *user, char *host)
     68        1.1   lukem {
     69        1.2   lukem 	char *c, *s, *r;
     70        1.1   lukem 	int  i = 0;
     71        1.1   lukem 
     72        1.2   lukem 	if ((strchr(address, '@')) != NULL) {
     73        1.1   lukem 
     74        1.1   lukem 		s = user;
     75        1.1   lukem 
     76        1.1   lukem 		for(c = address; i < len; i++) {
     77        1.1   lukem 			if (*c == '@') {
     78        1.1   lukem 				*s = '\0';
     79        1.1   lukem 				s = host;
     80        1.2   lukem 			} else
     81        1.1   lukem 				*s++ = *c;
     82        1.1   lukem 			c++;
     83        1.1   lukem 		}
     84        1.1   lukem 		*s = '\0';
     85        1.1   lukem 	}
     86        1.1   lukem 
     87        1.2   lukem 	if ((r = strrchr(address, '!')) != NULL) {
     88        1.1   lukem 
     89        1.1   lukem 		s = host;
     90        1.1   lukem 
     91        1.1   lukem 		for(c = address; i < len; i++) {
     92        1.1   lukem 			if (c == r) {
     93        1.1   lukem 				*s = '\0';
     94        1.1   lukem 				s = user;
     95        1.2   lukem 			} else
     96        1.1   lukem 				*s++ = *c;
     97        1.1   lukem 			c++;
     98        1.1   lukem 		}
     99        1.1   lukem 		*s = '\0';
    100        1.1   lukem 	}
    101        1.1   lukem }
    102        1.1   lukem 
    103        1.1   lukem int
    104       1.10     wiz check_host(char *address, char *host, int dflag, int uflag, int Eflag)
    105        1.1   lukem {
    106       1.14     mrg 	u_char answer[PACKETSZ];
    107        1.1   lukem 	int  status;
    108        1.1   lukem 
    109        1.2   lukem 	if ((dflag && strchr(address, '@')) ||
    110        1.2   lukem 	    (uflag && strchr(address, '!')))
    111        1.2   lukem 		return(0);
    112        1.1   lukem 
    113        1.1   lukem 	if ((_res.options & RES_INIT) == 0)
    114        1.1   lukem 		res_init();
    115        1.1   lukem 
    116        1.1   lukem 	status = res_search(host, C_IN, T_AAAA, answer, sizeof(answer));
    117        1.1   lukem 
    118        1.1   lukem 	if (status == -1)
    119        1.1   lukem 		status = res_search(host, C_IN, T_A, answer, sizeof(answer));
    120        1.1   lukem 
    121        1.1   lukem 	if ((status == -1) && Eflag)
    122        1.1   lukem 		status = res_search(host, C_IN, T_MX, answer, sizeof(answer));
    123        1.1   lukem 
    124        1.1   lukem 	return(status == -1);
    125        1.1   lukem }
    126        1.1   lukem 
    127        1.1   lukem void
    128       1.10     wiz capitalize(char *name, int len)
    129        1.1   lukem {
    130        1.1   lukem 	char last = ' ';
    131        1.1   lukem 	char *c;
    132        1.1   lukem 	int  i = 0;
    133        1.1   lukem 
    134        1.1   lukem 	for(c = name; i < len; i++) {
    135        1.1   lukem 		if (*c == '.') last = '.';
    136        1.1   lukem 		c++;
    137        1.1   lukem 	}
    138        1.1   lukem 
    139        1.1   lukem 	i = 0;
    140        1.1   lukem 	if (last == '.') {
    141        1.1   lukem 		for(c = name; i < len; i++) {
    142        1.2   lukem 			if (last == '.')
    143       1.12     dsl 				*c = toupper((unsigned char)*c);
    144        1.1   lukem 			last = *c++;
    145        1.1   lukem 		}
    146        1.1   lukem 	}
    147        1.1   lukem }
    148        1.1   lukem 
    149        1.1   lukem int
    150       1.10     wiz main(int argc, char *argv[])
    151        1.1   lukem {
    152        1.1   lukem 	int	eflag = 0;
    153        1.1   lukem 	int	dflag = 0;
    154        1.1   lukem 	int	nflag = 0;
    155        1.1   lukem 	int	sflag = 0;
    156        1.1   lukem 	int	uflag = 0;
    157        1.1   lukem 	int	vflag = 0;
    158        1.1   lukem 	int	Eflag = 0;
    159        1.1   lukem 	int	ch;
    160        1.1   lukem 	char	*input = NULL;
    161        1.1   lukem 	char	*output = NULL;
    162        1.1   lukem 	DBM	*db;
    163        1.2   lukem 	datum	key, val;
    164        1.1   lukem 	char	*slash;
    165        1.1   lukem 	DBM	*new_db = NULL;
    166       1.15   lukem 	static	const char template[] = "ypdbXXXXXX";
    167       1.15   lukem 	char	db_mapname[MAXPATHLEN], db_outfile[MAXPATHLEN];
    168        1.1   lukem 	int	status;
    169        1.2   lukem 	char	user[4096], host[4096]; /* XXX: DB bsize = 4096 in ypdb.c */
    170        1.1   lukem 	char	datestr[11];
    171        1.1   lukem 	char	myname[MAXHOSTNAMELEN];
    172        1.1   lukem 
    173        1.2   lukem 	while ((ch = getopt(argc, argv, "Edensuv")) != -1) {
    174        1.2   lukem 		switch(ch) {
    175        1.2   lukem 		case 'd':
    176        1.2   lukem 			dflag++;		/* Don't check DNS hostname */
    177        1.2   lukem 			break;
    178        1.2   lukem 
    179        1.2   lukem 		case 'e':
    180        1.2   lukem 			eflag++;		/* Check hostname */
    181        1.2   lukem 			break;
    182        1.2   lukem 
    183        1.2   lukem 		case 'E':
    184        1.2   lukem 			eflag++;		/* Check hostname */
    185        1.2   lukem 			Eflag++;		/* .. even check MX records */
    186        1.2   lukem 			break;
    187        1.2   lukem 
    188        1.2   lukem 		case 'n':
    189        1.2   lukem 			nflag++;		/* Capitalize name parts */
    190        1.2   lukem 			break;
    191        1.2   lukem 
    192        1.2   lukem 		case 's':
    193        1.2   lukem 			sflag++;		/* Don't know... */
    194        1.2   lukem 			break;
    195        1.2   lukem 
    196        1.2   lukem 		case 'u':
    197        1.2   lukem 			uflag++;		/* Don't check UUCP hostname */
    198        1.2   lukem 			break;
    199        1.2   lukem 
    200        1.2   lukem 		case 'v':
    201        1.2   lukem 			vflag++;		/* Verbose */
    202        1.2   lukem 			break;
    203        1.2   lukem 
    204        1.2   lukem 		default:
    205        1.2   lukem 			usage();
    206        1.2   lukem 		}
    207        1.1   lukem 	}
    208        1.1   lukem 
    209        1.2   lukem 	if (optind == argc)
    210        1.2   lukem 		usage();
    211        1.2   lukem 
    212        1.2   lukem 	input = argv[optind++];
    213        1.2   lukem 	if (optind < argc)
    214        1.2   lukem 		output = argv[optind++];
    215        1.2   lukem 	if (optind < argc)
    216        1.2   lukem 		usage();
    217        1.1   lukem 
    218       1.15   lukem 	db = ypdb_open(input);
    219        1.2   lukem 	if (db == NULL)
    220        1.3   lukem 		err(1, "Unable to open input database `%s'", input);
    221        1.1   lukem 
    222        1.1   lukem 	if (output != NULL) {
    223       1.13   lukem 		if (strlen(output) + strlen(YPDB_SUFFIX) >
    224       1.13   lukem 		    (sizeof(db_outfile) + 1))
    225        1.2   lukem 			warnx("file name `%s' too long", output);
    226        1.1   lukem 		snprintf(db_outfile, sizeof(db_outfile),
    227        1.1   lukem 			 "%s%s", output, YPDB_SUFFIX);
    228        1.1   lukem 
    229        1.1   lukem 		slash = strrchr(output, '/');
    230        1.1   lukem 		if (slash != NULL)
    231        1.1   lukem 			slash[1] = 0; 			/* truncate to dir */
    232        1.1   lukem 		else
    233        1.1   lukem 			*output = 0;			/* elminate */
    234        1.1   lukem 
    235        1.1   lukem 		/* note: output is now directory where map goes ! */
    236        1.1   lukem 
    237       1.15   lukem 		if (strlen(output) + strlen(template) + strlen(YPDB_SUFFIX) >
    238       1.13   lukem 		    (sizeof(db_mapname) - 1))
    239        1.3   lukem 			errx(1, "Directory name `%s' too long", output);
    240        1.1   lukem 
    241       1.15   lukem 		snprintf(db_mapname, sizeof(db_mapname), "%s%s",
    242       1.15   lukem 		    output, template);
    243        1.1   lukem 
    244       1.15   lukem 		new_db = ypdb_mktemp(db_mapname);
    245        1.2   lukem 		if (new_db == NULL)
    246        1.3   lukem 			err(1, "Unable to open output database `%s'",
    247        1.2   lukem 			    db_outfile);
    248        1.1   lukem 	}
    249        1.1   lukem 
    250        1.1   lukem 	for (key = ypdb_firstkey(db);
    251        1.1   lukem 	     key.dptr != NULL;
    252        1.1   lukem 	     key = ypdb_nextkey(db)) {
    253        1.1   lukem 
    254        1.2   lukem 	        val = ypdb_fetch(db, key);
    255        1.1   lukem 
    256        1.2   lukem 		if (val.dptr == NULL)
    257        1.2   lukem 			continue;			/* No value */
    258        1.1   lukem 		if ((*key.dptr == '@') && (key.dsize == 1))
    259        1.1   lukem 			continue;			/* Sendmail token */
    260        1.1   lukem 		if (strncmp(key.dptr, "YP_", 3)==0)	/* YP token */
    261        1.1   lukem 			continue;
    262        1.2   lukem 		if (strchr(val.dptr, ','))		/* List... */
    263        1.2   lukem 			continue;
    264        1.2   lukem 		if (strchr(val.dptr, '|'))		/* Pipe... */
    265        1.2   lukem 			continue;
    266        1.1   lukem 
    267        1.2   lukem 		if (!((strchr(val.dptr, '@')) ||
    268        1.2   lukem 		    (strchr(val.dptr, '!'))))
    269        1.2   lukem 			continue;			/* Skip local users */
    270        1.1   lukem 
    271        1.2   lukem 		split_address(val.dptr, val.dsize, user, host);
    272        1.1   lukem 
    273        1.1   lukem 		if (eflag && check_host(val.dptr, host, dflag, uflag, Eflag)) {
    274        1.2   lukem 			printf("Invalid host %s in %*.*s:%*.*s\n", host,
    275        1.1   lukem 			       key.dsize, key.dsize, key.dptr,
    276        1.1   lukem 			       val.dsize, val.dsize, val.dptr);
    277        1.1   lukem 			continue;
    278        1.1   lukem 		}
    279        1.1   lukem 
    280        1.2   lukem 		if (nflag)
    281        1.2   lukem 			capitalize(key.dptr, key.dsize);
    282        1.1   lukem 
    283        1.1   lukem 		if (new_db != NULL) {
    284        1.1   lukem 			status = ypdb_store(new_db, val, key, YPDB_INSERT);
    285        1.1   lukem 			if (status != 0) {
    286        1.1   lukem 				printf("%s: problem storing %*.*s %*.*s\n",
    287        1.9     cgd 				       getprogname(),
    288        1.1   lukem 				       val.dsize, val.dsize, val.dptr,
    289        1.1   lukem 				       key.dsize, key.dsize, key.dptr);
    290        1.1   lukem 			}
    291        1.1   lukem 		}
    292        1.1   lukem 
    293        1.1   lukem 		if (vflag) {
    294        1.1   lukem 			printf("%*.*s --> %*.*s\n",
    295        1.1   lukem 			       val.dsize, val.dsize, val.dptr,
    296        1.1   lukem 			       key.dsize, key.dsize, key.dptr);
    297        1.1   lukem 		}
    298        1.1   lukem 
    299        1.1   lukem 	}
    300        1.1   lukem 
    301        1.1   lukem 	if (new_db != NULL) {
    302       1.11  itojun 	  	snprintf(datestr, sizeof(datestr), "%010d", (int)time(NULL));
    303  1.15.10.1     jym 		key.dptr = __UNCONST(YP_LAST_KEY);
    304        1.1   lukem 		key.dsize = strlen(YP_LAST_KEY);
    305        1.1   lukem 		val.dptr = datestr;
    306        1.1   lukem 		val.dsize = strlen(datestr);
    307        1.1   lukem 		status = ypdb_store(new_db, key, val, YPDB_INSERT);
    308        1.2   lukem 		if (status != 0)
    309        1.2   lukem 			warnx("problem storing %*.*s %*.*s",
    310        1.1   lukem 			       key.dsize, key.dsize, key.dptr,
    311        1.1   lukem 			       val.dsize, val.dsize, val.dptr);
    312        1.1   lukem 	}
    313        1.1   lukem 
    314        1.1   lukem 	if (new_db != NULL) {
    315        1.5   lukem 	  	localhostname(myname, sizeof(myname) - 1);
    316  1.15.10.1     jym 		key.dptr = __UNCONST(YP_MASTER_KEY);
    317        1.1   lukem 		key.dsize = strlen(YP_MASTER_KEY);
    318        1.1   lukem 		val.dptr = myname;
    319        1.1   lukem 		val.dsize = strlen(myname);
    320        1.1   lukem 		status = ypdb_store(new_db, key, val, YPDB_INSERT);
    321        1.2   lukem 		if (status != 0)
    322        1.2   lukem 			warnx("problem storing %*.*s %*.*s",
    323        1.1   lukem 			       key.dsize, key.dsize, key.dptr,
    324        1.1   lukem 			       val.dsize, val.dsize, val.dptr);
    325        1.1   lukem 	}
    326        1.1   lukem 
    327        1.1   lukem 	ypdb_close(db);
    328        1.1   lukem 
    329        1.1   lukem 	if (new_db != NULL) {
    330        1.1   lukem 		ypdb_close(new_db);
    331        1.2   lukem 		if (rename(db_mapname, db_outfile) < 0)
    332        1.2   lukem 			err(1, "rename `%s' to `%s' failed", db_mapname,
    333        1.1   lukem 				db_outfile);
    334        1.1   lukem 	}
    335        1.1   lukem 
    336        1.2   lukem 	exit(0);
    337        1.2   lukem }
    338        1.2   lukem 
    339        1.2   lukem void
    340       1.10     wiz usage(void)
    341        1.2   lukem {
    342        1.2   lukem 	fprintf(stderr,
    343        1.2   lukem 		"usage: %s [-e|-E [-d] [-u]] [-n] [-v] input [output]\n",
    344        1.9     cgd 		getprogname());
    345        1.2   lukem 	exit(1);
    346        1.1   lukem }
    347