1/*	$OpenBSD: ypset.c,v 1.20 2015/01/16 06:40:23 deraadt Exp $ */
2/*	$NetBSD: ypset.c,v 1.8 1996/05/13 02:46:33 thorpej Exp $	*/
3
4/*-
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35
36#include <err.h>
37#include <netdb.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43#include <rpc/rpc.h>
44#include <rpc/xdr.h>
45#include <rpcsvc/yp.h>
46#include <rpcsvc/ypclnt.h>
47#include <arpa/inet.h>
48
49static void
50usage(void)
51{
52	fprintf(stderr, "usage: ypset [-d domain] [-h host] server\n");
53	exit(1);
54}
55
56static int
57bind_tohost(struct sockaddr_in *sin, char *dom, char *server)
58{
59	struct ypbind_setdom ypsd;
60	struct in_addr iaddr;
61	struct hostent *hp;
62	struct timeval tv;
63	CLIENT *client;
64	int sock, port, r;
65
66	port = getrpcport(server, YPPROG, YPPROC_NULL, IPPROTO_UDP);
67	if (port == 0)
68		errx(1, "%s not running ypserv", server);
69	port = htons(port);
70
71	memset(&ypsd, 0, sizeof ypsd);
72
73	if (inet_aton(server, &iaddr) == 0) {
74		hp = gethostbyname(server);
75		if (hp == NULL)
76			errx(1, "can't find address for %s", server);
77		memmove(&iaddr.s_addr, hp->h_addr, sizeof(iaddr.s_addr));
78	}
79	ypsd.ypsetdom_domain = dom;
80	bcopy(&iaddr.s_addr, &ypsd.ypsetdom_binding.ypbind_binding_addr,
81	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_addr));
82	bcopy(&port, &ypsd.ypsetdom_binding.ypbind_binding_port,
83	    sizeof(ypsd.ypsetdom_binding.ypbind_binding_port));
84	ypsd.ypsetdom_vers = YPVERS;
85
86	tv.tv_sec = 15;
87	tv.tv_usec = 0;
88	sock = RPC_ANYSOCK;
89	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
90	if (client == NULL) {
91		warnx("can't yp_bind, reason: %s", yperr_string(YPERR_YPBIND));
92		return (YPERR_YPBIND);
93	}
94	client->cl_auth = authunix_create_default();
95
96	r = clnt_call(client, YPBINDPROC_SETDOM,
97		(xdrproc_t)xdr_ypbind_setdom, &ypsd,
98		(xdrproc_t)xdr_void, NULL, tv);
99	if (r) {
100		warnx("cannot ypset for domain %s on host %s: %s"
101                " - make sure ypbind was started with -ypset or -ypsetme", dom,
102		    server, clnt_sperrno(r));
103		clnt_destroy(client);
104		return (YPERR_YPBIND);
105	}
106	clnt_destroy(client);
107	return (0);
108}
109
110int
111main(int argc, char *argv[])
112{
113	struct sockaddr_in sin;
114	struct hostent *hent;
115	char *domainname;
116	int c;
117
118	yp_get_default_domain(&domainname);
119
120	bzero(&sin, sizeof sin);
121	sin.sin_family = AF_INET;
122	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
123
124	while ((c = getopt(argc, argv, "h:d:")) != -1)
125		switch (c) {
126		case 'd':
127			domainname = optarg;
128			break;
129		case 'h':
130			if (inet_aton(optarg, &sin.sin_addr) == 0) {
131				hent = gethostbyname(optarg);
132				if (hent == NULL)
133					errx(1, "host %s unknown\n", optarg);
134				bcopy(hent->h_addr, &sin.sin_addr,
135				    sizeof(sin.sin_addr));
136			}
137			break;
138		default:
139			usage();
140		}
141
142	if (optind + 1 != argc)
143		usage();
144
145	if (bind_tohost(&sin, domainname, argv[optind]))
146		exit(1);
147	exit(0);
148}
149