xref: /freebsd/usr.sbin/rpcbind/rpcb_svc.c (revision 8a16b7a18f5d0b031f09832fd7752fba717e2a97)
18360efbdSAlfred Perlstein /*	$NetBSD: rpcb_svc.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $	*/
28360efbdSAlfred Perlstein /*	$FreeBSD$ */
38360efbdSAlfred Perlstein 
4a7c51fa1SHiroki Sato /*-
5*8a16b7a1SPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
6*8a16b7a1SPedro F. Giffuni  *
7a7c51fa1SHiroki Sato  * Copyright (c) 2009, Sun Microsystems, Inc.
8a7c51fa1SHiroki Sato  * All rights reserved.
98360efbdSAlfred Perlstein  *
10a7c51fa1SHiroki Sato  * Redistribution and use in source and binary forms, with or without
11a7c51fa1SHiroki Sato  * modification, are permitted provided that the following conditions are met:
12a7c51fa1SHiroki Sato  * - Redistributions of source code must retain the above copyright notice,
13a7c51fa1SHiroki Sato  *   this list of conditions and the following disclaimer.
14a7c51fa1SHiroki Sato  * - Redistributions in binary form must reproduce the above copyright notice,
15a7c51fa1SHiroki Sato  *   this list of conditions and the following disclaimer in the documentation
16a7c51fa1SHiroki Sato  *   and/or other materials provided with the distribution.
17a7c51fa1SHiroki Sato  * - Neither the name of Sun Microsystems, Inc. nor the names of its
18a7c51fa1SHiroki Sato  *   contributors may be used to endorse or promote products derived
19a7c51fa1SHiroki Sato  *   from this software without specific prior written permission.
208360efbdSAlfred Perlstein  *
21a7c51fa1SHiroki Sato  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22a7c51fa1SHiroki Sato  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23a7c51fa1SHiroki Sato  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24a7c51fa1SHiroki Sato  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25a7c51fa1SHiroki Sato  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26a7c51fa1SHiroki Sato  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27a7c51fa1SHiroki Sato  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28a7c51fa1SHiroki Sato  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29a7c51fa1SHiroki Sato  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30a7c51fa1SHiroki Sato  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31a7c51fa1SHiroki Sato  * POSSIBILITY OF SUCH DAMAGE.
328360efbdSAlfred Perlstein  */
338360efbdSAlfred Perlstein /*
348360efbdSAlfred Perlstein  * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
358360efbdSAlfred Perlstein  */
368360efbdSAlfred Perlstein 
378360efbdSAlfred Perlstein /* #ident	"@(#)rpcb_svc.c	1.16	93/07/05 SMI" */
388360efbdSAlfred Perlstein 
398360efbdSAlfred Perlstein /*
408360efbdSAlfred Perlstein  * rpcb_svc.c
418360efbdSAlfred Perlstein  * The server procedure for the version 3 rpcbind (TLI).
428360efbdSAlfred Perlstein  *
438360efbdSAlfred Perlstein  * It maintains a separate list of all the registered services with the
448360efbdSAlfred Perlstein  * version 3 of rpcbind.
458360efbdSAlfred Perlstein  */
468360efbdSAlfred Perlstein #include <sys/types.h>
478360efbdSAlfred Perlstein #include <rpc/rpc.h>
488360efbdSAlfred Perlstein #include <rpc/rpcb_prot.h>
498360efbdSAlfred Perlstein #include <netconfig.h>
508360efbdSAlfred Perlstein #include <syslog.h>
518360efbdSAlfred Perlstein #include <stdlib.h>
528360efbdSAlfred Perlstein #include <stdio.h>
538360efbdSAlfred Perlstein #include <string.h>
548360efbdSAlfred Perlstein 
558360efbdSAlfred Perlstein #include "rpcbind.h"
568360efbdSAlfred Perlstein 
57784bddbcSKevin Lo static void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *,
58784bddbcSKevin Lo 					   rpcvers_t);
59784bddbcSKevin Lo static void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *,
60784bddbcSKevin Lo 					rpcvers_t);
618360efbdSAlfred Perlstein 
628360efbdSAlfred Perlstein /*
638360efbdSAlfred Perlstein  * Called by svc_getreqset. There is a separate server handle for
648360efbdSAlfred Perlstein  * every transport that it waits on.
658360efbdSAlfred Perlstein  */
668360efbdSAlfred Perlstein void
678360efbdSAlfred Perlstein rpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp)
688360efbdSAlfred Perlstein {
698360efbdSAlfred Perlstein 	union {
708360efbdSAlfred Perlstein 		RPCB rpcbproc_set_3_arg;
718360efbdSAlfred Perlstein 		RPCB rpcbproc_unset_3_arg;
728360efbdSAlfred Perlstein 		RPCB rpcbproc_getaddr_3_local_arg;
738360efbdSAlfred Perlstein 		struct rpcb_rmtcallargs rpcbproc_callit_3_arg;
748360efbdSAlfred Perlstein 		char *rpcbproc_uaddr2taddr_3_arg;
758360efbdSAlfred Perlstein 		struct netbuf rpcbproc_taddr2uaddr_3_arg;
768360efbdSAlfred Perlstein 	} argument;
778360efbdSAlfred Perlstein 	char *result;
788360efbdSAlfred Perlstein 	xdrproc_t xdr_argument, xdr_result;
79784bddbcSKevin Lo 	void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
808360efbdSAlfred Perlstein 
818360efbdSAlfred Perlstein 	rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
828360efbdSAlfred Perlstein 
838360efbdSAlfred Perlstein 	switch (rqstp->rq_proc) {
848360efbdSAlfred Perlstein 	case NULLPROC:
858360efbdSAlfred Perlstein 		/*
868360efbdSAlfred Perlstein 		 * Null proc call
878360efbdSAlfred Perlstein 		 */
888360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
898360efbdSAlfred Perlstein 		if (debugging)
908360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_NULL\n");
918360efbdSAlfred Perlstein #endif
928360efbdSAlfred Perlstein 		/* This call just logs, no actual checks */
938360efbdSAlfred Perlstein 		check_access(transp, rqstp->rq_proc, NULL, RPCBVERS);
948360efbdSAlfred Perlstein 		(void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
958360efbdSAlfred Perlstein 		return;
968360efbdSAlfred Perlstein 
978360efbdSAlfred Perlstein 	case RPCBPROC_SET:
988360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t )xdr_rpcb;
998360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t )xdr_bool;
1008360efbdSAlfred Perlstein 		local = rpcbproc_set_com;
1018360efbdSAlfred Perlstein 		break;
1028360efbdSAlfred Perlstein 
1038360efbdSAlfred Perlstein 	case RPCBPROC_UNSET:
1048360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1058360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_bool;
1068360efbdSAlfred Perlstein 		local = rpcbproc_unset_com;
1078360efbdSAlfred Perlstein 		break;
1088360efbdSAlfred Perlstein 
1098360efbdSAlfred Perlstein 	case RPCBPROC_GETADDR:
1108360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_rpcb;
1118360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_wrapstring;
1128360efbdSAlfred Perlstein 		local = rpcbproc_getaddr_3_local;
1138360efbdSAlfred Perlstein 		break;
1148360efbdSAlfred Perlstein 
1158360efbdSAlfred Perlstein 	case RPCBPROC_DUMP:
1168360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1178360efbdSAlfred Perlstein 		if (debugging)
1188360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_DUMP\n");
1198360efbdSAlfred Perlstein #endif
1208360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_void;
1218360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
1228360efbdSAlfred Perlstein 		local = rpcbproc_dump_3_local;
1238360efbdSAlfred Perlstein 		break;
1248360efbdSAlfred Perlstein 
1258360efbdSAlfred Perlstein 	case RPCBPROC_CALLIT:
1268360efbdSAlfred Perlstein 		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
1278360efbdSAlfred Perlstein 		return;
1288360efbdSAlfred Perlstein 
1298360efbdSAlfred Perlstein 	case RPCBPROC_GETTIME:
1308360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1318360efbdSAlfred Perlstein 		if (debugging)
1328360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_GETTIME\n");
1338360efbdSAlfred Perlstein #endif
1348360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_void;
1358360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_u_long;
1368360efbdSAlfred Perlstein 		local = rpcbproc_gettime_com;
1378360efbdSAlfred Perlstein 		break;
1388360efbdSAlfred Perlstein 
1398360efbdSAlfred Perlstein 	case RPCBPROC_UADDR2TADDR:
1408360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1418360efbdSAlfred Perlstein 		if (debugging)
1428360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
1438360efbdSAlfred Perlstein #endif
1448360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_wrapstring;
1458360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_netbuf;
1468360efbdSAlfred Perlstein 		local = rpcbproc_uaddr2taddr_com;
1478360efbdSAlfred Perlstein 		break;
1488360efbdSAlfred Perlstein 
1498360efbdSAlfred Perlstein 	case RPCBPROC_TADDR2UADDR:
1508360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
1518360efbdSAlfred Perlstein 		if (debugging)
1528360efbdSAlfred Perlstein 			fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
1538360efbdSAlfred Perlstein #endif
1548360efbdSAlfred Perlstein 		xdr_argument = (xdrproc_t)xdr_netbuf;
1558360efbdSAlfred Perlstein 		xdr_result = (xdrproc_t)xdr_wrapstring;
1568360efbdSAlfred Perlstein 		local = rpcbproc_taddr2uaddr_com;
1578360efbdSAlfred Perlstein 		break;
1588360efbdSAlfred Perlstein 
1598360efbdSAlfred Perlstein 	default:
1608360efbdSAlfred Perlstein 		svcerr_noproc(transp);
1618360efbdSAlfred Perlstein 		return;
1628360efbdSAlfred Perlstein 	}
1638360efbdSAlfred Perlstein 	(void) memset((char *)&argument, 0, sizeof (argument));
1648360efbdSAlfred Perlstein 	if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
1658360efbdSAlfred Perlstein 				(char *) &argument)) {
1668360efbdSAlfred Perlstein 		svcerr_decode(transp);
1678360efbdSAlfred Perlstein 		if (debugging)
1688360efbdSAlfred Perlstein 			(void) fprintf(stderr, "rpcbind: could not decode\n");
1698360efbdSAlfred Perlstein 		return;
1708360efbdSAlfred Perlstein 	}
1718360efbdSAlfred Perlstein 	if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) {
1728360efbdSAlfred Perlstein 		svcerr_weakauth(transp);
1738360efbdSAlfred Perlstein 		goto done;
1748360efbdSAlfred Perlstein 	}
1758360efbdSAlfred Perlstein 	result = (*local)(&argument, rqstp, transp, RPCBVERS);
1768360efbdSAlfred Perlstein 	if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result,
1778360efbdSAlfred Perlstein 						result)) {
1788360efbdSAlfred Perlstein 		svcerr_systemerr(transp);
1798360efbdSAlfred Perlstein 		if (debugging) {
1808360efbdSAlfred Perlstein 			(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
1818360efbdSAlfred Perlstein 			if (doabort) {
1828360efbdSAlfred Perlstein 				rpcbind_abort();
1838360efbdSAlfred Perlstein 			}
1848360efbdSAlfred Perlstein 		}
1858360efbdSAlfred Perlstein 	}
1868360efbdSAlfred Perlstein done:
1878360efbdSAlfred Perlstein 	if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)
1888360efbdSAlfred Perlstein 				&argument)) {
1898360efbdSAlfred Perlstein 		if (debugging) {
1908360efbdSAlfred Perlstein 			(void) fprintf(stderr, "unable to free arguments\n");
1918360efbdSAlfred Perlstein 			if (doabort) {
1928360efbdSAlfred Perlstein 				rpcbind_abort();
1938360efbdSAlfred Perlstein 			}
1948360efbdSAlfred Perlstein 		}
1958360efbdSAlfred Perlstein 	}
1968360efbdSAlfred Perlstein }
1978360efbdSAlfred Perlstein 
1988360efbdSAlfred Perlstein /*
1998360efbdSAlfred Perlstein  * Lookup the mapping for a program, version and return its
2008360efbdSAlfred Perlstein  * address. Assuming that the caller wants the address of the
2018360efbdSAlfred Perlstein  * server running on the transport on which the request came.
2028360efbdSAlfred Perlstein  *
2038360efbdSAlfred Perlstein  * We also try to resolve the universal address in terms of
2048360efbdSAlfred Perlstein  * address of the caller.
2058360efbdSAlfred Perlstein  */
2068360efbdSAlfred Perlstein /* ARGSUSED */
2078360efbdSAlfred Perlstein static void *
2084180788fSAlfred Perlstein rpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused,
2094180788fSAlfred Perlstein 			 SVCXPRT *transp __unused, rpcvers_t versnum __unused)
2108360efbdSAlfred Perlstein {
2118360efbdSAlfred Perlstein 	RPCB *regp = (RPCB *)arg;
2128360efbdSAlfred Perlstein #ifdef RPCBIND_DEBUG
2138360efbdSAlfred Perlstein 	if (debugging) {
2148360efbdSAlfred Perlstein 		char *uaddr;
2158360efbdSAlfred Perlstein 
2168360efbdSAlfred Perlstein 		uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
2178360efbdSAlfred Perlstein 			    svc_getrpccaller(transp));
2188360efbdSAlfred Perlstein 		fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
2198360efbdSAlfred Perlstein 		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
2208360efbdSAlfred Perlstein 		    regp->r_netid, uaddr);
2218360efbdSAlfred Perlstein 		free(uaddr);
2228360efbdSAlfred Perlstein 	}
2238360efbdSAlfred Perlstein #endif
2248360efbdSAlfred Perlstein 	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS,
2258360efbdSAlfred Perlstein 	    RPCB_ALLVERS));
2268360efbdSAlfred Perlstein }
2278360efbdSAlfred Perlstein 
2288360efbdSAlfred Perlstein /* ARGSUSED */
2298360efbdSAlfred Perlstein static void *
2304180788fSAlfred Perlstein rpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused,
2314180788fSAlfred Perlstein 		      SVCXPRT *transp __unused, rpcvers_t versnum __unused)
2328360efbdSAlfred Perlstein {
2338360efbdSAlfred Perlstein 	return ((void *)&list_rbl);
2348360efbdSAlfred Perlstein }
235