ypwhich.c revision 28895
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
3087672Smarkm#ifndef lint
3187672Smarkmstatic const char rcsid[] =
3287672Smarkm	"$Id$";
331930Swollman#endif /* not lint */
341930Swollman
351930Swollman#include <sys/param.h>
3687672Smarkm#include <sys/types.h>
3787672Smarkm#include <sys/socket.h>
3887672Smarkm#include <ctype.h>
3936914Speter#include <err.h>
4087672Smarkm#include <netdb.h>
4136914Speter#include <stdio.h>
4287672Smarkm#include <stdlib.h>
431930Swollman#include <string.h>
4428895Scharnier#include <unistd.h>
451930Swollman#include <rpc/rpc.h>
4628895Scharnier#include <rpc/xdr.h>
4728895Scharnier#include <rpcsvc/yp.h>
4828895Scharnierstruct dom_binding{};
4928895Scharnier#include <rpcsvc/ypclnt.h>
501930Swollman
511930Swollman#define ERR_USAGE	1	/* bad arguments - display 'usage' message */
5212862Swpaul#define ERR_NOSUCHHOST	2	/* no such host */
5312862Swpaul#define ERR_NOBINDING	3	/* error from ypbind -- domain not bound */
541930Swollman#define ERR_NOYPBIND	4	/* ypbind not running */
557990Swpaul#define ERR_NOMASTER	5	/* could not find master server */
567990Swpaul
577990Swpaulextern bool_t xdr_domainname();
587990Swpaul
597990Swpaulstruct ypalias {
607990Swpaul	char *alias, *name;
611930Swollman} ypaliases[] = {
621930Swollman	{ "passwd", "passwd.byname" },
631930Swollman	{ "master.passwd", "master.passwd.byname" },
6487672Smarkm	{ "group", "group.byname" },
651930Swollman	{ "networks", "networks.byaddr" },
661930Swollman	{ "hosts", "hosts.byaddr" },
6727345Speter	{ "protocols", "protocols.bynumber" },
681930Swollman	{ "services", "services.byname" },
691930Swollman	{ "aliases", "mail.aliases" },
701930Swollman	{ "ethers", "ethers.byname" },
711930Swollman};
721930Swollman
731930Swollmanstatic void
741930Swollmanusage()
751930Swollman{
761930Swollman	fprintf(stderr, "%s\n%s\n",
7728895Scharnier		"usage: ypwhich [-d domain] [[-t] -m [mname] | host]",
7887672Smarkm		"       ypwhich -x");
791930Swollman	exit(ERR_USAGE);
8028895Scharnier}
8128895Scharnier
8228895Scharnier
837990Swpaul/*
841930Swollman * Like yp_bind except can query a specific host
851930Swollman */
861930Swollmanint
871930Swollmanbind_host(dom, sin)
881930Swollmanchar *dom;
891930Swollmanstruct sockaddr_in *sin;
9087672Smarkm{
9187672Smarkm	struct hostent *hent = NULL;
921930Swollman	struct ypbind_resp ypbr;
931930Swollman	struct timeval tv;
941930Swollman	CLIENT *client;
951930Swollman	int sock, r;
961930Swollman	u_long ss_addr;
971930Swollman
9836914Speter	sock = RPC_ANYSOCK;
991930Swollman	tv.tv_sec = 15;
1001930Swollman	tv.tv_usec = 0;
1011930Swollman	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
1021930Swollman	if(client==NULL) {
10387672Smarkm		warnx("can't clntudp_create: %s", yperr_string(YPERR_YPBIND));
10490297Sdes		return YPERR_YPBIND;
10528895Scharnier	}
10690297Sdes
1071930Swollman	tv.tv_sec = 5;
1081930Swollman	tv.tv_usec = 0;
1091930Swollman	r = clnt_call(client, YPBINDPROC_DOMAIN,
1101930Swollman		xdr_domainname, &dom, xdr_ypbind_resp, &ypbr, tv);
1111930Swollman	if( r != RPC_SUCCESS) {
11212862Swpaul		warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND));
11390297Sdes		clnt_destroy(client);
11428895Scharnier		return YPERR_YPBIND;
1151930Swollman	} else {
11690297Sdes		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
1171930Swollman			warnx("can't yp_bind: reason: %s",
1181930Swollman				ypbinderr_string(ypbr.ypbind_resp_u.ypbind_error));
11928895Scharnier			clnt_destroy(client);
12012862Swpaul			return r;
1211930Swollman		}
12290297Sdes	}
1231930Swollman	clnt_destroy(client);
1241930Swollman
1251930Swollman	ss_addr = *(u_long *)ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr;
1261930Swollman	/*printf("%08x\n", ss_addr);*/
12736914Speter	hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET);
1281930Swollman	if (hent)
1291930Swollman		printf("%s\n", hent->h_name);
1301930Swollman	else
1311930Swollman		printf("%s\n", inet_ntoa(ss_addr));
1321930Swollman	return 0;
1331930Swollman}
13490297Sdes
1351930Swollmanint
1368874Srgrimesmain(argc, argv)
1371930Swollmanchar **argv;
13887672Smarkm{
1391930Swollman	char *domainname = NULL, *master, *map = NULL;
14087672Smarkm	struct ypmaplist *ypml, *y;
14187672Smarkm	struct hostent *hent;
1421930Swollman	struct sockaddr_in sin;
1431930Swollman	int notrans, mode, getmap;
14487672Smarkm	int c, r, i;
1451930Swollman
14687672Smarkm	getmap = notrans = mode = 0;
14787672Smarkm	while( (c=getopt(argc, argv, "xd:mt")) != -1)
1481930Swollman		switch(c) {
1491930Swollman		case 'x':
15090297Sdes			for(i=0; i<sizeof ypaliases/sizeof ypaliases[0]; i++)
15190297Sdes				printf("\"%s\" is an alias for \"%s\"\n",
1521930Swollman					ypaliases[i].alias,
15390297Sdes					ypaliases[i].name);
1549594Swollman			exit(0);
1551930Swollman		case 'd':
1561930Swollman			domainname = optarg;
1571930Swollman			break;
1581930Swollman		case 't':
15987672Smarkm			notrans++;
1601930Swollman			break;
1611930Swollman		case 'm':
1621930Swollman			mode++;
1631930Swollman			break;
1641930Swollman		default:
1651930Swollman			usage();
1661930Swollman		}
1671930Swollman
1681930Swollman	if(!domainname)
1691930Swollman		yp_get_default_domain(&domainname);
1701930Swollman
17190297Sdes	if(mode==0) {
17287672Smarkm		switch(argc-optind) {
17328895Scharnier		case 0:
17490297Sdes			bzero(&sin, sizeof sin);
17590297Sdes			sin.sin_family = AF_INET;
1761930Swollman			sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
17787672Smarkm
17887672Smarkm			if(bind_host(domainname, &sin))
17987672Smarkm				exit(ERR_NOBINDING);
1801930Swollman			break;
18190297Sdes		case 1:
1827990Swpaul			bzero(&sin, sizeof sin);
1831930Swollman			sin.sin_family = AF_INET;
1841930Swollman			if( (sin.sin_addr.s_addr=inet_addr(argv[optind]))==-1) {
18587672Smarkm				hent = gethostbyname(argv[optind]);
18687672Smarkm				if(!hent)
18791377Sdwmalone					errx(ERR_NOSUCHHOST, "host %s unknown", argv[optind]);
1881930Swollman				bcopy((char *)hent->h_addr_list[0],
18990297Sdes					(char *)&sin.sin_addr, sizeof sin.sin_addr);
19028895Scharnier			}
1911930Swollman			if(bind_host(domainname, &sin))
19287672Smarkm				exit(ERR_NOBINDING);
1931930Swollman			break;
19490297Sdes		default:
1957990Swpaul			usage();
1961930Swollman		}
1971930Swollman		exit(0);
1981930Swollman	}
1991930Swollman
2001930Swollman	if( argc-optind > 1)
2011930Swollman		usage();
2021930Swollman
20390297Sdes	if(argv[optind]) {
2041930Swollman		map = argv[optind];
2051930Swollman		for(i=0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++)
20690297Sdes			if( strcmp(map, ypaliases[i].alias) == 0)
2071930Swollman				map = ypaliases[i].name;
20890297Sdes		r = yp_master(domainname, map, &master);
20990297Sdes		switch(r) {
2101930Swollman		case 0:
21187672Smarkm			printf("%s\n", master);
21290297Sdes			free(master);
2131930Swollman			break;
2141930Swollman		case YPERR_YPBIND:
2151930Swollman			errx(ERR_NOYPBIND, "not running ypbind");
2161930Swollman		default:
2171930Swollman			errx(ERR_NOMASTER, "can't find master for map %s. reason: %s",
21828895Scharnier				map, yperr_string(r));
2191930Swollman		}
22028895Scharnier		exit(0);
2211930Swollman	}
2221930Swollman
2231930Swollman	ypml = NULL;
2241930Swollman	r = yp_maplist(domainname, &ypml);
2251930Swollman	switch(r) {
2261930Swollman	case 0:
22787672Smarkm		for(y=ypml; y; ) {
22890297Sdes			ypml = y;
2291930Swollman			r = yp_master(domainname, ypml->map, &master);
23090297Sdes			switch(r) {
2311930Swollman			case 0:
23287672Smarkm				printf("%s %s\n", ypml->map, master);
23390297Sdes				free(master);
2341930Swollman				break;
23512862Swpaul			default:
2361930Swollman				warnx("can't find the master of %s: reason: %s",
2371930Swollman					ypml->map, yperr_string(r));
2381930Swollman				break;
23928895Scharnier			}
24012862Swpaul			y = ypml->next;
2411930Swollman			free(ypml);
2421930Swollman		}
24312862Swpaul		break;
2441930Swollman	case YPERR_YPBIND:
2451930Swollman		errx(ERR_NOYPBIND, "not running ypbind");
2461930Swollman	default:
2471930Swollman		errx(ERR_NOMASTER, "can't get map list for domain %s. reason: %s",
24828895Scharnier			domainname, yperr_string(r));
2491930Swollman	}
25028895Scharnier	exit(0);
25187672Smarkm}
2521930Swollman