xref: /freebsd/crypto/krb5/src/lib/rpc/clnt_raw.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1*7f2fe78bSCy Schubert /* @(#)clnt_raw.c	2.2 88/08/01 4.0 RPCSRC */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert  * Copyright (c) 2010, Oracle America, Inc.
4*7f2fe78bSCy Schubert  *
5*7f2fe78bSCy Schubert  * All rights reserved.
6*7f2fe78bSCy Schubert  *
7*7f2fe78bSCy Schubert  * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert  * modification, are permitted provided that the following conditions are met:
9*7f2fe78bSCy Schubert  *
10*7f2fe78bSCy Schubert  *     * Redistributions of source code must retain the above copyright
11*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer.
12*7f2fe78bSCy Schubert  *
13*7f2fe78bSCy Schubert  *     * Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert  *       notice, this list of conditions and the following disclaimer in
15*7f2fe78bSCy Schubert  *       the documentation and/or other materials provided with the
16*7f2fe78bSCy Schubert  *       distribution.
17*7f2fe78bSCy Schubert  *
18*7f2fe78bSCy Schubert  *     * Neither the name of the "Oracle America, Inc." nor the names of
19*7f2fe78bSCy Schubert  *       its contributors may be used to endorse or promote products
20*7f2fe78bSCy Schubert  *       derived from this software without specific prior written permission.
21*7f2fe78bSCy Schubert  *
22*7f2fe78bSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*7f2fe78bSCy Schubert  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*7f2fe78bSCy Schubert  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25*7f2fe78bSCy Schubert  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*7f2fe78bSCy Schubert  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*7f2fe78bSCy Schubert  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28*7f2fe78bSCy Schubert  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*7f2fe78bSCy Schubert  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert  */
34*7f2fe78bSCy Schubert #if !defined(lint) && defined(SCCSIDS)
35*7f2fe78bSCy Schubert static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
36*7f2fe78bSCy Schubert #endif
37*7f2fe78bSCy Schubert 
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert  * clnt_raw.c
40*7f2fe78bSCy Schubert  *
41*7f2fe78bSCy Schubert  * Memory based rpc for simple testing and timing.
42*7f2fe78bSCy Schubert  * Interface to create an rpc client and server in the same process.
43*7f2fe78bSCy Schubert  * This lets us similate rpc and get round trip overhead, without
44*7f2fe78bSCy Schubert  * any interference from the kernel.
45*7f2fe78bSCy Schubert  */
46*7f2fe78bSCy Schubert 
47*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
48*7f2fe78bSCy Schubert 
49*7f2fe78bSCy Schubert #define MCALL_MSG_SIZE 24
50*7f2fe78bSCy Schubert 
51*7f2fe78bSCy Schubert /*
52*7f2fe78bSCy Schubert  * This is the "network" we will be moving stuff over.
53*7f2fe78bSCy Schubert  */
54*7f2fe78bSCy Schubert static struct clntraw_private {
55*7f2fe78bSCy Schubert 	CLIENT	client_object;
56*7f2fe78bSCy Schubert 	XDR	xdr_stream;
57*7f2fe78bSCy Schubert 	char	_raw_buf[UDPMSGSIZE];
58*7f2fe78bSCy Schubert         union {
59*7f2fe78bSCy Schubert 	  struct rpc_msg    mashl_rpcmsg;
60*7f2fe78bSCy Schubert 	  char	            mashl_callmsg[MCALL_MSG_SIZE];
61*7f2fe78bSCy Schubert 	} u;
62*7f2fe78bSCy Schubert 	u_int	mcnt;
63*7f2fe78bSCy Schubert } *clntraw_private;
64*7f2fe78bSCy Schubert 
65*7f2fe78bSCy Schubert static enum clnt_stat	clntraw_call(CLIENT *, rpcproc_t, xdrproc_t,
66*7f2fe78bSCy Schubert 				     void *, xdrproc_t, void *,
67*7f2fe78bSCy Schubert 				     struct timeval);
68*7f2fe78bSCy Schubert static void		clntraw_abort(CLIENT *);
69*7f2fe78bSCy Schubert static void		clntraw_geterr(CLIENT *, struct rpc_err *);
70*7f2fe78bSCy Schubert static bool_t		clntraw_freeres(CLIENT *, xdrproc_t, void *);
71*7f2fe78bSCy Schubert static bool_t		clntraw_control(CLIENT *, int, void *);
72*7f2fe78bSCy Schubert static void		clntraw_destroy(CLIENT *);
73*7f2fe78bSCy Schubert 
74*7f2fe78bSCy Schubert static struct clnt_ops client_ops = {
75*7f2fe78bSCy Schubert 	clntraw_call,
76*7f2fe78bSCy Schubert 	clntraw_abort,
77*7f2fe78bSCy Schubert 	clntraw_geterr,
78*7f2fe78bSCy Schubert 	clntraw_freeres,
79*7f2fe78bSCy Schubert 	clntraw_destroy,
80*7f2fe78bSCy Schubert 	clntraw_control
81*7f2fe78bSCy Schubert };
82*7f2fe78bSCy Schubert 
83*7f2fe78bSCy Schubert void	svc_getreq();
84*7f2fe78bSCy Schubert 
85*7f2fe78bSCy Schubert /*
86*7f2fe78bSCy Schubert  * Create a client handle for memory based rpc.
87*7f2fe78bSCy Schubert  */
88*7f2fe78bSCy Schubert CLIENT *
clntraw_create(rpcprog_t prog,rpcvers_t vers)89*7f2fe78bSCy Schubert clntraw_create(
90*7f2fe78bSCy Schubert 	rpcprog_t prog,
91*7f2fe78bSCy Schubert 	rpcvers_t vers)
92*7f2fe78bSCy Schubert {
93*7f2fe78bSCy Schubert 	struct clntraw_private *clp;
94*7f2fe78bSCy Schubert 	struct rpc_msg call_msg;
95*7f2fe78bSCy Schubert 	XDR *xdrs;
96*7f2fe78bSCy Schubert 	CLIENT *client;
97*7f2fe78bSCy Schubert 
98*7f2fe78bSCy Schubert 	if (clntraw_private == NULL) {
99*7f2fe78bSCy Schubert 		clntraw_private = calloc(1, sizeof(*clp));
100*7f2fe78bSCy Schubert 		if (clntraw_private == NULL)
101*7f2fe78bSCy Schubert 			return (NULL);
102*7f2fe78bSCy Schubert 	}
103*7f2fe78bSCy Schubert 	clp = clntraw_private;
104*7f2fe78bSCy Schubert 	xdrs = &clp->xdr_stream;
105*7f2fe78bSCy Schubert 	client = &clp->client_object;
106*7f2fe78bSCy Schubert 	/*
107*7f2fe78bSCy Schubert 	 * pre-serialize the staic part of the call msg and stash it away
108*7f2fe78bSCy Schubert 	 */
109*7f2fe78bSCy Schubert 	call_msg.rm_direction = CALL;
110*7f2fe78bSCy Schubert 	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
111*7f2fe78bSCy Schubert 	call_msg.rm_call.cb_prog = prog;
112*7f2fe78bSCy Schubert 	call_msg.rm_call.cb_vers = vers;
113*7f2fe78bSCy Schubert 	xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
114*7f2fe78bSCy Schubert 	if (! xdr_callhdr(xdrs, &call_msg)) {
115*7f2fe78bSCy Schubert 		perror("clnt_raw.c - Fatal header serialization error.");
116*7f2fe78bSCy Schubert 	}
117*7f2fe78bSCy Schubert 	clp->mcnt = XDR_GETPOS(xdrs);
118*7f2fe78bSCy Schubert 	XDR_DESTROY(xdrs);
119*7f2fe78bSCy Schubert 
120*7f2fe78bSCy Schubert 	/*
121*7f2fe78bSCy Schubert 	 * Set xdrmem for client/server shared buffer
122*7f2fe78bSCy Schubert 	 */
123*7f2fe78bSCy Schubert 	xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
124*7f2fe78bSCy Schubert 
125*7f2fe78bSCy Schubert 	/*
126*7f2fe78bSCy Schubert 	 * create client handle
127*7f2fe78bSCy Schubert 	 */
128*7f2fe78bSCy Schubert 	client->cl_ops = &client_ops;
129*7f2fe78bSCy Schubert 	client->cl_auth = authnone_create();
130*7f2fe78bSCy Schubert 	return (client);
131*7f2fe78bSCy Schubert }
132*7f2fe78bSCy Schubert 
133*7f2fe78bSCy Schubert static enum clnt_stat
clntraw_call(CLIENT * h,rpcproc_t proc,xdrproc_t xargs,void * argsp,xdrproc_t xresults,void * resultsp,struct timeval timeout)134*7f2fe78bSCy Schubert clntraw_call(
135*7f2fe78bSCy Schubert 	CLIENT *h,
136*7f2fe78bSCy Schubert 	rpcproc_t proc,
137*7f2fe78bSCy Schubert 	xdrproc_t xargs,
138*7f2fe78bSCy Schubert 	void * argsp,
139*7f2fe78bSCy Schubert 	xdrproc_t xresults,
140*7f2fe78bSCy Schubert 	void * resultsp,
141*7f2fe78bSCy Schubert 	struct timeval timeout)
142*7f2fe78bSCy Schubert {
143*7f2fe78bSCy Schubert 	struct clntraw_private *clp = clntraw_private;
144*7f2fe78bSCy Schubert 	XDR *xdrs = &clp->xdr_stream;
145*7f2fe78bSCy Schubert 	struct rpc_msg msg;
146*7f2fe78bSCy Schubert 	enum clnt_stat status;
147*7f2fe78bSCy Schubert 	struct rpc_err error;
148*7f2fe78bSCy Schubert 	long procl = proc;
149*7f2fe78bSCy Schubert 
150*7f2fe78bSCy Schubert 	if (clp == 0)
151*7f2fe78bSCy Schubert 		return (RPC_FAILED);
152*7f2fe78bSCy Schubert call_again:
153*7f2fe78bSCy Schubert 	/*
154*7f2fe78bSCy Schubert 	 * send request
155*7f2fe78bSCy Schubert 	 */
156*7f2fe78bSCy Schubert 	xdrs->x_op = XDR_ENCODE;
157*7f2fe78bSCy Schubert 	XDR_SETPOS(xdrs, 0);
158*7f2fe78bSCy Schubert 	clp->u.mashl_rpcmsg.rm_xid ++ ;
159*7f2fe78bSCy Schubert 	if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
160*7f2fe78bSCy Schubert 	    (! XDR_PUTLONG(xdrs, &procl)) ||
161*7f2fe78bSCy Schubert 	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
162*7f2fe78bSCy Schubert 	    (! (*xargs)(xdrs, argsp))) {
163*7f2fe78bSCy Schubert 		return (RPC_CANTENCODEARGS);
164*7f2fe78bSCy Schubert 	}
165*7f2fe78bSCy Schubert 	(void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
166*7f2fe78bSCy Schubert 
167*7f2fe78bSCy Schubert 	/*
168*7f2fe78bSCy Schubert 	 * We have to call server input routine here because this is
169*7f2fe78bSCy Schubert 	 * all going on in one process. Yuk.
170*7f2fe78bSCy Schubert 	 */
171*7f2fe78bSCy Schubert 	svc_getreq(1);
172*7f2fe78bSCy Schubert 
173*7f2fe78bSCy Schubert 	/*
174*7f2fe78bSCy Schubert 	 * get results
175*7f2fe78bSCy Schubert 	 */
176*7f2fe78bSCy Schubert 	xdrs->x_op = XDR_DECODE;
177*7f2fe78bSCy Schubert 	XDR_SETPOS(xdrs, 0);
178*7f2fe78bSCy Schubert 	msg.acpted_rply.ar_verf = gssrpc__null_auth;
179*7f2fe78bSCy Schubert 	msg.acpted_rply.ar_results.where = resultsp;
180*7f2fe78bSCy Schubert 	msg.acpted_rply.ar_results.proc = xresults;
181*7f2fe78bSCy Schubert 	if (! xdr_replymsg(xdrs, &msg)) {
182*7f2fe78bSCy Schubert 		/*
183*7f2fe78bSCy Schubert 		 * It's possible for xdr_replymsg() to fail partway
184*7f2fe78bSCy Schubert 		 * through its attempt to decode the result from the
185*7f2fe78bSCy Schubert 		 * server. If this happens, it will leave the reply
186*7f2fe78bSCy Schubert 		 * structure partially populated with dynamically
187*7f2fe78bSCy Schubert 		 * allocated memory. (This can happen if someone uses
188*7f2fe78bSCy Schubert 		 * clntudp_bufcreate() to create a CLIENT handle and
189*7f2fe78bSCy Schubert 		 * specifies a receive buffer size that is too small.)
190*7f2fe78bSCy Schubert 		 * This memory must be free()ed to avoid a leak.
191*7f2fe78bSCy Schubert 		 */
192*7f2fe78bSCy Schubert 		enum xdr_op op = xdrs->x_op;
193*7f2fe78bSCy Schubert 		xdrs->x_op = XDR_FREE;
194*7f2fe78bSCy Schubert 		xdr_replymsg(xdrs, &msg);
195*7f2fe78bSCy Schubert 		xdrs->x_op = op;
196*7f2fe78bSCy Schubert 		return (RPC_CANTDECODERES);
197*7f2fe78bSCy Schubert 	}
198*7f2fe78bSCy Schubert 	gssrpc__seterr_reply(&msg, &error);
199*7f2fe78bSCy Schubert 	status = error.re_status;
200*7f2fe78bSCy Schubert 
201*7f2fe78bSCy Schubert 	if (status == RPC_SUCCESS) {
202*7f2fe78bSCy Schubert 		if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
203*7f2fe78bSCy Schubert 			status = RPC_AUTHERROR;
204*7f2fe78bSCy Schubert 		}
205*7f2fe78bSCy Schubert 	}  /* end successful completion */
206*7f2fe78bSCy Schubert 	else {
207*7f2fe78bSCy Schubert 		if (AUTH_REFRESH(h->cl_auth, &msg))
208*7f2fe78bSCy Schubert 			goto call_again;
209*7f2fe78bSCy Schubert 	}  /* end of unsuccessful completion */
210*7f2fe78bSCy Schubert 
211*7f2fe78bSCy Schubert 	if (status == RPC_SUCCESS) {
212*7f2fe78bSCy Schubert 		if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
213*7f2fe78bSCy Schubert 			status = RPC_AUTHERROR;
214*7f2fe78bSCy Schubert 		}
215*7f2fe78bSCy Schubert 		if (msg.acpted_rply.ar_verf.oa_base != NULL) {
216*7f2fe78bSCy Schubert 			xdrs->x_op = XDR_FREE;
217*7f2fe78bSCy Schubert 			(void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
218*7f2fe78bSCy Schubert 		}
219*7f2fe78bSCy Schubert 	}
220*7f2fe78bSCy Schubert 
221*7f2fe78bSCy Schubert 	return (status);
222*7f2fe78bSCy Schubert }
223*7f2fe78bSCy Schubert 
224*7f2fe78bSCy Schubert /*ARGSUSED*/
225*7f2fe78bSCy Schubert static void
clntraw_geterr(CLIENT * cl,struct rpc_err * err)226*7f2fe78bSCy Schubert clntraw_geterr(
227*7f2fe78bSCy Schubert 	CLIENT *cl,
228*7f2fe78bSCy Schubert 	struct rpc_err *err)
229*7f2fe78bSCy Schubert {
230*7f2fe78bSCy Schubert }
231*7f2fe78bSCy Schubert 
232*7f2fe78bSCy Schubert 
233*7f2fe78bSCy Schubert static bool_t
clntraw_freeres(CLIENT * cl,xdrproc_t xdr_res,void * res_ptr)234*7f2fe78bSCy Schubert clntraw_freeres(
235*7f2fe78bSCy Schubert 	CLIENT *cl,
236*7f2fe78bSCy Schubert 	xdrproc_t xdr_res,
237*7f2fe78bSCy Schubert 	void *res_ptr)
238*7f2fe78bSCy Schubert {
239*7f2fe78bSCy Schubert 	struct clntraw_private *clp = clntraw_private;
240*7f2fe78bSCy Schubert 	XDR *xdrs = &clp->xdr_stream;
241*7f2fe78bSCy Schubert 	bool_t rval;
242*7f2fe78bSCy Schubert 
243*7f2fe78bSCy Schubert 	if (clp == 0)
244*7f2fe78bSCy Schubert 	{
245*7f2fe78bSCy Schubert 		rval = (bool_t) RPC_FAILED;
246*7f2fe78bSCy Schubert 		return (rval);
247*7f2fe78bSCy Schubert 	}
248*7f2fe78bSCy Schubert 	xdrs->x_op = XDR_FREE;
249*7f2fe78bSCy Schubert 	return ((*xdr_res)(xdrs, res_ptr));
250*7f2fe78bSCy Schubert }
251*7f2fe78bSCy Schubert 
252*7f2fe78bSCy Schubert /*ARGSUSED*/
253*7f2fe78bSCy Schubert static void
clntraw_abort(CLIENT * cl)254*7f2fe78bSCy Schubert clntraw_abort(CLIENT *cl)
255*7f2fe78bSCy Schubert {
256*7f2fe78bSCy Schubert }
257*7f2fe78bSCy Schubert 
258*7f2fe78bSCy Schubert /*ARGSUSED*/
259*7f2fe78bSCy Schubert static bool_t
clntraw_control(CLIENT * cl,int request,void * info)260*7f2fe78bSCy Schubert clntraw_control(
261*7f2fe78bSCy Schubert 	CLIENT *cl,
262*7f2fe78bSCy Schubert 	int request,
263*7f2fe78bSCy Schubert 	void *info)
264*7f2fe78bSCy Schubert {
265*7f2fe78bSCy Schubert 	return (FALSE);
266*7f2fe78bSCy Schubert }
267*7f2fe78bSCy Schubert 
268*7f2fe78bSCy Schubert /*ARGSUSED*/
269*7f2fe78bSCy Schubert static void
clntraw_destroy(CLIENT * cl)270*7f2fe78bSCy Schubert clntraw_destroy(CLIENT *cl)
271*7f2fe78bSCy Schubert {
272*7f2fe78bSCy Schubert }
273