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 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * rpc_calmsg.c 39 */ 40 41 #include <sys/param.h> 42 #include <sys/types.h> 43 #include <sys/t_lock.h> 44 #include <sys/systm.h> 45 46 #include <rpc/types.h> 47 #include <rpc/xdr.h> 48 #include <rpc/auth.h> 49 #include <rpc/clnt.h> 50 #include <rpc/rpc_msg.h> 51 52 /* 53 * XDR a call message 54 */ 55 bool_t 56 xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg) 57 { 58 int32_t *buf; 59 struct opaque_auth *oa; 60 61 if (xdrs->x_op == XDR_ENCODE) { 62 if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) 63 return (FALSE); 64 if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) 65 return (FALSE); 66 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + 67 RNDUP(cmsg->rm_call.cb_cred.oa_length) + 68 2 * BYTES_PER_XDR_UNIT + 69 RNDUP(cmsg->rm_call.cb_verf.oa_length)); 70 if (buf != NULL) { 71 IXDR_PUT_INT32(buf, cmsg->rm_xid); 72 IXDR_PUT_ENUM(buf, cmsg->rm_direction); 73 if (cmsg->rm_direction != CALL) 74 return (FALSE); 75 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers); 76 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) 77 return (FALSE); 78 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog); 79 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers); 80 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc); 81 oa = &cmsg->rm_call.cb_cred; 82 IXDR_PUT_ENUM(buf, oa->oa_flavor); 83 IXDR_PUT_INT32(buf, oa->oa_length); 84 if (oa->oa_length) { 85 bcopy(oa->oa_base, buf, oa->oa_length); 86 buf += RNDUP(oa->oa_length) / sizeof (int32_t); 87 } 88 oa = &cmsg->rm_call.cb_verf; 89 IXDR_PUT_ENUM(buf, oa->oa_flavor); 90 IXDR_PUT_INT32(buf, oa->oa_length); 91 if (oa->oa_length) 92 bcopy(oa->oa_base, buf, oa->oa_length); 93 return (TRUE); 94 } 95 } 96 if (xdrs->x_op == XDR_DECODE) { 97 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); 98 if (buf != NULL) { 99 cmsg->rm_xid = IXDR_GET_INT32(buf); 100 cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); 101 if (cmsg->rm_direction != CALL) 102 return (FALSE); 103 cmsg->rm_call.cb_rpcvers = IXDR_GET_INT32(buf); 104 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) 105 return (FALSE); 106 cmsg->rm_call.cb_prog = IXDR_GET_INT32(buf); 107 cmsg->rm_call.cb_vers = IXDR_GET_INT32(buf); 108 cmsg->rm_call.cb_proc = IXDR_GET_INT32(buf); 109 oa = &cmsg->rm_call.cb_cred; 110 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 111 oa->oa_length = IXDR_GET_INT32(buf); 112 if (oa->oa_length) { 113 if (oa->oa_length > MAX_AUTH_BYTES) 114 return (FALSE); 115 if (oa->oa_base == NULL) 116 oa->oa_base = (caddr_t) 117 mem_alloc(oa->oa_length); 118 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 119 if (buf == NULL) { 120 if (xdr_opaque(xdrs, oa->oa_base, 121 oa->oa_length) == FALSE) 122 return (FALSE); 123 } else { 124 bcopy(buf, oa->oa_base, oa->oa_length); 125 } 126 } 127 oa = &cmsg->rm_call.cb_verf; 128 buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); 129 if (buf == NULL) { 130 if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || 131 xdr_u_int(xdrs, &oa->oa_length) == FALSE) 132 return (FALSE); 133 } else { 134 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 135 oa->oa_length = IXDR_GET_INT32(buf); 136 } 137 if (oa->oa_length) { 138 if (oa->oa_length > MAX_AUTH_BYTES) 139 return (FALSE); 140 if (oa->oa_base == NULL) 141 oa->oa_base = (caddr_t) 142 mem_alloc(oa->oa_length); 143 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 144 if (buf == NULL) { 145 if (xdr_opaque(xdrs, oa->oa_base, 146 oa->oa_length) == FALSE) 147 return (FALSE); 148 } else { 149 bcopy(buf, oa->oa_base, oa->oa_length); 150 } 151 } 152 return (TRUE); 153 } 154 } 155 156 if (xdr_u_int(xdrs, &(cmsg->rm_xid)) && 157 xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && 158 cmsg->rm_direction == CALL && 159 xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_rpcvers)) && 160 cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION && 161 xdr_rpcprog(xdrs, &(cmsg->rm_call.cb_prog)) && 162 xdr_rpcvers(xdrs, &(cmsg->rm_call.cb_vers)) && 163 xdr_rpcproc(xdrs, &(cmsg->rm_call.cb_proc)) && 164 xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred))) 165 return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); 166 167 return (FALSE); 168 } 169