]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.sbin/ypserv/common/yplib_host.c
virtio_mmio: Fix feature negotiation copy-paste issue in r361943
[FreeBSD/FreeBSD.git] / usr.sbin / ypserv / common / yplib_host.c
1 /*      $OpenBSD: yplib_host.c,v 1.18 2015/01/16 06:40:22 deraadt Exp $ */
2
3 /*
4  * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
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.
15  *
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
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
35 #include <sys/uio.h>
36 #include <sys/file.h>
37
38 #include <ctype.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <netdb.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include <netinet/in.h>
48 #include <arpa/inet.h>
49
50 #include <rpc/rpc.h>
51 #include <rpc/xdr.h>
52 #include <rpcsvc/yp.h>
53 #include <rpcsvc/ypclnt.h>
54
55 #include "yplib_host.h"
56
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();
61
62 static int _yplib_host_timeout = 10;
63
64 CLIENT *
65 yp_bind_host(char *server, u_long program, u_long version, u_short port,
66     int usetcp)
67 {
68         struct sockaddr_in rsrv_sin;
69         static CLIENT *client;
70         struct hostent *h;
71         struct timeval tv;
72         int rsrv_sock;
73
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;
78         if (port != 0)
79                 rsrv_sin.sin_port = htons(port);
80
81         if (*server >= '0' && *server <= '9') {
82                 if (inet_aton(server, &rsrv_sin.sin_addr) == 0) {
83                         errx(1, "inet_aton: invalid address %s.",
84                             server);
85                 }
86         } else {
87                 h = gethostbyname(server);
88                 if (h == NULL) {
89                         errx(1, "gethostbyname: unknown host %s.",
90                             server);
91                 }
92                 rsrv_sin.sin_addr.s_addr = *(u_int32_t *)h->h_addr;
93         }
94
95         tv.tv_sec = 10;
96         tv.tv_usec = 0;
97
98         if (usetcp)
99                 client = clnttcp_create(&rsrv_sin, program, version,
100                     &rsrv_sock, 0, 0);
101         else
102                 client = clntudp_create(&rsrv_sin, program, version, tv,
103                     &rsrv_sock);
104
105         if (client == NULL) {
106                 errx(1, "clntudp_create: no contact with host %s.",
107                     server);
108         }
109
110         return (client);
111 }
112
113 CLIENT *
114 yp_bind_local(u_long program, u_long version)
115 {
116         struct sockaddr_in rsrv_sin;
117         static CLIENT *client;
118         struct timeval tv;
119         int rsrv_sock;
120
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;
126
127         tv.tv_sec = 10;
128         tv.tv_usec = 0;
129
130         client = clntudp_create(&rsrv_sin, program, version, tv, &rsrv_sock);
131         if (client == NULL) {
132                 errx(1, "clntudp_create: no contact with localhost.");
133         }
134
135         return (client);
136 }
137
138 int
139 yp_match_host(CLIENT *client, char *indomain, char *inmap, const char *inkey,
140     int inkeylen, char **outval, int *outvallen)
141 {
142         struct ypresp_val yprv;
143         struct ypreq_key yprk;
144         struct timeval tv;
145         int r;
146
147         *outval = NULL;
148         *outvallen = 0;
149
150         tv.tv_sec = _yplib_host_timeout;
151         tv.tv_usec = 0;
152
153         yprk.domain = indomain;
154         yprk.map = inmap;
155         yprk.key.keydat_val = (char *)inkey;
156         yprk.key.keydat_len = inkeylen;
157
158         memset(&yprv, 0, sizeof yprv);
159
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';
170         }
171         xdr_free((xdrproc_t)xdr_ypresp_val, (char *)&yprv);
172
173         return (r);
174 }
175
176 int
177 yp_first_host(CLIENT *client, char *indomain, char *inmap, char **outkey,
178     int *outkeylen, char **outval, int *outvallen)
179 {
180         struct ypresp_key_val yprkv;
181         struct ypreq_nokey yprnk;
182         struct timeval tv;
183         int r;
184
185         *outkey = *outval = NULL;
186         *outkeylen = *outvallen = 0;
187
188         tv.tv_sec = _yplib_host_timeout;
189         tv.tv_usec = 0;
190
191         yprnk.domain = indomain;
192         yprnk.map = inmap;
193         memset(&yprkv, 0, sizeof yprkv);
194
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';
209         }
210         xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)&yprkv);
211
212         return (r);
213 }
214
215 int
216 yp_next_host(CLIENT *client, char *indomain, char *inmap, char *inkey,
217     int inkeylen, char **outkey, int *outkeylen, char **outval, int *outvallen)
218 {
219         struct ypresp_key_val yprkv;
220         struct ypreq_key yprk;
221         struct timeval tv;
222         int r;
223
224         *outkey = *outval = NULL;
225         *outkeylen = *outvallen = 0;
226
227         tv.tv_sec = _yplib_host_timeout;
228         tv.tv_usec = 0;
229
230         yprk.domain = indomain;
231         yprk.map = inmap;
232         yprk.key.keydat_val = inkey;
233         yprk.key.keydat_len = inkeylen;
234         memset(&yprkv, 0, sizeof yprkv);
235
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';
250         }
251         xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *)&yprkv);
252
253         return (r);
254 }
255
256 int
257 yp_all_host(CLIENT *client, char *indomain, char *inmap,
258     struct ypall_callback *incallback)
259 {
260         struct ypreq_nokey yprnk;
261         struct timeval tv;
262         u_long status;
263
264         tv.tv_sec = _yplib_host_timeout;
265         tv.tv_usec = 0;
266
267         yprnk.domain = indomain;
268         yprnk.map = inmap;
269         ypresp_allfn = incallback->foreach;
270         ypresp_data = (void *)incallback->data;
271
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);
277
278         return (0);
279 }
280
281 int
282 yp_order_host(CLIENT *client, char *indomain, char *inmap, u_int32_t *outorder)
283 {
284         struct ypresp_order ypro;
285         struct ypreq_nokey yprnk;
286         struct timeval tv;
287         int r;
288
289         tv.tv_sec = _yplib_host_timeout;
290         tv.tv_usec = 0;
291
292         yprnk.domain = indomain;
293         yprnk.map = inmap;
294
295         memset(&ypro, 0, sizeof ypro);
296
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);
304
305         return ypprot_err(ypro.stat);
306 }
307
308 int
309 yp_master_host(CLIENT *client, char *indomain, char *inmap, char **outname)
310 {
311         struct ypresp_master yprm;
312         struct ypreq_nokey yprnk;
313         struct timeval tv;
314         int r;
315
316         tv.tv_sec = _yplib_host_timeout;
317         tv.tv_usec = 0;
318         yprnk.domain = indomain;
319         yprnk.map = inmap;
320
321         memset(&yprm, 0, sizeof yprm);
322
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);
331
332         return (r);
333 }
334
335 int
336 yp_maplist_host(CLIENT *client, char *indomain, struct ypmaplist **outmaplist)
337 {
338         struct ypresp_maplist ypml;
339         struct timeval tv;
340         int r;
341
342         tv.tv_sec = _yplib_host_timeout;
343         tv.tv_usec = 0;
344
345         memset(&ypml, 0, sizeof ypml);
346
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);*/
354
355         return ypprot_err(ypml.stat);
356 }