1ce0e08e2SPeter Avalos /*
2*bd91f5c3SJustin C. Sherrill * Copyright (c) 2009, Sun Microsystems, Inc.
3*bd91f5c3SJustin C. Sherrill * All rights reserved.
4ce0e08e2SPeter Avalos *
5*bd91f5c3SJustin C. Sherrill * Redistribution and use in source and binary forms, with or without
6*bd91f5c3SJustin C. Sherrill * modification, are permitted provided that the following conditions are met:
7*bd91f5c3SJustin C. Sherrill * - Redistributions of source code must retain the above copyright notice,
8*bd91f5c3SJustin C. Sherrill * this list of conditions and the following disclaimer.
9*bd91f5c3SJustin C. Sherrill * - Redistributions in binary form must reproduce the above copyright notice,
10*bd91f5c3SJustin C. Sherrill * this list of conditions and the following disclaimer in the documentation
11*bd91f5c3SJustin C. Sherrill * and/or other materials provided with the distribution.
12*bd91f5c3SJustin C. Sherrill * - Neither the name of Sun Microsystems, Inc. nor the names of its
13*bd91f5c3SJustin C. Sherrill * contributors may be used to endorse or promote products derived
14*bd91f5c3SJustin C. Sherrill * from this software without specific prior written permission.
15ce0e08e2SPeter Avalos *
16*bd91f5c3SJustin C. Sherrill * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*bd91f5c3SJustin C. Sherrill * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*bd91f5c3SJustin C. Sherrill * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*bd91f5c3SJustin C. Sherrill * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*bd91f5c3SJustin C. Sherrill * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*bd91f5c3SJustin C. Sherrill * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*bd91f5c3SJustin C. Sherrill * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*bd91f5c3SJustin C. Sherrill * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*bd91f5c3SJustin C. Sherrill * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*bd91f5c3SJustin C. Sherrill * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*bd91f5c3SJustin C. Sherrill * POSSIBILITY OF SUCH DAMAGE.
27ce0e08e2SPeter Avalos *
28ce0e08e2SPeter Avalos * @(#)rpcb_svc.c 1.16 93/07/05 SMI"
29ce0e08e2SPeter Avalos * $NetBSD: rpcb_svc.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $
30ce0e08e2SPeter Avalos * $FreeBSD: src/usr.sbin/rpcbind/rpcb_svc.c,v 1.3 2007/11/07 10:53:39 kevlo Exp $
31ce0e08e2SPeter Avalos */
32ce0e08e2SPeter Avalos /*
33ce0e08e2SPeter Avalos * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
34ce0e08e2SPeter Avalos */
35ce0e08e2SPeter Avalos
36ce0e08e2SPeter Avalos /*
37ce0e08e2SPeter Avalos * rpcb_svc.c
38ce0e08e2SPeter Avalos * The server procedure for the version 3 rpcbind (TLI).
39ce0e08e2SPeter Avalos *
40ce0e08e2SPeter Avalos * It maintains a separate list of all the registered services with the
41ce0e08e2SPeter Avalos * version 3 of rpcbind.
42ce0e08e2SPeter Avalos */
43ce0e08e2SPeter Avalos #include <sys/types.h>
44ce0e08e2SPeter Avalos #include <rpc/rpc.h>
45ce0e08e2SPeter Avalos #include <rpc/rpcb_prot.h>
46ce0e08e2SPeter Avalos #include <netconfig.h>
47ce0e08e2SPeter Avalos #include <syslog.h>
48ce0e08e2SPeter Avalos #include <stdlib.h>
49ce0e08e2SPeter Avalos #include <stdio.h>
50ce0e08e2SPeter Avalos #include <string.h>
51ce0e08e2SPeter Avalos
52ce0e08e2SPeter Avalos #include "rpcbind.h"
53ce0e08e2SPeter Avalos
54ce0e08e2SPeter Avalos static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *,
55ce0e08e2SPeter Avalos rpcvers_t);
56ce0e08e2SPeter Avalos static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *,
57ce0e08e2SPeter Avalos rpcvers_t);
58ce0e08e2SPeter Avalos
59ce0e08e2SPeter Avalos /*
60ce0e08e2SPeter Avalos * Called by svc_getreqset. There is a separate server handle for
61ce0e08e2SPeter Avalos * every transport that it waits on.
62ce0e08e2SPeter Avalos */
63ce0e08e2SPeter Avalos void
rpcb_service_3(struct svc_req * rqstp,SVCXPRT * transp)64ce0e08e2SPeter Avalos rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp)
65ce0e08e2SPeter Avalos {
66ce0e08e2SPeter Avalos union {
67ce0e08e2SPeter Avalos RPCB rpcbproc_set_3_arg;
68ce0e08e2SPeter Avalos RPCB rpcbproc_unset_3_arg;
69ce0e08e2SPeter Avalos RPCB rpcbproc_getaddr_3_local_arg;
70ce0e08e2SPeter Avalos struct rpcb_rmtcallargs rpcbproc_callit_3_arg;
71ce0e08e2SPeter Avalos char *rpcbproc_uaddr2taddr_3_arg;
72ce0e08e2SPeter Avalos struct netbuf rpcbproc_taddr2uaddr_3_arg;
73ce0e08e2SPeter Avalos } argument;
74ce0e08e2SPeter Avalos char *result;
75ce0e08e2SPeter Avalos xdrproc_t xdr_argument, xdr_result;
76ce0e08e2SPeter Avalos void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
77ce0e08e2SPeter Avalos
78ce0e08e2SPeter Avalos rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
79ce0e08e2SPeter Avalos
80ce0e08e2SPeter Avalos switch (rqstp->rq_proc) {
81ce0e08e2SPeter Avalos case NULLPROC:
82ce0e08e2SPeter Avalos /*
83ce0e08e2SPeter Avalos * Null proc call
84ce0e08e2SPeter Avalos */
85ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
86ce0e08e2SPeter Avalos if (debugging)
87ce0e08e2SPeter Avalos fprintf(stderr, "RPCBPROC_NULL\n");
88ce0e08e2SPeter Avalos #endif
89ce0e08e2SPeter Avalos /* This call just logs, no actual checks */
90ce0e08e2SPeter Avalos check_access(transp, rqstp->rq_proc, NULL, RPCBVERS);
91ce0e08e2SPeter Avalos svc_sendreply(transp, (xdrproc_t)xdr_void, NULL);
92ce0e08e2SPeter Avalos return;
93ce0e08e2SPeter Avalos
94ce0e08e2SPeter Avalos case RPCBPROC_SET:
95ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t )xdr_rpcb;
96ce0e08e2SPeter Avalos xdr_result = (xdrproc_t )xdr_bool;
97ce0e08e2SPeter Avalos local = rpcbproc_set_com;
98ce0e08e2SPeter Avalos break;
99ce0e08e2SPeter Avalos
100ce0e08e2SPeter Avalos case RPCBPROC_UNSET:
101ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t)xdr_rpcb;
102ce0e08e2SPeter Avalos xdr_result = (xdrproc_t)xdr_bool;
103ce0e08e2SPeter Avalos local = rpcbproc_unset_com;
104ce0e08e2SPeter Avalos break;
105ce0e08e2SPeter Avalos
106ce0e08e2SPeter Avalos case RPCBPROC_GETADDR:
107ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t)xdr_rpcb;
108ce0e08e2SPeter Avalos xdr_result = (xdrproc_t)xdr_wrapstring;
109ce0e08e2SPeter Avalos local = rpcbproc_getaddr_3_local;
110ce0e08e2SPeter Avalos break;
111ce0e08e2SPeter Avalos
112ce0e08e2SPeter Avalos case RPCBPROC_DUMP:
113ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
114ce0e08e2SPeter Avalos if (debugging)
115ce0e08e2SPeter Avalos fprintf(stderr, "RPCBPROC_DUMP\n");
116ce0e08e2SPeter Avalos #endif
117ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t)xdr_void;
118ce0e08e2SPeter Avalos xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
119ce0e08e2SPeter Avalos local = rpcbproc_dump_3_local;
120ce0e08e2SPeter Avalos break;
121ce0e08e2SPeter Avalos
122ce0e08e2SPeter Avalos case RPCBPROC_CALLIT:
123ce0e08e2SPeter Avalos rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
124ce0e08e2SPeter Avalos return;
125ce0e08e2SPeter Avalos
126ce0e08e2SPeter Avalos case RPCBPROC_GETTIME:
127ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
128ce0e08e2SPeter Avalos if (debugging)
129ce0e08e2SPeter Avalos fprintf(stderr, "RPCBPROC_GETTIME\n");
130ce0e08e2SPeter Avalos #endif
131ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t)xdr_void;
132ce0e08e2SPeter Avalos xdr_result = (xdrproc_t)xdr_u_long;
133ce0e08e2SPeter Avalos local = rpcbproc_gettime_com;
134ce0e08e2SPeter Avalos break;
135ce0e08e2SPeter Avalos
136ce0e08e2SPeter Avalos case RPCBPROC_UADDR2TADDR:
137ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
138ce0e08e2SPeter Avalos if (debugging)
139ce0e08e2SPeter Avalos fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
140ce0e08e2SPeter Avalos #endif
141ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t)xdr_wrapstring;
142ce0e08e2SPeter Avalos xdr_result = (xdrproc_t)xdr_netbuf;
143ce0e08e2SPeter Avalos local = rpcbproc_uaddr2taddr_com;
144ce0e08e2SPeter Avalos break;
145ce0e08e2SPeter Avalos
146ce0e08e2SPeter Avalos case RPCBPROC_TADDR2UADDR:
147ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
148ce0e08e2SPeter Avalos if (debugging)
149ce0e08e2SPeter Avalos fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
150ce0e08e2SPeter Avalos #endif
151ce0e08e2SPeter Avalos xdr_argument = (xdrproc_t)xdr_netbuf;
152ce0e08e2SPeter Avalos xdr_result = (xdrproc_t)xdr_wrapstring;
153ce0e08e2SPeter Avalos local = rpcbproc_taddr2uaddr_com;
154ce0e08e2SPeter Avalos break;
155ce0e08e2SPeter Avalos
156ce0e08e2SPeter Avalos default:
157ce0e08e2SPeter Avalos svcerr_noproc(transp);
158ce0e08e2SPeter Avalos return;
159ce0e08e2SPeter Avalos }
160ce0e08e2SPeter Avalos memset((char *)&argument, 0, sizeof (argument));
161ce0e08e2SPeter Avalos if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
162ce0e08e2SPeter Avalos (char *) &argument)) {
163ce0e08e2SPeter Avalos svcerr_decode(transp);
164ce0e08e2SPeter Avalos if (debugging)
165ce0e08e2SPeter Avalos fprintf(stderr, "rpcbind: could not decode\n");
166ce0e08e2SPeter Avalos return;
167ce0e08e2SPeter Avalos }
168ce0e08e2SPeter Avalos if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) {
169ce0e08e2SPeter Avalos svcerr_weakauth(transp);
170ce0e08e2SPeter Avalos goto done;
171ce0e08e2SPeter Avalos }
172ce0e08e2SPeter Avalos result = (*local)(&argument, rqstp, transp, RPCBVERS);
173ce0e08e2SPeter Avalos if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result,
174ce0e08e2SPeter Avalos result)) {
175ce0e08e2SPeter Avalos svcerr_systemerr(transp);
176ce0e08e2SPeter Avalos if (debugging) {
177ce0e08e2SPeter Avalos fprintf(stderr, "rpcbind: svc_sendreply\n");
178ce0e08e2SPeter Avalos if (doabort) {
179ce0e08e2SPeter Avalos rpcbind_abort();
180ce0e08e2SPeter Avalos }
181ce0e08e2SPeter Avalos }
182ce0e08e2SPeter Avalos }
183ce0e08e2SPeter Avalos done:
184ce0e08e2SPeter Avalos if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)
185ce0e08e2SPeter Avalos &argument)) {
186ce0e08e2SPeter Avalos if (debugging) {
187ce0e08e2SPeter Avalos fprintf(stderr, "unable to free arguments\n");
188ce0e08e2SPeter Avalos if (doabort) {
189ce0e08e2SPeter Avalos rpcbind_abort();
190ce0e08e2SPeter Avalos }
191ce0e08e2SPeter Avalos }
192ce0e08e2SPeter Avalos }
193ce0e08e2SPeter Avalos }
194ce0e08e2SPeter Avalos
195ce0e08e2SPeter Avalos /*
196ce0e08e2SPeter Avalos * Lookup the mapping for a program, version and return its
197ce0e08e2SPeter Avalos * address. Assuming that the caller wants the address of the
198ce0e08e2SPeter Avalos * server running on the transport on which the request came.
199ce0e08e2SPeter Avalos *
200ce0e08e2SPeter Avalos * We also try to resolve the universal address in terms of
201ce0e08e2SPeter Avalos * address of the caller.
202ce0e08e2SPeter Avalos */
203ce0e08e2SPeter Avalos /* ARGSUSED */
204ce0e08e2SPeter Avalos static void *
rpcbproc_getaddr_3_local(void * arg,struct svc_req * rqstp __unused,SVCXPRT * transp __unused,rpcvers_t versnum __unused)205ce0e08e2SPeter Avalos rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused,
206ce0e08e2SPeter Avalos SVCXPRT *transp __unused, rpcvers_t versnum __unused)
207ce0e08e2SPeter Avalos {
208ce0e08e2SPeter Avalos RPCB *regp = (RPCB *)arg;
209ce0e08e2SPeter Avalos #ifdef RPCBIND_DEBUG
210ce0e08e2SPeter Avalos if (debugging) {
211ce0e08e2SPeter Avalos char *uaddr;
212ce0e08e2SPeter Avalos
213ce0e08e2SPeter Avalos uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
214ce0e08e2SPeter Avalos svc_getrpccaller(transp));
215ce0e08e2SPeter Avalos fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
216ce0e08e2SPeter Avalos (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
217ce0e08e2SPeter Avalos regp->r_netid, uaddr);
218ce0e08e2SPeter Avalos free(uaddr);
219ce0e08e2SPeter Avalos }
220ce0e08e2SPeter Avalos #endif
221ce0e08e2SPeter Avalos return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS,
222ce0e08e2SPeter Avalos RPCB_ALLVERS));
223ce0e08e2SPeter Avalos }
224ce0e08e2SPeter Avalos
225ce0e08e2SPeter Avalos /* ARGSUSED */
226ce0e08e2SPeter Avalos static void *
rpcbproc_dump_3_local(void * arg __unused,struct svc_req * rqstp __unused,SVCXPRT * transp __unused,rpcvers_t versnum __unused)227ce0e08e2SPeter Avalos rpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused,
228ce0e08e2SPeter Avalos SVCXPRT *transp __unused, rpcvers_t versnum __unused)
229ce0e08e2SPeter Avalos {
230ce0e08e2SPeter Avalos return ((void *)&list_rbl);
231ce0e08e2SPeter Avalos }
232