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 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