115423Swpaul/* 215423Swpaul * Copyright (c) 1995, 1996 315423Swpaul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 415423Swpaul * 515423Swpaul * Redistribution and use in source and binary forms, with or without 615423Swpaul * modification, are permitted provided that the following conditions 715423Swpaul * are met: 815423Swpaul * 1. Redistributions of source code must retain the above copyright 915423Swpaul * notice, this list of conditions and the following disclaimer. 1015423Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1115423Swpaul * notice, this list of conditions and the following disclaimer in the 1215423Swpaul * documentation and/or other materials provided with the distribution. 1315423Swpaul * 3. All advertising materials mentioning features or use of this software 1415423Swpaul * must display the following acknowledgement: 1515423Swpaul * This product includes software developed by Bill Paul. 1615423Swpaul * 4. Neither the name of the author nor the names of any co-contributors 1715423Swpaul * may be used to endorse or promote products derived from this software 1815423Swpaul * without specific prior written permission. 1915423Swpaul * 2015423Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 2115423Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2215423Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2315423Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 2415423Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2515423Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2615423Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2715423Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2815423Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2915423Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3015423Swpaul * SUCH DAMAGE. 3115423Swpaul */ 3215423Swpaul 33114601Sobrien#include <sys/cdefs.h> 34114601Sobrien__FBSDID("$FreeBSD: releng/10.3/usr.sbin/yp_mkdb/yp_mkdb.c 228722 2011-12-19 20:44:44Z dim $"); 3530777Scharnier 3630777Scharnier#include <err.h> 3715423Swpaul#include <fcntl.h> 3815423Swpaul#include <limits.h> 39228722Sdim#include <stdint.h> 4030777Scharnier#include <stdio.h> 4115423Swpaul#include <stdlib.h> 4230777Scharnier#include <string.h> 4330777Scharnier#include <time.h> 4415423Swpaul#include <unistd.h> 4515423Swpaul#include <rpc/rpc.h> 4615423Swpaul#include <rpcsvc/yp.h> 4730777Scharnier#include <sys/param.h> 4830777Scharnier#include <sys/types.h> 4930777Scharnier#include <sys/stat.h> 5015423Swpaul#include "yp_extern.h" 5116133Swpaul#include "ypxfr_extern.h" 5215423Swpaul 5315423Swpaulchar *yp_dir = ""; /* No particular default needed. */ 5415423Swpaulint _rpcpmstart = 0; 5515423Swpaulint debug = 1; 5615423Swpaul 5790298Sdesstatic void 5890298Sdesusage(void) 5915423Swpaul{ 6030777Scharnier fprintf(stderr, "%s\n%s\n%s\n%s\n", 6130777Scharnier "usage: yp_mkdb -c", 6230777Scharnier " yp_mkdb -u dbname", 6350159Swpaul " yp_mkdb [-c] [-b] [-s] [-f] [-i inputfile] [-o outputfile]", 6430777Scharnier " [-d domainname ] [-m mastername] inputfile dbname"); 6515423Swpaul exit(1); 6615423Swpaul} 6715423Swpaul 6815423Swpaul#define PERM_SECURE (S_IRUSR|S_IWUSR) 6915423Swpaul 7090298Sdesstatic DB * 7190298Sdesopen_db(char *path, int flags) 7215423Swpaul{ 7315423Swpaul extern HASHINFO openinfo; 7415423Swpaul 7515423Swpaul return(dbopen(path, flags, PERM_SECURE, DB_HASH, &openinfo)); 7615423Swpaul} 7715423Swpaul 7890298Sdesstatic void 7990298Sdesunwind(char *map) 8015423Swpaul{ 8115423Swpaul DB *dbp; 8215423Swpaul DBT key, data; 8315423Swpaul 8415423Swpaul dbp = open_db(map, O_RDONLY); 8515423Swpaul 8615423Swpaul if (dbp == NULL) 8715423Swpaul err(1, "open_db(%s) failed", map); 8815423Swpaul 8915423Swpaul key.data = NULL; 9090297Sdes while (yp_next_record(dbp, &key, &data, 1, 1) == YP_TRUE) 91228722Sdim printf("%.*s %.*s\n", (int)key.size, key.data, (int)data.size, 92228722Sdim data.data); 9315423Swpaul 9415423Swpaul (void)(dbp->close)(dbp); 9515423Swpaul return; 9615423Swpaul} 9715423Swpaul 9890298Sdesint 9990298Sdesmain(int argc, char *argv[]) 10015423Swpaul{ 10115423Swpaul int ch; 10215423Swpaul int un = 0; 10315423Swpaul int clear = 0; 10450159Swpaul int filter_plusminus = 0; 10515423Swpaul char *infile = NULL; 10615423Swpaul char *map = NULL; 10715423Swpaul char *domain = NULL; 10815423Swpaul char *infilename = NULL; 10915423Swpaul char *outfilename = NULL; 11015423Swpaul char *mastername = NULL; 11119155Swpaul int interdom = 0; 11219155Swpaul int secure = 0; 11315423Swpaul DB *dbp; 11415423Swpaul DBT key, data; 11515423Swpaul char buf[10240]; 11615423Swpaul char *keybuf, *datbuf; 11715423Swpaul FILE *ifp; 11815423Swpaul char hname[MAXHOSTNAMELEN + 2]; 11915423Swpaul 12050746Ssheldonh while ((ch = getopt(argc, argv, "uhcbsfd:i:o:m:")) != -1) { 12190297Sdes switch (ch) { 12250159Swpaul case 'f': 12350159Swpaul filter_plusminus++; 12450159Swpaul break; 12515423Swpaul case 'u': 12615423Swpaul un++; 12715423Swpaul break; 12815423Swpaul case 'c': 12915423Swpaul clear++; 13015423Swpaul break; 13119155Swpaul case 'b': 13219155Swpaul interdom++; 13319155Swpaul break; 13419155Swpaul case 's': 13519155Swpaul secure++; 13619155Swpaul break; 13715423Swpaul case 'd': 13815423Swpaul domain = optarg; 13915423Swpaul break; 14015423Swpaul case 'i': 14115423Swpaul infilename = optarg; 14215423Swpaul break; 14315423Swpaul case 'o': 14415423Swpaul outfilename = optarg; 14515423Swpaul break; 14615423Swpaul case 'm': 14715423Swpaul mastername = optarg; 14815423Swpaul break; 14915423Swpaul case 'h': 15015423Swpaul default: 15115423Swpaul usage(); 15215423Swpaul break; 15315423Swpaul } 15415423Swpaul } 15515423Swpaul 15615423Swpaul argc -= optind; 15715423Swpaul argv += optind; 15815423Swpaul 15915423Swpaul if (un) { 16015423Swpaul map = argv[0]; 16115423Swpaul if (map == NULL) 16215423Swpaul usage(); 16315423Swpaul unwind(map); 16415423Swpaul exit(0); 16515423Swpaul 16615423Swpaul } 16715423Swpaul 16815423Swpaul infile = argv[0]; 16915423Swpaul map = argv[1]; 17015423Swpaul 17115423Swpaul if (infile == NULL || map == NULL) { 17215423Swpaul if (clear) 17315423Swpaul goto doclear; 17415423Swpaul usage(); 17515423Swpaul } 17615423Swpaul 17715423Swpaul if (mastername == NULL) { 17815423Swpaul if (gethostname((char *)&hname, sizeof(hname)) == -1) 17915423Swpaul err(1, "gethostname() failed"); 18015423Swpaul mastername = (char *)&hname; 18115423Swpaul } 18215423Swpaul 18315423Swpaul /* 18415423Swpaul * Note that while we can read from stdin, we can't 18515423Swpaul * write to stdout; the db library doesn't let you 18615423Swpaul * write to a file stream like that. 18715423Swpaul */ 18815423Swpaul 18915423Swpaul if (!strcmp(infile, "-")) { 19015423Swpaul ifp = stdin; 19115423Swpaul } else { 19215423Swpaul if ((ifp = fopen(infile, "r")) == NULL) 19315423Swpaul err(1, "failed to open %s", infile); 19415423Swpaul } 19515423Swpaul 19615423Swpaul if ((dbp = open_db(map, O_RDWR|O_EXLOCK|O_EXCL|O_CREAT)) == NULL) 19715423Swpaul err(1, "open_db(%s) failed", map); 19815423Swpaul 19919155Swpaul if (interdom) { 20019155Swpaul key.data = "YP_INTERDOMAIN"; 20119155Swpaul key.size = sizeof("YP_INTERDOMAIN") - 1; 20219155Swpaul data.data = ""; 20319155Swpaul data.size = 0; 20419155Swpaul yp_put_record(dbp, &key, &data, 0); 20519155Swpaul } 20619155Swpaul 20719155Swpaul if (secure) { 20819155Swpaul key.data = "YP_SECURE"; 20919155Swpaul key.size = sizeof("YP_SECURE") - 1; 21019155Swpaul data.data = ""; 21119155Swpaul data.size = 0; 21219155Swpaul yp_put_record(dbp, &key, &data, 0); 21319155Swpaul } 21419155Swpaul 21515423Swpaul key.data = "YP_MASTER_NAME"; 21615423Swpaul key.size = sizeof("YP_MASTER_NAME") - 1; 21715423Swpaul data.data = mastername; 21815423Swpaul data.size = strlen(mastername); 21916133Swpaul yp_put_record(dbp, &key, &data, 0); 22015423Swpaul 22115423Swpaul key.data = "YP_LAST_MODIFIED"; 22215423Swpaul key.size = sizeof("YP_LAST_MODIFIED") - 1; 223228722Sdim snprintf(buf, sizeof(buf), "%jd", (intmax_t)time(NULL)); 22416133Swpaul data.data = (char *)&buf; 22515423Swpaul data.size = strlen(buf); 22616133Swpaul yp_put_record(dbp, &key, &data, 0); 22715423Swpaul 22815423Swpaul if (infilename) { 22915423Swpaul key.data = "YP_INPUT_FILE"; 23015423Swpaul key.size = sizeof("YP_INPUT_FILE") - 1; 23115423Swpaul data.data = infilename; 23215423Swpaul data.size = strlen(infilename); 23316133Swpaul yp_put_record(dbp, &key, &data, 0); 23415423Swpaul } 23515423Swpaul 23615423Swpaul if (outfilename) { 23715423Swpaul key.data = "YP_OUTPUT_FILE"; 23815423Swpaul key.size = sizeof("YP_OUTPUT_FILE") - 1; 23915423Swpaul data.data = outfilename; 24015423Swpaul data.size = strlen(outfilename); 24116133Swpaul yp_put_record(dbp, &key, &data, 0); 24215423Swpaul } 24315423Swpaul 24415423Swpaul if (domain) { 24515423Swpaul key.data = "YP_DOMAIN_NAME"; 24615423Swpaul key.size = sizeof("YP_DOMAIN_NAME") - 1; 24715423Swpaul data.data = domain; 24815423Swpaul data.size = strlen(domain); 24916133Swpaul yp_put_record(dbp, &key, &data, 0); 25015423Swpaul } 25115423Swpaul 25290297Sdes while (fgets((char *)&buf, sizeof(buf), ifp)) { 25315423Swpaul char *sep = NULL; 25415423Swpaul int rval; 25515423Swpaul 25615423Swpaul /* NUL terminate */ 25715423Swpaul if ((sep = strchr(buf, '\n'))) 25815423Swpaul *sep = '\0'; 25915423Swpaul 26015423Swpaul /* handle backslash line continuations */ 26190297Sdes while (buf[strlen(buf) - 1] == '\\') { 26215423Swpaul fgets((char *)&buf[strlen(buf) - 1], 26315423Swpaul sizeof(buf) - strlen(buf), ifp); 26415423Swpaul if ((sep = strchr(buf, '\n'))) 26515423Swpaul *sep = '\0'; 26615423Swpaul } 26715423Swpaul 26815423Swpaul /* find the separation between the key and data */ 26915423Swpaul if ((sep = strpbrk(buf, " \t")) == NULL) { 27015423Swpaul warnx("bad input -- no white space: %s", buf); 27115423Swpaul continue; 27215423Swpaul } 27315423Swpaul 27415423Swpaul /* separate the strings */ 27515423Swpaul keybuf = (char *)&buf; 27615423Swpaul datbuf = sep + 1; 27715423Swpaul *sep = '\0'; 27815423Swpaul 27915423Swpaul /* set datbuf to start at first non-whitespace character */ 28015423Swpaul while (*datbuf == ' ' || *datbuf == '\t') 28115423Swpaul datbuf++; 28215423Swpaul 28315423Swpaul /* Check for silliness. */ 28450159Swpaul if (filter_plusminus) { 28550159Swpaul if (*keybuf == '+' || *keybuf == '-' || 28650159Swpaul *datbuf == '+' || *datbuf == '-') { 28750159Swpaul warnx("bad character at " 28850159Swpaul "start of line: %s", buf); 28950159Swpaul continue; 29050159Swpaul } 29115423Swpaul } 29215423Swpaul 29315423Swpaul if (strlen(keybuf) > YPMAXRECORD) { 29415423Swpaul warnx("key too long: %s", keybuf); 29515423Swpaul continue; 29615423Swpaul } 29715423Swpaul 29822496Swpaul if (!strlen(keybuf)) { 29922496Swpaul warnx("no key -- check source file for blank lines"); 30022496Swpaul continue; 30122496Swpaul } 30222496Swpaul 30315423Swpaul if (strlen(datbuf) > YPMAXRECORD) { 30415423Swpaul warnx("data too long: %s", datbuf); 30515423Swpaul continue; 30615423Swpaul } 30715423Swpaul 30815423Swpaul key.data = keybuf; 30915423Swpaul key.size = strlen(keybuf); 31015423Swpaul data.data = datbuf; 31115423Swpaul data.size = strlen(datbuf); 31215423Swpaul 31316133Swpaul if ((rval = yp_put_record(dbp, &key, &data, 0)) != YP_TRUE) { 31490297Sdes switch (rval) { 31515423Swpaul case YP_FALSE: 31615423Swpaul warnx("duplicate key '%s' - skipping", keybuf); 31715423Swpaul break; 31815423Swpaul case YP_BADDB: 31915423Swpaul default: 32015423Swpaul err(1,"failed to write new record - exiting"); 32115423Swpaul break; 32215423Swpaul } 32315423Swpaul } 32415423Swpaul 32515423Swpaul } 32615423Swpaul 32715423Swpaul (void)(dbp->close)(dbp); 32815423Swpaul 32915423Swpauldoclear: 33015423Swpaul 33115423Swpaul if (clear) { 33215423Swpaul char in = 0; 33315423Swpaul char *out = NULL; 33415423Swpaul int stat; 33595658Sdes if ((stat = callrpc("localhost", YPPROG,YPVERS, YPPROC_CLEAR, 33695658Sdes (xdrproc_t)xdr_void, &in, 33795658Sdes (xdrproc_t)xdr_void, out)) != RPC_SUCCESS) { 33815423Swpaul warnx("failed to send 'clear' to local ypserv: %s", 33915423Swpaul clnt_sperrno((enum clnt_stat) stat)); 34015423Swpaul } 34115423Swpaul } 34215423Swpaul 34315423Swpaul exit(0); 34415423Swpaul} 345