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