1 /* $OpenBSD: yplib_host.c,v 1.18 2015/01/16 06:40:22 deraadt Exp $ */
4 * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
32 #include <sys/param.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
52 #include <rpcsvc/yp.h>
53 #include <rpcsvc/ypclnt.h>
55 #include "yplib_host.h"
57 extern int (*ypresp_allfn)(u_long, char *, int, char *, int, void *);
58 extern void *ypresp_data;
59 extern bool_t xdr_ypreq_key(), xdr_ypresp_val();
60 extern bool_t xdr_ypresp_all_seq();
62 static int _yplib_host_timeout = 10;
65 yp_bind_host(char *server, u_long program, u_long version, u_short port,
68 struct sockaddr_in rsrv_sin;
69 static CLIENT *client;
74 memset(&rsrv_sin, 0, sizeof rsrv_sin);
75 rsrv_sin.sin_len = sizeof rsrv_sin;
76 rsrv_sin.sin_family = AF_INET;
77 rsrv_sock = RPC_ANYSOCK;
79 rsrv_sin.sin_port = htons(port);
81 if (*server >= '0' && *server <= '9') {
82 if (inet_aton(server, &rsrv_sin.sin_addr) == 0) {
83 errx(1, "inet_aton: invalid address %s.",
87 h = gethostbyname(server);
89 errx(1, "gethostbyname: unknown host %s.",
92 rsrv_sin.sin_addr.s_addr = *(u_int32_t *)h->h_addr;
99 client = clnttcp_create(&rsrv_sin, program, version,
102 client = clntudp_create(&rsrv_sin, program, version, tv,
105 if (client == NULL) {
106 errx(1, "clntudp_create: no contact with host %s.",
114 yp_bind_local(u_long program, u_long version)
116 struct sockaddr_in rsrv_sin;
117 static CLIENT *client;
121 memset(&rsrv_sin, 0, sizeof rsrv_sin);
122 rsrv_sin.sin_len = sizeof rsrv_sin;
123 rsrv_sin.sin_family = AF_INET;
124 rsrv_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
125 rsrv_sock = RPC_ANYSOCK;
130 client = clntudp_create(&rsrv_sin, program, version, tv, &rsrv_sock);
131 if (client == NULL) {
132 errx(1, "clntudp_create: no contact with localhost.");
139 yp_match_host(CLIENT *client, char *indomain, char *inmap, const char *inkey,
140 int inkeylen, char **outval, int *outvallen)
142 struct ypresp_val yprv;
143 struct ypreq_key yprk;
150 tv.tv_sec = _yplib_host_timeout;
153 yprk.domain = indomain;
155 yprk.key.keydat_val = (char *)inkey;
156 yprk.key.keydat_len = inkeylen;
158 memset(&yprv, 0, sizeof yprv);
160 r = clnt_call(client, YPPROC_MATCH,
161 (xdrproc_t)xdr_ypreq_key, &yprk,
162 (xdrproc_t)xdr_ypresp_val, &yprv, tv);
163 if (r != RPC_SUCCESS)
164 clnt_perror(client, "yp_match_host: clnt_call");
165 if ( !(r = ypprot_err(yprv.stat)) ) {
166 *outvallen = yprv.val.valdat_len;
167 *outval = malloc(*outvallen + 1);
168 memcpy(*outval, yprv.val.valdat_val, *outvallen);
169 (*outval)[*outvallen] = '\0';
171 xdr_free((xdrproc_t)xdr_ypresp_val, (char *)&yprv);
177 yp_first_host(CLIENT *client, char *indomain, char *inmap, char **outkey,
178 int *outkeylen, char **outval, int *outvallen)
180 struct ypresp_key_val yprkv;
181 struct ypreq_nokey yprnk;
185 *outkey = *outval = NULL;
186 *outkeylen = *outvallen = 0;
188 tv.tv_sec = _yplib_host_timeout;
191 yprnk.domain = indomain;
193 memset(&yprkv, 0, sizeof yprkv);
195 r = clnt_call(client, YPPROC_FIRST,
196 (xdrproc_t)xdr_ypreq_nokey, &yprnk,
197 (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv);
198 if (r != RPC_SUCCESS)
199 clnt_perror(client, "yp_first_host: clnt_call");
200 if ( !(r = ypprot_err(yprkv.stat)) ) {
201 *outkeylen = yprkv.key.keydat_len;
202 *outkey = malloc(*outkeylen+1);
203 memcpy(*outkey, yprkv.key.keydat_val, *outkeylen);
204 (*outkey)[*outkeylen] = '\0';
205 *outvallen = yprkv.val.valdat_len;
206 *outval = malloc(*outvallen+1);
207 memcpy(*outval, yprkv.val.valdat_val, *outvallen);
208 (*outval)[*outvallen] = '\0';
210 xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)&yprkv);
216 yp_next_host(CLIENT *client, char *indomain, char *inmap, char *inkey,
217 int inkeylen, char **outkey, int *outkeylen, char **outval, int *outvallen)
219 struct ypresp_key_val yprkv;
220 struct ypreq_key yprk;
224 *outkey = *outval = NULL;
225 *outkeylen = *outvallen = 0;
227 tv.tv_sec = _yplib_host_timeout;
230 yprk.domain = indomain;
232 yprk.key.keydat_val = inkey;
233 yprk.key.keydat_len = inkeylen;
234 memset(&yprkv, 0, sizeof yprkv);
236 r = clnt_call(client, YPPROC_NEXT,
237 (xdrproc_t)xdr_ypreq_key, &yprk,
238 (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv);
239 if (r != RPC_SUCCESS)
240 clnt_perror(client, "yp_next_host: clnt_call");
241 if ( !(r = ypprot_err(yprkv.stat)) ) {
242 *outkeylen = yprkv.key.keydat_len;
243 *outkey = malloc(*outkeylen+1);
244 memcpy(*outkey, yprkv.key.keydat_val, *outkeylen);
245 (*outkey)[*outkeylen] = '\0';
246 *outvallen = yprkv.val.valdat_len;
247 *outval = malloc(*outvallen+1);
248 memcpy(*outval, yprkv.val.valdat_val, *outvallen);
249 (*outval)[*outvallen] = '\0';
251 xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)&yprkv);
257 yp_all_host(CLIENT *client, char *indomain, char *inmap,
258 struct ypall_callback *incallback)
260 struct ypreq_nokey yprnk;
264 tv.tv_sec = _yplib_host_timeout;
267 yprnk.domain = indomain;
269 ypresp_allfn = incallback->foreach;
270 ypresp_data = (void *)incallback->data;
272 (void) clnt_call(client, YPPROC_ALL,
273 (xdrproc_t)xdr_ypreq_nokey, &yprnk,
274 (xdrproc_t)xdr_ypresp_all_seq, &status, tv);
275 if (status != YP_FALSE)
276 return ypprot_err(status);
282 yp_order_host(CLIENT *client, char *indomain, char *inmap, u_int32_t *outorder)
284 struct ypresp_order ypro;
285 struct ypreq_nokey yprnk;
289 tv.tv_sec = _yplib_host_timeout;
292 yprnk.domain = indomain;
295 memset(&ypro, 0, sizeof ypro);
297 r = clnt_call(client, YPPROC_ORDER,
298 (xdrproc_t)xdr_ypreq_nokey, &yprnk,
299 (xdrproc_t)xdr_ypresp_order, &ypro, tv);
300 if (r != RPC_SUCCESS)
301 clnt_perror(client, "yp_order_host: clnt_call");
302 *outorder = ypro.ordernum;
303 xdr_free((xdrproc_t)xdr_ypresp_order, (char *)&ypro);
305 return ypprot_err(ypro.stat);
309 yp_master_host(CLIENT *client, char *indomain, char *inmap, char **outname)
311 struct ypresp_master yprm;
312 struct ypreq_nokey yprnk;
316 tv.tv_sec = _yplib_host_timeout;
318 yprnk.domain = indomain;
321 memset(&yprm, 0, sizeof yprm);
323 r = clnt_call(client, YPPROC_MASTER,
324 (xdrproc_t)xdr_ypreq_nokey, &yprnk,
325 (xdrproc_t)xdr_ypresp_master, &yprm, tv);
326 if (r != RPC_SUCCESS)
327 clnt_perror(client, "yp_master: clnt_call");
328 if (!(r = ypprot_err(yprm.stat)))
329 *outname = strdup(yprm.peer);
330 xdr_free((xdrproc_t)xdr_ypresp_master, (char *)&yprm);
336 yp_maplist_host(CLIENT *client, char *indomain, struct ypmaplist **outmaplist)
338 struct ypresp_maplist ypml;
342 tv.tv_sec = _yplib_host_timeout;
345 memset(&ypml, 0, sizeof ypml);
347 r = clnt_call(client, YPPROC_MAPLIST,
348 (xdrproc_t)xdr_domainname, &indomain,
349 (xdrproc_t)xdr_ypresp_maplist, &ypml, tv);
350 if (r != RPC_SUCCESS)
351 clnt_perror(client, "yp_maplist: clnt_call");
352 *outmaplist = ypml.maps;
353 /* NO: xdr_free(xdr_ypresp_maplist, &ypml);*/
355 return ypprot_err(ypml.stat);