ypwhich.c revision 127856
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#include <sys/cdefs.h>
3187672Smarkm__FBSDID("$FreeBSD: head/usr.bin/ypwhich/ypwhich.c 127856 2004-04-04 19:17:38Z charnier $");
3287672Smarkm
331930Swollman#include <sys/param.h>
341930Swollman#include <sys/types.h>
351930Swollman#include <sys/socket.h>
3687672Smarkm
37121551Speter#include <rpc/rpc.h>
38121551Speter#include <rpc/xdr.h>
39121551Speter#include <rpcsvc/yp_prot.h>
4087672Smarkm#include <rpcsvc/ypclnt.h>
4187672Smarkm
4236914Speter#include <netinet/in.h>
4387672Smarkm
4436914Speter#include <arpa/inet.h>
4587672Smarkm
461930Swollman#include <ctype.h>
4728895Scharnier#include <err.h>
481930Swollman#include <netdb.h>
4928895Scharnier#include <stdio.h>
5028895Scharnier#include <stdlib.h>
5128895Scharnier#include <string.h>
5228895Scharnier#include <unistd.h>
531930Swollman
547990Swpaul#define ERR_USAGE	1	/* bad arguments - display 'usage' message */
557990Swpaul#define ERR_NOSUCHHOST	2	/* no such host */
567990Swpaul#define ERR_NOBINDING	3	/* error from ypbind -- domain not bound */
577990Swpaul#define ERR_NOYPBIND	4	/* ypbind not running */
587990Swpaul#define ERR_NOMASTER	5	/* could not find master server */
597990Swpaul
601930Swollmanextern bool_t xdr_domainname();
611930Swollman
621930Swollmanstruct ypalias {
63121551Speter	char *alias, *name;
641930Swollman} ypaliases[] = {
651930Swollman	{ "passwd", "passwd.byname" },
6627345Speter	{ "master.passwd", "master.passwd.byname" },
671930Swollman	{ "group", "group.byname" },
681930Swollman	{ "networks", "networks.byaddr" },
691930Swollman	{ "hosts", "hosts.byaddr" },
701930Swollman	{ "protocols", "protocols.bynumber" },
711930Swollman	{ "services", "services.byname" },
721930Swollman	{ "aliases", "mail.aliases" },
731930Swollman	{ "ethers", "ethers.byname" },
741930Swollman};
751930Swollman
7628895Scharnierstatic void
7787672Smarkmusage(void)
781930Swollman{
7928895Scharnier	fprintf(stderr, "%s\n%s\n",
8028895Scharnier		"usage: ypwhich [-d domain] [[-t] -m [mname] | host]",
8128895Scharnier		"       ypwhich -x");
827990Swpaul	exit(ERR_USAGE);
831930Swollman}
841930Swollman
851930Swollman
861930Swollman/*
871930Swollman * Like yp_bind except can query a specific host
881930Swollman */
8987672Smarkmstatic int
9087672Smarkmbind_host(char *dom, struct sockaddr_in *lsin)
911930Swollman{
921930Swollman	struct hostent *hent = NULL;
931930Swollman	struct ypbind_resp ypbr;
941930Swollman	struct timeval tv;
951930Swollman	CLIENT *client;
961930Swollman	int sock, r;
9736914Speter	struct in_addr ss_addr;
981930Swollman
991930Swollman	sock = RPC_ANYSOCK;
1001930Swollman	tv.tv_sec = 15;
1011930Swollman	tv.tv_usec = 0;
10287672Smarkm	client = clntudp_create(lsin, YPBINDPROG, YPBINDVERS, tv, &sock);
10390297Sdes	if (client == NULL) {
10428895Scharnier		warnx("can't clntudp_create: %s", yperr_string(YPERR_YPBIND));
10590297Sdes		return (YPERR_YPBIND);
1061930Swollman	}
1071930Swollman
1081930Swollman	tv.tv_sec = 5;
1091930Swollman	tv.tv_usec = 0;
1101930Swollman	r = clnt_call(client, YPBINDPROC_DOMAIN,
111121551Speter		(xdrproc_t)xdr_domainname, &dom,
112121551Speter		(xdrproc_t)xdr_ypbind_resp, &ypbr, tv);
11390297Sdes	if (r != RPC_SUCCESS) {
11428895Scharnier		warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND));
1151930Swollman		clnt_destroy(client);
11690297Sdes		return (YPERR_YPBIND);
1171930Swollman	} else {
1181930Swollman		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
11928895Scharnier			warnx("can't yp_bind: reason: %s",
120121551Speter				ypbinderr_string(ypbr.ypbind_respbody.ypbind_error));
1211930Swollman			clnt_destroy(client);
12290297Sdes			return (r);
1231930Swollman		}
1241930Swollman	}
1251930Swollman	clnt_destroy(client);
1261930Swollman
127121551Speter	ss_addr = ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr;
1281930Swollman	/*printf("%08x\n", ss_addr);*/
1291930Swollman	hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET);
1301930Swollman	if (hent)
1311930Swollman		printf("%s\n", hent->h_name);
1321930Swollman	else
1331930Swollman		printf("%s\n", inet_ntoa(ss_addr));
13490297Sdes	return (0);
1351930Swollman}
1368874Srgrimes
1371930Swollmanint
13887672Smarkmmain(int argc, char *argv[])
1391930Swollman{
14087672Smarkm	char *domnam = NULL, *master;
141121551Speter	char *map = NULL;
1421930Swollman	struct ypmaplist *ypml, *y;
1431930Swollman	struct hostent *hent;
14487672Smarkm	struct sockaddr_in lsin;
1451930Swollman	int notrans, mode, getmap;
14687672Smarkm	int c, r;
14787672Smarkm	u_int i;
1481930Swollman
1491930Swollman	getmap = notrans = mode = 0;
15090297Sdes	while ((c = getopt(argc, argv, "xd:mt")) != -1)
15190297Sdes		switch (c) {
1521930Swollman		case 'x':
15390297Sdes			for (i = 0; i<sizeof ypaliases/sizeof ypaliases[0]; i++)
1549594Swollman				printf("\"%s\" is an alias for \"%s\"\n",
1551930Swollman					ypaliases[i].alias,
1561930Swollman					ypaliases[i].name);
1571930Swollman			exit(0);
1581930Swollman		case 'd':
15987672Smarkm			domnam = optarg;
1601930Swollman			break;
1611930Swollman		case 't':
1621930Swollman			notrans++;
1631930Swollman			break;
1641930Swollman		case 'm':
1651930Swollman			mode++;
1661930Swollman			break;
1671930Swollman		default:
1681930Swollman			usage();
1691930Swollman		}
1701930Swollman
17190297Sdes	if (!domnam)
17287672Smarkm		yp_get_default_domain(&domnam);
17328895Scharnier
17490297Sdes	if (mode == 0) {
17590297Sdes		switch (argc-optind) {
1761930Swollman		case 0:
17787672Smarkm			bzero(&lsin, sizeof lsin);
17887672Smarkm			lsin.sin_family = AF_INET;
17987672Smarkm			lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1801930Swollman
18190297Sdes			if (bind_host(domnam, &lsin))
1827990Swpaul				exit(ERR_NOBINDING);
1831930Swollman			break;
1841930Swollman		case 1:
18587672Smarkm			bzero(&lsin, sizeof lsin);
18687672Smarkm			lsin.sin_family = AF_INET;
18791377Sdwmalone			if ((lsin.sin_addr.s_addr = inet_addr(argv[optind])) == INADDR_NONE) {
1881930Swollman				hent = gethostbyname(argv[optind]);
18990297Sdes				if (!hent)
19028895Scharnier					errx(ERR_NOSUCHHOST, "host %s unknown", argv[optind]);
1911930Swollman				bcopy((char *)hent->h_addr_list[0],
19287672Smarkm					(char *)&lsin.sin_addr, sizeof lsin.sin_addr);
1931930Swollman			}
19490297Sdes			if (bind_host(domnam, &lsin))
1957990Swpaul				exit(ERR_NOBINDING);
1961930Swollman			break;
1971930Swollman		default:
1981930Swollman			usage();
1991930Swollman		}
2001930Swollman		exit(0);
2011930Swollman	}
2021930Swollman
20390297Sdes	if (argc-optind > 1)
2041930Swollman		usage();
2051930Swollman
20690297Sdes	if (argv[optind]) {
2071930Swollman		map = argv[optind];
20890297Sdes		for (i = 0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++)
20990297Sdes			if (strcmp(map, ypaliases[i].alias) == 0)
2101930Swollman				map = ypaliases[i].name;
21187672Smarkm		r = yp_master(domnam, map, &master);
21290297Sdes		switch (r) {
2131930Swollman		case 0:
2141930Swollman			printf("%s\n", master);
2151930Swollman			free(master);
2161930Swollman			break;
2171930Swollman		case YPERR_YPBIND:
21828895Scharnier			errx(ERR_NOYPBIND, "not running ypbind");
2191930Swollman		default:
220127856Scharnier			errx(ERR_NOMASTER, "can't find master for map %s: reason: %s",
2211930Swollman				map, yperr_string(r));
2221930Swollman		}
2231930Swollman		exit(0);
2241930Swollman	}
2251930Swollman
2261930Swollman	ypml = NULL;
22787672Smarkm	r = yp_maplist(domnam, &ypml);
22890297Sdes	switch (r) {
2291930Swollman	case 0:
23090297Sdes		for (y = ypml; y;) {
2311930Swollman			ypml = y;
232121551Speter			r = yp_master(domnam, ypml->ypml_name, &master);
23390297Sdes			switch (r) {
2341930Swollman			case 0:
235121551Speter				printf("%s %s\n", ypml->ypml_name, master);
2361930Swollman				free(master);
2371930Swollman				break;
2381930Swollman			default:
23928895Scharnier				warnx("can't find the master of %s: reason: %s",
240121551Speter					ypml->ypml_name, yperr_string(r));
2411930Swollman				break;
2421930Swollman			}
243121551Speter			y = ypml->ypml_next;
2441930Swollman			free(ypml);
2451930Swollman		}
2461930Swollman		break;
2471930Swollman	case YPERR_YPBIND:
24828895Scharnier		errx(ERR_NOYPBIND, "not running ypbind");
2491930Swollman	default:
250127856Scharnier		errx(ERR_NOMASTER, "can't get map list for domain %s: reason: %s",
25187672Smarkm			domnam, yperr_string(r));
2521930Swollman	}
2531930Swollman	exit(0);
2541930Swollman}
255