1 /* @(#)svc.h	2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */
2 /*
3  * Copyright (c) 2010, Oracle America, Inc.
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *
18  *     * Neither the name of the "Oracle America, Inc." nor the names of
19  *       its contributors may be used to endorse or promote products
20  *       derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 /*
36  * svc.h, Server-side remote procedure call interface.
37  */
38 
39 #ifndef GSSRPC_SVC_H
40 #define GSSRPC_SVC_H
41 
42 #include <gssrpc/svc_auth.h>
43 
44 GSSRPC__BEGIN_DECLS
45 /*
46  * This interface must manage two items concerning remote procedure calling:
47  *
48  * 1) An arbitrary number of transport connections upon which rpc requests
49  * are received.  The two most notable transports are TCP and UDP;  they are
50  * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
51  * they in turn call xprt_register and xprt_unregister.
52  *
53  * 2) An arbitrary number of locally registered services.  Services are
54  * described by the following four data: program number, version number,
55  * "service dispatch" function, a transport handle, and a boolean that
56  * indicates whether or not the exported program should be registered with a
57  * local binder service;  if true the program's number and version and the
58  * port number from the transport handle are registered with the binder.
59  * These data are registered with the rpc svc system via svc_register.
60  *
61  * A service's dispatch function is called whenever an rpc request comes in
62  * on a transport.  The request's program and version numbers must match
63  * those of the registered service.  The dispatch function is passed two
64  * parameters, struct svc_req * and SVCXPRT *, defined below.
65  */
66 
67 enum xprt_stat {
68 	XPRT_DIED,
69 	XPRT_MOREREQS,
70 	XPRT_IDLE
71 };
72 
73 /*
74  * Server side transport handle
75  */
76 typedef struct SVCXPRT {
77 #ifdef _WIN32
78         SOCKET          xp_sock;
79 #else
80 	int		xp_sock;
81 #endif
82 	u_short		xp_port;	 /* associated port number */
83 	struct xp_ops {
84 	    /* receive incoming requests */
85 	    bool_t	(*xp_recv)(struct SVCXPRT *, struct rpc_msg *);
86 	    /* get transport status */
87 	    enum xprt_stat (*xp_stat)(struct SVCXPRT *);
88 	    /* get arguments */
89 	    bool_t	(*xp_getargs)(struct SVCXPRT *, xdrproc_t,
90 				      void *);
91 	    /* send reply */
92 	    bool_t	(*xp_reply)(struct SVCXPRT *,
93 				    struct rpc_msg *);
94             /* free mem allocated for args */
95 	    bool_t	(*xp_freeargs)(struct SVCXPRT *, xdrproc_t,
96 				       void *);
97 	    /* destroy this struct */
98 	    void	(*xp_destroy)(struct SVCXPRT *);
99 	} *xp_ops;
100 	int		xp_addrlen;	 /* length of remote address */
101 	struct sockaddr_in xp_raddr;	 /* remote address */
102 	struct opaque_auth xp_verf;	 /* raw response verifier */
103 	SVCAUTH		*xp_auth;	 /* auth flavor of current req */
104 	void		*xp_p1;		 /* private */
105 	void		*xp_p2;		 /* private */
106 	int		xp_laddrlen;	 /* length of local address */
107 	struct sockaddr_in xp_laddr;	 /* local address */
108 } SVCXPRT;
109 
110 /*
111  *  Approved way of getting address of caller
112  */
113 #define svc_getcaller(x) (&(x)->xp_raddr)
114 
115 /*
116  * Operations defined on an SVCXPRT handle
117  *
118  * SVCXPRT		*xprt;
119  * struct rpc_msg	*msg;
120  * xdrproc_t		 xargs;
121  * caddr_t		 argsp;
122  */
123 #define SVC_RECV(xprt, msg)				\
124 	(*(xprt)->xp_ops->xp_recv)((xprt), (msg))
125 #define svc_recv(xprt, msg)				\
126 	(*(xprt)->xp_ops->xp_recv)((xprt), (msg))
127 
128 #define SVC_STAT(xprt)					\
129 	(*(xprt)->xp_ops->xp_stat)(xprt)
130 #define svc_stat(xprt)					\
131 	(*(xprt)->xp_ops->xp_stat)(xprt)
132 
133 #define SVC_GETARGS(xprt, xargs, argsp)			\
134 	(*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
135 #define svc_getargs(xprt, xargs, argsp)			\
136 	(*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
137 
138 #define SVC_GETARGS_REQ(xprt, req, xargs, argsp)	\
139 	(*(xprt)->xp_ops->xp_getargs_req)((xprt), (req), (xargs), (argsp))
140 #define svc_getargs_req(xprt, req, xargs, argsp)	\
141 	(*(xprt)->xp_ops->xp_getargs_req)((xprt), (req), (xargs), (argsp))
142 
143 #define SVC_REPLY(xprt, msg)				\
144 	(*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
145 #define svc_reply(xprt, msg)				\
146 	(*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
147 
148 #define SVC_REPLY_REQ(xprt, req, msg)			\
149 	(*(xprt)->xp_ops->xp_reply_req) ((xprt), (req), (msg))
150 #define svc_reply_req(xprt, msg)			\
151 	(*(xprt)->xp_ops->xp_reply_req) ((xprt), (req), (msg))
152 
153 #define SVC_FREEARGS(xprt, xargs, argsp)		\
154 	(*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
155 #define svc_freeargs(xprt, xargs, argsp)		\
156 	(*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
157 
158 #define SVC_DESTROY(xprt)				\
159 	(*(xprt)->xp_ops->xp_destroy)(xprt)
160 #define svc_destroy(xprt)				\
161 	(*(xprt)->xp_ops->xp_destroy)(xprt)
162 
163 
164 /*
165  * Service request
166  */
167 struct svc_req {
168 	rpcprog_t		rq_prog;	/* service program number */
169 	rpcvers_t		rq_vers;	/* service protocol version */
170 	rpcproc_t		rq_proc;	/* the desired procedure */
171 	struct opaque_auth rq_cred;	/* raw creds from the wire */
172 	void *		rq_clntcred;	/* read only cooked client cred */
173 	void *		rq_svccred;	/* read only svc cred/context */
174 	void *		rq_clntname;	/* read only client name */
175 	SVCXPRT		*rq_xprt;	/* associated transport */
176 	/* The request's auth flavor *should* be here, but the svc_req 	*/
177 	/* isn't passed around everywhere it is necessary.  The 	*/
178 	/* transport *is* passed around, so the auth flavor it stored 	*/
179 	/* there.  This means that the transport must be single 	*/
180 	/* threaded, but other parts of SunRPC already require that. 	*/
181 	/*SVCAUTH		*rq_auth;	 associated auth flavor */
182 };
183 
184 
185 /*
186  * Service registration
187  *
188  * svc_register(xprt, prog, vers, dispatch, protocol)
189  *	SVCXPRT *xprt;
190  *	rpcprog_t prog;
191  *	rpcvers_t vers;
192  *	void (*dispatch)();
193  *	int protocol;  like IPPROTO_TCP or _UDP; zero means do not register
194  *
195  * registerrpc(prog, vers, proc, routine, inproc, outproc)
196  * 	returns 0 upon success, -1 if error.
197  */
198 extern bool_t	svc_register(SVCXPRT *, rpcprog_t, rpcvers_t,
199 			     void (*)(struct svc_req *, SVCXPRT *), int);
200 
201 extern int registerrpc(rpcprog_t, rpcvers_t, rpcproc_t,
202 		       char *(*)(void *),
203 		       xdrproc_t, xdrproc_t);
204 
205 /*
206  * Service un-registration
207  *
208  * svc_unregister(prog, vers)
209  *	rpcprog_t prog;
210  *	rpcvers_t vers;
211  */
212 extern void	svc_unregister(rpcprog_t, rpcvers_t);
213 
214 /*
215  * Transport registration.
216  *
217  * xprt_register(xprt)
218  *	SVCXPRT *xprt;
219  */
220 extern void	xprt_register(SVCXPRT *);
221 
222 /*
223  * Transport un-register
224  *
225  * xprt_unregister(xprt)
226  *	SVCXPRT *xprt;
227  */
228 extern void	xprt_unregister(SVCXPRT *);
229 
230 
231 /*
232  * When the service routine is called, it must first check to see if
233  * it knows about the procedure; if not, it should call svcerr_noproc
234  * and return.  If so, it should deserialize its arguments via
235  * SVC_GETARGS or the new SVC_GETARGS_REQ (both defined above).  If
236  * the deserialization does not work, svcerr_decode should be called
237  * followed by a return.  Successful decoding of the arguments should
238  * be followed the execution of the procedure's code and a call to
239  * svc_sendreply or the new svc_sendreply_req.
240  *
241  * Also, if the service refuses to execute the procedure due to too-
242  * weak authentication parameters, svcerr_weakauth should be called.
243  * Note: do not confuse access-control failure with weak authentication!
244  *
245  * NB: In pure implementations of rpc, the caller always waits for a reply
246  * msg.  This message is sent when svc_sendreply is called.
247  * Therefore pure service implementations should always call
248  * svc_sendreply even if the function logically returns void;  use
249  * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
250  * for the abuse of pure rpc via batched calling or pipelining.  In the
251  * case of a batched call, svc_sendreply should NOT be called since
252  * this would send a return message, which is what batching tries to avoid.
253  * It is the service/protocol writer's responsibility to know which calls are
254  * batched and which are not.  Warning: responding to batch calls may
255  * deadlock the caller and server processes!
256  */
257 
258 extern bool_t	svc_sendreply(SVCXPRT *, xdrproc_t, caddr_t);
259 extern void	svcerr_decode(SVCXPRT *);
260 extern void	svcerr_weakauth(SVCXPRT *);
261 extern void	svcerr_noproc(SVCXPRT *);
262 extern void	svcerr_progvers(SVCXPRT *, rpcvers_t, rpcvers_t);
263 extern void	svcerr_auth(SVCXPRT *, enum auth_stat);
264 extern void	svcerr_noprog(SVCXPRT *);
265 extern void	svcerr_systemerr(SVCXPRT *);
266 
267 /*
268  * Lowest level dispatching -OR- who owns this process anyway.
269  * Somebody has to wait for incoming requests and then call the correct
270  * service routine.  The routine svc_run does infinite waiting; i.e.,
271  * svc_run never returns.
272  * Since another (co-existant) package may wish to selectively wait for
273  * incoming calls or other events outside of the rpc architecture, the
274  * routine svc_getreq is provided.  It must be passed readfds, the
275  * "in-place" results of a select system call (see select, section 2).
276  */
277 
278 /*
279  * Global keeper of rpc service descriptors in use
280  * dynamic; must be inspected before each call to select
281  */
282 extern int svc_maxfd;
283 #ifdef FD_SETSIZE
284 extern fd_set svc_fdset;
285 /* RENAMED */
286 #define gssrpc_svc_fds gsssrpc_svc_fdset.fds_bits[0]	/* compatibility */
287 #else
288 extern int svc_fds;
289 #endif /* def FD_SETSIZE */
290 extern int svc_maxfd;
291 
292 /*
293  * a small program implemented by the svc_rpc implementation itself;
294  * also see clnt.h for protocol numbers.
295  */
296 extern void rpctest_service();
297 
298 extern void	svc_getreq(int);
299 #ifdef FD_SETSIZE
300 extern void	svc_getreqset(fd_set *);/* takes fdset instead of int */
301 extern void	svc_getreqset2(fd_set *, int);
302 #else
303 extern void	svc_getreqset(int *);
304 #endif
305 extern void	svc_run(void); 	 /* never returns */
306 
307 /*
308  * Socket to use on svcxxx_create call to get default socket
309  */
310 #define	RPC_ANYSOCK	-1
311 
312 /*
313  * These are the existing service side transport implementations
314  */
315 
316 /*
317  * Memory based rpc for testing and timing.
318  */
319 extern SVCXPRT *svcraw_create(void);
320 
321 /*
322  * Udp based rpc.
323  */
324 extern SVCXPRT *svcudp_create(int);
325 extern SVCXPRT *svcudp_bufcreate(int, u_int, u_int);
326 extern int svcudp_enablecache(SVCXPRT *, uint32_t);
327 
328 /*
329  * Tcp based rpc.
330  */
331 extern SVCXPRT *svctcp_create(int, u_int, u_int);
332 
333 /*
334  * Like svtcp_create(), except the routine takes any *open* UNIX file
335  * descriptor as its first input.
336  */
337 extern SVCXPRT *svcfd_create(int, u_int, u_int);
338 
339 /* XXX add auth_gsapi_log_*? */
340 
341 GSSRPC__END_DECLS
342 
343 #endif /* !defined(GSSRPC_SVC_H) */
344