ypwhich.c revision 90297
1286438Sbapt/* 2286438Sbapt * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca> 3286438Sbapt * All rights reserved. 4286438Sbapt * 5286438Sbapt * Redistribution and use in source and binary forms, with or without 6286438Sbapt * modification, are permitted provided that the following conditions 7286438Sbapt * are met: 8286438Sbapt * 1. Redistributions of source code must retain the above copyright 9286438Sbapt * notice, this list of conditions and the following disclaimer. 10286438Sbapt * 2. Redistributions in binary form must reproduce the above copyright 11286438Sbapt * notice, this list of conditions and the following disclaimer in the 12286438Sbapt * documentation and/or other materials provided with the distribution. 13286438Sbapt * 3. The name of the author may not be used to endorse or promote 14286438Sbapt * products derived from this software without specific prior written 15286438Sbapt * permission. 16286438Sbapt * 17286438Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18286438Sbapt * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19286438Sbapt * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20286438Sbapt * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 21286438Sbapt * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22286438Sbapt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23286438Sbapt * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24286438Sbapt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25286438Sbapt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26286438Sbapt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27286438Sbapt * SUCH DAMAGE. 28286438Sbapt */ 29286438Sbapt 30286438Sbapt#include <sys/cdefs.h> 31286438Sbapt 32286438Sbapt__FBSDID("$FreeBSD: head/usr.bin/ypwhich/ypwhich.c 90297 2002-02-06 13:30:31Z des $"); 33286438Sbapt 34286438Sbapt#include <sys/param.h> 35286438Sbapt#include <sys/types.h> 36286438Sbapt#include <sys/socket.h> 37286438Sbapt 38286438Sbapt#include <rpcsvc/ypclnt.h> 39286438Sbapt 40286438Sbapt#include <netinet/in.h> 41286438Sbapt 42286438Sbapt#include <arpa/inet.h> 43286438Sbapt 44286438Sbapt#include <ctype.h> 45286438Sbapt#include <err.h> 46286438Sbapt#include <netdb.h> 47286438Sbapt#include <stdio.h> 48286438Sbapt#include <stdlib.h> 49286438Sbapt#include <string.h> 50286438Sbapt#include <unistd.h> 51286438Sbapt#include <rpc/rpc.h> 52286438Sbapt#include <rpc/xdr.h> 53286438Sbapt#include <rpcsvc/yp.h> 54286438Sbaptstruct dom_binding{}; 55286438Sbapt 56286438Sbapt#define ERR_USAGE 1 /* bad arguments - display 'usage' message */ 57286438Sbapt#define ERR_NOSUCHHOST 2 /* no such host */ 58286438Sbapt#define ERR_NOBINDING 3 /* error from ypbind -- domain not bound */ 59286438Sbapt#define ERR_NOYPBIND 4 /* ypbind not running */ 60286438Sbapt#define ERR_NOMASTER 5 /* could not find master server */ 61286438Sbapt 62286438Sbaptextern bool_t xdr_domainname(); 63286438Sbapt 64286438Sbaptstruct ypalias { 65286438Sbapt const char *alias, *name; 66286438Sbapt} ypaliases[] = { 67286438Sbapt { "passwd", "passwd.byname" }, 68286438Sbapt { "master.passwd", "master.passwd.byname" }, 69286438Sbapt { "group", "group.byname" }, 70286438Sbapt { "networks", "networks.byaddr" }, 71286438Sbapt { "hosts", "hosts.byaddr" }, 72286438Sbapt { "protocols", "protocols.bynumber" }, 73286438Sbapt { "services", "services.byname" }, 74286438Sbapt { "aliases", "mail.aliases" }, 75286438Sbapt { "ethers", "ethers.byname" }, 76286438Sbapt}; 77286438Sbapt 78286438Sbaptstatic void 79286438Sbaptusage(void) 80286438Sbapt{ 81325928Sbapt fprintf(stderr, "%s\n%s\n", 82325928Sbapt "usage: ypwhich [-d domain] [[-t] -m [mname] | host]", 83325928Sbapt " ypwhich -x"); 84286438Sbapt exit(ERR_USAGE); 85312336Sbapt} 86312336Sbapt 87312336Sbapt 88312336Sbapt/* 89312336Sbapt * Like yp_bind except can query a specific host 90312336Sbapt */ 91312336Sbaptstatic int 92312336Sbaptbind_host(char *dom, struct sockaddr_in *lsin) 93312336Sbapt{ 94312336Sbapt struct hostent *hent = NULL; 95312336Sbapt struct ypbind_resp ypbr; 96312336Sbapt struct timeval tv; 97312336Sbapt CLIENT *client; 98312336Sbapt int sock, r; 99312336Sbapt struct in_addr ss_addr; 100286438Sbapt 101286438Sbapt sock = RPC_ANYSOCK; 102312336Sbapt tv.tv_sec = 15; 103312336Sbapt tv.tv_usec = 0; 104312336Sbapt client = clntudp_create(lsin, YPBINDPROG, YPBINDVERS, tv, &sock); 105312336Sbapt if (client == NULL) { 106312336Sbapt warnx("can't clntudp_create: %s", yperr_string(YPERR_YPBIND)); 107312336Sbapt return (YPERR_YPBIND); 108325928Sbapt } 109312336Sbapt 110312336Sbapt tv.tv_sec = 5; 111312336Sbapt tv.tv_usec = 0; 112312336Sbapt r = clnt_call(client, YPBINDPROC_DOMAIN, 113312336Sbapt xdr_domainname, &dom, xdr_ypbind_resp, &ypbr, tv); 114312336Sbapt if (r != RPC_SUCCESS) { 115286438Sbapt warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND)); 116286438Sbapt clnt_destroy(client); 117286438Sbapt return (YPERR_YPBIND); 118286438Sbapt } else { 119286438Sbapt if (ypbr.ypbind_status != YPBIND_SUCC_VAL) { 120286438Sbapt warnx("can't yp_bind: reason: %s", 121286438Sbapt ypbinderr_string(ypbr.ypbind_resp_u.ypbind_error)); 122286438Sbapt clnt_destroy(client); 123286438Sbapt return (r); 124286438Sbapt } 125286438Sbapt } 126286438Sbapt clnt_destroy(client); 127286438Sbapt 128286438Sbapt ss_addr = *(struct in_addr *)ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr; 129286438Sbapt /*printf("%08x\n", ss_addr);*/ 130286438Sbapt hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET); 131286438Sbapt if (hent) 132286438Sbapt printf("%s\n", hent->h_name); 133286438Sbapt else 134286438Sbapt printf("%s\n", inet_ntoa(ss_addr)); 135286438Sbapt return (0); 136286438Sbapt} 137286438Sbapt 138286438Sbaptint 139286438Sbaptmain(int argc, char *argv[]) 140286438Sbapt{ 141286438Sbapt char *domnam = NULL, *master; 142286438Sbapt const char *map = NULL; 143286438Sbapt struct ypmaplist *ypml, *y; 144286438Sbapt struct hostent *hent; 145286438Sbapt struct sockaddr_in lsin; 146286438Sbapt int notrans, mode, getmap; 147286438Sbapt int c, r; 148312336Sbapt u_int i; 149286438Sbapt 150286438Sbapt getmap = notrans = mode = 0; 151286438Sbapt while ((c = getopt(argc, argv, "xd:mt")) != -1) 152286438Sbapt switch (c) { 153286438Sbapt case 'x': 154286438Sbapt for (i = 0; i<sizeof ypaliases/sizeof ypaliases[0]; i++) 155286438Sbapt printf("\"%s\" is an alias for \"%s\"\n", 156286438Sbapt ypaliases[i].alias, 157286438Sbapt ypaliases[i].name); 158286438Sbapt exit(0); 159286438Sbapt case 'd': 160286438Sbapt domnam = optarg; 161286438Sbapt break; 162286438Sbapt case 't': 163286438Sbapt notrans++; 164286438Sbapt break; 165286438Sbapt case 'm': 166286438Sbapt mode++; 167286438Sbapt break; 168286438Sbapt default: 169286438Sbapt usage(); 170286438Sbapt } 171286438Sbapt 172286438Sbapt if (!domnam) 173286438Sbapt yp_get_default_domain(&domnam); 174286438Sbapt 175286438Sbapt if (mode == 0) { 176286438Sbapt switch (argc-optind) { 177286438Sbapt case 0: 178286438Sbapt bzero(&lsin, sizeof lsin); 179286438Sbapt lsin.sin_family = AF_INET; 180286438Sbapt lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 181286438Sbapt 182286438Sbapt if (bind_host(domnam, &lsin)) 183286438Sbapt exit(ERR_NOBINDING); 184286438Sbapt break; 185286438Sbapt case 1: 186286438Sbapt bzero(&lsin, sizeof lsin); 187286438Sbapt lsin.sin_family = AF_INET; 188286438Sbapt if ((lsin.sin_addr.s_addr = inet_addr(argv[optind])) == -1) { 189286438Sbapt hent = gethostbyname(argv[optind]); 190286438Sbapt if (!hent) 191286438Sbapt errx(ERR_NOSUCHHOST, "host %s unknown", argv[optind]); 192286438Sbapt bcopy((char *)hent->h_addr_list[0], 193286438Sbapt (char *)&lsin.sin_addr, sizeof lsin.sin_addr); 194286438Sbapt } 195286438Sbapt if (bind_host(domnam, &lsin)) 196286438Sbapt exit(ERR_NOBINDING); 197286438Sbapt break; 198286438Sbapt default: 199286438Sbapt usage(); 200286438Sbapt } 201286438Sbapt exit(0); 202286438Sbapt } 203286438Sbapt 204286438Sbapt if (argc-optind > 1) 205286438Sbapt usage(); 206286438Sbapt 207286438Sbapt if (argv[optind]) { 208286438Sbapt map = argv[optind]; 209286438Sbapt for (i = 0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++) 210286438Sbapt if (strcmp(map, ypaliases[i].alias) == 0) 211286438Sbapt map = ypaliases[i].name; 212286438Sbapt r = yp_master(domnam, map, &master); 213286438Sbapt switch (r) { 214286438Sbapt case 0: 215286438Sbapt printf("%s\n", master); 216286438Sbapt free(master); 217286438Sbapt break; 218286438Sbapt case YPERR_YPBIND: 219286438Sbapt errx(ERR_NOYPBIND, "not running ypbind"); 220286438Sbapt default: 221286438Sbapt errx(ERR_NOMASTER, "can't find master for map %s. reason: %s", 222286438Sbapt map, yperr_string(r)); 223286438Sbapt } 224286438Sbapt exit(0); 225286438Sbapt } 226286438Sbapt 227286438Sbapt ypml = NULL; 228286438Sbapt r = yp_maplist(domnam, &ypml); 229286438Sbapt switch (r) { 230286438Sbapt case 0: 231286438Sbapt for (y = ypml; y;) { 232286438Sbapt ypml = y; 233286438Sbapt r = yp_master(domnam, ypml->map, &master); 234286438Sbapt switch (r) { 235286438Sbapt case 0: 236286438Sbapt printf("%s %s\n", ypml->map, master); 237286438Sbapt free(master); 238286438Sbapt break; 239286438Sbapt default: 240286438Sbapt warnx("can't find the master of %s: reason: %s", 241286438Sbapt ypml->map, yperr_string(r)); 242286438Sbapt break; 243286438Sbapt } 244286438Sbapt y = ypml->next; 245286438Sbapt free(ypml); 246286438Sbapt } 247286438Sbapt break; 248286438Sbapt case YPERR_YPBIND: 249286438Sbapt errx(ERR_NOYPBIND, "not running ypbind"); 250286438Sbapt default: 251286438Sbapt errx(ERR_NOMASTER, "can't get map list for domain %s. reason: %s", 252286438Sbapt domnam, yperr_string(r)); 253286438Sbapt } 254286438Sbapt exit(0); 255286438Sbapt} 256286438Sbapt