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 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 /* 36 * rpc_calmsg.c 37 */ 38 39 #include <sys/param.h> 40 #include <sys/types.h> 41 #include <sys/t_lock.h> 42 #include <sys/systm.h> 43 44 #include <rpc/types.h> 45 #include <rpc/xdr.h> 46 #include <rpc/auth.h> 47 #include <rpc/clnt.h> 48 #include <rpc/rpc_msg.h> 49 50 /* 51 * XDR a call message 52 */ 53 bool_t 54 xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg) 55 { 56 rpc_inline_t *buf; 57 struct opaque_auth *oa; 58 59 if (xdrs->x_op == XDR_ENCODE) { 60 uint_t credrndup; 61 uint_t verfrndup; 62 63 if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) 64 return (FALSE); 65 if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) 66 return (FALSE); 67 credrndup = RNDUP(cmsg->rm_call.cb_cred.oa_length); 68 verfrndup = RNDUP(cmsg->rm_call.cb_verf.oa_length); 69 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + 70 credrndup + 2 * BYTES_PER_XDR_UNIT + verfrndup); 71 if (buf != NULL) { 72 IXDR_PUT_INT32(buf, cmsg->rm_xid); 73 IXDR_PUT_ENUM(buf, cmsg->rm_direction); 74 if (cmsg->rm_direction != CALL) 75 return (FALSE); 76 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers); 77 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) 78 return (FALSE); 79 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog); 80 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers); 81 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc); 82 oa = &cmsg->rm_call.cb_cred; 83 IXDR_PUT_ENUM(buf, oa->oa_flavor); 84 IXDR_PUT_INT32(buf, oa->oa_length); 85 if (oa->oa_length) { 86 bcopy(oa->oa_base, buf, oa->oa_length); 87 buf += credrndup / BYTES_PER_XDR_UNIT; 88 if ((credrndup -= oa->oa_length) > 0) 89 bzero((char *)buf - credrndup, 90 credrndup); 91 } 92 oa = &cmsg->rm_call.cb_verf; 93 IXDR_PUT_ENUM(buf, oa->oa_flavor); 94 IXDR_PUT_INT32(buf, oa->oa_length); 95 if (oa->oa_length) { 96 bcopy(oa->oa_base, buf, oa->oa_length); 97 buf += verfrndup / BYTES_PER_XDR_UNIT; 98 if ((verfrndup -= oa->oa_length) > 0) 99 bzero((char *)buf - verfrndup, 100 verfrndup); 101 } 102 return (TRUE); 103 } 104 } 105 if (xdrs->x_op == XDR_DECODE) { 106 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); 107 if (buf != NULL) { 108 cmsg->rm_xid = IXDR_GET_INT32(buf); 109 cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); 110 if (cmsg->rm_direction != CALL) 111 return (FALSE); 112 cmsg->rm_call.cb_rpcvers = IXDR_GET_INT32(buf); 113 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) 114 return (FALSE); 115 cmsg->rm_call.cb_prog = IXDR_GET_INT32(buf); 116 cmsg->rm_call.cb_vers = IXDR_GET_INT32(buf); 117 cmsg->rm_call.cb_proc = IXDR_GET_INT32(buf); 118 oa = &cmsg->rm_call.cb_cred; 119 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 120 oa->oa_length = IXDR_GET_INT32(buf); 121 if (oa->oa_length) { 122 if (oa->oa_length > MAX_AUTH_BYTES) 123 return (FALSE); 124 if (oa->oa_base == NULL) 125 oa->oa_base = (caddr_t) 126 mem_alloc(oa->oa_length); 127 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 128 if (buf == NULL) { 129 if (xdr_opaque(xdrs, oa->oa_base, 130 oa->oa_length) == FALSE) 131 return (FALSE); 132 } else { 133 bcopy(buf, oa->oa_base, oa->oa_length); 134 } 135 } 136 oa = &cmsg->rm_call.cb_verf; 137 buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); 138 if (buf == NULL) { 139 if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || 140 xdr_u_int(xdrs, &oa->oa_length) == FALSE) 141 return (FALSE); 142 } else { 143 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 144 oa->oa_length = IXDR_GET_INT32(buf); 145 } 146 if (oa->oa_length) { 147 if (oa->oa_length > MAX_AUTH_BYTES) 148 return (FALSE); 149 if (oa->oa_base == NULL) 150 oa->oa_base = (caddr_t) 151 mem_alloc(oa->oa_length); 152 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 153 if (buf == NULL) { 154 if (xdr_opaque(xdrs, oa->oa_base, 155 oa->oa_length) == FALSE) 156 return (FALSE); 157 } else { 158 bcopy(buf, oa->oa_base, oa->oa_length); 159 } 160 } 161 return (TRUE); 162 } 163 } 164 165 if (xdr_u_int(xdrs, &(cmsg->rm_xid)) && 166 xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && 167 cmsg->rm_direction == CALL && 168 xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_rpcvers)) && 169 cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION && 170 xdr_rpcprog(xdrs, &(cmsg->rm_call.cb_prog)) && 171 xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_vers)) && 172 xdr_rpcproc(xdrs, &(cmsg->rm_call.cb_proc)) && 173 xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred))) 174 return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); 175 176 return (FALSE); 177 } 178