1*3e9c5584Schristos /* $NetBSD: rpcb_svc_4.c,v 1.9 2019/01/03 19:04:21 christos Exp $ */
2df898ddbSchristos /* $FreeBSD: head/usr.sbin/rpcbind/rpcb_svc_4.c 258564 2013-11-25 16:44:02Z hrs $ */
3d687de29Sfvdl
4df898ddbSchristos /*-
5df898ddbSchristos * Copyright (c) 2009, Sun Microsystems, Inc.
6df898ddbSchristos * All rights reserved.
7d687de29Sfvdl *
8df898ddbSchristos * Redistribution and use in source and binary forms, with or without
9df898ddbSchristos * modification, are permitted provided that the following conditions are met:
10df898ddbSchristos * - Redistributions of source code must retain the above copyright notice,
11df898ddbSchristos * this list of conditions and the following disclaimer.
12df898ddbSchristos * - Redistributions in binary form must reproduce the above copyright notice,
13df898ddbSchristos * this list of conditions and the following disclaimer in the documentation
14df898ddbSchristos * and/or other materials provided with the distribution.
15df898ddbSchristos * - Neither the name of Sun Microsystems, Inc. nor the names of its
16df898ddbSchristos * contributors may be used to endorse or promote products derived
17df898ddbSchristos * from this software without specific prior written permission.
18d687de29Sfvdl *
19df898ddbSchristos * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20df898ddbSchristos * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21df898ddbSchristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22df898ddbSchristos * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23df898ddbSchristos * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24df898ddbSchristos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25df898ddbSchristos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26df898ddbSchristos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27df898ddbSchristos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28df898ddbSchristos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29df898ddbSchristos * POSSIBILITY OF SUCH DAMAGE.
30d687de29Sfvdl */
31d687de29Sfvdl /*
32d687de29Sfvdl * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
33d687de29Sfvdl */
34d687de29Sfvdl
35d687de29Sfvdl /* #ident "@(#)rpcb_svc_4.c 1.8 93/07/05 SMI" */
36d687de29Sfvdl
37d687de29Sfvdl /*
38d687de29Sfvdl * rpcb_svc_4.c
39d687de29Sfvdl * The server procedure for the version 4 rpcbind.
40d687de29Sfvdl *
41d687de29Sfvdl */
42d687de29Sfvdl
43d687de29Sfvdl #include <sys/types.h>
44d687de29Sfvdl #include <sys/stat.h>
45d687de29Sfvdl #include <rpc/rpc.h>
46d687de29Sfvdl #include <stdio.h>
47d687de29Sfvdl #include <unistd.h>
48d687de29Sfvdl #include <netconfig.h>
49d687de29Sfvdl #include <syslog.h>
50d687de29Sfvdl #include <string.h>
51d687de29Sfvdl #include <stdlib.h>
52d687de29Sfvdl #include "rpcbind.h"
53d687de29Sfvdl
54de327a01Schristos static void *rpcbproc_getaddr_4_local(void *, struct svc_req *, SVCXPRT *,
55de327a01Schristos rpcvers_t);
56de327a01Schristos static void *rpcbproc_getversaddr_4_local(void *, struct svc_req *, SVCXPRT *,
57de327a01Schristos rpcvers_t);
58de327a01Schristos static void *rpcbproc_getaddrlist_4_local(void *, struct svc_req *, SVCXPRT *,
59de327a01Schristos rpcvers_t);
60de327a01Schristos static void free_rpcb_entry_list(rpcb_entry_list_ptr *);
61de327a01Schristos static void *rpcbproc_dump_4_local(void *, struct svc_req *, SVCXPRT *,
62de327a01Schristos rpcvers_t);
63d687de29Sfvdl
64d687de29Sfvdl /*
65d687de29Sfvdl * Called by svc_getreqset. There is a separate server handle for
66d687de29Sfvdl * every transport that it waits on.
67d687de29Sfvdl */
68d687de29Sfvdl void
rpcb_service_4(struct svc_req * rqstp,SVCXPRT * transp)69d687de29Sfvdl rpcb_service_4(struct svc_req *rqstp, SVCXPRT *transp)
70d687de29Sfvdl {
71d687de29Sfvdl union {
72d687de29Sfvdl rpcb rpcbproc_set_4_arg;
73d687de29Sfvdl rpcb rpcbproc_unset_4_arg;
74d687de29Sfvdl rpcb rpcbproc_getaddr_4_local_arg;
75d687de29Sfvdl char *rpcbproc_uaddr2taddr_4_arg;
76d687de29Sfvdl struct netbuf rpcbproc_taddr2uaddr_4_arg;
77d687de29Sfvdl } argument;
78d687de29Sfvdl char *result;
79d687de29Sfvdl xdrproc_t xdr_argument, xdr_result;
80de327a01Schristos void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
81d687de29Sfvdl
82d687de29Sfvdl rpcbs_procinfo(RPCBVERS_4_STAT, rqstp->rq_proc);
83d687de29Sfvdl
84d687de29Sfvdl switch (rqstp->rq_proc) {
85d687de29Sfvdl case NULLPROC:
86d687de29Sfvdl /*
87d687de29Sfvdl * Null proc call
88d687de29Sfvdl */
89d687de29Sfvdl #ifdef RPCBIND_DEBUG
90d687de29Sfvdl if (debugging)
91d687de29Sfvdl fprintf(stderr, "RPCBPROC_NULL\n");
92d687de29Sfvdl #endif
93d687de29Sfvdl check_access(transp, rqstp->rq_proc, NULL, RPCBVERS4);
944a1b3429Splunky (void) svc_sendreply(transp, (xdrproc_t) xdr_void, NULL);
95d687de29Sfvdl return;
96d687de29Sfvdl
97d687de29Sfvdl case RPCBPROC_SET:
98d687de29Sfvdl /*
99d687de29Sfvdl * Check to see whether the message came from
100d687de29Sfvdl * loopback transports (for security reasons)
101d687de29Sfvdl */
102d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_rpcb;
103d687de29Sfvdl xdr_result = (xdrproc_t)xdr_bool;
104d687de29Sfvdl local = rpcbproc_set_com;
105d687de29Sfvdl break;
106d687de29Sfvdl
107d687de29Sfvdl case RPCBPROC_UNSET:
108d687de29Sfvdl /*
109d687de29Sfvdl * Check to see whether the message came from
110d687de29Sfvdl * loopback transports (for security reasons)
111d687de29Sfvdl */
112d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_rpcb;
113d687de29Sfvdl xdr_result = (xdrproc_t)xdr_bool;
114d687de29Sfvdl local = rpcbproc_unset_com;
115d687de29Sfvdl break;
116d687de29Sfvdl
117d687de29Sfvdl case RPCBPROC_GETADDR:
118d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_rpcb;
119d687de29Sfvdl xdr_result = (xdrproc_t)xdr_wrapstring;
120d687de29Sfvdl local = rpcbproc_getaddr_4_local;
121d687de29Sfvdl break;
122d687de29Sfvdl
123d687de29Sfvdl case RPCBPROC_GETVERSADDR:
124d687de29Sfvdl #ifdef RPCBIND_DEBUG
125d687de29Sfvdl if (debugging)
126d687de29Sfvdl fprintf(stderr, "RPCBPROC_GETVERSADDR\n");
127d687de29Sfvdl #endif
128d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_rpcb;
129d687de29Sfvdl xdr_result = (xdrproc_t)xdr_wrapstring;
130d687de29Sfvdl local = rpcbproc_getversaddr_4_local;
131d687de29Sfvdl break;
132d687de29Sfvdl
133d687de29Sfvdl case RPCBPROC_DUMP:
134d687de29Sfvdl #ifdef RPCBIND_DEBUG
135d687de29Sfvdl if (debugging)
136d687de29Sfvdl fprintf(stderr, "RPCBPROC_DUMP\n");
137d687de29Sfvdl #endif
138d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_void;
139d687de29Sfvdl xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
140d687de29Sfvdl local = rpcbproc_dump_4_local;
141d687de29Sfvdl break;
142d687de29Sfvdl
143d687de29Sfvdl case RPCBPROC_INDIRECT:
144d687de29Sfvdl #ifdef RPCBIND_DEBUG
145d687de29Sfvdl if (debugging)
146d687de29Sfvdl fprintf(stderr, "RPCBPROC_INDIRECT\n");
147d687de29Sfvdl #endif
148d687de29Sfvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
149d687de29Sfvdl return;
150d687de29Sfvdl
151d687de29Sfvdl /* case RPCBPROC_CALLIT: */
152d687de29Sfvdl case RPCBPROC_BCAST:
153d687de29Sfvdl #ifdef RPCBIND_DEBUG
154d687de29Sfvdl if (debugging)
155d687de29Sfvdl fprintf(stderr, "RPCBPROC_BCAST\n");
156d687de29Sfvdl #endif
157d687de29Sfvdl rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS4);
158d687de29Sfvdl return;
159d687de29Sfvdl
160d687de29Sfvdl case RPCBPROC_GETTIME:
161d687de29Sfvdl #ifdef RPCBIND_DEBUG
162d687de29Sfvdl if (debugging)
163d687de29Sfvdl fprintf(stderr, "RPCBPROC_GETTIME\n");
164d687de29Sfvdl #endif
165d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_void;
166d687de29Sfvdl xdr_result = (xdrproc_t)xdr_u_long;
167d687de29Sfvdl local = rpcbproc_gettime_com;
168d687de29Sfvdl break;
169d687de29Sfvdl
170d687de29Sfvdl case RPCBPROC_UADDR2TADDR:
171d687de29Sfvdl #ifdef RPCBIND_DEBUG
172d687de29Sfvdl if (debugging)
173d687de29Sfvdl fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
174d687de29Sfvdl #endif
175d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_wrapstring;
176d687de29Sfvdl xdr_result = (xdrproc_t)xdr_netbuf;
177d687de29Sfvdl local = rpcbproc_uaddr2taddr_com;
178d687de29Sfvdl break;
179d687de29Sfvdl
180d687de29Sfvdl case RPCBPROC_TADDR2UADDR:
181d687de29Sfvdl #ifdef RPCBIND_DEBUG
182d687de29Sfvdl if (debugging)
183d687de29Sfvdl fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
184d687de29Sfvdl #endif
185d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_netbuf;
186d687de29Sfvdl xdr_result = (xdrproc_t)xdr_wrapstring;
187d687de29Sfvdl local = rpcbproc_taddr2uaddr_com;
188d687de29Sfvdl break;
189d687de29Sfvdl
190d687de29Sfvdl case RPCBPROC_GETADDRLIST:
191d687de29Sfvdl #ifdef RPCBIND_DEBUG
192d687de29Sfvdl if (debugging)
193d687de29Sfvdl fprintf(stderr, "RPCBPROC_GETADDRLIST\n");
194d687de29Sfvdl #endif
195d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_rpcb;
196d687de29Sfvdl xdr_result = (xdrproc_t)xdr_rpcb_entry_list_ptr;
197d687de29Sfvdl local = rpcbproc_getaddrlist_4_local;
198d687de29Sfvdl break;
199d687de29Sfvdl
200d687de29Sfvdl case RPCBPROC_GETSTAT:
201d687de29Sfvdl #ifdef RPCBIND_DEBUG
202d687de29Sfvdl if (debugging)
203d687de29Sfvdl fprintf(stderr, "RPCBPROC_GETSTAT\n");
204d687de29Sfvdl #endif
205d687de29Sfvdl xdr_argument = (xdrproc_t)xdr_void;
206d687de29Sfvdl xdr_result = (xdrproc_t)xdr_rpcb_stat_byvers;
207d687de29Sfvdl local = rpcbproc_getstat;
208d687de29Sfvdl break;
209d687de29Sfvdl
210d687de29Sfvdl default:
211d687de29Sfvdl svcerr_noproc(transp);
212d687de29Sfvdl return;
213d687de29Sfvdl }
214d687de29Sfvdl memset((char *)&argument, 0, sizeof (argument));
215d687de29Sfvdl if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
216d687de29Sfvdl (char *)&argument)) {
217d687de29Sfvdl svcerr_decode(transp);
218d687de29Sfvdl if (debugging)
219d687de29Sfvdl (void) fprintf(stderr, "rpcbind: could not decode\n");
220d687de29Sfvdl return;
221d687de29Sfvdl }
222d687de29Sfvdl if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS4)) {
223d687de29Sfvdl svcerr_weakauth(transp);
224d687de29Sfvdl goto done;
225d687de29Sfvdl }
226d687de29Sfvdl result = (*local)(&argument, rqstp, transp, RPCBVERS4);
227d687de29Sfvdl if (result != NULL && !svc_sendreply(transp, (xdrproc_t) xdr_result,
228d687de29Sfvdl result)) {
229d687de29Sfvdl svcerr_systemerr(transp);
230d687de29Sfvdl if (debugging) {
231d687de29Sfvdl (void) fprintf(stderr, "rpcbind: svc_sendreply\n");
232d687de29Sfvdl if (doabort) {
233d687de29Sfvdl rpcbind_abort();
234d687de29Sfvdl }
235d687de29Sfvdl }
236d687de29Sfvdl }
237d687de29Sfvdl done:
238d687de29Sfvdl if (!svc_freeargs(transp, (xdrproc_t) xdr_argument,
239d687de29Sfvdl (char *)&argument)) {
240d687de29Sfvdl if (debugging) {
241d687de29Sfvdl (void) fprintf(stderr, "unable to free arguments\n");
242d687de29Sfvdl if (doabort) {
243d687de29Sfvdl rpcbind_abort();
244d687de29Sfvdl }
245d687de29Sfvdl }
246d687de29Sfvdl }
247d687de29Sfvdl return;
248d687de29Sfvdl }
249d687de29Sfvdl
250d687de29Sfvdl /*
251d687de29Sfvdl * Lookup the mapping for a program, version and return its
252d687de29Sfvdl * address. Assuming that the caller wants the address of the
253d687de29Sfvdl * server running on the transport on which the request came.
254d687de29Sfvdl * Even if a service with a different version number is available,
255d687de29Sfvdl * it will return that address. The client should check with an
256d687de29Sfvdl * clnt_call to verify whether the service is the one that is desired.
257d687de29Sfvdl * We also try to resolve the universal address in terms of
258d687de29Sfvdl * address of the caller.
259d687de29Sfvdl */
260d687de29Sfvdl /* ARGSUSED */
261d687de29Sfvdl static void *
rpcbproc_getaddr_4_local(void * arg,struct svc_req * rqstp,SVCXPRT * transp,rpcvers_t rpcbversnum __unused)262d687de29Sfvdl rpcbproc_getaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
263df898ddbSchristos rpcvers_t rpcbversnum __unused)
264d687de29Sfvdl {
265d687de29Sfvdl RPCB *regp = (RPCB *)arg;
266d687de29Sfvdl #ifdef RPCBIND_DEBUG
267d687de29Sfvdl if (debugging) {
268d687de29Sfvdl char *uaddr;
269d687de29Sfvdl
270d687de29Sfvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
271d687de29Sfvdl svc_getrpccaller(transp));
272d687de29Sfvdl fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
273d687de29Sfvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
274d687de29Sfvdl regp->r_netid, uaddr);
275d687de29Sfvdl free(uaddr);
276d687de29Sfvdl }
277d687de29Sfvdl #endif
278d687de29Sfvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
279d687de29Sfvdl RPCB_ALLVERS));
280d687de29Sfvdl }
281d687de29Sfvdl
282d687de29Sfvdl /*
283d687de29Sfvdl * Lookup the mapping for a program, version and return its
284d687de29Sfvdl * address. Assuming that the caller wants the address of the
285d687de29Sfvdl * server running on the transport on which the request came.
286d687de29Sfvdl *
287d687de29Sfvdl * We also try to resolve the universal address in terms of
288d687de29Sfvdl * address of the caller.
289d687de29Sfvdl */
290d687de29Sfvdl /* ARGSUSED */
291d687de29Sfvdl static void *
rpcbproc_getversaddr_4_local(void * arg,struct svc_req * rqstp,SVCXPRT * transp,rpcvers_t versnum __unused)292d687de29Sfvdl rpcbproc_getversaddr_4_local(void *arg, struct svc_req *rqstp, SVCXPRT *transp,
293df898ddbSchristos rpcvers_t versnum __unused)
294d687de29Sfvdl {
295d687de29Sfvdl RPCB *regp = (RPCB *)arg;
296d687de29Sfvdl #ifdef RPCBIND_DEBUG
297d687de29Sfvdl if (debugging) {
298d687de29Sfvdl char *uaddr;
299d687de29Sfvdl
300d687de29Sfvdl uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
301d687de29Sfvdl svc_getrpccaller(transp));
302d687de29Sfvdl fprintf(stderr, "RPCB_GETVERSADDR rqst for (%lu, %lu, %s)"
303d687de29Sfvdl " from %s : ",
304d687de29Sfvdl (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
305d687de29Sfvdl regp->r_netid, uaddr);
306d687de29Sfvdl free(uaddr);
307d687de29Sfvdl }
308d687de29Sfvdl #endif
309d687de29Sfvdl return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS4,
310d687de29Sfvdl RPCB_ONEVERS));
311d687de29Sfvdl }
312d687de29Sfvdl
313d687de29Sfvdl /*
314d687de29Sfvdl * Lookup the mapping for a program, version and return the
315d687de29Sfvdl * addresses for all transports in the current transport family.
316d687de29Sfvdl * We return a merged address.
317d687de29Sfvdl */
318d687de29Sfvdl /* ARGSUSED */
319d687de29Sfvdl static void *
rpcbproc_getaddrlist_4_local(void * arg,struct svc_req * rqstp __unused,SVCXPRT * transp,rpcvers_t versnum __unused)320df898ddbSchristos rpcbproc_getaddrlist_4_local(void *arg, struct svc_req *rqstp __unused,
321df898ddbSchristos SVCXPRT *transp, rpcvers_t versnum __unused)
322d687de29Sfvdl {
323d687de29Sfvdl RPCB *regp = (RPCB *)arg;
324d687de29Sfvdl static rpcb_entry_list_ptr rlist;
325d687de29Sfvdl register rpcblist_ptr rbl;
326df898ddbSchristos rpcb_entry_list_ptr rp, tail;
327d687de29Sfvdl rpcprog_t prog;
328d687de29Sfvdl rpcvers_t vers;
329d687de29Sfvdl rpcb_entry *a;
330d687de29Sfvdl struct netconfig *nconf;
331d687de29Sfvdl struct netconfig *reg_nconf;
332d687de29Sfvdl char *saddr, *maddr = NULL;
333d687de29Sfvdl
334d687de29Sfvdl free_rpcb_entry_list(&rlist);
335df898ddbSchristos tail = NULL;
336d687de29Sfvdl prog = regp->r_prog;
337d687de29Sfvdl vers = regp->r_vers;
338d687de29Sfvdl reg_nconf = rpcbind_get_conf(transp->xp_netid);
339d687de29Sfvdl if (reg_nconf == NULL)
340d687de29Sfvdl return (NULL);
341d687de29Sfvdl if (*(regp->r_addr) != '\0') {
342d687de29Sfvdl saddr = regp->r_addr;
343d687de29Sfvdl } else {
344d687de29Sfvdl saddr = NULL;
345d687de29Sfvdl }
346d687de29Sfvdl #ifdef RPCBIND_DEBUG
347d687de29Sfvdl if (debugging) {
348d687de29Sfvdl fprintf(stderr, "r_addr: %s r_netid: %s nc_protofmly: %s\n",
349d687de29Sfvdl regp->r_addr, regp->r_netid, reg_nconf->nc_protofmly);
350d687de29Sfvdl }
351d687de29Sfvdl #endif
352d687de29Sfvdl for (rbl = list_rbl; rbl != NULL; rbl = rbl->rpcb_next) {
353d687de29Sfvdl if ((rbl->rpcb_map.r_prog == prog) &&
354d687de29Sfvdl (rbl->rpcb_map.r_vers == vers)) {
355d687de29Sfvdl nconf = rpcbind_get_conf(rbl->rpcb_map.r_netid);
356d687de29Sfvdl if (nconf == NULL)
357d687de29Sfvdl goto fail;
358d687de29Sfvdl if (strcmp(nconf->nc_protofmly, reg_nconf->nc_protofmly)
359d687de29Sfvdl != 0) {
360d687de29Sfvdl continue; /* not same proto family */
361d687de29Sfvdl }
362d687de29Sfvdl #ifdef RPCBIND_DEBUG
363d687de29Sfvdl if (debugging)
364df898ddbSchristos fprintf(stderr, "\tmerge with: %s\n",
365df898ddbSchristos rbl->rpcb_map.r_addr);
366d687de29Sfvdl #endif
367d687de29Sfvdl if ((maddr = mergeaddr(transp, rbl->rpcb_map.r_netid,
368d687de29Sfvdl rbl->rpcb_map.r_addr, saddr)) == NULL) {
369d687de29Sfvdl #ifdef RPCBIND_DEBUG
370d687de29Sfvdl if (debugging)
371d687de29Sfvdl fprintf(stderr, " FAILED\n");
372d687de29Sfvdl #endif
373d687de29Sfvdl continue;
374d687de29Sfvdl } else if (!maddr[0]) {
375d687de29Sfvdl #ifdef RPCBIND_DEBUG
376d687de29Sfvdl if (debugging)
377d687de29Sfvdl fprintf(stderr, " SUCCEEDED, but port died - maddr: nullstring\n");
378d687de29Sfvdl #endif
379d687de29Sfvdl /* The server died. Unset this combination */
380d687de29Sfvdl delete_prog(regp->r_prog);
381d687de29Sfvdl continue;
382d687de29Sfvdl }
383d687de29Sfvdl #ifdef RPCBIND_DEBUG
384d687de29Sfvdl if (debugging)
385d687de29Sfvdl fprintf(stderr, " SUCCEEDED maddr: %s\n", maddr);
386d687de29Sfvdl #endif
387d687de29Sfvdl /*
388d687de29Sfvdl * Add it to rlist.
389d687de29Sfvdl */
390*3e9c5584Schristos rp = malloc(sizeof(*rp));
391df898ddbSchristos if (rp == NULL)
392d687de29Sfvdl goto fail;
393d687de29Sfvdl a = &rp->rpcb_entry_map;
394d687de29Sfvdl a->r_maddr = maddr;
395d687de29Sfvdl a->r_nc_netid = nconf->nc_netid;
396d687de29Sfvdl a->r_nc_semantics = nconf->nc_semantics;
397d687de29Sfvdl a->r_nc_protofmly = nconf->nc_protofmly;
398d687de29Sfvdl a->r_nc_proto = nconf->nc_proto;
399d687de29Sfvdl rp->rpcb_entry_next = NULL;
400d687de29Sfvdl if (rlist == NULL) {
401d687de29Sfvdl rlist = rp;
402d687de29Sfvdl tail = rp;
4031716cd4eSchristos } else if (tail) {
404d687de29Sfvdl tail->rpcb_entry_next = rp;
405d687de29Sfvdl tail = rp;
406d687de29Sfvdl }
407d687de29Sfvdl rp = NULL;
408d687de29Sfvdl }
409d687de29Sfvdl }
410d687de29Sfvdl #ifdef RPCBIND_DEBUG
411d687de29Sfvdl if (debugging) {
412d687de29Sfvdl for (rp = rlist; rp; rp = rp->rpcb_entry_next) {
413d687de29Sfvdl fprintf(stderr, "\t%s %s\n", rp->rpcb_entry_map.r_maddr,
414d687de29Sfvdl rp->rpcb_entry_map.r_nc_proto);
415d687de29Sfvdl }
416d687de29Sfvdl }
417d687de29Sfvdl #endif
418d687de29Sfvdl /*
419d687de29Sfvdl * XXX: getaddrlist info is also being stuffed into getaddr.
420d687de29Sfvdl * Perhaps wrong, but better than it not getting counted at all.
421d687de29Sfvdl */
422d687de29Sfvdl rpcbs_getaddr(RPCBVERS4 - 2, prog, vers, transp->xp_netid, maddr);
423d687de29Sfvdl return (void *)&rlist;
424d687de29Sfvdl
425d687de29Sfvdl fail: free_rpcb_entry_list(&rlist);
426d687de29Sfvdl return (NULL);
427d687de29Sfvdl }
428d687de29Sfvdl
429d687de29Sfvdl /*
430d687de29Sfvdl * Free only the allocated structure, rest is all a pointer to some
431d687de29Sfvdl * other data somewhere else.
432d687de29Sfvdl */
433d687de29Sfvdl static void
free_rpcb_entry_list(rpcb_entry_list_ptr * rlistp)434d687de29Sfvdl free_rpcb_entry_list(rpcb_entry_list_ptr *rlistp)
435d687de29Sfvdl {
436d687de29Sfvdl register rpcb_entry_list_ptr rbl, tmp;
437d687de29Sfvdl
438d687de29Sfvdl for (rbl = *rlistp; rbl != NULL; ) {
439d687de29Sfvdl tmp = rbl;
440d687de29Sfvdl rbl = rbl->rpcb_entry_next;
441d687de29Sfvdl free((char *)tmp->rpcb_entry_map.r_maddr);
442d687de29Sfvdl free((char *)tmp);
443d687de29Sfvdl }
444d687de29Sfvdl *rlistp = NULL;
445d687de29Sfvdl }
446d687de29Sfvdl
447d687de29Sfvdl /* ARGSUSED */
448d687de29Sfvdl static void *
rpcbproc_dump_4_local(void * arg __unused,struct svc_req * req __unused,SVCXPRT * xprt __unused,rpcvers_t versnum __unused)449df898ddbSchristos rpcbproc_dump_4_local(void *arg __unused, struct svc_req *req __unused,
450df898ddbSchristos SVCXPRT *xprt __unused, rpcvers_t versnum __unused)
451d687de29Sfvdl {
452d687de29Sfvdl return ((void *)&list_rbl);
453d687de29Sfvdl }
454