Check-in of original version of ONCRPC library (and headers) from
[shibboleth/sp.git] / oncrpc / rpc_prot.c
1 /*********************************************************************
2  * RPC for the Windows NT Operating System
3  * 1993 by Martin F. Gergeleit
4  * Users may use, copy or modify Sun RPC for the Windows NT Operating 
5  * System according to the Sun copyright below.
6  *
7  * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
8  * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
9  * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
10  *********************************************************************/
11
12 /* @(#)rpc_prot.c       2.3 88/08/07 4.0 RPCSRC */
13 /*
14  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
15  * unrestricted use provided that this legend is included on all tape
16  * media and as a part of the software program in whole or part.  Users
17  * may copy or modify Sun RPC without charge, but are not authorized
18  * to license or distribute it to anyone else except as part of a product or
19  * program developed by the user.
20  * 
21  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
22  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
24  * 
25  * Sun RPC is provided with no support and without any obligation on the
26  * part of Sun Microsystems, Inc. to assist in its use, correction,
27  * modification or enhancement.
28  * 
29  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
30  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
31  * OR ANY PART THEREOF.
32  * 
33  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
34  * or profits or other special, indirect and consequential damages, even if
35  * Sun has been advised of the possibility of such damages.
36  * 
37  * Sun Microsystems, Inc.
38  * 2550 Garcia Avenue
39  * Mountain View, California  94043
40  */
41 #if !defined(lint) && defined(SCCSIDS)
42 static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
43 #endif
44
45 /*
46  * rpc_prot.c
47  *
48  * Copyright (C) 1984, Sun Microsystems, Inc.
49  *
50  * This set of routines implements the rpc message definition,
51  * its serializer and some common rpc utility routines.
52  * The routines are meant for various implementations of rpc -
53  * they are NOT for the rpc client or rpc service implementations!
54  * Because authentication stuff is easy and is part of rpc, the opaque
55  * routines are also in this program.
56  */
57
58 #ifndef WIN32
59 #include <sys/param.h>
60 #endif
61
62 #include <rpc/rpc.h>
63
64 /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
65 #ifdef WIN32
66 extern
67 #endif
68 struct opaque_auth _null_auth;
69
70 /*
71  * XDR an opaque authentication struct
72  * (see auth.h)
73  */
74 bool_t
75 xdr_opaque_auth(xdrs, ap)
76         register XDR *xdrs;
77         register struct opaque_auth *ap;
78 {
79
80         if (xdr_enum(xdrs, &(ap->oa_flavor)))
81                 return (xdr_bytes(xdrs, &ap->oa_base,
82                         &ap->oa_length, MAX_AUTH_BYTES));
83         return (FALSE);
84 }
85
86 /*
87  * XDR a DES block
88  */
89 bool_t
90 xdr_des_block(xdrs, blkp)
91         register XDR *xdrs;
92         register des_block *blkp;
93 {
94         return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
95 }
96
97 /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
98
99 /*
100  * XDR the MSG_ACCEPTED part of a reply message union
101  */
102 bool_t 
103 xdr_accepted_reply(xdrs, ar)
104         register XDR *xdrs;   
105         register struct accepted_reply *ar;
106 {
107
108         /* personalized union, rather than calling xdr_union */
109         if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
110                 return (FALSE);
111         if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
112                 return (FALSE);
113         switch (ar->ar_stat) {
114
115         case SUCCESS:
116                 return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
117
118         case PROG_MISMATCH:
119                 if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
120                         return (FALSE);
121                 return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
122         }
123         return (TRUE);  /* TRUE => open ended set of problems */
124 }
125
126 /*
127  * XDR the MSG_DENIED part of a reply message union
128  */
129 bool_t 
130 xdr_rejected_reply(xdrs, rr)
131         register XDR *xdrs;
132         register struct rejected_reply *rr;
133 {
134
135         /* personalized union, rather than calling xdr_union */
136         if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
137                 return (FALSE);
138         switch (rr->rj_stat) {
139
140         case RPC_MISMATCH:
141                 if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
142                         return (FALSE);
143                 return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
144
145         case AUTH_ERROR:
146                 return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
147         }
148         return (FALSE);
149 }
150
151 static struct xdr_discrim reply_dscrm[3] = {
152         { (int)MSG_ACCEPTED, xdr_accepted_reply },
153         { (int)MSG_DENIED, xdr_rejected_reply },
154         { __dontcare__, NULL_xdrproc_t } };
155
156 /*
157  * XDR a reply message
158  */
159 bool_t
160 xdr_replymsg(xdrs, rmsg)
161         register XDR *xdrs;
162         register struct rpc_msg *rmsg;
163 {
164         if (
165             xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
166             xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
167             (rmsg->rm_direction == REPLY) )
168                 return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
169                    (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
170         return (FALSE);
171 }
172
173
174 /*
175  * Serializes the "static part" of a call message header.
176  * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
177  * The rm_xid is not really static, but the user can easily munge on the fly.
178  */
179 bool_t
180 xdr_callhdr(xdrs, cmsg)
181         register XDR *xdrs;
182         register struct rpc_msg *cmsg;
183 {
184
185         cmsg->rm_direction = CALL;
186         cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
187         if (
188             (xdrs->x_op == XDR_ENCODE) &&
189             xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
190             xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
191             xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
192             xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
193             return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
194         return (FALSE);
195 }
196
197 /* ************************** Client utility routine ************* */
198
199 static void
200 accepted(acpt_stat, error)
201         register enum accept_stat acpt_stat;
202         register struct rpc_err *error;
203 {
204
205         switch (acpt_stat) {
206
207         case PROG_UNAVAIL:
208                 error->re_status = RPC_PROGUNAVAIL;
209                 return;
210
211         case PROG_MISMATCH:
212                 error->re_status = RPC_PROGVERSMISMATCH;
213                 return;
214
215         case PROC_UNAVAIL:
216                 error->re_status = RPC_PROCUNAVAIL;
217                 return;
218
219         case GARBAGE_ARGS:
220                 error->re_status = RPC_CANTDECODEARGS;
221                 return;
222
223         case SYSTEM_ERR:
224                 error->re_status = RPC_SYSTEMERROR;
225                 return;
226
227         case SUCCESS:
228                 error->re_status = RPC_SUCCESS;
229                 return;
230         }
231         /* something's wrong, but we don't know what ... */
232         error->re_status = RPC_FAILED;
233         error->re_lb.s1 = (long)MSG_ACCEPTED;
234         error->re_lb.s2 = (long)acpt_stat;
235 }
236
237 static void 
238 rejected(rjct_stat, error)
239         register enum reject_stat rjct_stat;
240         register struct rpc_err *error;
241 {
242
243         switch (rjct_stat) {
244
245         case RPC_VERSMISMATCH:
246                 error->re_status = RPC_VERSMISMATCH;
247                 return;
248
249         case AUTH_ERROR:
250                 error->re_status = RPC_AUTHERROR;
251                 return;
252         }
253         /* something's wrong, but we don't know what ... */
254         error->re_status = RPC_FAILED;
255         error->re_lb.s1 = (long)MSG_DENIED;
256         error->re_lb.s2 = (long)rjct_stat;
257 }
258
259 /*
260  * given a reply message, fills in the error
261  */
262 void
263 _seterr_reply(msg, error)
264         register struct rpc_msg *msg;
265         register struct rpc_err *error;
266 {
267
268         /* optimized for normal, SUCCESSful case */
269         switch (msg->rm_reply.rp_stat) {
270
271         case MSG_ACCEPTED:
272                 if (msg->acpted_rply.ar_stat == SUCCESS) {
273                         error->re_status = RPC_SUCCESS;
274                         return;
275                 };
276                 accepted(msg->acpted_rply.ar_stat, error);
277                 break;
278
279         case MSG_DENIED:
280                 rejected(msg->rjcted_rply.rj_stat, error);
281                 break;
282
283         default:
284                 error->re_status = RPC_FAILED;
285                 error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
286                 break;
287         }
288         switch (error->re_status) {
289
290         case RPC_VERSMISMATCH:
291                 error->re_vers.low = msg->rjcted_rply.rj_vers.low;
292                 error->re_vers.high = msg->rjcted_rply.rj_vers.high;
293                 break;
294
295         case RPC_AUTHERROR:
296                 error->re_why = msg->rjcted_rply.rj_why;
297                 break;
298
299         case RPC_PROGVERSMISMATCH:
300                 error->re_vers.low = msg->acpted_rply.ar_vers.low;
301                 error->re_vers.high = msg->acpted_rply.ar_vers.high;
302                 break;
303         }
304 }