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/types.h> |
31 |
|
|
#include <sys/socket.h> |
32 |
|
|
|
33 |
|
|
#include <netinet/in.h> |
34 |
|
|
#include <arpa/inet.h> |
35 |
|
|
|
36 |
|
|
#include <ctype.h> |
37 |
|
|
#include <err.h> |
38 |
|
|
#include <netdb.h> |
39 |
|
|
#include <stdio.h> |
40 |
|
|
#include <stdlib.h> |
41 |
|
|
#include <string.h> |
42 |
|
|
#include <unistd.h> |
43 |
|
|
|
44 |
|
|
#include <rpc/rpc.h> |
45 |
|
|
#include <rpc/xdr.h> |
46 |
|
|
#include <rpcsvc/yp.h> |
47 |
|
|
#include <rpcsvc/ypclnt.h> |
48 |
|
|
|
49 |
|
|
#include "yplib_host.h" |
50 |
|
|
|
51 |
|
|
struct ypalias { |
52 |
|
|
char *alias, *name; |
53 |
|
|
} ypaliases[] = { |
54 |
|
|
{ "passwd", "passwd.byname" }, |
55 |
|
|
{ "group", "group.byname" }, |
56 |
|
|
{ "networks", "networks.byaddr" }, |
57 |
|
|
{ "hosts", "hosts.byaddr" }, |
58 |
|
|
{ "protocols", "protocols.bynumber" }, |
59 |
|
|
{ "services", "services.byname" }, |
60 |
|
|
{ "aliases", "mail.aliases" }, |
61 |
|
|
{ "ethers", "ethers.byname" }, |
62 |
|
|
}; |
63 |
|
|
|
64 |
|
|
int bind_host(char *dom, struct sockaddr_in *sin); |
65 |
|
|
|
66 |
|
|
static void |
67 |
|
|
usage(void) |
68 |
|
|
{ |
69 |
|
|
fprintf(stderr, |
70 |
|
|
"usage: ypwhich [-t] [-d domain] [[-h] host]\n" |
71 |
|
|
" ypwhich [-t] [-d domain] [-h host] -m [mname]\n" |
72 |
|
|
" ypwhich -x\n"); |
73 |
|
|
exit(1); |
74 |
|
|
} |
75 |
|
|
|
76 |
|
|
|
77 |
|
|
/* |
78 |
|
|
* Like yp_bind except can query a specific host |
79 |
|
|
*/ |
80 |
|
|
int |
81 |
|
|
bind_host(char *dom, struct sockaddr_in *sin) |
82 |
|
|
{ |
83 |
|
|
struct hostent *hent = NULL; |
84 |
|
|
struct ypbind_resp ypbr; |
85 |
|
|
struct in_addr ss_addr; |
86 |
|
|
struct timeval tv; |
87 |
|
|
CLIENT *client; |
88 |
|
|
int sock, r; |
89 |
|
|
|
90 |
|
|
sock = RPC_ANYSOCK; |
91 |
|
|
tv.tv_sec = 15; |
92 |
|
|
tv.tv_usec = 0; |
93 |
|
|
client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock); |
94 |
|
|
|
95 |
|
|
if (client == NULL) { |
96 |
|
|
fprintf(stderr, "ypwhich: host is not bound to a ypmaster\n"); |
97 |
|
|
return YPERR_YPBIND; |
98 |
|
|
} |
99 |
|
|
|
100 |
|
|
tv.tv_sec = 5; |
101 |
|
|
tv.tv_usec = 0; |
102 |
|
|
|
103 |
|
|
r = clnt_call(client, YPBINDPROC_DOMAIN, |
104 |
|
|
xdr_domainname, &dom, xdr_ypbind_resp, &ypbr, tv); |
105 |
|
|
if (r != RPC_SUCCESS) { |
106 |
|
|
fprintf(stderr, "can't clnt_call: %s\n", |
107 |
|
|
yperr_string(YPERR_YPBIND)); |
108 |
|
|
clnt_destroy(client); |
109 |
|
|
return YPERR_YPBIND; |
110 |
|
|
} else { |
111 |
|
|
if (ypbr.ypbind_status != YPBIND_SUCC_VAL) { |
112 |
|
|
fprintf(stderr, "can't yp_bind: Reason: %s\n", |
113 |
|
|
yperr_string(ypbr.ypbind_status)); |
114 |
|
|
clnt_destroy(client); |
115 |
|
|
return r; |
116 |
|
|
} |
117 |
|
|
} |
118 |
|
|
clnt_destroy(client); |
119 |
|
|
|
120 |
|
|
memmove(&ss_addr.s_addr, &ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr, |
121 |
|
|
sizeof (ss_addr)); |
122 |
|
|
|
123 |
|
|
hent = gethostbyaddr((char *)&ss_addr.s_addr, sizeof(ss_addr.s_addr), |
124 |
|
|
AF_INET); |
125 |
|
|
if (hent != NULL) |
126 |
|
|
printf("%s\n", hent->h_name); |
127 |
|
|
else |
128 |
|
|
printf("%s\n", inet_ntoa(ss_addr)); |
129 |
|
|
|
130 |
|
|
return 0; |
131 |
|
|
} |
132 |
|
|
|
133 |
|
|
int |
134 |
|
|
main(int argc, char *argv[]) |
135 |
|
|
{ |
136 |
|
|
char *domain, *master, *map = NULL, *host = NULL; |
137 |
|
|
int notrans = 0, mode = 0, c, r, i; |
138 |
|
|
struct ypmaplist *ypml, *y; |
139 |
|
|
struct sockaddr_in sin; |
140 |
|
|
struct hostent *hent; |
141 |
|
|
CLIENT *client = NULL; |
142 |
|
|
|
143 |
|
|
yp_get_default_domain(&domain); |
144 |
|
|
if (domain == NULL) |
145 |
|
|
errx(1, "YP domain name not set"); |
146 |
|
|
|
147 |
|
|
while ((c = getopt(argc, argv, "xd:h:mt")) != -1) |
148 |
|
|
switch (c) { |
149 |
|
|
case 'x': |
150 |
|
|
for (i=0; i<sizeof ypaliases/sizeof ypaliases[0]; i++) |
151 |
|
|
printf("Use \"%s\" for \"%s\"\n", |
152 |
|
|
ypaliases[i].alias, ypaliases[i].name); |
153 |
|
|
exit(0); |
154 |
|
|
case 'h': |
155 |
|
|
host = optarg; |
156 |
|
|
break; |
157 |
|
|
case 'd': |
158 |
|
|
domain = optarg; |
159 |
|
|
break; |
160 |
|
|
case 't': |
161 |
|
|
notrans = 1; |
162 |
|
|
break; |
163 |
|
|
case 'm': |
164 |
|
|
mode = 1; |
165 |
|
|
break; |
166 |
|
|
default: |
167 |
|
|
usage(); |
168 |
|
|
} |
169 |
|
|
argc -= optind; |
170 |
|
|
argv += optind; |
171 |
|
|
|
172 |
|
|
if (mode == 0) { |
173 |
|
|
switch (argc) { |
174 |
|
|
case 0: |
175 |
|
|
memset(&sin, 0, sizeof sin); |
176 |
|
|
sin.sin_family = AF_INET; |
177 |
|
|
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
178 |
|
|
|
179 |
|
|
if (bind_host(domain, &sin)) |
180 |
|
|
exit(1); |
181 |
|
|
break; |
182 |
|
|
case 1: |
183 |
|
|
bzero(&sin, sizeof sin); |
184 |
|
|
sin.sin_family = AF_INET; |
185 |
|
|
if (inet_aton(argv[0], &sin.sin_addr) == 0) { |
186 |
|
|
hent = gethostbyname(argv[0]); |
187 |
|
|
if (!hent) { |
188 |
|
|
fprintf(stderr, "ypwhich: host %s unknown\n", |
189 |
|
|
argv[0]); |
190 |
|
|
exit(1); |
191 |
|
|
} |
192 |
|
|
bcopy(hent->h_addr, &sin.sin_addr, |
193 |
|
|
sizeof sin.sin_addr); |
194 |
|
|
} |
195 |
|
|
if (bind_host(domain, &sin)) |
196 |
|
|
exit(1); |
197 |
|
|
break; |
198 |
|
|
default: |
199 |
|
|
usage(); |
200 |
|
|
} |
201 |
|
|
exit(0); |
202 |
|
|
} |
203 |
|
|
|
204 |
|
|
if (argc > 1) |
205 |
|
|
usage(); |
206 |
|
|
|
207 |
|
|
if (host != NULL) |
208 |
|
|
client = yp_bind_host(host, YPPROG, YPVERS, 0, 1); |
209 |
|
|
|
210 |
|
|
if (argv[0]) { |
211 |
|
|
map = argv[0]; |
212 |
|
|
for (i=0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++) |
213 |
|
|
if (strcmp(map, ypaliases[i].alias) == 0) |
214 |
|
|
map = ypaliases[i].name; |
215 |
|
|
|
216 |
|
|
if (host != NULL) |
217 |
|
|
r = yp_master_host(client, domain, map, &master); |
218 |
|
|
else |
219 |
|
|
r = yp_master(domain, map, &master); |
220 |
|
|
|
221 |
|
|
switch (r) { |
222 |
|
|
case 0: |
223 |
|
|
printf("%s\n", master); |
224 |
|
|
free(master); |
225 |
|
|
break; |
226 |
|
|
case YPERR_YPBIND: |
227 |
|
|
fprintf(stderr, "ypwhich: not running ypbind\n"); |
228 |
|
|
exit(1); |
229 |
|
|
default: |
230 |
|
|
fprintf(stderr, "Can't find master for map %s. Reason: %s\n", |
231 |
|
|
map, yperr_string(r)); |
232 |
|
|
exit(1); |
233 |
|
|
} |
234 |
|
|
exit(0); |
235 |
|
|
} |
236 |
|
|
|
237 |
|
|
ypml = NULL; |
238 |
|
|
if (host != NULL) |
239 |
|
|
r = yp_maplist_host(client, domain, &ypml); |
240 |
|
|
else |
241 |
|
|
r = yp_maplist(domain, &ypml); |
242 |
|
|
|
243 |
|
|
r = 0; |
244 |
|
|
switch (r) { |
245 |
|
|
case 0: |
246 |
|
|
for (y = ypml; y; ) { |
247 |
|
|
ypml = y; |
248 |
|
|
if (host != NULL) { |
249 |
|
|
r = yp_master_host(client, |
250 |
|
|
domain, ypml->map, &master); |
251 |
|
|
} else { |
252 |
|
|
r = yp_master(domain, ypml->map, &master); |
253 |
|
|
} |
254 |
|
|
switch (r) { |
255 |
|
|
case 0: |
256 |
|
|
printf("%s %s\n", ypml->map, master); |
257 |
|
|
free(master); |
258 |
|
|
break; |
259 |
|
|
default: |
260 |
|
|
fprintf(stderr, |
261 |
|
|
"YP: can't find the master of %s: Reason: %s\n", |
262 |
|
|
ypml->map, yperr_string(r)); |
263 |
|
|
break; |
264 |
|
|
} |
265 |
|
|
y = ypml->next; |
266 |
|
|
free(ypml); |
267 |
|
|
} |
268 |
|
|
break; |
269 |
|
|
case YPERR_YPBIND: |
270 |
|
|
fprintf(stderr, "ypwhich: not running ypbind\n"); |
271 |
|
|
exit(1); |
272 |
|
|
default: |
273 |
|
|
fprintf(stderr, "Can't get map list for domain %s. Reason: %s\n", |
274 |
|
|
domain, yperr_string(r)); |
275 |
|
|
exit(1); |
276 |
|
|
} |
277 |
|
|
exit(0); |
278 |
|
|
} |