1dc20a302Sas200622 /* 2dc20a302Sas200622 * CDDL HEADER START 3dc20a302Sas200622 * 4dc20a302Sas200622 * The contents of this file are subject to the terms of the 5dc20a302Sas200622 * Common Development and Distribution License (the "License"). 6dc20a302Sas200622 * You may not use this file except in compliance with the License. 7dc20a302Sas200622 * 8dc20a302Sas200622 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9dc20a302Sas200622 * or http://www.opensolaris.org/os/licensing. 10dc20a302Sas200622 * See the License for the specific language governing permissions 11dc20a302Sas200622 * and limitations under the License. 12dc20a302Sas200622 * 13dc20a302Sas200622 * When distributing Covered Code, include this CDDL HEADER in each 14dc20a302Sas200622 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15dc20a302Sas200622 * If applicable, add the following below this CDDL HEADER, with the 16dc20a302Sas200622 * fields enclosed by brackets "[]" replaced with your own identifying 17dc20a302Sas200622 * information: Portions Copyright [yyyy] [name of copyright owner] 18dc20a302Sas200622 * 19dc20a302Sas200622 * CDDL HEADER END 20dc20a302Sas200622 */ 21dc20a302Sas200622 /* 22*c5866007SKeyur Desai * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23dc20a302Sas200622 */ 24dc20a302Sas200622 25b1352070SAlan Wright #include <assert.h> 26dc20a302Sas200622 #include <strings.h> 27dc20a302Sas200622 #include <sys/param.h> 28dc20a302Sas200622 29dc20a302Sas200622 #include <smbsrv/libsmb.h> 308d7e4166Sjose borrego #include <smbsrv/libmlrpc.h> 31dc20a302Sas200622 32dc20a302Sas200622 #ifdef _BIG_ENDIAN 338d7e4166Sjose borrego static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN; 34dc20a302Sas200622 #else 358d7e4166Sjose borrego static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN; 36dc20a302Sas200622 #endif 37dc20a302Sas200622 38b1352070SAlan Wright static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *); 39*c5866007SKeyur Desai static int ndr_decode_pac_hdr(ndr_stream_t *, ndr_pac_hdr_t *); 40b1352070SAlan Wright 41b1352070SAlan Wright static int 42b1352070SAlan Wright ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum, 438d7e4166Sjose borrego ndr_typeinfo_t *ti, void *datum) 44dc20a302Sas200622 { 45dc20a302Sas200622 int rc; 46dc20a302Sas200622 47dc20a302Sas200622 /* 48dc20a302Sas200622 * Perform the (un)marshalling 49dc20a302Sas200622 */ 508d7e4166Sjose borrego if (ndo_operation(nds, ti, opnum, datum)) 518d7e4166Sjose borrego return (NDR_DRC_OK); 52dc20a302Sas200622 538d7e4166Sjose borrego switch (nds->error) { 54dc20a302Sas200622 case NDR_ERR_MALLOC_FAILED: 558d7e4166Sjose borrego rc = NDR_DRC_FAULT_OUT_OF_MEMORY; 56dc20a302Sas200622 break; 57dc20a302Sas200622 58dc20a302Sas200622 case NDR_ERR_SWITCH_VALUE_INVALID: 598d7e4166Sjose borrego rc = NDR_DRC_FAULT_PARAM_0_INVALID; 60dc20a302Sas200622 break; 61dc20a302Sas200622 62dc20a302Sas200622 case NDR_ERR_UNDERFLOW: 638d7e4166Sjose borrego rc = NDR_DRC_FAULT_RECEIVED_RUNT; 64dc20a302Sas200622 break; 65dc20a302Sas200622 66dc20a302Sas200622 case NDR_ERR_GROW_FAILED: 678d7e4166Sjose borrego rc = NDR_DRC_FAULT_ENCODE_TOO_BIG; 68dc20a302Sas200622 break; 69dc20a302Sas200622 70dc20a302Sas200622 default: 71b1352070SAlan Wright if (nds->m_op == NDR_M_OP_MARSHALL) 728d7e4166Sjose borrego rc = NDR_DRC_FAULT_ENCODE_FAILED; 73dc20a302Sas200622 else 748d7e4166Sjose borrego rc = NDR_DRC_FAULT_DECODE_FAILED; 75dc20a302Sas200622 break; 76dc20a302Sas200622 } 77dc20a302Sas200622 78dc20a302Sas200622 return (rc); 79dc20a302Sas200622 } 80dc20a302Sas200622 81b1352070SAlan Wright ndr_buf_t * 82b1352070SAlan Wright ndr_buf_init(ndr_typeinfo_t *ti) 83b1352070SAlan Wright { 84b1352070SAlan Wright ndr_buf_t *nbuf; 85b1352070SAlan Wright 86b1352070SAlan Wright if ((nbuf = calloc(1, sizeof (ndr_buf_t))) == NULL) 87b1352070SAlan Wright return (NULL); 88b1352070SAlan Wright 89b1352070SAlan Wright if ((nbuf->nb_heap = ndr_heap_create()) == NULL) { 90b1352070SAlan Wright free(nbuf); 91b1352070SAlan Wright return (NULL); 92b1352070SAlan Wright } 93b1352070SAlan Wright 94b1352070SAlan Wright nbuf->nb_ti = ti; 95b1352070SAlan Wright nbuf->nb_magic = NDR_BUF_MAGIC; 96b1352070SAlan Wright return (nbuf); 97b1352070SAlan Wright } 98b1352070SAlan Wright 99b1352070SAlan Wright void 100b1352070SAlan Wright ndr_buf_fini(ndr_buf_t *nbuf) 101b1352070SAlan Wright { 102b1352070SAlan Wright assert(nbuf->nb_magic == NDR_BUF_MAGIC); 103b1352070SAlan Wright 104b1352070SAlan Wright nds_destruct(&nbuf->nb_nds); 105b1352070SAlan Wright ndr_heap_destroy(nbuf->nb_heap); 106b1352070SAlan Wright nbuf->nb_magic = 0; 107b1352070SAlan Wright free(nbuf); 108b1352070SAlan Wright } 109b1352070SAlan Wright 110b1352070SAlan Wright /* 111b1352070SAlan Wright * Decode an NDR encoded buffer. The buffer is expected to contain 112b1352070SAlan Wright * a single fragment packet with a valid PDU header followed by NDR 113b1352070SAlan Wright * encoded data. The structure to which result points should be 114b1352070SAlan Wright * of the appropriate type to hold the decoded output. For example: 115b1352070SAlan Wright * 116b1352070SAlan Wright * pac_info_t info; 117b1352070SAlan Wright * 118b1352070SAlan Wright * if ((nbuf = ndr_buf_init(&TYPEINFO(ndr_pac)) != NULL) { 119b1352070SAlan Wright * rc = ndr_decode_buf(nbuf, opnum, data, datalen, &info); 120b1352070SAlan Wright * ... 121b1352070SAlan Wright * ndr_buf_fini(nbuf); 122b1352070SAlan Wright * } 123b1352070SAlan Wright */ 124b1352070SAlan Wright int 125*c5866007SKeyur Desai ndr_buf_decode(ndr_buf_t *nbuf, unsigned hdr_type, unsigned opnum, 126*c5866007SKeyur Desai const char *data, size_t datalen, void *result) 127b1352070SAlan Wright { 128b1352070SAlan Wright ndr_common_header_t hdr; 129*c5866007SKeyur Desai ndr_pac_hdr_t pac_hdr; 130b1352070SAlan Wright unsigned pdu_size_hint; 131b1352070SAlan Wright int rc; 132b1352070SAlan Wright 133b1352070SAlan Wright assert(nbuf->nb_magic == NDR_BUF_MAGIC); 134b1352070SAlan Wright assert(nbuf->nb_heap != NULL); 135b1352070SAlan Wright assert(nbuf->nb_ti != NULL); 136b1352070SAlan Wright 137b1352070SAlan Wright if (datalen < NDR_PDU_SIZE_HINT_DEFAULT) 138b1352070SAlan Wright pdu_size_hint = NDR_PDU_SIZE_HINT_DEFAULT; 139b1352070SAlan Wright else 140b1352070SAlan Wright pdu_size_hint = datalen; 141b1352070SAlan Wright 142fe1c642dSBill Krier rc = nds_initialize(&nbuf->nb_nds, pdu_size_hint, NDR_MODE_BUF_DECODE, 143b1352070SAlan Wright nbuf->nb_heap); 144fe1c642dSBill Krier if (NDR_DRC_IS_FAULT(rc)) 145fe1c642dSBill Krier return (rc); 146fe1c642dSBill Krier 147b1352070SAlan Wright bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen); 148b1352070SAlan Wright 149*c5866007SKeyur Desai switch (hdr_type) { 150*c5866007SKeyur Desai case NDR_PTYPE_COMMON: 151b1352070SAlan Wright rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr); 152b1352070SAlan Wright if (NDR_DRC_IS_FAULT(rc)) 153b1352070SAlan Wright return (rc); 154b1352070SAlan Wright 155b1352070SAlan Wright if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags)) 156fe1c642dSBill Krier return (NDR_DRC_FAULT_DECODE_FAILED); 157*c5866007SKeyur Desai break; 158*c5866007SKeyur Desai 159*c5866007SKeyur Desai case NDR_PTYPE_PAC: 160*c5866007SKeyur Desai rc = ndr_decode_pac_hdr(&nbuf->nb_nds, &pac_hdr); 161*c5866007SKeyur Desai if (NDR_DRC_IS_FAULT(rc)) 162*c5866007SKeyur Desai return (rc); 163*c5866007SKeyur Desai 164*c5866007SKeyur Desai if (pac_hdr.common_hdr.hdrlen != sizeof (ndr_serialtype1_hdr_t)) 165*c5866007SKeyur Desai return (NDR_DRC_FAULT_DECODE_FAILED); 166*c5866007SKeyur Desai break; 167*c5866007SKeyur Desai 168*c5866007SKeyur Desai default: 169*c5866007SKeyur Desai return (NDR_ERR_UNIMPLEMENTED); 170*c5866007SKeyur Desai } 171b1352070SAlan Wright 172b1352070SAlan Wright rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti, 173b1352070SAlan Wright result); 174b1352070SAlan Wright return (rc); 175b1352070SAlan Wright } 176b1352070SAlan Wright 177b1352070SAlan Wright /* 178b1352070SAlan Wright * Use the receive stream to unmarshall data (NDR_MODE_CALL_RECV). 179b1352070SAlan Wright */ 180dc20a302Sas200622 int 1818d7e4166Sjose borrego ndr_decode_call(ndr_xa_t *mxa, void *params) 182dc20a302Sas200622 { 183b1352070SAlan Wright ndr_stream_t *nds = &mxa->recv_nds; 184dc20a302Sas200622 int rc; 185dc20a302Sas200622 186b1352070SAlan Wright if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_RECV)) 187b1352070SAlan Wright return (NDR_DRC_FAULT_MODE_MISMATCH); 188b1352070SAlan Wright 189b1352070SAlan Wright rc = ndr_encode_decode_common(nds, mxa->opnum, 190b1352070SAlan Wright mxa->binding->service->interface_ti, params); 191dc20a302Sas200622 1928d7e4166Sjose borrego return (rc + NDR_PTYPE_REQUEST); 193dc20a302Sas200622 } 194dc20a302Sas200622 195b1352070SAlan Wright /* 196b1352070SAlan Wright * Use the send stream to marshall data (NDR_MODE_RETURN_SEND). 197b1352070SAlan Wright */ 198dc20a302Sas200622 int 1998d7e4166Sjose borrego ndr_encode_return(ndr_xa_t *mxa, void *params) 200dc20a302Sas200622 { 201b1352070SAlan Wright ndr_stream_t *nds = &mxa->send_nds; 202dc20a302Sas200622 int rc; 203dc20a302Sas200622 204b1352070SAlan Wright if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND)) 205b1352070SAlan Wright return (NDR_DRC_FAULT_MODE_MISMATCH); 206b1352070SAlan Wright 207b1352070SAlan Wright rc = ndr_encode_decode_common(nds, mxa->opnum, 208b1352070SAlan Wright mxa->binding->service->interface_ti, params); 209dc20a302Sas200622 2108d7e4166Sjose borrego return (rc + NDR_PTYPE_RESPONSE); 211dc20a302Sas200622 } 212dc20a302Sas200622 213b1352070SAlan Wright /* 214b1352070SAlan Wright * Use the send stream to marshall data (NDR_MODE_CALL_SEND). 215b1352070SAlan Wright */ 216dc20a302Sas200622 int 2178d7e4166Sjose borrego ndr_encode_call(ndr_xa_t *mxa, void *params) 218dc20a302Sas200622 { 219b1352070SAlan Wright ndr_stream_t *nds = &mxa->send_nds; 220dc20a302Sas200622 int rc; 221dc20a302Sas200622 222b1352070SAlan Wright if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_SEND)) 223b1352070SAlan Wright return (NDR_DRC_FAULT_MODE_MISMATCH); 224b1352070SAlan Wright 225b1352070SAlan Wright rc = ndr_encode_decode_common(nds, mxa->opnum, 226b1352070SAlan Wright mxa->binding->service->interface_ti, params); 227dc20a302Sas200622 2288d7e4166Sjose borrego return (rc + NDR_PTYPE_REQUEST); 229dc20a302Sas200622 } 230dc20a302Sas200622 231b1352070SAlan Wright /* 232b1352070SAlan Wright * Use the receive stream to unmarshall data (NDR_MODE_RETURN_RECV). 233b1352070SAlan Wright */ 234dc20a302Sas200622 int 2358d7e4166Sjose borrego ndr_decode_return(ndr_xa_t *mxa, void *params) 236dc20a302Sas200622 { 237b1352070SAlan Wright ndr_stream_t *nds = &mxa->recv_nds; 238dc20a302Sas200622 int rc; 239dc20a302Sas200622 240b1352070SAlan Wright if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_RECV)) 241b1352070SAlan Wright return (NDR_DRC_FAULT_MODE_MISMATCH); 242b1352070SAlan Wright 243b1352070SAlan Wright rc = ndr_encode_decode_common(nds, mxa->opnum, 244b1352070SAlan Wright mxa->binding->service->interface_ti, params); 245dc20a302Sas200622 2468d7e4166Sjose borrego return (rc + NDR_PTYPE_RESPONSE); 247dc20a302Sas200622 } 248dc20a302Sas200622 249dc20a302Sas200622 int 2508d7e4166Sjose borrego ndr_decode_pdu_hdr(ndr_xa_t *mxa) 251dc20a302Sas200622 { 2522c1b14e5Sjose borrego ndr_common_header_t *hdr = &mxa->recv_hdr.common_hdr; 2538d7e4166Sjose borrego ndr_stream_t *nds = &mxa->recv_nds; 254b1352070SAlan Wright int rc; 255b1352070SAlan Wright 256b1352070SAlan Wright rc = ndr_decode_hdr_common(nds, hdr); 257b1352070SAlan Wright if (NDR_DRC_IS_FAULT(rc)) 258b1352070SAlan Wright return (rc); 259b1352070SAlan Wright 260b1352070SAlan Wright /* 261b1352070SAlan Wright * Verify the protocol version. 262b1352070SAlan Wright */ 263b1352070SAlan Wright if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0)) 264*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); 265b1352070SAlan Wright 266b1352070SAlan Wright mxa->ptype = hdr->ptype; 267b1352070SAlan Wright return (NDR_DRC_OK); 268b1352070SAlan Wright } 269b1352070SAlan Wright 270b1352070SAlan Wright static int 271b1352070SAlan Wright ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) 272b1352070SAlan Wright { 273dc20a302Sas200622 int ptype; 274dc20a302Sas200622 int rc; 275dc20a302Sas200622 int charset; 276dc20a302Sas200622 int byte_order; 277dc20a302Sas200622 2788d7e4166Sjose borrego if (nds->m_op != NDR_M_OP_UNMARSHALL) 279*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); 280dc20a302Sas200622 281dc20a302Sas200622 /* 282dc20a302Sas200622 * All PDU headers are at least this big 283dc20a302Sas200622 */ 2848d7e4166Sjose borrego rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0); 285dc20a302Sas200622 if (!rc) 286*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT); 287dc20a302Sas200622 288dc20a302Sas200622 /* 289dc20a302Sas200622 * Peek at the first eight bytes to figure out what we're doing. 290dc20a302Sas200622 */ 2918d7e4166Sjose borrego rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); 292dc20a302Sas200622 if (!rc) 293*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); 294dc20a302Sas200622 295dc20a302Sas200622 /* 296dc20a302Sas200622 * Check for ASCII as the character set. This is an ASCII 297dc20a302Sas200622 * versus EBCDIC option and has nothing to do with Unicode. 298dc20a302Sas200622 */ 2998d7e4166Sjose borrego charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK; 3008d7e4166Sjose borrego if (charset != NDR_REPLAB_CHAR_ASCII) 301*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); 302dc20a302Sas200622 303dc20a302Sas200622 /* 304dc20a302Sas200622 * Set the byte swap flag if the PDU byte-order 305dc20a302Sas200622 * is different from the local byte-order. 306dc20a302Sas200622 */ 3078d7e4166Sjose borrego byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK; 3088d7e4166Sjose borrego nds->swap = (byte_order != ndr_native_byte_order) ? 1 : 0; 309dc20a302Sas200622 310dc20a302Sas200622 ptype = hdr->ptype; 3118d7e4166Sjose borrego if (ptype == NDR_PTYPE_REQUEST && 3128d7e4166Sjose borrego (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) { 3138d7e4166Sjose borrego ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */ 314dc20a302Sas200622 } 315dc20a302Sas200622 316b1352070SAlan Wright rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr); 317dc20a302Sas200622 3188d7e4166Sjose borrego return (NDR_DRC_PTYPE_RPCHDR(rc)); 319dc20a302Sas200622 } 320dc20a302Sas200622 321*c5866007SKeyur Desai static int 322*c5866007SKeyur Desai ndr_decode_pac_hdr(ndr_stream_t *nds, ndr_pac_hdr_t *hdr) 323*c5866007SKeyur Desai { 324*c5866007SKeyur Desai int rc; 325*c5866007SKeyur Desai 326*c5866007SKeyur Desai if (nds->m_op != NDR_M_OP_UNMARSHALL) 327*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); 328*c5866007SKeyur Desai 329*c5866007SKeyur Desai /* 330*c5866007SKeyur Desai * All PDU headers are at least this big 331*c5866007SKeyur Desai */ 332*c5866007SKeyur Desai rc = NDS_GROW_PDU(nds, sizeof (ndr_pac_hdr_t), 0); 333*c5866007SKeyur Desai if (!rc) 334*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT); 335*c5866007SKeyur Desai 336*c5866007SKeyur Desai /* 337*c5866007SKeyur Desai * Peek at the first eight bytes to figure out what we're doing. 338*c5866007SKeyur Desai */ 339*c5866007SKeyur Desai rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); 340*c5866007SKeyur Desai if (!rc) 341*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); 342*c5866007SKeyur Desai 343*c5866007SKeyur Desai /* Must be set to 1 to indicate type serialization version 1. */ 344*c5866007SKeyur Desai if (hdr->common_hdr.version != 1) 345*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_DECODE_FAILED); 346*c5866007SKeyur Desai 347*c5866007SKeyur Desai /* 348*c5866007SKeyur Desai * Set the byte swap flag if the PDU byte-order 349*c5866007SKeyur Desai * is different from the local byte-order. 350*c5866007SKeyur Desai */ 351*c5866007SKeyur Desai nds->swap = 352*c5866007SKeyur Desai (hdr->common_hdr.endianness != ndr_native_byte_order) ? 1 : 0; 353*c5866007SKeyur Desai 354*c5866007SKeyur Desai rc = ndr_encode_decode_common(nds, NDR_PTYPE_PAC, 355*c5866007SKeyur Desai &TYPEINFO(ndr_hdr), hdr); 356*c5866007SKeyur Desai 357*c5866007SKeyur Desai return (NDR_DRC_PTYPE_RPCHDR(rc)); 358*c5866007SKeyur Desai } 359*c5866007SKeyur Desai 360dc20a302Sas200622 /* 3618d7e4166Sjose borrego * Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process 362dc20a302Sas200622 * the first fragment header then this function to process additional 363dc20a302Sas200622 * fragment headers. 364dc20a302Sas200622 */ 365dc20a302Sas200622 void 3668d7e4166Sjose borrego ndr_decode_frag_hdr(ndr_stream_t *nds, ndr_common_header_t *hdr) 367dc20a302Sas200622 { 3682c1b14e5Sjose borrego ndr_common_header_t *tmp; 369dc20a302Sas200622 uint8_t *pdu; 370dc20a302Sas200622 int byte_order; 371dc20a302Sas200622 3728d7e4166Sjose borrego pdu = (uint8_t *)nds->pdu_base_offset + nds->pdu_scan_offset; 3738d7e4166Sjose borrego bcopy(pdu, hdr, NDR_RSP_HDR_SIZE); 374dc20a302Sas200622 375dc20a302Sas200622 /* 376dc20a302Sas200622 * Swap non-byte fields if the PDU byte-order 377dc20a302Sas200622 * is different from the local byte-order. 378dc20a302Sas200622 */ 3798d7e4166Sjose borrego byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK; 380dc20a302Sas200622 3818d7e4166Sjose borrego if (byte_order != ndr_native_byte_order) { 382dc20a302Sas200622 /*LINTED E_BAD_PTR_CAST_ALIGN*/ 3832c1b14e5Sjose borrego tmp = (ndr_common_header_t *)pdu; 384dc20a302Sas200622 3858d7e4166Sjose borrego nds_bswap(&tmp->frag_length, &hdr->frag_length, 386dc20a302Sas200622 sizeof (WORD)); 3878d7e4166Sjose borrego nds_bswap(&tmp->auth_length, &hdr->auth_length, 388dc20a302Sas200622 sizeof (WORD)); 3898d7e4166Sjose borrego nds_bswap(&tmp->call_id, &hdr->call_id, sizeof (DWORD)); 390dc20a302Sas200622 } 391dc20a302Sas200622 } 392dc20a302Sas200622 3939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 3949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Remove an RPC fragment header from the received data stream. 3959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 3969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * NDR stream on entry: 3979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 3989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * |<--- frag --->| 3999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * +-----+--------+-----+--------+-----+---------+-----+ 4009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | hdr | data | hdr | data | hdr | data | ... | 4019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * +-----+--------+-----+--------+-----+---------+-----+ 4029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * <---- 4039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 4049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * NDR stream on return: 4059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 4069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * +-----+----------------+-----+---------+-----+ 4079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | hdr | data | hdr | data | ... | 4089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * +-----+----------------+-----+---------+-----+ 4099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 4109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ndr_remove_frag_hdr(ndr_stream_t *nds) 4129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 4139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *hdr; 4149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States char *data; 4159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int nbytes; 4169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 4179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States hdr = (char *)nds->pdu_base_offset + nds->pdu_scan_offset; 4189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States data = hdr + NDR_RSP_HDR_SIZE; 4199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States nbytes = nds->pdu_size - nds->pdu_scan_offset - NDR_RSP_HDR_SIZE; 4209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bcopy(data, hdr, nbytes); 4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States nds->pdu_size -= NDR_RSP_HDR_SIZE; 4239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 4249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 4250658b32dSAlan Wright void 4260658b32dSAlan Wright ndr_show_hdr(ndr_common_header_t *hdr) 4270658b32dSAlan Wright { 4280658b32dSAlan Wright char *fragtype; 4290658b32dSAlan Wright 4300658b32dSAlan Wright if (hdr == NULL) { 4310658b32dSAlan Wright ndo_printf(NULL, NULL, "ndr hdr: <null>"); 4320658b32dSAlan Wright return; 4330658b32dSAlan Wright } 4340658b32dSAlan Wright 4350658b32dSAlan Wright if (NDR_IS_SINGLE_FRAG(hdr->pfc_flags)) 4360658b32dSAlan Wright fragtype = "single"; 4370658b32dSAlan Wright else if (NDR_IS_FIRST_FRAG(hdr->pfc_flags)) 4380658b32dSAlan Wright fragtype = "first"; 4390658b32dSAlan Wright else if (NDR_IS_LAST_FRAG(hdr->pfc_flags)) 4400658b32dSAlan Wright fragtype = "last"; 4410658b32dSAlan Wright else 4420658b32dSAlan Wright fragtype = "intermediate"; 4430658b32dSAlan Wright 4440658b32dSAlan Wright ndo_printf(NULL, NULL, 4450658b32dSAlan Wright "ndr hdr: %d.%d ptype=%d, %s frag (flags=0x%08x) len=%d", 4460658b32dSAlan Wright hdr->rpc_vers, hdr->rpc_vers_minor, hdr->ptype, 4470658b32dSAlan Wright fragtype, hdr->pfc_flags, hdr->frag_length); 4480658b32dSAlan Wright } 4490658b32dSAlan Wright 450dc20a302Sas200622 int 4518d7e4166Sjose borrego ndr_encode_pdu_hdr(ndr_xa_t *mxa) 452dc20a302Sas200622 { 4532c1b14e5Sjose borrego ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; 4548d7e4166Sjose borrego ndr_stream_t *nds = &mxa->send_nds; 455dc20a302Sas200622 int ptype; 456dc20a302Sas200622 int rc; 457dc20a302Sas200622 4588d7e4166Sjose borrego if (nds->m_op != NDR_M_OP_MARSHALL) 459*c5866007SKeyur Desai return (NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH); 460dc20a302Sas200622 461dc20a302Sas200622 ptype = hdr->ptype; 4628d7e4166Sjose borrego if (ptype == NDR_PTYPE_REQUEST && 4638d7e4166Sjose borrego (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) { 4648d7e4166Sjose borrego ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */ 465dc20a302Sas200622 } 466dc20a302Sas200622 467b1352070SAlan Wright rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr); 468dc20a302Sas200622 4698d7e4166Sjose borrego return (NDR_DRC_PTYPE_RPCHDR(rc)); 470dc20a302Sas200622 } 471dc20a302Sas200622 472dc20a302Sas200622 /* 473dc20a302Sas200622 * This is a hand-coded derivative of the automatically generated 474dc20a302Sas200622 * (un)marshalling routine for bind_ack headers. bind_ack headers 475dc20a302Sas200622 * have an interior conformant array, which is inconsistent with 476dc20a302Sas200622 * IDL/NDR rules. 477dc20a302Sas200622 */ 478dc20a302Sas200622 extern struct ndr_typeinfo ndt__uchar; 479dc20a302Sas200622 extern struct ndr_typeinfo ndt__ushort; 480dc20a302Sas200622 extern struct ndr_typeinfo ndt__ulong; 481dc20a302Sas200622 4828d7e4166Sjose borrego int ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref); 4838d7e4166Sjose borrego ndr_typeinfo_t ndt__ndr_bind_ack_hdr = { 484dc20a302Sas200622 1, /* NDR version */ 485dc20a302Sas200622 3, /* alignment */ 486dc20a302Sas200622 NDR_F_STRUCT, /* flags */ 4878d7e4166Sjose borrego ndr__ndr_bind_ack_hdr, /* ndr_func */ 488dc20a302Sas200622 68, /* pdu_size_fixed_part */ 489dc20a302Sas200622 0, /* pdu_size_variable_part */ 490dc20a302Sas200622 68, /* c_size_fixed_part */ 491dc20a302Sas200622 0, /* c_size_variable_part */ 492dc20a302Sas200622 }; 493dc20a302Sas200622 494dc20a302Sas200622 /* 495dc20a302Sas200622 * [_no_reorder] 496dc20a302Sas200622 */ 497dc20a302Sas200622 int 4988d7e4166Sjose borrego ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref) 499dc20a302Sas200622 { 5008d7e4166Sjose borrego ndr_stream_t *nds = encl_ref->stream; 5012c1b14e5Sjose borrego struct ndr_bind_ack_hdr *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/ 5022c1b14e5Sjose borrego (struct ndr_bind_ack_hdr *)encl_ref->datum; 5038d7e4166Sjose borrego ndr_ref_t myref; 504dc20a302Sas200622 unsigned long offset; 505dc20a302Sas200622 506dc20a302Sas200622 bzero(&myref, sizeof (myref)); 507dc20a302Sas200622 myref.enclosing = encl_ref; 508dc20a302Sas200622 myref.stream = encl_ref->stream; 509dc20a302Sas200622 myref.packed_alignment = 0; 510dc20a302Sas200622 511dc20a302Sas200622 /* do all members in order */ 5122c1b14e5Sjose borrego NDR_MEMBER(_ndr_common_header, common_hdr, 0UL); 513dc20a302Sas200622 NDR_MEMBER(_ushort, max_xmit_frag, 16UL); 514dc20a302Sas200622 NDR_MEMBER(_ushort, max_recv_frag, 18UL); 515dc20a302Sas200622 NDR_MEMBER(_ulong, assoc_group_id, 20UL); 516dc20a302Sas200622 517dc20a302Sas200622 /* port any is the conformant culprit */ 518dc20a302Sas200622 offset = 24UL; 519dc20a302Sas200622 5208d7e4166Sjose borrego switch (nds->m_op) { 521dc20a302Sas200622 case NDR_M_OP_MARSHALL: 522dc20a302Sas200622 val->sec_addr.length = 523dc20a302Sas200622 strlen((char *)val->sec_addr.port_spec) + 1; 524dc20a302Sas200622 break; 525dc20a302Sas200622 526dc20a302Sas200622 case NDR_M_OP_UNMARSHALL: 527dc20a302Sas200622 break; 528dc20a302Sas200622 529dc20a302Sas200622 default: 530dc20a302Sas200622 NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID); 531dc20a302Sas200622 return (0); 532dc20a302Sas200622 } 533dc20a302Sas200622 534dc20a302Sas200622 NDR_MEMBER(_ushort, sec_addr.length, offset); 535dc20a302Sas200622 NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec, 536dc20a302Sas200622 offset+2UL, val->sec_addr.length); 537dc20a302Sas200622 538dc20a302Sas200622 offset += 2; 539dc20a302Sas200622 offset += val->sec_addr.length; 5408d7e4166Sjose borrego offset += NDR_ALIGN4(offset); 541dc20a302Sas200622 5428d7e4166Sjose borrego NDR_MEMBER(_ndr_p_result_list, p_result_list, offset); 543dc20a302Sas200622 return (1); 544dc20a302Sas200622 } 545dc20a302Sas200622 5462c1b14e5Sjose borrego /* 5472c1b14e5Sjose borrego * Assume a single presentation context element in the result list. 5482c1b14e5Sjose borrego */ 549dc20a302Sas200622 unsigned 5508d7e4166Sjose borrego ndr_bind_ack_hdr_size(ndr_xa_t *mxa) 551dc20a302Sas200622 { 5522c1b14e5Sjose borrego ndr_bind_ack_hdr_t *bahdr = &mxa->send_hdr.bind_ack_hdr; 553dc20a302Sas200622 unsigned offset; 554dc20a302Sas200622 unsigned length; 555dc20a302Sas200622 556dc20a302Sas200622 /* port any is the conformant culprit */ 557dc20a302Sas200622 offset = 24UL; 558dc20a302Sas200622 559dc20a302Sas200622 length = strlen((char *)bahdr->sec_addr.port_spec) + 1; 560dc20a302Sas200622 561dc20a302Sas200622 offset += 2; 562dc20a302Sas200622 offset += length; 5638d7e4166Sjose borrego offset += NDR_ALIGN4(offset); 5648d7e4166Sjose borrego offset += sizeof (ndr_p_result_list_t); 5652c1b14e5Sjose borrego return (offset); 5662c1b14e5Sjose borrego } 5672c1b14e5Sjose borrego 5682c1b14e5Sjose borrego /* 5692c1b14e5Sjose borrego * This is a hand-coded derivative of the automatically generated 5702c1b14e5Sjose borrego * (un)marshalling routine for alter_context_rsp headers. 5712c1b14e5Sjose borrego * Alter context response headers have an interior conformant array, 5722c1b14e5Sjose borrego * which is inconsistent with IDL/NDR rules. 5732c1b14e5Sjose borrego */ 5748d7e4166Sjose borrego int ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref); 5758d7e4166Sjose borrego ndr_typeinfo_t ndt__ndr_alter_context_rsp_hdr = { 5762c1b14e5Sjose borrego 1, /* NDR version */ 5772c1b14e5Sjose borrego 3, /* alignment */ 5782c1b14e5Sjose borrego NDR_F_STRUCT, /* flags */ 5798d7e4166Sjose borrego ndr__ndr_alter_context_rsp_hdr, /* ndr_func */ 5802c1b14e5Sjose borrego 56, /* pdu_size_fixed_part */ 5812c1b14e5Sjose borrego 0, /* pdu_size_variable_part */ 5822c1b14e5Sjose borrego 56, /* c_size_fixed_part */ 5832c1b14e5Sjose borrego 0, /* c_size_variable_part */ 5842c1b14e5Sjose borrego }; 5852c1b14e5Sjose borrego 5862c1b14e5Sjose borrego /* 5872c1b14e5Sjose borrego * [_no_reorder] 5882c1b14e5Sjose borrego */ 5892c1b14e5Sjose borrego int 5908d7e4166Sjose borrego ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref) 5912c1b14e5Sjose borrego { 5928d7e4166Sjose borrego ndr_stream_t *nds = encl_ref->stream; 5932c1b14e5Sjose borrego ndr_alter_context_rsp_hdr_t *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/ 5942c1b14e5Sjose borrego (ndr_alter_context_rsp_hdr_t *)encl_ref->datum; 5958d7e4166Sjose borrego ndr_ref_t myref; 5962c1b14e5Sjose borrego unsigned long offset; 5972c1b14e5Sjose borrego 5982c1b14e5Sjose borrego bzero(&myref, sizeof (myref)); 5992c1b14e5Sjose borrego myref.enclosing = encl_ref; 6002c1b14e5Sjose borrego myref.stream = encl_ref->stream; 6012c1b14e5Sjose borrego myref.packed_alignment = 0; 6022c1b14e5Sjose borrego 6032c1b14e5Sjose borrego /* do all members in order */ 6042c1b14e5Sjose borrego NDR_MEMBER(_ndr_common_header, common_hdr, 0UL); 6052c1b14e5Sjose borrego NDR_MEMBER(_ushort, max_xmit_frag, 16UL); 6062c1b14e5Sjose borrego NDR_MEMBER(_ushort, max_recv_frag, 18UL); 6072c1b14e5Sjose borrego NDR_MEMBER(_ulong, assoc_group_id, 20UL); 6082c1b14e5Sjose borrego 6092c1b14e5Sjose borrego offset = 24UL; /* offset of sec_addr */ 6102c1b14e5Sjose borrego 6118d7e4166Sjose borrego switch (nds->m_op) { 6122c1b14e5Sjose borrego case NDR_M_OP_MARSHALL: 6132c1b14e5Sjose borrego val->sec_addr.length = 0; 6142c1b14e5Sjose borrego break; 6152c1b14e5Sjose borrego 6162c1b14e5Sjose borrego case NDR_M_OP_UNMARSHALL: 6172c1b14e5Sjose borrego break; 6182c1b14e5Sjose borrego 6192c1b14e5Sjose borrego default: 6202c1b14e5Sjose borrego NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID); 6212c1b14e5Sjose borrego return (0); 6222c1b14e5Sjose borrego } 6232c1b14e5Sjose borrego 6242c1b14e5Sjose borrego NDR_MEMBER(_ushort, sec_addr.length, offset); 6252c1b14e5Sjose borrego NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec, 6262c1b14e5Sjose borrego offset+2UL, val->sec_addr.length); 6272c1b14e5Sjose borrego 6282c1b14e5Sjose borrego offset += 2; /* sizeof (sec_addr.length) */ 6298d7e4166Sjose borrego offset += NDR_ALIGN4(offset); 6302c1b14e5Sjose borrego 6318d7e4166Sjose borrego NDR_MEMBER(_ndr_p_result_list, p_result_list, offset); 6322c1b14e5Sjose borrego return (1); 6332c1b14e5Sjose borrego } 6342c1b14e5Sjose borrego 6352c1b14e5Sjose borrego /* 6362c1b14e5Sjose borrego * Assume a single presentation context element in the result list. 6372c1b14e5Sjose borrego */ 6382c1b14e5Sjose borrego unsigned 6398d7e4166Sjose borrego ndr_alter_context_rsp_hdr_size(void) 6402c1b14e5Sjose borrego { 6412c1b14e5Sjose borrego unsigned offset; 6422c1b14e5Sjose borrego 6432c1b14e5Sjose borrego offset = 24UL; /* offset of sec_addr */ 6442c1b14e5Sjose borrego offset += 2; /* sizeof (sec_addr.length) */ 6458d7e4166Sjose borrego offset += NDR_ALIGN4(offset); 6468d7e4166Sjose borrego offset += sizeof (ndr_p_result_list_t); 647dc20a302Sas200622 return (offset); 648dc20a302Sas200622 } 649