xref: /dflybsd-src/usr.sbin/rpcbind/rpcb_svc.c (revision bd91f5c31d05935d34ffa5befc63a95350bbf000)
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