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 /* 24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 /* 30 * Portions of this source code were derived from Berkeley 31 * 4.3 BSD under license from the Regents of the University of 32 * California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * rpc_callmsg.c 39 * 40 */ 41 42 #include <stdlib.h> 43 #include <sys/param.h> 44 #include <rpc/rpc.h> 45 #include <syslog.h> 46 #include <sys/byteorder.h> 47 48 extern bool_t xdr_opaque_auth(XDR *, struct opaque_auth *); 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 if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) 61 return (FALSE); 62 if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) 63 return (FALSE); 64 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT 65 + RNDUP(cmsg->rm_call.cb_cred.oa_length) 66 + 2 * BYTES_PER_XDR_UNIT 67 + RNDUP(cmsg->rm_call.cb_verf.oa_length)); 68 if (buf != NULL) { 69 IXDR_PUT_INT32(buf, cmsg->rm_xid); 70 IXDR_PUT_ENUM(buf, cmsg->rm_direction); 71 if (cmsg->rm_direction != CALL) 72 return (FALSE); 73 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers); 74 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) 75 return (FALSE); 76 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog); 77 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers); 78 IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc); 79 oa = &cmsg->rm_call.cb_cred; 80 IXDR_PUT_ENUM(buf, oa->oa_flavor); 81 IXDR_PUT_INT32(buf, oa->oa_length); 82 if (oa->oa_length) { 83 (void) memcpy(buf, oa->oa_base, oa->oa_length); 84 buf += RNDUP(oa->oa_length) / sizeof (int32_t); 85 } 86 oa = &cmsg->rm_call.cb_verf; 87 IXDR_PUT_ENUM(buf, oa->oa_flavor); 88 IXDR_PUT_INT32(buf, oa->oa_length); 89 if (oa->oa_length) { 90 (void) memcpy(buf, oa->oa_base, oa->oa_length); 91 /* 92 * no real need.... 93 * buf += RNDUP(oa->oa_length) / sizeof 94 * (int32_t); 95 */ 96 } 97 return (TRUE); 98 } 99 } 100 if (xdrs->x_op == XDR_DECODE) { 101 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); 102 if (buf != NULL) { 103 cmsg->rm_xid = IXDR_GET_INT32(buf); 104 cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); 105 if (cmsg->rm_direction != CALL) 106 return (FALSE); 107 cmsg->rm_call.cb_rpcvers = IXDR_GET_INT32(buf); 108 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) 109 return (FALSE); 110 cmsg->rm_call.cb_prog = IXDR_GET_INT32(buf); 111 cmsg->rm_call.cb_vers = IXDR_GET_INT32(buf); 112 cmsg->rm_call.cb_proc = IXDR_GET_INT32(buf); 113 oa = &cmsg->rm_call.cb_cred; 114 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 115 oa->oa_length = IXDR_GET_INT32(buf); 116 if (oa->oa_length) { 117 if (oa->oa_length > MAX_AUTH_BYTES) 118 return (FALSE); 119 if (oa->oa_base == NULL) { 120 oa->oa_base = malloc(oa->oa_length); 121 if (oa->oa_base == NULL) { 122 syslog(LOG_ERR, 123 "xdr_callmsg : " 124 "out of memory."); 125 return (FALSE); 126 } 127 } 128 buf = XDR_INLINE(xdrs, 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 } else { 134 (void) memcpy(oa->oa_base, 135 buf, (size_t)oa->oa_length); 136 /* 137 * no real need.... 138 * buf += RNDUP(oa->oa_length) / 139 * (int)sizeof (int32_t); 140 */ 141 } 142 } 143 oa = &cmsg->rm_call.cb_verf; 144 buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); 145 if (buf == NULL) { 146 if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || 147 xdr_u_int(xdrs, &oa->oa_length) == FALSE) 148 return (FALSE); 149 } else { 150 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 151 oa->oa_length = IXDR_GET_INT32(buf); 152 } 153 if (oa->oa_length) { 154 if (oa->oa_length > MAX_AUTH_BYTES) 155 return (FALSE); 156 if (oa->oa_base == NULL) { 157 oa->oa_base = malloc(oa->oa_length); 158 if (oa->oa_base == NULL) { 159 syslog(LOG_ERR, 160 "xdr_callmsg : " 161 "out of memory."); 162 return (FALSE); 163 } 164 } 165 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 166 if (buf == NULL) { 167 if (xdr_opaque(xdrs, oa->oa_base, 168 oa->oa_length) == FALSE) 169 return (FALSE); 170 } else { 171 (void) memcpy(oa->oa_base, 172 buf, (size_t)oa->oa_length); 173 /* 174 * no real need... 175 * buf += RNDUP(oa->oa_length) / 176 * (int)sizeof (int32_t); 177 */ 178 } 179 } 180 return (TRUE); 181 } 182 } 183 if (xdr_u_int(xdrs, &(cmsg->rm_xid)) && 184 xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && 185 (cmsg->rm_direction == CALL) && 186 xdr_u_int(xdrs, (uint_t *)&(cmsg->rm_call.cb_rpcvers)) && 187 (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && 188 xdr_u_int(xdrs, (uint_t *)&(cmsg->rm_call.cb_prog)) && 189 xdr_u_int(xdrs, (uint_t *)&(cmsg->rm_call.cb_vers)) && 190 xdr_u_int(xdrs, (uint_t *)&(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 } 194 return (FALSE); 195 } 196