]> git.ipfire.org Git - thirdparty/glibc.git/blame - sunrpc/rpc_prot.c
S390: Increase function alignment to 16 bytes.
[thirdparty/glibc.git] / sunrpc / rpc_prot.c
CommitLineData
28f540f4 1/*
a7ab6ec8 2 * rpc_prot.c
a5113b14 3 *
a7ab6ec8 4 * Copyright (c) 2010, Oracle America, Inc.
a5113b14 5 *
a7ab6ec8
UD
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
cb636bb2 9 *
a7ab6ec8
UD
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.
cb636bb2 19 *
a7ab6ec8
UD
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.
28f540f4
RM
32 *
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.
39 */
40
41#include <sys/param.h>
28f540f4 42#include <rpc/rpc.h>
82f43dd2 43#include <shlib-compat.h>
28f540f4
RM
44
45/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
46
28f540f4
RM
47/*
48 * XDR an opaque authentication struct
49 * (see auth.h)
50 */
51bool_t
e7fd8a39 52xdr_opaque_auth (XDR *xdrs, struct opaque_auth *ap)
28f540f4
RM
53{
54
7b57bfe5
UD
55 if (xdr_enum (xdrs, &(ap->oa_flavor)))
56 return xdr_bytes (xdrs, &ap->oa_base,
e7fd8a39
UD
57 &ap->oa_length, MAX_AUTH_BYTES);
58 return FALSE;
28f540f4 59}
021db4be 60libc_hidden_nolink_sunrpc (xdr_opaque_auth, GLIBC_2_0)
28f540f4
RM
61
62/*
63 * XDR a DES block
64 */
65bool_t
e7fd8a39 66xdr_des_block (XDR *xdrs, des_block *blkp)
28f540f4 67{
7b57bfe5 68 return xdr_opaque (xdrs, (caddr_t) blkp, sizeof (des_block));
28f540f4 69}
021db4be 70libc_hidden_nolink_sunrpc (xdr_des_block, GLIBC_2_0)
28f540f4
RM
71
72/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
73
74/*
75 * XDR the MSG_ACCEPTED part of a reply message union
76 */
a5113b14 77bool_t
e7fd8a39 78xdr_accepted_reply (XDR *xdrs, struct accepted_reply *ar)
28f540f4 79{
e7fd8a39 80 /* personalized union, rather than calling xdr_union */
7b57bfe5 81 if (!xdr_opaque_auth (xdrs, &(ar->ar_verf)))
e7fd8a39 82 return FALSE;
7b57bfe5 83 if (!xdr_enum (xdrs, (enum_t *) & (ar->ar_stat)))
e7fd8a39
UD
84 return FALSE;
85 switch (ar->ar_stat)
86 {
87 case SUCCESS:
88 return ((*(ar->ar_results.proc)) (xdrs, ar->ar_results.where));
89 case PROG_MISMATCH:
7b57bfe5 90 if (!xdr_u_long (xdrs, &(ar->ar_vers.low)))
e7fd8a39 91 return FALSE;
7b57bfe5 92 return (xdr_u_long (xdrs, &(ar->ar_vers.high)));
e7fd8a39
UD
93 default:
94 return TRUE;
95 }
96 return TRUE; /* TRUE => open ended set of problems */
28f540f4 97}
021db4be 98libc_hidden_nolink_sunrpc (xdr_accepted_reply, GLIBC_2_0)
28f540f4
RM
99
100/*
101 * XDR the MSG_DENIED part of a reply message union
102 */
a5113b14 103bool_t
e7fd8a39 104xdr_rejected_reply (XDR *xdrs, struct rejected_reply *rr)
28f540f4 105{
e7fd8a39 106 /* personalized union, rather than calling xdr_union */
7b57bfe5 107 if (!xdr_enum (xdrs, (enum_t *) & (rr->rj_stat)))
e7fd8a39
UD
108 return FALSE;
109 switch (rr->rj_stat)
110 {
111 case RPC_MISMATCH:
7b57bfe5 112 if (!xdr_u_long (xdrs, &(rr->rj_vers.low)))
e7fd8a39 113 return FALSE;
7b57bfe5 114 return xdr_u_long (xdrs, &(rr->rj_vers.high));
e7fd8a39
UD
115
116 case AUTH_ERROR:
7b57bfe5 117 return xdr_enum (xdrs, (enum_t *) & (rr->rj_why));
e7fd8a39
UD
118 }
119 return FALSE;
28f540f4 120}
021db4be 121libc_hidden_nolink_sunrpc (xdr_rejected_reply, GLIBC_2_0)
28f540f4 122
e7fd8a39
UD
123static const struct xdr_discrim reply_dscrm[3] =
124{
7b57bfe5
UD
125 {(int) MSG_ACCEPTED, (xdrproc_t) xdr_accepted_reply},
126 {(int) MSG_DENIED, (xdrproc_t) xdr_rejected_reply},
e7fd8a39 127 {__dontcare__, NULL_xdrproc_t}};
28f540f4
RM
128
129/*
130 * XDR a reply message
131 */
132bool_t
9d46370c 133xdr_replymsg (XDR *xdrs, struct rpc_msg *rmsg)
28f540f4 134{
7b57bfe5
UD
135 if (xdr_u_long (xdrs, &(rmsg->rm_xid)) &&
136 xdr_enum (xdrs, (enum_t *) & (rmsg->rm_direction)) &&
e7fd8a39 137 (rmsg->rm_direction == REPLY))
7b57bfe5
UD
138 return xdr_union (xdrs, (enum_t *) & (rmsg->rm_reply.rp_stat),
139 (caddr_t) & (rmsg->rm_reply.ru), reply_dscrm,
140 NULL_xdrproc_t);
e7fd8a39 141 return FALSE;
28f540f4 142}
021db4be 143libc_hidden_nolink_sunrpc (xdr_replymsg, GLIBC_2_0)
28f540f4
RM
144
145
146/*
147 * Serializes the "static part" of a call message header.
148 * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
149 * The rm_xid is not really static, but the user can easily munge on the fly.
150 */
151bool_t
9d46370c 152xdr_callhdr (XDR *xdrs, struct rpc_msg *cmsg)
28f540f4
RM
153{
154
e7fd8a39
UD
155 cmsg->rm_direction = CALL;
156 cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
157 if (
158 (xdrs->x_op == XDR_ENCODE) &&
7b57bfe5
UD
159 xdr_u_long (xdrs, &(cmsg->rm_xid)) &&
160 xdr_enum (xdrs, (enum_t *) & (cmsg->rm_direction)) &&
161 xdr_u_long (xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
162 xdr_u_long (xdrs, &(cmsg->rm_call.cb_prog)))
163 return xdr_u_long (xdrs, &(cmsg->rm_call.cb_vers));
e7fd8a39 164 return FALSE;
28f540f4 165}
021db4be 166libc_hidden_nolink_sunrpc (xdr_callhdr, GLIBC_2_0)
28f540f4
RM
167
168/* ************************** Client utility routine ************* */
169
170static void
e7fd8a39
UD
171accepted (enum accept_stat acpt_stat,
172 struct rpc_err *error)
28f540f4 173{
e7fd8a39
UD
174 switch (acpt_stat)
175 {
176
177 case PROG_UNAVAIL:
178 error->re_status = RPC_PROGUNAVAIL;
179 return;
180
181 case PROG_MISMATCH:
182 error->re_status = RPC_PROGVERSMISMATCH;
183 return;
184
185 case PROC_UNAVAIL:
186 error->re_status = RPC_PROCUNAVAIL;
187 return;
188
189 case GARBAGE_ARGS:
190 error->re_status = RPC_CANTDECODEARGS;
191 return;
192
193 case SYSTEM_ERR:
194 error->re_status = RPC_SYSTEMERROR;
195 return;
196
197 case SUCCESS:
198 error->re_status = RPC_SUCCESS;
199 return;
200 }
201 /* something's wrong, but we don't know what ... */
202 error->re_status = RPC_FAILED;
203 error->re_lb.s1 = (long) MSG_ACCEPTED;
204 error->re_lb.s2 = (long) acpt_stat;
28f540f4
RM
205}
206
a5113b14 207static void
e7fd8a39
UD
208rejected (enum reject_stat rjct_stat,
209 struct rpc_err *error)
28f540f4 210{
e7fd8a39
UD
211 switch (rjct_stat)
212 {
f3c2577f 213 case RPC_MISMATCH:
e7fd8a39
UD
214 error->re_status = RPC_VERSMISMATCH;
215 return;
216 case AUTH_ERROR:
217 error->re_status = RPC_AUTHERROR;
218 return;
219 default:
220 /* something's wrong, but we don't know what ... */
221 error->re_status = RPC_FAILED;
222 error->re_lb.s1 = (long) MSG_DENIED;
223 error->re_lb.s2 = (long) rjct_stat;
224 return;
225 }
28f540f4
RM
226}
227
228/*
229 * given a reply message, fills in the error
230 */
231void
e7fd8a39
UD
232_seterr_reply (struct rpc_msg *msg,
233 struct rpc_err *error)
28f540f4 234{
e7fd8a39
UD
235 /* optimized for normal, SUCCESSful case */
236 switch (msg->rm_reply.rp_stat)
237 {
238 case MSG_ACCEPTED:
239 if (msg->acpted_rply.ar_stat == SUCCESS)
240 {
241 error->re_status = RPC_SUCCESS;
242 return;
243 };
244 accepted (msg->acpted_rply.ar_stat, error);
245 break;
246
247 case MSG_DENIED:
248 rejected (msg->rjcted_rply.rj_stat, error);
249 break;
250
251 default:
252 error->re_status = RPC_FAILED;
253 error->re_lb.s1 = (long) (msg->rm_reply.rp_stat);
254 break;
255 }
256 switch (error->re_status)
257 {
258
259 case RPC_VERSMISMATCH:
260 error->re_vers.low = msg->rjcted_rply.rj_vers.low;
261 error->re_vers.high = msg->rjcted_rply.rj_vers.high;
262 break;
263
264 case RPC_AUTHERROR:
265 error->re_why = msg->rjcted_rply.rj_why;
266 break;
267
268 case RPC_PROGVERSMISMATCH:
269 error->re_vers.low = msg->acpted_rply.ar_vers.low;
270 error->re_vers.high = msg->acpted_rply.ar_vers.high;
271 break;
272 default:
273 break;
274 }
28f540f4 275}
021db4be 276libc_hidden_nolink_sunrpc (_seterr_reply, GLIBC_2_0)