1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 1999 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * Portions of this source code were derived from Berkeley 29 * 4.3 BSD under license from the Regents of the University of 30 * California. 31 */ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 /* 36 * rpc_callmsg.c 37 * 38 */ 39 40 #include <sys/param.h> 41 #include <rpc/trace.h> 42 43 #ifdef KERNEL 44 #include <rpc/types.h> /* spell 'em out for make depend */ 45 #include <rpc/xdr.h> 46 #include <rpc/auth.h> 47 #include <rpc/clnt.h> 48 #include <rpc/rpc_msg.h> 49 #else 50 #include <rpc/rpc.h> 51 #endif 52 #include <syslog.h> 53 #include <sys/byteorder.h> 54 55 extern bool_t xdr_opaque_auth(); 56 extern char *malloc(); 57 58 /* 59 * XDR a call message 60 */ 61 bool_t 62 xdr_callmsg(xdrs, cmsg) 63 register XDR *xdrs; 64 register struct rpc_msg *cmsg; 65 { 66 register rpc_inline_t *buf; 67 register struct opaque_auth *oa; 68 bool_t dummy; 69 70 trace1(TR_xdr_callmsg, 0); 71 if (xdrs->x_op == XDR_ENCODE) { 72 if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { 73 trace1(TR_xdr_callmsg, 1); 74 return (FALSE); 75 } 76 if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { 77 trace1(TR_xdr_callmsg, 1); 78 return (FALSE); 79 } 80 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT 81 + RNDUP(cmsg->rm_call.cb_cred.oa_length) 82 + 2 * BYTES_PER_XDR_UNIT 83 + RNDUP(cmsg->rm_call.cb_verf.oa_length)); 84 if (buf != NULL) { 85 IXDR_PUT_INT32(buf, cmsg->rm_xid); 86 IXDR_PUT_ENUM(buf, cmsg->rm_direction); 87 if (cmsg->rm_direction != CALL) { 88 trace1(TR_xdr_callmsg, 1); 89 return (FALSE); 90 } 91 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers); 92 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { 93 trace1(TR_xdr_callmsg, 1); 94 return (FALSE); 95 } 96 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog); 97 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers); 98 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc); 99 oa = &cmsg->rm_call.cb_cred; 100 IXDR_PUT_ENUM(buf, oa->oa_flavor); 101 IXDR_PUT_INT32(buf, oa->oa_length); 102 if (oa->oa_length) { 103 (void) memcpy((caddr_t)buf, oa->oa_base, 104 oa->oa_length); 105 buf += RNDUP(oa->oa_length) / sizeof (int32_t); 106 } 107 oa = &cmsg->rm_call.cb_verf; 108 IXDR_PUT_ENUM(buf, oa->oa_flavor); 109 IXDR_PUT_INT32(buf, oa->oa_length); 110 if (oa->oa_length) { 111 (void) memcpy((caddr_t)buf, oa->oa_base, 112 oa->oa_length); 113 /* 114 * no real need.... 115 * buf += RNDUP(oa->oa_length) / sizeof 116 * (int32_t); 117 */ 118 } 119 trace1(TR_xdr_callmsg, 1); 120 return (TRUE); 121 } 122 } 123 if (xdrs->x_op == XDR_DECODE) { 124 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); 125 if (buf != NULL) { 126 cmsg->rm_xid = IXDR_GET_INT32(buf); 127 cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); 128 if (cmsg->rm_direction != CALL) { 129 trace1(TR_xdr_callmsg, 1); 130 return (FALSE); 131 } 132 cmsg->rm_call.cb_rpcvers = IXDR_GET_INT32(buf); 133 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { 134 trace1(TR_xdr_callmsg, 1); 135 return (FALSE); 136 } 137 cmsg->rm_call.cb_prog = IXDR_GET_INT32(buf); 138 cmsg->rm_call.cb_vers = IXDR_GET_INT32(buf); 139 cmsg->rm_call.cb_proc = IXDR_GET_INT32(buf); 140 oa = &cmsg->rm_call.cb_cred; 141 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 142 oa->oa_length = IXDR_GET_INT32(buf); 143 if (oa->oa_length) { 144 if (oa->oa_length > MAX_AUTH_BYTES) { 145 trace1(TR_xdr_callmsg, 1); 146 return (FALSE); 147 } 148 if (oa->oa_base == NULL) { 149 oa->oa_base = (caddr_t) 150 mem_alloc(oa->oa_length); 151 if (oa->oa_base == NULL) { 152 syslog(LOG_ERR, 153 "xdr_callmsg : " 154 "out of memory."); 155 trace1(TR_xdr_callmsg, 1); 156 return (FALSE); 157 } 158 } 159 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 160 if (buf == NULL) { 161 if (xdr_opaque(xdrs, oa->oa_base, 162 oa->oa_length) == FALSE) { 163 trace1(TR_xdr_callmsg, 1); 164 return (FALSE); 165 } 166 } else { 167 (void) memcpy(oa->oa_base, 168 (caddr_t)buf, (int)oa->oa_length); 169 /* 170 * no real need.... 171 * buf += RNDUP(oa->oa_length) / 172 * (int) sizeof (int32_t); 173 */ 174 } 175 } 176 oa = &cmsg->rm_call.cb_verf; 177 buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); 178 if (buf == NULL) { 179 if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || 180 xdr_u_int(xdrs, &oa->oa_length) == FALSE) { 181 trace1(TR_xdr_callmsg, 1); 182 return (FALSE); 183 } 184 } else { 185 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 186 oa->oa_length = IXDR_GET_INT32(buf); 187 } 188 if (oa->oa_length) { 189 if (oa->oa_length > MAX_AUTH_BYTES) { 190 trace1(TR_xdr_callmsg, 1); 191 return (FALSE); 192 } 193 if (oa->oa_base == NULL) { 194 oa->oa_base = (caddr_t) 195 mem_alloc(oa->oa_length); 196 if (oa->oa_base == NULL) { 197 syslog(LOG_ERR, 198 "xdr_callmsg : " 199 "out of memory."); 200 trace1(TR_xdr_callmsg, 1); 201 return (FALSE); 202 } 203 } 204 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 205 if (buf == NULL) { 206 if (xdr_opaque(xdrs, oa->oa_base, 207 oa->oa_length) == FALSE) { 208 trace1(TR_xdr_callmsg, 1); 209 return (FALSE); 210 } 211 } else { 212 (void) memcpy(oa->oa_base, 213 (caddr_t)buf, (int)oa->oa_length); 214 /* 215 * no real need... 216 * buf += RNDUP(oa->oa_length) / 217 * (int) sizeof (int32_t); 218 */ 219 } 220 } 221 trace1(TR_xdr_callmsg, 1); 222 return (TRUE); 223 } 224 } 225 if (xdr_u_int(xdrs, &(cmsg->rm_xid)) && 226 xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && 227 (cmsg->rm_direction == CALL) && 228 xdr_u_int(xdrs, (u_int *)&(cmsg->rm_call.cb_rpcvers)) && 229 (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && 230 xdr_u_int(xdrs, (u_int *)&(cmsg->rm_call.cb_prog)) && 231 xdr_u_int(xdrs, (u_int *)&(cmsg->rm_call.cb_vers)) && 232 xdr_u_int(xdrs, (u_int *)&(cmsg->rm_call.cb_proc)) && 233 xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred))) { 234 dummy = xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)); 235 trace1(TR_xdr_callmsg, 1); 236 return (dummy); 237 } 238 trace1(TR_xdr_callmsg, 1); 239 return (FALSE); 240 } 241