15772Sas200622 /* 25772Sas200622 * CDDL HEADER START 35772Sas200622 * 45772Sas200622 * The contents of this file are subject to the terms of the 55772Sas200622 * Common Development and Distribution License (the "License"). 65772Sas200622 * You may not use this file except in compliance with the License. 75772Sas200622 * 85772Sas200622 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95772Sas200622 * or http://www.opensolaris.org/os/licensing. 105772Sas200622 * See the License for the specific language governing permissions 115772Sas200622 * and limitations under the License. 125772Sas200622 * 135772Sas200622 * When distributing Covered Code, include this CDDL HEADER in each 145772Sas200622 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155772Sas200622 * If applicable, add the following below this CDDL HEADER, with the 165772Sas200622 * fields enclosed by brackets "[]" replaced with your own identifying 175772Sas200622 * information: Portions Copyright [yyyy] [name of copyright owner] 185772Sas200622 * 195772Sas200622 * CDDL HEADER END 205772Sas200622 */ 215772Sas200622 /* 22*11963SAfshin.Ardakani@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 235772Sas200622 * Use is subject to license terms. 245772Sas200622 */ 255772Sas200622 269914Samw@Sun.COM #include <assert.h> 275772Sas200622 #include <strings.h> 285772Sas200622 #include <sys/param.h> 295772Sas200622 305772Sas200622 #include <smbsrv/libsmb.h> 318334SJose.Borrego@Sun.COM #include <smbsrv/libmlrpc.h> 325772Sas200622 335772Sas200622 #ifdef _BIG_ENDIAN 348334SJose.Borrego@Sun.COM static const int ndr_native_byte_order = NDR_REPLAB_INTG_BIG_ENDIAN; 355772Sas200622 #else 368334SJose.Borrego@Sun.COM static const int ndr_native_byte_order = NDR_REPLAB_INTG_LITTLE_ENDIAN; 375772Sas200622 #endif 385772Sas200622 399914Samw@Sun.COM static int ndr_decode_hdr_common(ndr_stream_t *, ndr_common_header_t *); 409914Samw@Sun.COM 419914Samw@Sun.COM static int 429914Samw@Sun.COM ndr_encode_decode_common(ndr_stream_t *nds, unsigned opnum, 438334SJose.Borrego@Sun.COM ndr_typeinfo_t *ti, void *datum) 445772Sas200622 { 459914Samw@Sun.COM int rc; 465772Sas200622 475772Sas200622 /* 485772Sas200622 * Perform the (un)marshalling 495772Sas200622 */ 508334SJose.Borrego@Sun.COM if (ndo_operation(nds, ti, opnum, datum)) 518334SJose.Borrego@Sun.COM return (NDR_DRC_OK); 525772Sas200622 538334SJose.Borrego@Sun.COM switch (nds->error) { 545772Sas200622 case NDR_ERR_MALLOC_FAILED: 558334SJose.Borrego@Sun.COM rc = NDR_DRC_FAULT_OUT_OF_MEMORY; 565772Sas200622 break; 575772Sas200622 585772Sas200622 case NDR_ERR_SWITCH_VALUE_INVALID: 598334SJose.Borrego@Sun.COM rc = NDR_DRC_FAULT_PARAM_0_INVALID; 605772Sas200622 break; 615772Sas200622 625772Sas200622 case NDR_ERR_UNDERFLOW: 638334SJose.Borrego@Sun.COM rc = NDR_DRC_FAULT_RECEIVED_RUNT; 645772Sas200622 break; 655772Sas200622 665772Sas200622 case NDR_ERR_GROW_FAILED: 678334SJose.Borrego@Sun.COM rc = NDR_DRC_FAULT_ENCODE_TOO_BIG; 685772Sas200622 break; 695772Sas200622 705772Sas200622 default: 719914Samw@Sun.COM if (nds->m_op == NDR_M_OP_MARSHALL) 728334SJose.Borrego@Sun.COM rc = NDR_DRC_FAULT_ENCODE_FAILED; 735772Sas200622 else 748334SJose.Borrego@Sun.COM rc = NDR_DRC_FAULT_DECODE_FAILED; 755772Sas200622 break; 765772Sas200622 } 775772Sas200622 785772Sas200622 return (rc); 795772Sas200622 } 805772Sas200622 819914Samw@Sun.COM ndr_buf_t * 829914Samw@Sun.COM ndr_buf_init(ndr_typeinfo_t *ti) 839914Samw@Sun.COM { 849914Samw@Sun.COM ndr_buf_t *nbuf; 859914Samw@Sun.COM 869914Samw@Sun.COM if ((nbuf = calloc(1, sizeof (ndr_buf_t))) == NULL) 879914Samw@Sun.COM return (NULL); 889914Samw@Sun.COM 899914Samw@Sun.COM if ((nbuf->nb_heap = ndr_heap_create()) == NULL) { 909914Samw@Sun.COM free(nbuf); 919914Samw@Sun.COM return (NULL); 929914Samw@Sun.COM } 939914Samw@Sun.COM 949914Samw@Sun.COM nbuf->nb_ti = ti; 959914Samw@Sun.COM nbuf->nb_magic = NDR_BUF_MAGIC; 969914Samw@Sun.COM return (nbuf); 979914Samw@Sun.COM } 989914Samw@Sun.COM 999914Samw@Sun.COM void 1009914Samw@Sun.COM ndr_buf_fini(ndr_buf_t *nbuf) 1019914Samw@Sun.COM { 1029914Samw@Sun.COM assert(nbuf->nb_magic == NDR_BUF_MAGIC); 1039914Samw@Sun.COM 1049914Samw@Sun.COM nds_destruct(&nbuf->nb_nds); 1059914Samw@Sun.COM ndr_heap_destroy(nbuf->nb_heap); 1069914Samw@Sun.COM nbuf->nb_magic = 0; 1079914Samw@Sun.COM free(nbuf); 1089914Samw@Sun.COM } 1099914Samw@Sun.COM 1109914Samw@Sun.COM /* 1119914Samw@Sun.COM * Decode an NDR encoded buffer. The buffer is expected to contain 1129914Samw@Sun.COM * a single fragment packet with a valid PDU header followed by NDR 1139914Samw@Sun.COM * encoded data. The structure to which result points should be 1149914Samw@Sun.COM * of the appropriate type to hold the decoded output. For example: 1159914Samw@Sun.COM * 1169914Samw@Sun.COM * pac_info_t info; 1179914Samw@Sun.COM * 1189914Samw@Sun.COM * if ((nbuf = ndr_buf_init(&TYPEINFO(ndr_pac)) != NULL) { 1199914Samw@Sun.COM * rc = ndr_decode_buf(nbuf, opnum, data, datalen, &info); 1209914Samw@Sun.COM * ... 1219914Samw@Sun.COM * ndr_buf_fini(nbuf); 1229914Samw@Sun.COM * } 1239914Samw@Sun.COM */ 1249914Samw@Sun.COM int 1259914Samw@Sun.COM ndr_buf_decode(ndr_buf_t *nbuf, unsigned opnum, const char *data, 1269914Samw@Sun.COM size_t datalen, void *result) 1279914Samw@Sun.COM { 1289914Samw@Sun.COM ndr_common_header_t hdr; 1299914Samw@Sun.COM unsigned pdu_size_hint; 1309914Samw@Sun.COM int rc; 1319914Samw@Sun.COM 1329914Samw@Sun.COM assert(nbuf->nb_magic == NDR_BUF_MAGIC); 1339914Samw@Sun.COM assert(nbuf->nb_heap != NULL); 1349914Samw@Sun.COM assert(nbuf->nb_ti != NULL); 1359914Samw@Sun.COM 1369914Samw@Sun.COM if (datalen < NDR_PDU_SIZE_HINT_DEFAULT) 1379914Samw@Sun.COM pdu_size_hint = NDR_PDU_SIZE_HINT_DEFAULT; 1389914Samw@Sun.COM else 1399914Samw@Sun.COM pdu_size_hint = datalen; 1409914Samw@Sun.COM 14111337SWilliam.Krier@Sun.COM rc = nds_initialize(&nbuf->nb_nds, pdu_size_hint, NDR_MODE_BUF_DECODE, 1429914Samw@Sun.COM nbuf->nb_heap); 14311337SWilliam.Krier@Sun.COM if (NDR_DRC_IS_FAULT(rc)) 14411337SWilliam.Krier@Sun.COM return (rc); 14511337SWilliam.Krier@Sun.COM 1469914Samw@Sun.COM bcopy(data, nbuf->nb_nds.pdu_base_addr, datalen); 1479914Samw@Sun.COM 1489914Samw@Sun.COM rc = ndr_decode_hdr_common(&nbuf->nb_nds, &hdr); 1499914Samw@Sun.COM if (NDR_DRC_IS_FAULT(rc)) 1509914Samw@Sun.COM return (rc); 1519914Samw@Sun.COM 1529914Samw@Sun.COM if (!NDR_IS_SINGLE_FRAG(hdr.pfc_flags)) 15311337SWilliam.Krier@Sun.COM return (NDR_DRC_FAULT_DECODE_FAILED); 1549914Samw@Sun.COM 1559914Samw@Sun.COM rc = ndr_encode_decode_common(&nbuf->nb_nds, opnum, nbuf->nb_ti, 1569914Samw@Sun.COM result); 1579914Samw@Sun.COM return (rc); 1589914Samw@Sun.COM } 1599914Samw@Sun.COM 1609914Samw@Sun.COM /* 1619914Samw@Sun.COM * Use the receive stream to unmarshall data (NDR_MODE_CALL_RECV). 1629914Samw@Sun.COM */ 1635772Sas200622 int 1648334SJose.Borrego@Sun.COM ndr_decode_call(ndr_xa_t *mxa, void *params) 1655772Sas200622 { 1669914Samw@Sun.COM ndr_stream_t *nds = &mxa->recv_nds; 1679914Samw@Sun.COM int rc; 1685772Sas200622 1699914Samw@Sun.COM if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_RECV)) 1709914Samw@Sun.COM return (NDR_DRC_FAULT_MODE_MISMATCH); 1719914Samw@Sun.COM 1729914Samw@Sun.COM rc = ndr_encode_decode_common(nds, mxa->opnum, 1739914Samw@Sun.COM mxa->binding->service->interface_ti, params); 1745772Sas200622 1758334SJose.Borrego@Sun.COM return (rc + NDR_PTYPE_REQUEST); 1765772Sas200622 } 1775772Sas200622 1789914Samw@Sun.COM /* 1799914Samw@Sun.COM * Use the send stream to marshall data (NDR_MODE_RETURN_SEND). 1809914Samw@Sun.COM */ 1815772Sas200622 int 1828334SJose.Borrego@Sun.COM ndr_encode_return(ndr_xa_t *mxa, void *params) 1835772Sas200622 { 1849914Samw@Sun.COM ndr_stream_t *nds = &mxa->send_nds; 1859914Samw@Sun.COM int rc; 1865772Sas200622 1879914Samw@Sun.COM if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_SEND)) 1889914Samw@Sun.COM return (NDR_DRC_FAULT_MODE_MISMATCH); 1899914Samw@Sun.COM 1909914Samw@Sun.COM rc = ndr_encode_decode_common(nds, mxa->opnum, 1919914Samw@Sun.COM mxa->binding->service->interface_ti, params); 1925772Sas200622 1938334SJose.Borrego@Sun.COM return (rc + NDR_PTYPE_RESPONSE); 1945772Sas200622 } 1955772Sas200622 1969914Samw@Sun.COM /* 1979914Samw@Sun.COM * Use the send stream to marshall data (NDR_MODE_CALL_SEND). 1989914Samw@Sun.COM */ 1995772Sas200622 int 2008334SJose.Borrego@Sun.COM ndr_encode_call(ndr_xa_t *mxa, void *params) 2015772Sas200622 { 2029914Samw@Sun.COM ndr_stream_t *nds = &mxa->send_nds; 2039914Samw@Sun.COM int rc; 2045772Sas200622 2059914Samw@Sun.COM if (!NDR_MODE_MATCH(nds, NDR_MODE_CALL_SEND)) 2069914Samw@Sun.COM return (NDR_DRC_FAULT_MODE_MISMATCH); 2079914Samw@Sun.COM 2089914Samw@Sun.COM rc = ndr_encode_decode_common(nds, mxa->opnum, 2099914Samw@Sun.COM mxa->binding->service->interface_ti, params); 2105772Sas200622 2118334SJose.Borrego@Sun.COM return (rc + NDR_PTYPE_REQUEST); 2125772Sas200622 } 2135772Sas200622 2149914Samw@Sun.COM /* 2159914Samw@Sun.COM * Use the receive stream to unmarshall data (NDR_MODE_RETURN_RECV). 2169914Samw@Sun.COM */ 2175772Sas200622 int 2188334SJose.Borrego@Sun.COM ndr_decode_return(ndr_xa_t *mxa, void *params) 2195772Sas200622 { 2209914Samw@Sun.COM ndr_stream_t *nds = &mxa->recv_nds; 2219914Samw@Sun.COM int rc; 2225772Sas200622 2239914Samw@Sun.COM if (!NDR_MODE_MATCH(nds, NDR_MODE_RETURN_RECV)) 2249914Samw@Sun.COM return (NDR_DRC_FAULT_MODE_MISMATCH); 2259914Samw@Sun.COM 2269914Samw@Sun.COM rc = ndr_encode_decode_common(nds, mxa->opnum, 2279914Samw@Sun.COM mxa->binding->service->interface_ti, params); 2285772Sas200622 2298334SJose.Borrego@Sun.COM return (rc + NDR_PTYPE_RESPONSE); 2305772Sas200622 } 2315772Sas200622 2325772Sas200622 int 2338334SJose.Borrego@Sun.COM ndr_decode_pdu_hdr(ndr_xa_t *mxa) 2345772Sas200622 { 2358334SJose.Borrego@Sun.COM ndr_common_header_t *hdr = &mxa->recv_hdr.common_hdr; 2368334SJose.Borrego@Sun.COM ndr_stream_t *nds = &mxa->recv_nds; 2379914Samw@Sun.COM int rc; 2389914Samw@Sun.COM 2399914Samw@Sun.COM rc = ndr_decode_hdr_common(nds, hdr); 2409914Samw@Sun.COM if (NDR_DRC_IS_FAULT(rc)) 2419914Samw@Sun.COM return (rc); 2429914Samw@Sun.COM 2439914Samw@Sun.COM /* 2449914Samw@Sun.COM * Verify the protocol version. 2459914Samw@Sun.COM */ 2469914Samw@Sun.COM if ((hdr->rpc_vers != 5) || (hdr->rpc_vers_minor != 0)) 2479914Samw@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); 2489914Samw@Sun.COM 2499914Samw@Sun.COM mxa->ptype = hdr->ptype; 2509914Samw@Sun.COM return (NDR_DRC_OK); 2519914Samw@Sun.COM } 2529914Samw@Sun.COM 2539914Samw@Sun.COM static int 2549914Samw@Sun.COM ndr_decode_hdr_common(ndr_stream_t *nds, ndr_common_header_t *hdr) 2559914Samw@Sun.COM { 2565772Sas200622 int ptype; 2575772Sas200622 int rc; 2585772Sas200622 int charset; 2595772Sas200622 int byte_order; 2605772Sas200622 2618334SJose.Borrego@Sun.COM if (nds->m_op != NDR_M_OP_UNMARSHALL) 2628334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); 2635772Sas200622 2645772Sas200622 /* 2655772Sas200622 * All PDU headers are at least this big 2665772Sas200622 */ 2678334SJose.Borrego@Sun.COM rc = NDS_GROW_PDU(nds, sizeof (ndr_common_header_t), 0); 2685772Sas200622 if (!rc) 2698334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_RECEIVED_RUNT)); 2705772Sas200622 2715772Sas200622 /* 2725772Sas200622 * Peek at the first eight bytes to figure out what we're doing. 2735772Sas200622 */ 2748334SJose.Borrego@Sun.COM rc = NDS_GET_PDU(nds, 0, 8, (char *)hdr, 0, 0); 2755772Sas200622 if (!rc) 2768334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); 2775772Sas200622 2785772Sas200622 /* 2795772Sas200622 * Check for ASCII as the character set. This is an ASCII 2805772Sas200622 * versus EBCDIC option and has nothing to do with Unicode. 2815772Sas200622 */ 2828334SJose.Borrego@Sun.COM charset = hdr->packed_drep.intg_char_rep & NDR_REPLAB_CHAR_MASK; 2838334SJose.Borrego@Sun.COM if (charset != NDR_REPLAB_CHAR_ASCII) 2848334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_DECODE_FAILED)); 2855772Sas200622 2865772Sas200622 /* 2875772Sas200622 * Set the byte swap flag if the PDU byte-order 2885772Sas200622 * is different from the local byte-order. 2895772Sas200622 */ 2908334SJose.Borrego@Sun.COM byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK; 2918334SJose.Borrego@Sun.COM nds->swap = (byte_order != ndr_native_byte_order) ? 1 : 0; 2925772Sas200622 2935772Sas200622 ptype = hdr->ptype; 2948334SJose.Borrego@Sun.COM if (ptype == NDR_PTYPE_REQUEST && 2958334SJose.Borrego@Sun.COM (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) { 2968334SJose.Borrego@Sun.COM ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */ 2975772Sas200622 } 2985772Sas200622 2999914Samw@Sun.COM rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr); 3005772Sas200622 3018334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(rc)); 3025772Sas200622 } 3035772Sas200622 3045772Sas200622 /* 3058334SJose.Borrego@Sun.COM * Decode an RPC fragment header. Use ndr_decode_pdu_hdr() to process 3065772Sas200622 * the first fragment header then this function to process additional 3075772Sas200622 * fragment headers. 3085772Sas200622 */ 3095772Sas200622 void 3108334SJose.Borrego@Sun.COM ndr_decode_frag_hdr(ndr_stream_t *nds, ndr_common_header_t *hdr) 3115772Sas200622 { 3127619SJose.Borrego@Sun.COM ndr_common_header_t *tmp; 3135772Sas200622 uint8_t *pdu; 3145772Sas200622 int byte_order; 3155772Sas200622 3168334SJose.Borrego@Sun.COM pdu = (uint8_t *)nds->pdu_base_offset + nds->pdu_scan_offset; 3178334SJose.Borrego@Sun.COM bcopy(pdu, hdr, NDR_RSP_HDR_SIZE); 3185772Sas200622 3195772Sas200622 /* 3205772Sas200622 * Swap non-byte fields if the PDU byte-order 3215772Sas200622 * is different from the local byte-order. 3225772Sas200622 */ 3238334SJose.Borrego@Sun.COM byte_order = hdr->packed_drep.intg_char_rep & NDR_REPLAB_INTG_MASK; 3245772Sas200622 3258334SJose.Borrego@Sun.COM if (byte_order != ndr_native_byte_order) { 3265772Sas200622 /*LINTED E_BAD_PTR_CAST_ALIGN*/ 3277619SJose.Borrego@Sun.COM tmp = (ndr_common_header_t *)pdu; 3285772Sas200622 3298334SJose.Borrego@Sun.COM nds_bswap(&tmp->frag_length, &hdr->frag_length, 3305772Sas200622 sizeof (WORD)); 3318334SJose.Borrego@Sun.COM nds_bswap(&tmp->auth_length, &hdr->auth_length, 3325772Sas200622 sizeof (WORD)); 3338334SJose.Borrego@Sun.COM nds_bswap(&tmp->call_id, &hdr->call_id, sizeof (DWORD)); 3345772Sas200622 } 3355772Sas200622 } 3365772Sas200622 337*11963SAfshin.Ardakani@Sun.COM /* 338*11963SAfshin.Ardakani@Sun.COM * Remove an RPC fragment header from the received data stream. 339*11963SAfshin.Ardakani@Sun.COM * 340*11963SAfshin.Ardakani@Sun.COM * NDR stream on entry: 341*11963SAfshin.Ardakani@Sun.COM * 342*11963SAfshin.Ardakani@Sun.COM * |<--- frag --->| 343*11963SAfshin.Ardakani@Sun.COM * +-----+--------+-----+--------+-----+---------+-----+ 344*11963SAfshin.Ardakani@Sun.COM * | hdr | data | hdr | data | hdr | data | ... | 345*11963SAfshin.Ardakani@Sun.COM * +-----+--------+-----+--------+-----+---------+-----+ 346*11963SAfshin.Ardakani@Sun.COM * <---- 347*11963SAfshin.Ardakani@Sun.COM * 348*11963SAfshin.Ardakani@Sun.COM * NDR stream on return: 349*11963SAfshin.Ardakani@Sun.COM * 350*11963SAfshin.Ardakani@Sun.COM * +-----+----------------+-----+---------+-----+ 351*11963SAfshin.Ardakani@Sun.COM * | hdr | data | hdr | data | ... | 352*11963SAfshin.Ardakani@Sun.COM * +-----+----------------+-----+---------+-----+ 353*11963SAfshin.Ardakani@Sun.COM */ 354*11963SAfshin.Ardakani@Sun.COM void 355*11963SAfshin.Ardakani@Sun.COM ndr_remove_frag_hdr(ndr_stream_t *nds) 356*11963SAfshin.Ardakani@Sun.COM { 357*11963SAfshin.Ardakani@Sun.COM char *hdr; 358*11963SAfshin.Ardakani@Sun.COM char *data; 359*11963SAfshin.Ardakani@Sun.COM int nbytes; 360*11963SAfshin.Ardakani@Sun.COM 361*11963SAfshin.Ardakani@Sun.COM hdr = (char *)nds->pdu_base_offset + nds->pdu_scan_offset; 362*11963SAfshin.Ardakani@Sun.COM data = hdr + NDR_RSP_HDR_SIZE; 363*11963SAfshin.Ardakani@Sun.COM nbytes = nds->pdu_size - nds->pdu_scan_offset - NDR_RSP_HDR_SIZE; 364*11963SAfshin.Ardakani@Sun.COM 365*11963SAfshin.Ardakani@Sun.COM bcopy(data, hdr, nbytes); 366*11963SAfshin.Ardakani@Sun.COM nds->pdu_size -= NDR_RSP_HDR_SIZE; 367*11963SAfshin.Ardakani@Sun.COM } 368*11963SAfshin.Ardakani@Sun.COM 36910475Samw@Sun.COM void 37010475Samw@Sun.COM ndr_show_hdr(ndr_common_header_t *hdr) 37110475Samw@Sun.COM { 37210475Samw@Sun.COM char *fragtype; 37310475Samw@Sun.COM 37410475Samw@Sun.COM if (hdr == NULL) { 37510475Samw@Sun.COM ndo_printf(NULL, NULL, "ndr hdr: <null>"); 37610475Samw@Sun.COM return; 37710475Samw@Sun.COM } 37810475Samw@Sun.COM 37910475Samw@Sun.COM if (NDR_IS_SINGLE_FRAG(hdr->pfc_flags)) 38010475Samw@Sun.COM fragtype = "single"; 38110475Samw@Sun.COM else if (NDR_IS_FIRST_FRAG(hdr->pfc_flags)) 38210475Samw@Sun.COM fragtype = "first"; 38310475Samw@Sun.COM else if (NDR_IS_LAST_FRAG(hdr->pfc_flags)) 38410475Samw@Sun.COM fragtype = "last"; 38510475Samw@Sun.COM else 38610475Samw@Sun.COM fragtype = "intermediate"; 38710475Samw@Sun.COM 38810475Samw@Sun.COM ndo_printf(NULL, NULL, 38910475Samw@Sun.COM "ndr hdr: %d.%d ptype=%d, %s frag (flags=0x%08x) len=%d", 39010475Samw@Sun.COM hdr->rpc_vers, hdr->rpc_vers_minor, hdr->ptype, 39110475Samw@Sun.COM fragtype, hdr->pfc_flags, hdr->frag_length); 39210475Samw@Sun.COM } 39310475Samw@Sun.COM 3945772Sas200622 int 3958334SJose.Borrego@Sun.COM ndr_encode_pdu_hdr(ndr_xa_t *mxa) 3965772Sas200622 { 3978334SJose.Borrego@Sun.COM ndr_common_header_t *hdr = &mxa->send_hdr.common_hdr; 3988334SJose.Borrego@Sun.COM ndr_stream_t *nds = &mxa->send_nds; 3995772Sas200622 int ptype; 4005772Sas200622 int rc; 4015772Sas200622 4028334SJose.Borrego@Sun.COM if (nds->m_op != NDR_M_OP_MARSHALL) 4038334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(NDR_DRC_FAULT_MODE_MISMATCH)); 4045772Sas200622 4055772Sas200622 ptype = hdr->ptype; 4068334SJose.Borrego@Sun.COM if (ptype == NDR_PTYPE_REQUEST && 4078334SJose.Borrego@Sun.COM (hdr->pfc_flags & NDR_PFC_OBJECT_UUID) != 0) { 4088334SJose.Borrego@Sun.COM ptype = NDR_PTYPE_REQUEST_WITH; /* fake for sizing */ 4095772Sas200622 } 4105772Sas200622 4119914Samw@Sun.COM rc = ndr_encode_decode_common(nds, ptype, &TYPEINFO(ndr_hdr), hdr); 4125772Sas200622 4138334SJose.Borrego@Sun.COM return (NDR_DRC_PTYPE_RPCHDR(rc)); 4145772Sas200622 } 4155772Sas200622 4165772Sas200622 /* 4175772Sas200622 * This is a hand-coded derivative of the automatically generated 4185772Sas200622 * (un)marshalling routine for bind_ack headers. bind_ack headers 4195772Sas200622 * have an interior conformant array, which is inconsistent with 4205772Sas200622 * IDL/NDR rules. 4215772Sas200622 */ 4225772Sas200622 extern struct ndr_typeinfo ndt__uchar; 4235772Sas200622 extern struct ndr_typeinfo ndt__ushort; 4245772Sas200622 extern struct ndr_typeinfo ndt__ulong; 4255772Sas200622 4268334SJose.Borrego@Sun.COM int ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref); 4278334SJose.Borrego@Sun.COM ndr_typeinfo_t ndt__ndr_bind_ack_hdr = { 4285772Sas200622 1, /* NDR version */ 4295772Sas200622 3, /* alignment */ 4305772Sas200622 NDR_F_STRUCT, /* flags */ 4318334SJose.Borrego@Sun.COM ndr__ndr_bind_ack_hdr, /* ndr_func */ 4325772Sas200622 68, /* pdu_size_fixed_part */ 4335772Sas200622 0, /* pdu_size_variable_part */ 4345772Sas200622 68, /* c_size_fixed_part */ 4355772Sas200622 0, /* c_size_variable_part */ 4365772Sas200622 }; 4375772Sas200622 4385772Sas200622 /* 4395772Sas200622 * [_no_reorder] 4405772Sas200622 */ 4415772Sas200622 int 4428334SJose.Borrego@Sun.COM ndr__ndr_bind_ack_hdr(ndr_ref_t *encl_ref) 4435772Sas200622 { 4448334SJose.Borrego@Sun.COM ndr_stream_t *nds = encl_ref->stream; 4457619SJose.Borrego@Sun.COM struct ndr_bind_ack_hdr *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/ 4467619SJose.Borrego@Sun.COM (struct ndr_bind_ack_hdr *)encl_ref->datum; 4478334SJose.Borrego@Sun.COM ndr_ref_t myref; 4485772Sas200622 unsigned long offset; 4495772Sas200622 4505772Sas200622 bzero(&myref, sizeof (myref)); 4515772Sas200622 myref.enclosing = encl_ref; 4525772Sas200622 myref.stream = encl_ref->stream; 4535772Sas200622 myref.packed_alignment = 0; 4545772Sas200622 4555772Sas200622 /* do all members in order */ 4567619SJose.Borrego@Sun.COM NDR_MEMBER(_ndr_common_header, common_hdr, 0UL); 4575772Sas200622 NDR_MEMBER(_ushort, max_xmit_frag, 16UL); 4585772Sas200622 NDR_MEMBER(_ushort, max_recv_frag, 18UL); 4595772Sas200622 NDR_MEMBER(_ulong, assoc_group_id, 20UL); 4605772Sas200622 4615772Sas200622 /* port any is the conformant culprit */ 4625772Sas200622 offset = 24UL; 4635772Sas200622 4648334SJose.Borrego@Sun.COM switch (nds->m_op) { 4655772Sas200622 case NDR_M_OP_MARSHALL: 4665772Sas200622 val->sec_addr.length = 4675772Sas200622 strlen((char *)val->sec_addr.port_spec) + 1; 4685772Sas200622 break; 4695772Sas200622 4705772Sas200622 case NDR_M_OP_UNMARSHALL: 4715772Sas200622 break; 4725772Sas200622 4735772Sas200622 default: 4745772Sas200622 NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID); 4755772Sas200622 return (0); 4765772Sas200622 } 4775772Sas200622 4785772Sas200622 NDR_MEMBER(_ushort, sec_addr.length, offset); 4795772Sas200622 NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec, 4805772Sas200622 offset+2UL, val->sec_addr.length); 4815772Sas200622 4825772Sas200622 offset += 2; 4835772Sas200622 offset += val->sec_addr.length; 4848334SJose.Borrego@Sun.COM offset += NDR_ALIGN4(offset); 4855772Sas200622 4868334SJose.Borrego@Sun.COM NDR_MEMBER(_ndr_p_result_list, p_result_list, offset); 4875772Sas200622 return (1); 4885772Sas200622 } 4895772Sas200622 4907619SJose.Borrego@Sun.COM /* 4917619SJose.Borrego@Sun.COM * Assume a single presentation context element in the result list. 4927619SJose.Borrego@Sun.COM */ 4935772Sas200622 unsigned 4948334SJose.Borrego@Sun.COM ndr_bind_ack_hdr_size(ndr_xa_t *mxa) 4955772Sas200622 { 4967619SJose.Borrego@Sun.COM ndr_bind_ack_hdr_t *bahdr = &mxa->send_hdr.bind_ack_hdr; 4975772Sas200622 unsigned offset; 4985772Sas200622 unsigned length; 4995772Sas200622 5005772Sas200622 /* port any is the conformant culprit */ 5015772Sas200622 offset = 24UL; 5025772Sas200622 5035772Sas200622 length = strlen((char *)bahdr->sec_addr.port_spec) + 1; 5045772Sas200622 5055772Sas200622 offset += 2; 5065772Sas200622 offset += length; 5078334SJose.Borrego@Sun.COM offset += NDR_ALIGN4(offset); 5088334SJose.Borrego@Sun.COM offset += sizeof (ndr_p_result_list_t); 5095772Sas200622 return (offset); 5105772Sas200622 } 5117619SJose.Borrego@Sun.COM 5127619SJose.Borrego@Sun.COM /* 5137619SJose.Borrego@Sun.COM * This is a hand-coded derivative of the automatically generated 5147619SJose.Borrego@Sun.COM * (un)marshalling routine for alter_context_rsp headers. 5157619SJose.Borrego@Sun.COM * Alter context response headers have an interior conformant array, 5167619SJose.Borrego@Sun.COM * which is inconsistent with IDL/NDR rules. 5177619SJose.Borrego@Sun.COM */ 5188334SJose.Borrego@Sun.COM int ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref); 5198334SJose.Borrego@Sun.COM ndr_typeinfo_t ndt__ndr_alter_context_rsp_hdr = { 5207619SJose.Borrego@Sun.COM 1, /* NDR version */ 5217619SJose.Borrego@Sun.COM 3, /* alignment */ 5227619SJose.Borrego@Sun.COM NDR_F_STRUCT, /* flags */ 5238334SJose.Borrego@Sun.COM ndr__ndr_alter_context_rsp_hdr, /* ndr_func */ 5247619SJose.Borrego@Sun.COM 56, /* pdu_size_fixed_part */ 5257619SJose.Borrego@Sun.COM 0, /* pdu_size_variable_part */ 5267619SJose.Borrego@Sun.COM 56, /* c_size_fixed_part */ 5277619SJose.Borrego@Sun.COM 0, /* c_size_variable_part */ 5287619SJose.Borrego@Sun.COM }; 5297619SJose.Borrego@Sun.COM 5307619SJose.Borrego@Sun.COM /* 5317619SJose.Borrego@Sun.COM * [_no_reorder] 5327619SJose.Borrego@Sun.COM */ 5337619SJose.Borrego@Sun.COM int 5348334SJose.Borrego@Sun.COM ndr__ndr_alter_context_rsp_hdr(ndr_ref_t *encl_ref) 5357619SJose.Borrego@Sun.COM { 5368334SJose.Borrego@Sun.COM ndr_stream_t *nds = encl_ref->stream; 5377619SJose.Borrego@Sun.COM ndr_alter_context_rsp_hdr_t *val = /*LINTED E_BAD_PTR_CAST_ALIGN*/ 5387619SJose.Borrego@Sun.COM (ndr_alter_context_rsp_hdr_t *)encl_ref->datum; 5398334SJose.Borrego@Sun.COM ndr_ref_t myref; 5407619SJose.Borrego@Sun.COM unsigned long offset; 5417619SJose.Borrego@Sun.COM 5427619SJose.Borrego@Sun.COM bzero(&myref, sizeof (myref)); 5437619SJose.Borrego@Sun.COM myref.enclosing = encl_ref; 5447619SJose.Borrego@Sun.COM myref.stream = encl_ref->stream; 5457619SJose.Borrego@Sun.COM myref.packed_alignment = 0; 5467619SJose.Borrego@Sun.COM 5477619SJose.Borrego@Sun.COM /* do all members in order */ 5487619SJose.Borrego@Sun.COM NDR_MEMBER(_ndr_common_header, common_hdr, 0UL); 5497619SJose.Borrego@Sun.COM NDR_MEMBER(_ushort, max_xmit_frag, 16UL); 5507619SJose.Borrego@Sun.COM NDR_MEMBER(_ushort, max_recv_frag, 18UL); 5517619SJose.Borrego@Sun.COM NDR_MEMBER(_ulong, assoc_group_id, 20UL); 5527619SJose.Borrego@Sun.COM 5537619SJose.Borrego@Sun.COM offset = 24UL; /* offset of sec_addr */ 5547619SJose.Borrego@Sun.COM 5558334SJose.Borrego@Sun.COM switch (nds->m_op) { 5567619SJose.Borrego@Sun.COM case NDR_M_OP_MARSHALL: 5577619SJose.Borrego@Sun.COM val->sec_addr.length = 0; 5587619SJose.Borrego@Sun.COM break; 5597619SJose.Borrego@Sun.COM 5607619SJose.Borrego@Sun.COM case NDR_M_OP_UNMARSHALL: 5617619SJose.Borrego@Sun.COM break; 5627619SJose.Borrego@Sun.COM 5637619SJose.Borrego@Sun.COM default: 5647619SJose.Borrego@Sun.COM NDR_SET_ERROR(encl_ref, NDR_ERR_M_OP_INVALID); 5657619SJose.Borrego@Sun.COM return (0); 5667619SJose.Borrego@Sun.COM } 5677619SJose.Borrego@Sun.COM 5687619SJose.Borrego@Sun.COM NDR_MEMBER(_ushort, sec_addr.length, offset); 5697619SJose.Borrego@Sun.COM NDR_MEMBER_ARR_WITH_DIMENSION(_uchar, sec_addr.port_spec, 5707619SJose.Borrego@Sun.COM offset+2UL, val->sec_addr.length); 5717619SJose.Borrego@Sun.COM 5727619SJose.Borrego@Sun.COM offset += 2; /* sizeof (sec_addr.length) */ 5738334SJose.Borrego@Sun.COM offset += NDR_ALIGN4(offset); 5747619SJose.Borrego@Sun.COM 5758334SJose.Borrego@Sun.COM NDR_MEMBER(_ndr_p_result_list, p_result_list, offset); 5767619SJose.Borrego@Sun.COM return (1); 5777619SJose.Borrego@Sun.COM } 5787619SJose.Borrego@Sun.COM 5797619SJose.Borrego@Sun.COM /* 5807619SJose.Borrego@Sun.COM * Assume a single presentation context element in the result list. 5817619SJose.Borrego@Sun.COM */ 5827619SJose.Borrego@Sun.COM unsigned 5838334SJose.Borrego@Sun.COM ndr_alter_context_rsp_hdr_size(void) 5847619SJose.Borrego@Sun.COM { 5857619SJose.Borrego@Sun.COM unsigned offset; 5867619SJose.Borrego@Sun.COM 5877619SJose.Borrego@Sun.COM offset = 24UL; /* offset of sec_addr */ 5887619SJose.Borrego@Sun.COM offset += 2; /* sizeof (sec_addr.length) */ 5898334SJose.Borrego@Sun.COM offset += NDR_ALIGN4(offset); 5908334SJose.Borrego@Sun.COM offset += sizeof (ndr_p_result_list_t); 5917619SJose.Borrego@Sun.COM return (offset); 5927619SJose.Borrego@Sun.COM } 593