ypwhich.c revision 1930
11930Swollman/*
21930Swollman * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
31930Swollman * All rights reserved.
41930Swollman *
51930Swollman * Redistribution and use in source and binary forms, with or without
61930Swollman * modification, are permitted provided that the following conditions
71930Swollman * are met:
81930Swollman * 1. Redistributions of source code must retain the above copyright
91930Swollman *    notice, this list of conditions and the following disclaimer.
101930Swollman * 2. Redistributions in binary form must reproduce the above copyright
111930Swollman *    notice, this list of conditions and the following disclaimer in the
121930Swollman *    documentation and/or other materials provided with the distribution.
131930Swollman * 3. The name of the author may not be used to endorse or promote
141930Swollman *    products derived from this software without specific prior written
151930Swollman *    permission.
161930Swollman *
171930Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
181930Swollman * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
191930Swollman * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201930Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
211930Swollman * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221930Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231930Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241930Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251930Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261930Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271930Swollman * SUCH DAMAGE.
281930Swollman */
291930Swollman
301930Swollman#ifndef LINT
311930Swollmanstatic char rcsid[] = "ypwhich.c,v 1.2 1993/05/16 02:49:10 deraadt Exp";
321930Swollman#endif
331930Swollman
341930Swollman#include <sys/param.h>
351930Swollman#include <sys/types.h>
361930Swollman#include <sys/socket.h>
371930Swollman#include <stdio.h>
381930Swollman#include <ctype.h>
391930Swollman#include <netdb.h>
401930Swollman#include <rpc/rpc.h>
411930Swollman#include <rpc/xdr.h>
421930Swollman#include <rpcsvc/yp_prot.h>
431930Swollman#include <rpcsvc/ypclnt.h>
441930Swollman
451930Swollmanextern bool_t xdr_domainname();
461930Swollman
471930Swollmanstruct ypalias {
481930Swollman	char *alias, *name;
491930Swollman} ypaliases[] = {
501930Swollman	{ "passwd", "passwd.byname" },
511930Swollman	{ "group", "group.byname" },
521930Swollman	{ "networks", "networks.byaddr" },
531930Swollman	{ "hosts", "hosts.byaddr" },
541930Swollman	{ "protocols", "protocols.bynumber" },
551930Swollman	{ "services", "services.byname" },
561930Swollman	{ "aliases", "mail.aliases" },
571930Swollman	{ "ethers", "ethers.byname" },
581930Swollman};
591930Swollman
601930Swollmanusage()
611930Swollman{
621930Swollman	fprintf(stderr, "Usage:\n");
631930Swollman	fprintf(stderr, "\typwhich [-d domain] [[-t] -m [mname] | host]\n");
641930Swollman	fprintf(stderr, "\typwhich -x\n");
651930Swollman	exit(1);
661930Swollman}
671930Swollman
681930Swollman
691930Swollman/*
701930Swollman * Like yp_bind except can query a specific host
711930Swollman */
721930Swollmanbind_host(dom, sin)
731930Swollmanchar *dom;
741930Swollmanstruct sockaddr_in *sin;
751930Swollman{
761930Swollman	struct hostent *hent = NULL;
771930Swollman	struct ypbind_resp ypbr;
781930Swollman	struct dom_binding *ysd;
791930Swollman	struct timeval tv;
801930Swollman	CLIENT *client;
811930Swollman	int sock, r;
821930Swollman	u_long ss_addr;
831930Swollman
841930Swollman	sock = RPC_ANYSOCK;
851930Swollman	tv.tv_sec = 15;
861930Swollman	tv.tv_usec = 0;
871930Swollman	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
881930Swollman	if(client==NULL) {
891930Swollman		fprintf(stderr, "can't clntudp_create: %s\n",
901930Swollman			yperr_string(YPERR_YPBIND));
911930Swollman		return YPERR_YPBIND;
921930Swollman	}
931930Swollman
941930Swollman	tv.tv_sec = 5;
951930Swollman	tv.tv_usec = 0;
961930Swollman	r = clnt_call(client, YPBINDPROC_DOMAIN,
971930Swollman		xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv);
981930Swollman	if( r != RPC_SUCCESS) {
991930Swollman		fprintf(stderr, "can't clnt_call: %s\n",
1001930Swollman			yperr_string(YPERR_YPBIND));
1011930Swollman		clnt_destroy(client);
1021930Swollman		return YPERR_YPBIND;
1031930Swollman	} else {
1041930Swollman		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
1051930Swollman			fprintf(stderr, "can't yp_bind: Reason: %s\n",
1061930Swollman				yperr_string(ypbr.ypbind_status));
1071930Swollman			clnt_destroy(client);
1081930Swollman			return r;
1091930Swollman		}
1101930Swollman	}
1111930Swollman	clnt_destroy(client);
1121930Swollman
1131930Swollman	ss_addr = ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr;
1141930Swollman	/*printf("%08x\n", ss_addr);*/
1151930Swollman	hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET);
1161930Swollman	if (hent)
1171930Swollman		printf("%s\n", hent->h_name);
1181930Swollman	else
1191930Swollman		printf("%s\n", inet_ntoa(ss_addr));
1201930Swollman	return 0;
1211930Swollman}
1221930Swollman
1231930Swollmanint
1241930Swollmanmain(argc, argv)
1251930Swollmanchar **argv;
1261930Swollman{
1271930Swollman	char *domainname, *master, *map;
1281930Swollman	struct ypmaplist *ypml, *y;
1291930Swollman	extern char *optarg;
1301930Swollman	extern int optind;
1311930Swollman	struct hostent *hent;
1321930Swollman	struct sockaddr_in sin;
1331930Swollman	int notrans, mode, getmap;
1341930Swollman	int c, r, i;
1351930Swollman
1361930Swollman	yp_get_default_domain(&domainname);
1371930Swollman
1381930Swollman	map = NULL;
1391930Swollman	getmap = notrans = mode = 0;
1401930Swollman	while( (c=getopt(argc, argv, "xd:mt")) != -1)
1411930Swollman		switch(c) {
1421930Swollman		case 'x':
1431930Swollman			for(i=0; i<sizeof ypaliases/sizeof ypaliases[0]; i++)
1441930Swollman				printf("Use \"%s\" for \"%s\"\n",
1451930Swollman					ypaliases[i].alias,
1461930Swollman					ypaliases[i].name);
1471930Swollman			exit(0);
1481930Swollman		case 'd':
1491930Swollman			domainname = optarg;
1501930Swollman			break;
1511930Swollman		case 't':
1521930Swollman			notrans++;
1531930Swollman			break;
1541930Swollman		case 'm':
1551930Swollman			mode++;
1561930Swollman			break;
1571930Swollman		default:
1581930Swollman			usage();
1591930Swollman		}
1601930Swollman
1611930Swollman	if(mode==0) {
1621930Swollman		switch(argc-optind) {
1631930Swollman		case 0:
1641930Swollman			bzero(&sin, sizeof sin);
1651930Swollman			sin.sin_family = AF_INET;
1661930Swollman			sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1671930Swollman
1681930Swollman			if(bind_host(domainname, &sin))
1691930Swollman				exit(1);
1701930Swollman			break;
1711930Swollman		case 1:
1721930Swollman			bzero(&sin, sizeof sin);
1731930Swollman			sin.sin_family = AF_INET;
1741930Swollman			if( (sin.sin_addr.s_addr=inet_addr(argv[optind]))==-1) {
1751930Swollman				hent = gethostbyname(argv[optind]);
1761930Swollman				if(!hent) {
1771930Swollman					fprintf(stderr, "ypwhich: host %s unknown\n",
1781930Swollman						argv[optind]);
1791930Swollman					exit(1);
1801930Swollman				}
1811930Swollman				bcopy((char *)hent->h_addr_list[0],
1821930Swollman					(char *)&sin.sin_addr, sizeof sin.sin_addr);
1831930Swollman			}
1841930Swollman			if(bind_host(domainname, &sin))
1851930Swollman				exit(1);
1861930Swollman			break;
1871930Swollman		default:
1881930Swollman			usage();
1891930Swollman		}
1901930Swollman		exit(0);
1911930Swollman	}
1921930Swollman
1931930Swollman	if( argc-optind > 1)
1941930Swollman		usage();
1951930Swollman
1961930Swollman	if(argv[optind]) {
1971930Swollman		map = argv[optind];
1981930Swollman		for(i=0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++)
1991930Swollman			if( strcmp(map, ypaliases[i].alias) == 0)
2001930Swollman				map = ypaliases[i].name;
2011930Swollman		r = yp_master(domainname, map, &master);
2021930Swollman		switch(r) {
2031930Swollman		case 0:
2041930Swollman			printf("%s\n", master);
2051930Swollman			free(master);
2061930Swollman			break;
2071930Swollman		case YPERR_YPBIND:
2081930Swollman			fprintf(stderr, "ypwhich: not running ypbind\n");
2091930Swollman			exit(1);
2101930Swollman		default:
2111930Swollman			fprintf(stderr, "Can't find master for map %s. Reason: %s\n",
2121930Swollman				map, yperr_string(r));
2131930Swollman			exit(1);
2141930Swollman		}
2151930Swollman		exit(0);
2161930Swollman	}
2171930Swollman
2181930Swollman	ypml = NULL;
2191930Swollman	r = yp_maplist(domainname, &ypml);
2201930Swollman	switch(r) {
2211930Swollman	case 0:
2221930Swollman		for(y=ypml; y; ) {
2231930Swollman			ypml = y;
2241930Swollman			r = yp_master(domainname, ypml->ypml_name, &master);
2251930Swollman			switch(r) {
2261930Swollman			case 0:
2271930Swollman				printf("%s %s\n", ypml->ypml_name, master);
2281930Swollman				free(master);
2291930Swollman				break;
2301930Swollman			default:
2311930Swollman				fprintf(stderr,
2321930Swollman					"YP: can't find the master of %s: Reason: %s\n",
2331930Swollman					ypml->ypml_name, yperr_string(r));
2341930Swollman				break;
2351930Swollman			}
2361930Swollman			y = ypml->ypml_next;
2371930Swollman			free(ypml);
2381930Swollman		}
2391930Swollman		break;
2401930Swollman	case YPERR_YPBIND:
2411930Swollman		fprintf(stderr, "ypwhich: not running ypbind\n");
2421930Swollman		exit(1);
2431930Swollman	default:
2441930Swollman		fprintf(stderr, "Can't get map list for domain %s. Reason: %s\n",
2451930Swollman			domainname, yperr_string(r));
2461930Swollman		exit(1);
2471930Swollman	}
2481930Swollman	exit(0);
2491930Swollman}
250