4 * Copyright (c) 2010, Oracle America, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 * * Neither the name of the "Oracle America, Inc." nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * This set of routines implements the rpc message definition,
34 * its serializer and some common rpc utility routines.
35 * The routines are meant for various implementations of rpc -
36 * they are NOT for the rpc client or rpc service implementations!
37 * Because authentication stuff is easy and is part of rpc, the opaque
38 * routines are also in this program.
41 #include <sys/param.h>
45 /* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
48 * XDR an opaque authentication struct
52 xdr_opaque_auth (XDR *xdrs, struct opaque_auth *ap)
55 if (xdr_enum (xdrs, &(ap->oa_flavor)))
56 return xdr_bytes (xdrs, &ap->oa_base,
57 &ap->oa_length, MAX_AUTH_BYTES);
60 libc_hidden_nolink_sunrpc (xdr_opaque_auth, GLIBC_2_0)
66 xdr_des_block (XDR *xdrs, des_block *blkp)
68 return xdr_opaque (xdrs, (caddr_t) blkp, sizeof (des_block));
70 libc_hidden_nolink_sunrpc (xdr_des_block, GLIBC_2_0)
72 /* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
75 * XDR the MSG_ACCEPTED part of a reply message union
78 xdr_accepted_reply (XDR *xdrs, struct accepted_reply *ar)
80 /* personalized union, rather than calling xdr_union */
81 if (!xdr_opaque_auth (xdrs, &(ar->ar_verf)))
83 if (!xdr_enum (xdrs, (enum_t *) & (ar->ar_stat)))
88 return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where));
90 if (!xdr_u_long (xdrs, &(ar->ar_vers.low)))
92 return (xdr_u_long (xdrs, &(ar->ar_vers.high)));
96 return TRUE; /* TRUE => open ended set of problems */
98 libc_hidden_nolink_sunrpc (xdr_accepted_reply, GLIBC_2_0)
101 * XDR the MSG_DENIED part of a reply message union
104 xdr_rejected_reply (XDR *xdrs, struct rejected_reply *rr)
106 /* personalized union, rather than calling xdr_union */
107 if (!xdr_enum (xdrs, (enum_t *) & (rr->rj_stat)))
112 if (!xdr_u_long (xdrs, &(rr->rj_vers.low)))
114 return xdr_u_long (xdrs, &(rr->rj_vers.high));
117 return xdr_enum (xdrs, (enum_t *) & (rr->rj_why));
121 libc_hidden_nolink_sunrpc (xdr_rejected_reply, GLIBC_2_0)
123 static const struct xdr_discrim reply_dscrm[3] =
125 {(int) MSG_ACCEPTED, (xdrproc_t) xdr_accepted_reply},
126 {(int) MSG_DENIED, (xdrproc_t) xdr_rejected_reply},
127 {__dontcare__, NULL_xdrproc_t}};
130 * XDR a reply message
133 xdr_replymsg (xdrs, rmsg)
135 struct rpc_msg *rmsg;
137 if (xdr_u_long (xdrs, &(rmsg->rm_xid)) &&
138 xdr_enum (xdrs, (enum_t *) & (rmsg->rm_direction)) &&
139 (rmsg->rm_direction == REPLY))
140 return xdr_union (xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
141 (caddr_t) & (rmsg->rm_reply.ru), reply_dscrm,
145 libc_hidden_nolink_sunrpc (xdr_replymsg, GLIBC_2_0)
149 * Serializes the "static part" of a call message header.
150 * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
151 * The rm_xid is not really static, but the user can easily munge on the fly.
154 xdr_callhdr (xdrs, cmsg)
156 struct rpc_msg *cmsg;
159 cmsg->rm_direction = CALL;
160 cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
162 (xdrs->x_op == XDR_ENCODE) &&
163 xdr_u_long (xdrs, &(cmsg->rm_xid)) &&
164 xdr_enum (xdrs, (enum_t *) & (cmsg->rm_direction)) &&
165 xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
166 xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)))
167 return xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers));
170 libc_hidden_nolink_sunrpc (xdr_callhdr, GLIBC_2_0)
172 /* ************************** Client utility routine ************* */
175 accepted (enum accept_stat acpt_stat,
176 struct rpc_err *error)
182 error->re_status = RPC_PROGUNAVAIL;
186 error->re_status = RPC_PROGVERSMISMATCH;
190 error->re_status = RPC_PROCUNAVAIL;
194 error->re_status = RPC_CANTDECODEARGS;
198 error->re_status = RPC_SYSTEMERROR;
202 error->re_status = RPC_SUCCESS;
205 /* something's wrong, but we don't know what ... */
206 error->re_status = RPC_FAILED;
207 error->re_lb.s1 = (long) MSG_ACCEPTED;
208 error->re_lb.s2 = (long) acpt_stat;
212 rejected (enum reject_stat rjct_stat,
213 struct rpc_err *error)
218 error->re_status = RPC_VERSMISMATCH;
221 error->re_status = RPC_AUTHERROR;
224 /* something's wrong, but we don't know what ... */
225 error->re_status = RPC_FAILED;
226 error->re_lb.s1 = (long) MSG_DENIED;
227 error->re_lb.s2 = (long) rjct_stat;
233 * given a reply message, fills in the error
236 _seterr_reply (struct rpc_msg *msg,
237 struct rpc_err *error)
239 /* optimized for normal, SUCCESSful case */
240 switch (msg->rm_reply.rp_stat)
243 if (msg->acpted_rply.ar_stat == SUCCESS)
245 error->re_status = RPC_SUCCESS;
248 accepted (msg->acpted_rply.ar_stat, error);
252 rejected (msg->rjcted_rply.rj_stat, error);
256 error->re_status = RPC_FAILED;
257 error->re_lb.s1 = (long) (msg->rm_reply.rp_stat);
260 switch (error->re_status)
263 case RPC_VERSMISMATCH:
264 error->re_vers.low = msg->rjcted_rply.rj_vers.low;
265 error->re_vers.high = msg->rjcted_rply.rj_vers.high;
269 error->re_why = msg->rjcted_rply.rj_why;
272 case RPC_PROGVERSMISMATCH:
273 error->re_vers.low = msg->acpted_rply.ar_vers.low;
274 error->re_vers.high = msg->acpted_rply.ar_vers.high;
280 libc_hidden_nolink_sunrpc (_seterr_reply, GLIBC_2_0)