1 /* @(#)rpc_callmsg.c	2.1 88/07/29 4.0 RPCSRC */
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 #if !defined(lint) && defined(SCCSIDS)
35 static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
36 #endif
37 
38 /*
39  * rpc_callmsg.c
40  */
41 
42 #include <sys/param.h>
43 #include <string.h>
44 #include <gssrpc/rpc.h>
45 
46 /*
47  * XDR a call message
48  */
49 bool_t
xdr_callmsg(XDR * xdrs,struct rpc_msg * cmsg)50 xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg)
51 {
52 	rpc_inline_t *buf;
53 	struct opaque_auth *oa;
54 
55 	if (xdrs->x_op == XDR_ENCODE) {
56 		if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
57 			return (FALSE);
58 		}
59 		if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
60 			return (FALSE);
61 		}
62 		buf = (rpc_inline_t *) XDR_INLINE(xdrs, (int) (
63 		        8 * BYTES_PER_XDR_UNIT
64 			+ RNDUP(cmsg->rm_call.cb_cred.oa_length)
65 			+ 2 * BYTES_PER_XDR_UNIT
66 			+ RNDUP(cmsg->rm_call.cb_verf.oa_length)));
67 		if (buf != NULL) {
68 			IXDR_PUT_LONG(buf, cmsg->rm_xid);
69 			IXDR_PUT_ENUM(buf, cmsg->rm_direction);
70 			if (cmsg->rm_direction != CALL) {
71 				return (FALSE);
72 			}
73 			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
74 			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
75 				return (FALSE);
76 			}
77 			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
78 			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
79 			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
80 			oa = &cmsg->rm_call.cb_cred;
81 			IXDR_PUT_ENUM(buf, oa->oa_flavor);
82 			IXDR_PUT_LONG(buf, oa->oa_length);
83 			if (oa->oa_length) {
84 				memmove((caddr_t)buf, oa->oa_base,
85 					oa->oa_length);
86 				buf += RNDUP(oa->oa_length) / BYTES_PER_XDR_UNIT;
87 			}
88 			oa = &cmsg->rm_call.cb_verf;
89 			IXDR_PUT_ENUM(buf, oa->oa_flavor);
90 			IXDR_PUT_LONG(buf, oa->oa_length);
91 			if (oa->oa_length) {
92 				memmove((caddr_t)buf, oa->oa_base,
93 					oa->oa_length);
94 				/* no real need....
95 				buf += RNDUP(oa->oa_length) / BYTES_PER_XDR_UNIT;
96 				*/
97 			}
98 			return (TRUE);
99 		}
100 	}
101 	if (xdrs->x_op == XDR_DECODE) {
102 		buf = (rpc_inline_t *) XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
103 		if (buf != NULL) {
104 			cmsg->rm_xid = IXDR_GET_LONG(buf);
105 			cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
106 			if (cmsg->rm_direction != CALL) {
107 				return (FALSE);
108 			}
109 			cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
110 			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
111 				return (FALSE);
112 			}
113 			cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
114 			cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
115 			cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
116 			oa = &cmsg->rm_call.cb_cred;
117 			oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
118 			oa->oa_length = IXDR_GET_LONG(buf);
119 			if (oa->oa_length) {
120 				if (oa->oa_length > MAX_AUTH_BYTES) {
121 					return (FALSE);
122 				}
123 				if (oa->oa_base == NULL) {
124 					oa->oa_base = (caddr_t)
125 						mem_alloc(oa->oa_length);
126 				}
127 				buf = (rpc_inline_t *)
128 				   XDR_INLINE(xdrs, (int)RNDUP(oa->oa_length));
129 				if (buf == NULL) {
130 					if (xdr_opaque(xdrs, oa->oa_base,
131 					    oa->oa_length) == FALSE) {
132 						return (FALSE);
133 					}
134 				} else {
135 					memmove(oa->oa_base, (caddr_t)buf,
136 						oa->oa_length);
137 					/* no real need....
138 					buf += RNDUP(oa->oa_length) /
139 						BYTES_PER_XDR_UNIT;
140 					*/
141 				}
142 			}
143 			oa = &cmsg->rm_call.cb_verf;
144 			buf = (rpc_inline_t *)
145 			   XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
146 			if (buf == NULL) {
147 				if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
148 				    xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
149 					return (FALSE);
150 				}
151 			} else {
152 				oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
153 				oa->oa_length = IXDR_GET_LONG(buf);
154 			}
155 			if (oa->oa_length) {
156 				if (oa->oa_length > MAX_AUTH_BYTES) {
157 					return (FALSE);
158 				}
159 				if (oa->oa_base == NULL) {
160 					oa->oa_base = (caddr_t)
161 						mem_alloc(oa->oa_length);
162 				}
163 				buf = (rpc_inline_t *)
164 				   XDR_INLINE(xdrs, (int)RNDUP(oa->oa_length));
165 				if (buf == NULL) {
166 					if (xdr_opaque(xdrs, oa->oa_base,
167 					    oa->oa_length) == FALSE) {
168 						return (FALSE);
169 					}
170 				} else {
171 					memmove(oa->oa_base, (caddr_t) buf,
172 					    oa->oa_length);
173 					/* no real need...
174 					buf += RNDUP(oa->oa_length) /
175 						BYTES_PER_XDR_UNIT;
176 					*/
177 				}
178 			}
179 			return (TRUE);
180 		}
181 	}
182 	if (
183 	    xdr_u_int32(xdrs, &(cmsg->rm_xid)) &&
184 	    xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
185 	    (cmsg->rm_direction == CALL) &&
186 	    xdr_u_int32(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
187 	    (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
188 	    xdr_u_int32(xdrs, &(cmsg->rm_call.cb_prog)) &&
189 	    xdr_u_int32(xdrs, &(cmsg->rm_call.cb_vers)) &&
190 	    xdr_u_int32(xdrs, &(cmsg->rm_call.cb_proc)) &&
191 	    xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
192 	    return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
193 	return (FALSE);
194 }
195