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