1 /* $OpenBSD: ypwhich.c,v 1.23 2015/02/08 23:40:35 deraadt Exp $ */
2 /* $NetBSD: ypwhich.c,v 1.6 1996/05/13 02:43:48 thorpej Exp $ */
3
4 /*
5 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36
37 #include <netinet/in.h>
38 #include <arpa/inet.h>
39
40 #include <ctype.h>
41 #include <err.h>
42 #include <netdb.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #include <rpc/rpc.h>
49 #include <rpc/xdr.h>
50 #include <rpcsvc/yp.h>
51 #include <rpcsvc/ypclnt.h>
52
53 #include "yplib_host.h"
54
55 static const struct ypalias {
56 char *alias, *name;
57 } ypaliases[] = {
58 { "passwd", "passwd.byname" },
59 { "master.passwd", "master.passwd.byname" },
60 { "shadow", "shadow.byname" },
61 { "group", "group.byname" },
62 { "networks", "networks.byaddr" },
63 { "hosts", "hosts.byaddr" },
64 { "protocols", "protocols.bynumber" },
65 { "services", "services.byname" },
66 { "aliases", "mail.aliases" },
67 { "ethers", "ethers.byname" },
68 };
69
70 static void
usage(void)71 usage(void)
72 {
73 fprintf(stderr,
74 "usage: ypwhich [-t] [-d domain] [[-h] host]\n"
75 " ypwhich [-t] [-d domain] [-h host] -m [mname]\n"
76 " ypwhich -x\n");
77 exit(1);
78 }
79
80
81 /*
82 * Like yp_bind except can query a specific host
83 */
84 static int
bind_host(char * dom,struct sockaddr_in * sin)85 bind_host(char *dom, struct sockaddr_in *sin)
86 {
87 struct hostent *hent = NULL;
88 struct ypbind_resp ypbr;
89 struct in_addr ss_addr;
90 struct timeval tv;
91 CLIENT *client;
92 int sock, r;
93
94 sock = RPC_ANYSOCK;
95 tv.tv_sec = 15;
96 tv.tv_usec = 0;
97 client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
98
99 if (client == NULL) {
100 warnx("host is not bound to a ypmaster");
101 return (YPERR_YPBIND);
102 }
103
104 tv.tv_sec = 5;
105 tv.tv_usec = 0;
106
107 r = clnt_call(client, YPBINDPROC_DOMAIN,
108 (xdrproc_t)xdr_domainname, &dom,
109 (xdrproc_t)xdr_ypbind_resp, &ypbr, tv);
110 if (r != RPC_SUCCESS) {
111 warnx("can't clnt_call: %s", yperr_string(YPERR_YPBIND));
112 clnt_destroy(client);
113 return (YPERR_YPBIND);
114 } else {
115 if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
116 warnx("can't yp_bind: reason: %s",
117 yperr_string(ypbr.ypbind_status));
118 clnt_destroy(client);
119 return (r);
120 }
121 }
122 clnt_destroy(client);
123
124 memmove(&ss_addr.s_addr, &ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
125 sizeof (ss_addr));
126
127 hent = gethostbyaddr((char *)&ss_addr.s_addr, sizeof(ss_addr.s_addr),
128 AF_INET);
129 if (hent != NULL)
130 printf("%s\n", hent->h_name);
131 else
132 printf("%s\n", inet_ntoa(ss_addr));
133
134 return (0);
135 }
136
137 int
main(int argc,char * argv[])138 main(int argc, char *argv[])
139 {
140 char *domain, *master, *map = NULL, *host = NULL;
141 int notrans = 0, mode = 0, c, r, i;
142 struct ypmaplist *ypml, *y;
143 struct sockaddr_in sin;
144 struct hostent *hent;
145 CLIENT *client = NULL;
146
147 yp_get_default_domain(&domain);
148 if (domain == NULL)
149 errx(1, "YP domain name not set");
150
151 while ((c = getopt(argc, argv, "xd:h:mt")) != -1)
152 switch (c) {
153 case 'x':
154 for (i = 0; i < nitems(ypaliases); i++)
155 printf("\"%s\" is an alias for \"%s\"\n",
156 ypaliases[i].alias,
157 ypaliases[i].name);
158 exit(0);
159 case 'h':
160 host = optarg;
161 break;
162 case 'd':
163 domain = optarg;
164 break;
165 case 't':
166 notrans = 1;
167 break;
168 case 'm':
169 mode = 1;
170 break;
171 default:
172 usage();
173 }
174 argc -= optind;
175 argv += optind;
176
177 if (mode == 0) {
178 switch (argc) {
179 case 0:
180 memset(&sin, 0, sizeof sin);
181 sin.sin_family = AF_INET;
182 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
183
184 if (bind_host(domain, &sin))
185 exit(1);
186 break;
187 case 1:
188 bzero(&sin, sizeof sin);
189 sin.sin_family = AF_INET;
190 if (inet_aton(argv[0], &sin.sin_addr) == 0) {
191 hent = gethostbyname(argv[0]);
192 if (!hent) {
193 errx(1, "host %s unknown",
194 argv[0]);
195 }
196 }
197 if (bind_host(domain, &sin))
198 exit(1);
199 break;
200 default:
201 usage();
202 }
203 exit(0);
204 }
205
206 if (argc > 1)
207 usage();
208
209 if (host != NULL)
210 client = yp_bind_host(host, YPPROG, YPVERS, 0, 1);
211
212 if (argv[0]) {
213 map = argv[0];
214 if (notrans == 0) {
215 for (i = 0; i < nitems(ypaliases); i++)
216 if (strcmp(map, ypaliases[i].alias) == 0)
217 map = ypaliases[i].name;
218 }
219
220 if (host != NULL)
221 r = yp_master_host(client, domain, map, &master);
222 else
223 r = yp_master(domain, map, &master);
224
225 switch (r) {
226 case 0:
227 printf("%s\n", master);
228 free(master);
229 break;
230 case YPERR_YPBIND:
231 errx(1, "not running ypbind");
232 default:
233 errx(1, "can't find master for map %s: reason: %s",
234 map, yperr_string(r));
235 }
236 exit(0);
237 }
238
239 ypml = NULL;
240 if (host != NULL)
241 r = yp_maplist_host(client, domain, &ypml);
242 else
243 r = yp_maplist(domain, &ypml);
244
245 r = 0;
246 switch (r) {
247 case 0:
248 for (y = ypml; y; ) {
249 ypml = y;
250 if (host != NULL) {
251 r = yp_master_host(client,
252 domain, ypml->map, &master);
253 } else {
254 r = yp_master(domain, ypml->map, &master);
255 }
256 switch (r) {
257 case 0:
258 printf("%s %s\n", ypml->map, master);
259 free(master);
260 break;
261 default:
262 warnx("can't find the master of %s: reason: %s",
263 ypml->map, yperr_string(r));
264 break;
265 }
266 y = ypml->next;
267 free(ypml);
268 }
269 break;
270 case YPERR_YPBIND:
271 errx(1, "not running ypbind");
272 default:
273 errx(1, "can't get map list for domain %s: reason: %s",
274 domain, yperr_string(r));
275 }
276 exit(0);
277 }
278