174462Salfred/*	$NetBSD: rpcb_svc.c,v 1.1 2000/06/02 23:15:41 fvdl Exp $	*/
274462Salfred/*	$FreeBSD$ */
374462Salfred
4258564Shrs/*-
5258564Shrs * Copyright (c) 2009, Sun Microsystems, Inc.
6258564Shrs * All rights reserved.
7258564Shrs *
8258564Shrs * Redistribution and use in source and binary forms, with or without
9258564Shrs * modification, are permitted provided that the following conditions are met:
10258564Shrs * - Redistributions of source code must retain the above copyright notice,
11258564Shrs *   this list of conditions and the following disclaimer.
12258564Shrs * - Redistributions in binary form must reproduce the above copyright notice,
13258564Shrs *   this list of conditions and the following disclaimer in the documentation
14258564Shrs *   and/or other materials provided with the distribution.
15258564Shrs * - Neither the name of Sun Microsystems, Inc. nor the names of its
16258564Shrs *   contributors may be used to endorse or promote products derived
17258564Shrs *   from this software without specific prior written permission.
18258564Shrs *
19258564Shrs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20258564Shrs * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21258564Shrs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22258564Shrs * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23258564Shrs * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24258564Shrs * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25258564Shrs * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26258564Shrs * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27258564Shrs * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28258564Shrs * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29258564Shrs * POSSIBILITY OF SUCH DAMAGE.
3074462Salfred */
3174462Salfred/*
3274462Salfred * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc.
3374462Salfred */
3474462Salfred
3574462Salfred/* #ident	"@(#)rpcb_svc.c	1.16	93/07/05 SMI" */
3674462Salfred
3774462Salfred/*
3874462Salfred * rpcb_svc.c
3974462Salfred * The server procedure for the version 3 rpcbind (TLI).
4074462Salfred *
4174462Salfred * It maintains a separate list of all the registered services with the
4274462Salfred * version 3 of rpcbind.
4374462Salfred */
4474462Salfred#include <sys/types.h>
4574462Salfred#include <rpc/rpc.h>
4674462Salfred#include <rpc/rpcb_prot.h>
4774462Salfred#include <netconfig.h>
4874462Salfred#include <syslog.h>
4974462Salfred#include <stdlib.h>
5074462Salfred#include <stdio.h>
5174462Salfred#include <string.h>
5274462Salfred
5374462Salfred#include "rpcbind.h"
5474462Salfred
55173412Skevlostatic void *rpcbproc_getaddr_3_local(void *, struct svc_req *, SVCXPRT *,
56173412Skevlo					   rpcvers_t);
57173412Skevlostatic void *rpcbproc_dump_3_local(void *, struct svc_req *, SVCXPRT *,
58173412Skevlo					rpcvers_t);
5974462Salfred
6074462Salfred/*
6174462Salfred * Called by svc_getreqset. There is a separate server handle for
6274462Salfred * every transport that it waits on.
6374462Salfred */
6474462Salfredvoid
6574462Salfredrpcb_service_3(struct svc_req *rqstp, SVCXPRT *transp)
6674462Salfred{
6774462Salfred	union {
6874462Salfred		RPCB rpcbproc_set_3_arg;
6974462Salfred		RPCB rpcbproc_unset_3_arg;
7074462Salfred		RPCB rpcbproc_getaddr_3_local_arg;
7174462Salfred		struct rpcb_rmtcallargs rpcbproc_callit_3_arg;
7274462Salfred		char *rpcbproc_uaddr2taddr_3_arg;
7374462Salfred		struct netbuf rpcbproc_taddr2uaddr_3_arg;
7474462Salfred	} argument;
7574462Salfred	char *result;
7674462Salfred	xdrproc_t xdr_argument, xdr_result;
77173412Skevlo	void *(*local)(void *, struct svc_req *, SVCXPRT *, rpcvers_t);
7874462Salfred
7974462Salfred	rpcbs_procinfo(RPCBVERS_3_STAT, rqstp->rq_proc);
8074462Salfred
8174462Salfred	switch (rqstp->rq_proc) {
8274462Salfred	case NULLPROC:
8374462Salfred		/*
8474462Salfred		 * Null proc call
8574462Salfred		 */
8674462Salfred#ifdef RPCBIND_DEBUG
8774462Salfred		if (debugging)
8874462Salfred			fprintf(stderr, "RPCBPROC_NULL\n");
8974462Salfred#endif
9074462Salfred		/* This call just logs, no actual checks */
9174462Salfred		check_access(transp, rqstp->rq_proc, NULL, RPCBVERS);
9274462Salfred		(void) svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL);
9374462Salfred		return;
9474462Salfred
9574462Salfred	case RPCBPROC_SET:
9674462Salfred		xdr_argument = (xdrproc_t )xdr_rpcb;
9774462Salfred		xdr_result = (xdrproc_t )xdr_bool;
9874462Salfred		local = rpcbproc_set_com;
9974462Salfred		break;
10074462Salfred
10174462Salfred	case RPCBPROC_UNSET:
10274462Salfred		xdr_argument = (xdrproc_t)xdr_rpcb;
10374462Salfred		xdr_result = (xdrproc_t)xdr_bool;
10474462Salfred		local = rpcbproc_unset_com;
10574462Salfred		break;
10674462Salfred
10774462Salfred	case RPCBPROC_GETADDR:
10874462Salfred		xdr_argument = (xdrproc_t)xdr_rpcb;
10974462Salfred		xdr_result = (xdrproc_t)xdr_wrapstring;
11074462Salfred		local = rpcbproc_getaddr_3_local;
11174462Salfred		break;
11274462Salfred
11374462Salfred	case RPCBPROC_DUMP:
11474462Salfred#ifdef RPCBIND_DEBUG
11574462Salfred		if (debugging)
11674462Salfred			fprintf(stderr, "RPCBPROC_DUMP\n");
11774462Salfred#endif
11874462Salfred		xdr_argument = (xdrproc_t)xdr_void;
11974462Salfred		xdr_result = (xdrproc_t)xdr_rpcblist_ptr;
12074462Salfred		local = rpcbproc_dump_3_local;
12174462Salfred		break;
12274462Salfred
12374462Salfred	case RPCBPROC_CALLIT:
12474462Salfred		rpcbproc_callit_com(rqstp, transp, rqstp->rq_proc, RPCBVERS);
12574462Salfred		return;
12674462Salfred
12774462Salfred	case RPCBPROC_GETTIME:
12874462Salfred#ifdef RPCBIND_DEBUG
12974462Salfred		if (debugging)
13074462Salfred			fprintf(stderr, "RPCBPROC_GETTIME\n");
13174462Salfred#endif
13274462Salfred		xdr_argument = (xdrproc_t)xdr_void;
13374462Salfred		xdr_result = (xdrproc_t)xdr_u_long;
13474462Salfred		local = rpcbproc_gettime_com;
13574462Salfred		break;
13674462Salfred
13774462Salfred	case RPCBPROC_UADDR2TADDR:
13874462Salfred#ifdef RPCBIND_DEBUG
13974462Salfred		if (debugging)
14074462Salfred			fprintf(stderr, "RPCBPROC_UADDR2TADDR\n");
14174462Salfred#endif
14274462Salfred		xdr_argument = (xdrproc_t)xdr_wrapstring;
14374462Salfred		xdr_result = (xdrproc_t)xdr_netbuf;
14474462Salfred		local = rpcbproc_uaddr2taddr_com;
14574462Salfred		break;
14674462Salfred
14774462Salfred	case RPCBPROC_TADDR2UADDR:
14874462Salfred#ifdef RPCBIND_DEBUG
14974462Salfred		if (debugging)
15074462Salfred			fprintf(stderr, "RPCBPROC_TADDR2UADDR\n");
15174462Salfred#endif
15274462Salfred		xdr_argument = (xdrproc_t)xdr_netbuf;
15374462Salfred		xdr_result = (xdrproc_t)xdr_wrapstring;
15474462Salfred		local = rpcbproc_taddr2uaddr_com;
15574462Salfred		break;
15674462Salfred
15774462Salfred	default:
15874462Salfred		svcerr_noproc(transp);
15974462Salfred		return;
16074462Salfred	}
16174462Salfred	(void) memset((char *)&argument, 0, sizeof (argument));
16274462Salfred	if (!svc_getargs(transp, (xdrproc_t) xdr_argument,
16374462Salfred				(char *) &argument)) {
16474462Salfred		svcerr_decode(transp);
16574462Salfred		if (debugging)
16674462Salfred			(void) fprintf(stderr, "rpcbind: could not decode\n");
16774462Salfred		return;
16874462Salfred	}
16974462Salfred	if (!check_access(transp, rqstp->rq_proc, &argument, RPCBVERS)) {
17074462Salfred		svcerr_weakauth(transp);
17174462Salfred		goto done;
17274462Salfred	}
17374462Salfred	result = (*local)(&argument, rqstp, transp, RPCBVERS);
17474462Salfred	if (result != NULL && !svc_sendreply(transp, (xdrproc_t)xdr_result,
17574462Salfred						result)) {
17674462Salfred		svcerr_systemerr(transp);
17774462Salfred		if (debugging) {
17874462Salfred			(void) fprintf(stderr, "rpcbind: svc_sendreply\n");
17974462Salfred			if (doabort) {
18074462Salfred				rpcbind_abort();
18174462Salfred			}
18274462Salfred		}
18374462Salfred	}
18474462Salfreddone:
18574462Salfred	if (!svc_freeargs(transp, (xdrproc_t)xdr_argument, (char *)
18674462Salfred				&argument)) {
18774462Salfred		if (debugging) {
18874462Salfred			(void) fprintf(stderr, "unable to free arguments\n");
18974462Salfred			if (doabort) {
19074462Salfred				rpcbind_abort();
19174462Salfred			}
19274462Salfred		}
19374462Salfred	}
19474462Salfred}
19574462Salfred
19674462Salfred/*
19774462Salfred * Lookup the mapping for a program, version and return its
19874462Salfred * address. Assuming that the caller wants the address of the
19974462Salfred * server running on the transport on which the request came.
20074462Salfred *
20174462Salfred * We also try to resolve the universal address in terms of
20274462Salfred * address of the caller.
20374462Salfred */
20474462Salfred/* ARGSUSED */
20574462Salfredstatic void *
206104592Salfredrpcbproc_getaddr_3_local(void *arg, struct svc_req *rqstp __unused,
207104592Salfred			 SVCXPRT *transp __unused, rpcvers_t versnum __unused)
20874462Salfred{
20974462Salfred	RPCB *regp = (RPCB *)arg;
21074462Salfred#ifdef RPCBIND_DEBUG
21174462Salfred	if (debugging) {
21274462Salfred		char *uaddr;
21374462Salfred
21474462Salfred		uaddr = taddr2uaddr(rpcbind_get_conf(transp->xp_netid),
21574462Salfred			    svc_getrpccaller(transp));
21674462Salfred		fprintf(stderr, "RPCB_GETADDR req for (%lu, %lu, %s) from %s: ",
21774462Salfred		    (unsigned long)regp->r_prog, (unsigned long)regp->r_vers,
21874462Salfred		    regp->r_netid, uaddr);
21974462Salfred		free(uaddr);
22074462Salfred	}
22174462Salfred#endif
22274462Salfred	return (rpcbproc_getaddr_com(regp, rqstp, transp, RPCBVERS,
22374462Salfred	    RPCB_ALLVERS));
22474462Salfred}
22574462Salfred
22674462Salfred/* ARGSUSED */
22774462Salfredstatic void *
228104592Salfredrpcbproc_dump_3_local(void *arg __unused, struct svc_req *rqstp __unused,
229104592Salfred		      SVCXPRT *transp __unused, rpcvers_t versnum __unused)
23074462Salfred{
23174462Salfred	return ((void *)&list_rbl);
23274462Salfred}
233