1287129Saraujo/*	$OpenBSD: ypwhich.c,v 1.23 2015/02/08 23:40:35 deraadt Exp $	*/
2287129Saraujo/*	$NetBSD: ypwhich.c,v 1.6 1996/05/13 02:43:48 thorpej Exp $	*/
3287129Saraujo
4330449Seadler/*-
5330449Seadler * SPDX-License-Identifier: BSD-2-Clause-NetBSD
6330449Seadler *
7287129Saraujo * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
81930Swollman * All rights reserved.
91930Swollman *
101930Swollman * Redistribution and use in source and binary forms, with or without
111930Swollman * modification, are permitted provided that the following conditions
121930Swollman * are met:
131930Swollman * 1. Redistributions of source code must retain the above copyright
141930Swollman *    notice, this list of conditions and the following disclaimer.
151930Swollman * 2. Redistributions in binary form must reproduce the above copyright
161930Swollman *    notice, this list of conditions and the following disclaimer in the
171930Swollman *    documentation and/or other materials provided with the distribution.
181930Swollman *
191930Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
201930Swollman * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
211930Swollman * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
221930Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
231930Swollman * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
241930Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
251930Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
261930Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
271930Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
281930Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
291930Swollman * SUCH DAMAGE.
301930Swollman */
311930Swollman
3287672Smarkm#include <sys/cdefs.h>
3387672Smarkm__FBSDID("$FreeBSD: stable/11/usr.bin/ypwhich/ypwhich.c 330449 2018-03-05 07:26:05Z eadler $");
3487672Smarkm
351930Swollman#include <sys/param.h>
361930Swollman#include <sys/types.h>
371930Swollman#include <sys/socket.h>
3887672Smarkm
3936914Speter#include <netinet/in.h>
4036914Speter#include <arpa/inet.h>
4187672Smarkm
42200462Sdelphij#include <ctype.h>
4328895Scharnier#include <err.h>
441930Swollman#include <netdb.h>
4528895Scharnier#include <stdio.h>
4628895Scharnier#include <stdlib.h>
4728895Scharnier#include <string.h>
4828895Scharnier#include <unistd.h>
491930Swollman
50287129Saraujo#include <rpc/rpc.h>
51287129Saraujo#include <rpc/xdr.h>
52287129Saraujo#include <rpcsvc/yp.h>
53287129Saraujo#include <rpcsvc/ypclnt.h>
547990Swpaul
55287129Saraujo#include "yplib_host.h"
561930Swollman
57285992Saraujostatic const struct ypalias {
58121551Speter	char *alias, *name;
59285992Saraujo} ypaliases[] = {
601930Swollman	{ "passwd", "passwd.byname" },
6127345Speter	{ "master.passwd", "master.passwd.byname" },
62194968Sbrian	{ "shadow", "shadow.byname" },
631930Swollman	{ "group", "group.byname" },
641930Swollman	{ "networks", "networks.byaddr" },
651930Swollman	{ "hosts", "hosts.byaddr" },
661930Swollman	{ "protocols", "protocols.bynumber" },
671930Swollman	{ "services", "services.byname" },
681930Swollman	{ "aliases", "mail.aliases" },
691930Swollman	{ "ethers", "ethers.byname" },
701930Swollman};
711930Swollman
7228895Scharnierstatic void
7387672Smarkmusage(void)
741930Swollman{
75287129Saraujo	fprintf(stderr,
76287129Saraujo	    "usage: ypwhich [-t] [-d domain] [[-h] host]\n"
77287129Saraujo	    "       ypwhich [-t] [-d domain] [-h host] -m [mname]\n"
78287129Saraujo	    "       ypwhich -x\n");
79287129Saraujo	exit(1);
801930Swollman}
811930Swollman
821930Swollman
831930Swollman/*
841930Swollman * Like yp_bind except can query a specific host
851930Swollman */
8687672Smarkmstatic int
87287129Saraujobind_host(char *dom, struct sockaddr_in *sin)
881930Swollman{
891930Swollman	struct hostent *hent = NULL;
901930Swollman	struct ypbind_resp ypbr;
91287129Saraujo	struct in_addr ss_addr;
921930Swollman	struct timeval tv;
931930Swollman	CLIENT *client;
941930Swollman	int sock, r;
951930Swollman
961930Swollman	sock = RPC_ANYSOCK;
971930Swollman	tv.tv_sec = 15;
981930Swollman	tv.tv_usec = 0;
99287129Saraujo	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
100287129Saraujo
10190297Sdes	if (client == NULL) {
102287129Saraujo		warnx("host is not bound to a ypmaster");
10390297Sdes		return (YPERR_YPBIND);
1041930Swollman	}
1051930Swollman
1061930Swollman	tv.tv_sec = 5;
1071930Swollman	tv.tv_usec = 0;
108287129Saraujo
1091930Swollman	r = clnt_call(client, YPBINDPROC_DOMAIN,
110121551Speter		(xdrproc_t)xdr_domainname, &dom,
111121551Speter		(xdrproc_t)xdr_ypbind_resp, &ypbr, tv);
11290297Sdes	if (r != RPC_SUCCESS) {
11328895Scharnier		warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND));
1141930Swollman		clnt_destroy(client);
11590297Sdes		return (YPERR_YPBIND);
1161930Swollman	} else {
1171930Swollman		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
11828895Scharnier			warnx("can't yp_bind: reason: %s",
119287129Saraujo			    yperr_string(ypbr.ypbind_status));
1201930Swollman			clnt_destroy(client);
12190297Sdes			return (r);
1221930Swollman		}
1231930Swollman	}
1241930Swollman	clnt_destroy(client);
1251930Swollman
126287129Saraujo	memmove(&ss_addr.s_addr, &ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
127287129Saraujo	    sizeof (ss_addr));
128287129Saraujo
129287129Saraujo	hent = gethostbyaddr((char *)&ss_addr.s_addr, sizeof(ss_addr.s_addr),
130287129Saraujo	    AF_INET);
131287129Saraujo	if (hent != NULL)
1321930Swollman		printf("%s\n", hent->h_name);
1331930Swollman	else
1341930Swollman		printf("%s\n", inet_ntoa(ss_addr));
135287129Saraujo
13690297Sdes	return (0);
1371930Swollman}
1388874Srgrimes
1391930Swollmanint
14087672Smarkmmain(int argc, char *argv[])
1411930Swollman{
142287129Saraujo	char *domain, *master, *map = NULL, *host = NULL;
143287129Saraujo	int notrans = 0, mode = 0, c, r, i;
1441930Swollman	struct ypmaplist *ypml, *y;
145287129Saraujo	struct sockaddr_in sin;
1461930Swollman	struct hostent *hent;
147287129Saraujo	CLIENT *client = NULL;
1481930Swollman
149287129Saraujo	yp_get_default_domain(&domain);
150287129Saraujo	if (domain == NULL)
151287129Saraujo		errx(1, "YP domain name not set");
152287129Saraujo
153287129Saraujo	while ((c = getopt(argc, argv, "xd:h:mt")) != -1)
15490297Sdes		switch (c) {
1551930Swollman		case 'x':
156286716Saraujo			for (i = 0; i < nitems(ypaliases); i++)
1579594Swollman				printf("\"%s\" is an alias for \"%s\"\n",
1581930Swollman					ypaliases[i].alias,
1591930Swollman					ypaliases[i].name);
1601930Swollman			exit(0);
161287129Saraujo		case 'h':
162287129Saraujo			host = optarg;
163287129Saraujo			break;
1641930Swollman		case 'd':
165287129Saraujo			domain = optarg;
1661930Swollman			break;
1671930Swollman		case 't':
168287129Saraujo			notrans = 1;
1691930Swollman			break;
1701930Swollman		case 'm':
171287129Saraujo			mode = 1;
1721930Swollman			break;
1731930Swollman		default:
1741930Swollman			usage();
1751930Swollman		}
176287129Saraujo	argc -= optind;
177287129Saraujo	argv += optind;
1781930Swollman
17990297Sdes	if (mode == 0) {
180287129Saraujo		switch (argc) {
1811930Swollman		case 0:
182287129Saraujo			memset(&sin, 0, sizeof sin);
183287129Saraujo			sin.sin_family = AF_INET;
184287129Saraujo			sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1851930Swollman
186287129Saraujo			if (bind_host(domain, &sin))
187287129Saraujo				exit(1);
1881930Swollman			break;
1891930Swollman		case 1:
190287129Saraujo			bzero(&sin, sizeof sin);
191287129Saraujo			sin.sin_family = AF_INET;
192287129Saraujo			if (inet_aton(argv[0], &sin.sin_addr) == 0) {
193287129Saraujo				hent = gethostbyname(argv[0]);
194287129Saraujo				if (!hent) {
195287129Saraujo					errx(1, "host %s unknown",
196287129Saraujo					    argv[0]);
197287129Saraujo				}
1981930Swollman			}
199287129Saraujo			if (bind_host(domain, &sin))
200287129Saraujo				exit(1);
2011930Swollman			break;
2021930Swollman		default:
2031930Swollman			usage();
2041930Swollman		}
2051930Swollman		exit(0);
2061930Swollman	}
2071930Swollman
208287129Saraujo	if (argc > 1)
2091930Swollman		usage();
2101930Swollman
211287129Saraujo	if (host != NULL)
212287129Saraujo		client = yp_bind_host(host, YPPROG, YPVERS, 0, 1);
213287129Saraujo
214287129Saraujo	if (argv[0]) {
215287129Saraujo		map = argv[0];
216286716Saraujo		if (notrans == 0) {
217286716Saraujo			for (i = 0; i < nitems(ypaliases); i++)
218286716Saraujo				if (strcmp(map, ypaliases[i].alias) == 0)
219286716Saraujo					map = ypaliases[i].name;
220286716Saraujo		}
221287129Saraujo
222287129Saraujo		if (host != NULL)
223287129Saraujo			r = yp_master_host(client, domain, map, &master);
224287129Saraujo		else
225287129Saraujo			r = yp_master(domain, map, &master);
226287129Saraujo
22790297Sdes		switch (r) {
2281930Swollman		case 0:
2291930Swollman			printf("%s\n", master);
2301930Swollman			free(master);
2311930Swollman			break;
2321930Swollman		case YPERR_YPBIND:
233287129Saraujo			errx(1, "not running ypbind");
2341930Swollman		default:
235287129Saraujo			errx(1, "can't find master for map %s: reason: %s",
236287129Saraujo			    map, yperr_string(r));
2371930Swollman		}
2381930Swollman		exit(0);
2391930Swollman	}
2401930Swollman
2411930Swollman	ypml = NULL;
242287129Saraujo	if (host != NULL)
243287129Saraujo		r = yp_maplist_host(client, domain, &ypml);
244287129Saraujo	else
245287129Saraujo		r = yp_maplist(domain, &ypml);
246287129Saraujo
247287129Saraujo	r = 0;
24890297Sdes	switch (r) {
2491930Swollman	case 0:
250287129Saraujo		for (y = ypml; y; ) {
2511930Swollman			ypml = y;
252287129Saraujo			if (host != NULL) {
253287129Saraujo				r = yp_master_host(client,
254287129Saraujo						   domain, ypml->map, &master);
255287129Saraujo			} else {
256287129Saraujo				r = yp_master(domain, ypml->map, &master);
257287129Saraujo			}
25890297Sdes			switch (r) {
2591930Swollman			case 0:
260287129Saraujo				printf("%s %s\n", ypml->map, master);
2611930Swollman				free(master);
2621930Swollman				break;
2631930Swollman			default:
26428895Scharnier				warnx("can't find the master of %s: reason: %s",
265287129Saraujo				    ypml->map, yperr_string(r));
2661930Swollman				break;
2671930Swollman			}
268287129Saraujo			y = ypml->next;
2691930Swollman			free(ypml);
2701930Swollman		}
2711930Swollman		break;
2721930Swollman	case YPERR_YPBIND:
273287129Saraujo		errx(1, "not running ypbind");
2741930Swollman	default:
275287129Saraujo		errx(1, "can't get map list for domain %s: reason: %s",
276287129Saraujo		    domain, yperr_string(r));
2771930Swollman	}
2781930Swollman	exit(0);
2791930Swollman}
280