15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 22*12065SKeyur.Desai@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 235331Samw */ 245331Samw 255331Samw #ifndef _LIBMLRPC_H 265331Samw #define _LIBMLRPC_H 275331Samw 287052Samw #include <sys/types.h> 298334SJose.Borrego@Sun.COM #include <sys/uio.h> 308334SJose.Borrego@Sun.COM #include <smbsrv/wintypes.h> 318334SJose.Borrego@Sun.COM #include <smbsrv/ndr.h> 328334SJose.Borrego@Sun.COM #include <smbsrv/smb_sid.h> 338334SJose.Borrego@Sun.COM #include <smbsrv/smb_xdr.h> 347052Samw 355331Samw #ifdef __cplusplus 365331Samw extern "C" { 375331Samw #endif 385331Samw 398334SJose.Borrego@Sun.COM /* 408334SJose.Borrego@Sun.COM * An MSRPC compatible implementation of OSF DCE RPC. DCE RPC is derived 418334SJose.Borrego@Sun.COM * from the Apollo Network Computing Architecture (NCA) RPC implementation. 428334SJose.Borrego@Sun.COM * 438334SJose.Borrego@Sun.COM * CAE Specification (1997) 448334SJose.Borrego@Sun.COM * DCE 1.1: Remote Procedure Call 458334SJose.Borrego@Sun.COM * Document Number: C706 468334SJose.Borrego@Sun.COM * The Open Group 478334SJose.Borrego@Sun.COM * ogspecs@opengroup.org 488334SJose.Borrego@Sun.COM * 498334SJose.Borrego@Sun.COM * This implementation is based on the DCE Remote Procedure Call spec with 508334SJose.Borrego@Sun.COM * enhancements to support Unicode strings. The diagram below shows the 518334SJose.Borrego@Sun.COM * DCE RPC layers compared against ONC SUN RPC. 528334SJose.Borrego@Sun.COM * 538334SJose.Borrego@Sun.COM * NDR RPC Layers Sun RPC Layers Remark 548334SJose.Borrego@Sun.COM * +---------------+ +---------------+ +---------------+ 558334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 568334SJose.Borrego@Sun.COM * | Application | | Application | The application 578334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 588334SJose.Borrego@Sun.COM * | Hand coded | | RPCGEN gen'd | Where the real 598334SJose.Borrego@Sun.COM * | client/server | | client/server | work happens 608334SJose.Borrego@Sun.COM * | srvsvc.ndl | | *_svc.c *_clnt| 618334SJose.Borrego@Sun.COM * | srvsvc.c | | | 628334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 638334SJose.Borrego@Sun.COM * | RPC Library | | RPC Library | Calls/Return 648334SJose.Borrego@Sun.COM * | ndr_*.c | | | Binding/PMAP 658334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 668334SJose.Borrego@Sun.COM * | RPC Protocol | | RPC Protocol | Headers, Auth, 678334SJose.Borrego@Sun.COM * | rpcpdu.ndl | | | 688334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 698334SJose.Borrego@Sun.COM * | IDL gen'd | | RPCGEN gen'd | Aggregate 708334SJose.Borrego@Sun.COM * | NDR stubs | | XDR stubs | Composition 718334SJose.Borrego@Sun.COM * | *__ndr.c | | *_xdr.c | 728334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 738334SJose.Borrego@Sun.COM * | NDR Represen | | XDR Represen | Byte order, padding 748334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 758334SJose.Borrego@Sun.COM * | Packet Heaps | | Network Conn | DCERPC does not talk 768334SJose.Borrego@Sun.COM * | ndo_*.c | | clnt_{tcp,udp}| directly to network. 778334SJose.Borrego@Sun.COM * +---------------+ +---------------+ 788334SJose.Borrego@Sun.COM * 798334SJose.Borrego@Sun.COM * There are two major differences between the DCE RPC and ONC RPC: 808334SJose.Borrego@Sun.COM * 818334SJose.Borrego@Sun.COM * 1. NDR RPC only generates or processes packets from buffers. Other 828334SJose.Borrego@Sun.COM * layers must take care of packet transmission and reception. 838334SJose.Borrego@Sun.COM * The packet heaps are managed through a simple interface provided 848334SJose.Borrego@Sun.COM * by the Network Data Representation (NDR) module called ndr_stream_t. 858334SJose.Borrego@Sun.COM * ndo_*.c modules implement the different flavors (operations) of 868334SJose.Borrego@Sun.COM * packet heaps. 878334SJose.Borrego@Sun.COM * 888334SJose.Borrego@Sun.COM * ONC RPC communicates directly with the network. You have to do 898334SJose.Borrego@Sun.COM * something special for the RPC packet to be placed in a buffer 908334SJose.Borrego@Sun.COM * rather than sent to the wire. 918334SJose.Borrego@Sun.COM * 928334SJose.Borrego@Sun.COM * 2. NDR RPC uses application provided heaps to support operations. 938334SJose.Borrego@Sun.COM * A heap is a single, monolithic chunk of memory that NDR RPC manages 948334SJose.Borrego@Sun.COM * as it allocates. When the operation and its result are done, the 958334SJose.Borrego@Sun.COM * heap is disposed of as a single item. The transaction, which 968334SJose.Borrego@Sun.COM * is the anchor of most operations, contains the necessary book- 978334SJose.Borrego@Sun.COM * keeping for the heap. 988334SJose.Borrego@Sun.COM * 998334SJose.Borrego@Sun.COM * ONC RPC uses malloc() liberally throughout its run-time system. 1008334SJose.Borrego@Sun.COM * To free results, ONC RPC supports an XDR_FREE operation that 1018334SJose.Borrego@Sun.COM * traverses data structures freeing memory as it goes, whether 1028334SJose.Borrego@Sun.COM * it was malloc'd or not. 1038334SJose.Borrego@Sun.COM */ 1048334SJose.Borrego@Sun.COM 1058334SJose.Borrego@Sun.COM /* 1068334SJose.Borrego@Sun.COM * Dispatch Return Code (DRC) 1078334SJose.Borrego@Sun.COM * 1088334SJose.Borrego@Sun.COM * 0x8000 15:01 Set to indicate a fault, clear indicates status 1098334SJose.Borrego@Sun.COM * 0x7F00 08:07 Status/Fault specific 1108334SJose.Borrego@Sun.COM * 0x00FF 00:08 PTYPE_... of PDU, 0xFF for header 1118334SJose.Borrego@Sun.COM */ 1128334SJose.Borrego@Sun.COM #define NDR_DRC_OK 0x0000 1138334SJose.Borrego@Sun.COM #define NDR_DRC_MASK_FAULT 0x8000 1148334SJose.Borrego@Sun.COM #define NDR_DRC_MASK_SPECIFIER 0xFF00 1158334SJose.Borrego@Sun.COM #define NDR_DRC_MASK_PTYPE 0x00FF 1168334SJose.Borrego@Sun.COM 1178334SJose.Borrego@Sun.COM /* Fake PTYPE DRC discriminators */ 1188334SJose.Borrego@Sun.COM #define NDR_DRC_PTYPE_RPCHDR(DRC) ((DRC) | 0x00FF) 1198334SJose.Borrego@Sun.COM #define NDR_DRC_PTYPE_API(DRC) ((DRC) | 0x00AA) 1208334SJose.Borrego@Sun.COM 1218334SJose.Borrego@Sun.COM /* DRC Recognizers */ 1228334SJose.Borrego@Sun.COM #define NDR_DRC_IS_OK(DRC) (((DRC) & NDR_DRC_MASK_SPECIFIER) == 0) 1238334SJose.Borrego@Sun.COM #define NDR_DRC_IS_FAULT(DRC) (((DRC) & NDR_DRC_MASK_FAULT) != 0) 1248334SJose.Borrego@Sun.COM 1258334SJose.Borrego@Sun.COM /* 1268334SJose.Borrego@Sun.COM * (Un)Marshalling category specifiers 1278334SJose.Borrego@Sun.COM */ 1288334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_MODE_MISMATCH 0x8100 1298334SJose.Borrego@Sun.COM #define NDR_DRC_RECEIVED 0x0200 1308334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RECEIVED_RUNT 0x8300 1318334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RECEIVED_MALFORMED 0x8400 1328334SJose.Borrego@Sun.COM #define NDR_DRC_DECODED 0x0500 1338334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_DECODE_FAILED 0x8600 1348334SJose.Borrego@Sun.COM #define NDR_DRC_ENCODED 0x0700 1358334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_ENCODE_FAILED 0x8800 1368334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_ENCODE_TOO_BIG 0x8900 1378334SJose.Borrego@Sun.COM #define NDR_DRC_SENT 0x0A00 1388334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_SEND_FAILED 0x8B00 1398334SJose.Borrego@Sun.COM 1408334SJose.Borrego@Sun.COM /* 1418334SJose.Borrego@Sun.COM * Resource category specifier 1428334SJose.Borrego@Sun.COM */ 1438334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RESOURCE_1 0x9100 1448334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RESOURCE_2 0x9200 1458334SJose.Borrego@Sun.COM 1468334SJose.Borrego@Sun.COM /* 1478334SJose.Borrego@Sun.COM * Parameters. Usually #define'd with useful alias 1488334SJose.Borrego@Sun.COM */ 1498334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_0_INVALID 0xC000 1508334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED 0xD000 1518334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_1_INVALID 0xC100 1528334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED 0xD100 1538334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_2_INVALID 0xC200 1548334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED 0xD200 1558334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_3_INVALID 0xC300 1568334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED 0xD300 1578334SJose.Borrego@Sun.COM 1588334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 1598334SJose.Borrego@Sun.COM 1608334SJose.Borrego@Sun.COM /* RPCHDR */ 161*12065SKeyur.Desai@Sun.COM #define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF 162*12065SKeyur.Desai@Sun.COM #define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF 163*12065SKeyur.Desai@Sun.COM #define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF 1648334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ 165*12065SKeyur.Desai@Sun.COM #define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ 1668334SJose.Borrego@Sun.COM 1678334SJose.Borrego@Sun.COM /* Request */ 1688334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */ 1698334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */ 1708334SJose.Borrego@Sun.COM 1718334SJose.Borrego@Sun.COM /* Bind */ 172*12065SKeyur.Desai@Sun.COM #define NDR_DRC_BINDING_MADE 0x000B /* OK */ 1738334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */ 1748334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */ 1758334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */ 1768334SJose.Borrego@Sun.COM 1778334SJose.Borrego@Sun.COM /* API */ 1788334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */ 1798334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA /* RESOURCE_1 */ 1808334SJose.Borrego@Sun.COM #define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA /* PARAM_1_INVALID */ 1818334SJose.Borrego@Sun.COM 1828334SJose.Borrego@Sun.COM struct ndr_xa; 1838334SJose.Borrego@Sun.COM struct ndr_client; 1848334SJose.Borrego@Sun.COM 1858334SJose.Borrego@Sun.COM typedef struct ndr_stub_table { 1868334SJose.Borrego@Sun.COM int (*func)(void *, struct ndr_xa *); 1878334SJose.Borrego@Sun.COM unsigned short opnum; 1888334SJose.Borrego@Sun.COM } ndr_stub_table_t; 1898334SJose.Borrego@Sun.COM 1908334SJose.Borrego@Sun.COM typedef struct ndr_service { 1918334SJose.Borrego@Sun.COM char *name; 1928334SJose.Borrego@Sun.COM char *desc; 1938334SJose.Borrego@Sun.COM char *endpoint; 1948334SJose.Borrego@Sun.COM char *sec_addr_port; 1958334SJose.Borrego@Sun.COM char *abstract_syntax_uuid; 1968334SJose.Borrego@Sun.COM int abstract_syntax_version; 1978334SJose.Borrego@Sun.COM char *transfer_syntax_uuid; 1988334SJose.Borrego@Sun.COM int transfer_syntax_version; 1998334SJose.Borrego@Sun.COM unsigned bind_instance_size; 2008334SJose.Borrego@Sun.COM int (*bind_req)(); 2018334SJose.Borrego@Sun.COM int (*unbind_and_close)(); 2028334SJose.Borrego@Sun.COM int (*call_stub)(struct ndr_xa *); 2038334SJose.Borrego@Sun.COM ndr_typeinfo_t *interface_ti; 2048334SJose.Borrego@Sun.COM ndr_stub_table_t *stub_table; 2058334SJose.Borrego@Sun.COM } ndr_service_t; 2068334SJose.Borrego@Sun.COM 2078334SJose.Borrego@Sun.COM /* 2088334SJose.Borrego@Sun.COM * The list of bindings is anchored at a connection. Nothing in the 2098334SJose.Borrego@Sun.COM * RPC mechanism allocates them. Binding elements which have service==0 2108334SJose.Borrego@Sun.COM * indicate free elements. When a connection is instantiated, at least 2118334SJose.Borrego@Sun.COM * one free binding entry should also be established. Something like 2128334SJose.Borrego@Sun.COM * this should suffice for most (all) situations: 2138334SJose.Borrego@Sun.COM * 2148334SJose.Borrego@Sun.COM * struct connection { 2158334SJose.Borrego@Sun.COM * .... 2168334SJose.Borrego@Sun.COM * ndr_binding_t *binding_list_head; 2178334SJose.Borrego@Sun.COM * ndr_binding_t binding_pool[N_BINDING_POOL]; 2188334SJose.Borrego@Sun.COM * .... 2198334SJose.Borrego@Sun.COM * }; 2208334SJose.Borrego@Sun.COM * 2218334SJose.Borrego@Sun.COM * init_connection(struct connection *conn) { 2228334SJose.Borrego@Sun.COM * .... 2238334SJose.Borrego@Sun.COM * ndr_svc_binding_pool_init(&conn->binding_list_head, 2248334SJose.Borrego@Sun.COM * conn->binding_pool, N_BINDING_POOL); 2258334SJose.Borrego@Sun.COM */ 2268334SJose.Borrego@Sun.COM typedef struct ndr_binding { 2278334SJose.Borrego@Sun.COM struct ndr_binding *next; 2288334SJose.Borrego@Sun.COM ndr_p_context_id_t p_cont_id; 2298334SJose.Borrego@Sun.COM unsigned char which_side; 2308334SJose.Borrego@Sun.COM struct ndr_client *clnt; 2318334SJose.Borrego@Sun.COM ndr_service_t *service; 2328334SJose.Borrego@Sun.COM void *instance_specific; 2338334SJose.Borrego@Sun.COM } ndr_binding_t; 2348334SJose.Borrego@Sun.COM 2358334SJose.Borrego@Sun.COM #define NDR_BIND_SIDE_CLIENT 1 2368334SJose.Borrego@Sun.COM #define NDR_BIND_SIDE_SERVER 2 2378334SJose.Borrego@Sun.COM 2388334SJose.Borrego@Sun.COM #define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \ 2398334SJose.Borrego@Sun.COM ((TYPE *) (BINDING)->instance_specific) 2408334SJose.Borrego@Sun.COM 2418334SJose.Borrego@Sun.COM /* 2428334SJose.Borrego@Sun.COM * The binding list space must be provided by the application library 2438334SJose.Borrego@Sun.COM * for use by the underlying RPC library. We need at least two binding 2448334SJose.Borrego@Sun.COM * slots per connection. 2458334SJose.Borrego@Sun.COM */ 2468334SJose.Borrego@Sun.COM #define NDR_N_BINDING_POOL 2 2478334SJose.Borrego@Sun.COM 2488334SJose.Borrego@Sun.COM typedef struct ndr_pipe { 2498334SJose.Borrego@Sun.COM int np_fid; 25011963SAfshin.Ardakani@Sun.COM uint32_t np_txid; 25110122SJordan.Brown@Sun.COM smb_netuserinfo_t np_user; 2528334SJose.Borrego@Sun.COM char *np_buf; 2538334SJose.Borrego@Sun.COM struct uio np_uio; 2548334SJose.Borrego@Sun.COM iovec_t np_iov; 2558334SJose.Borrego@Sun.COM ndr_fraglist_t np_frags; 2568334SJose.Borrego@Sun.COM int np_refcnt; 2578334SJose.Borrego@Sun.COM uint16_t np_max_xmit_frag; 2588334SJose.Borrego@Sun.COM uint16_t np_max_recv_frag; 2598334SJose.Borrego@Sun.COM ndr_binding_t *np_binding; 2608334SJose.Borrego@Sun.COM ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL]; 2618334SJose.Borrego@Sun.COM } ndr_pipe_t; 2628334SJose.Borrego@Sun.COM 2638474SJose.Borrego@Sun.COM typedef struct ndr_pipe_info { 2648474SJose.Borrego@Sun.COM uint32_t npi_fid; 2658474SJose.Borrego@Sun.COM uint32_t npi_permissions; 2668474SJose.Borrego@Sun.COM uint32_t npi_num_locks; 2678474SJose.Borrego@Sun.COM char npi_pathname[MAXPATHLEN]; 2688474SJose.Borrego@Sun.COM char npi_username[MAXNAMELEN]; 2698474SJose.Borrego@Sun.COM } ndr_pipe_info_t; 2708474SJose.Borrego@Sun.COM 2718334SJose.Borrego@Sun.COM /* 2728334SJose.Borrego@Sun.COM * Number of bytes required to align SIZE on the next dword/4-byte 2738334SJose.Borrego@Sun.COM * boundary. 2748334SJose.Borrego@Sun.COM */ 2758334SJose.Borrego@Sun.COM #define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3); 2768334SJose.Borrego@Sun.COM 2778334SJose.Borrego@Sun.COM /* 2788334SJose.Borrego@Sun.COM * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying 2798334SJose.Borrego@Sun.COM * and conformant one-dimensional arrays. Characters can be single-byte 2808334SJose.Borrego@Sun.COM * or multi-byte as long as all characters conform to a fixed element size, 2818334SJose.Borrego@Sun.COM * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The 2828334SJose.Borrego@Sun.COM * string is terminated by a null character of the appropriate element size. 2838334SJose.Borrego@Sun.COM * 2848334SJose.Borrego@Sun.COM * MSRPC strings should always be varying/conformant and not null terminated. 2858334SJose.Borrego@Sun.COM * This format uses the size_is, first_is and length_is attributes (CAE 2868334SJose.Borrego@Sun.COM * section 4.2.18). 2878334SJose.Borrego@Sun.COM * 2888334SJose.Borrego@Sun.COM * typedef struct string { 2898334SJose.Borrego@Sun.COM * DWORD size_is; 2908334SJose.Borrego@Sun.COM * DWORD first_is; 2918334SJose.Borrego@Sun.COM * DWORD length_is; 2928334SJose.Borrego@Sun.COM * wchar_t string[ANY_SIZE_ARRAY]; 2938334SJose.Borrego@Sun.COM * } string_t; 2948334SJose.Borrego@Sun.COM * 2958334SJose.Borrego@Sun.COM * The size_is attribute is used to specify the number of data elements in 2968334SJose.Borrego@Sun.COM * each dimension of an array. 2978334SJose.Borrego@Sun.COM * 2988334SJose.Borrego@Sun.COM * The first_is attribute is used to define the lower bound for significant 2998334SJose.Borrego@Sun.COM * elements in each dimension of an array. For strings this is always 0. 3008334SJose.Borrego@Sun.COM * 3018334SJose.Borrego@Sun.COM * The length_is attribute is used to define the number of significant 3028334SJose.Borrego@Sun.COM * elements in each dimension of an array. For strings this is typically 3038334SJose.Borrego@Sun.COM * the same as size_is. Although it might be (size_is - 1) if the string 3048334SJose.Borrego@Sun.COM * is null terminated. 3058334SJose.Borrego@Sun.COM * 3068334SJose.Borrego@Sun.COM * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes 3078334SJose.Borrego@Sun.COM * +---------+---------+---------+------+------+------+------+ 3088334SJose.Borrego@Sun.COM * |size_is |first_is |length_is| char | char | char | char | 3098334SJose.Borrego@Sun.COM * +---------+---------+---------+------+------+------+------+ 3108334SJose.Borrego@Sun.COM * 3118334SJose.Borrego@Sun.COM * Unfortunately, not all MSRPC Unicode strings are null terminated, which 3128334SJose.Borrego@Sun.COM * means that the recipient has to manually null-terminate the string after 3138334SJose.Borrego@Sun.COM * it has been unmarshalled. There may be a wide-char pad following a 3148334SJose.Borrego@Sun.COM * string, and it may sometimes contains zero, but it's not guaranteed. 3158334SJose.Borrego@Sun.COM * 3168334SJose.Borrego@Sun.COM * To deal with this, MSRPC sometimes uses an additional wrapper with two 3178334SJose.Borrego@Sun.COM * more fields, as shown below. 3188334SJose.Borrego@Sun.COM * length: the array length in bytes excluding terminating null bytes 3198334SJose.Borrego@Sun.COM * maxlen: the array length in bytes including null terminator bytes 3208334SJose.Borrego@Sun.COM * LPTSTR: converted to a string_t by NDR 3218334SJose.Borrego@Sun.COM * 3228334SJose.Borrego@Sun.COM * typedef struct ms_string { 3238334SJose.Borrego@Sun.COM * WORD length; 3248334SJose.Borrego@Sun.COM * WORD maxlen; 3258334SJose.Borrego@Sun.COM * LPTSTR str; 3268334SJose.Borrego@Sun.COM * } ms_string_t; 3278334SJose.Borrego@Sun.COM */ 3288334SJose.Borrego@Sun.COM typedef struct ndr_mstring { 3298334SJose.Borrego@Sun.COM uint16_t length; 3308334SJose.Borrego@Sun.COM uint16_t allosize; 3318334SJose.Borrego@Sun.COM LPTSTR str; 3328334SJose.Borrego@Sun.COM } ndr_mstring_t; 3338334SJose.Borrego@Sun.COM 3348334SJose.Borrego@Sun.COM /* 3358334SJose.Borrego@Sun.COM * A number of heap areas are used during marshalling and unmarshalling. 3368334SJose.Borrego@Sun.COM * Under some circumstances these areas can be discarded by the library 3378334SJose.Borrego@Sun.COM * code, i.e. on the server side before returning to the client and on 3388334SJose.Borrego@Sun.COM * completion of a client side bind. In the case of a client side RPC 3398334SJose.Borrego@Sun.COM * call, these areas must be preserved after an RPC returns to give the 3408334SJose.Borrego@Sun.COM * caller time to take a copy of the data. In this case the client must 3418334SJose.Borrego@Sun.COM * call ndr_clnt_free_heap to free the memory. 3428334SJose.Borrego@Sun.COM * 3438334SJose.Borrego@Sun.COM * The heap management data definition looks a bit like this: 3448334SJose.Borrego@Sun.COM * 3458334SJose.Borrego@Sun.COM * heap -> +---------------+ +------------+ 3468334SJose.Borrego@Sun.COM * | iovec[0].base | --> | data block | 3478334SJose.Borrego@Sun.COM * | iovec[0].len | +------------+ 3488334SJose.Borrego@Sun.COM * +---------------+ 3498334SJose.Borrego@Sun.COM * :: 3508334SJose.Borrego@Sun.COM * :: 3518334SJose.Borrego@Sun.COM * iov -> +---------------+ +------------+ 3528334SJose.Borrego@Sun.COM * | iovec[n].base | --> | data block | 3538334SJose.Borrego@Sun.COM * | iovec[n].len | +------------+ 3548334SJose.Borrego@Sun.COM * +---------------+ ^ ^ 3558334SJose.Borrego@Sun.COM * | | 3568334SJose.Borrego@Sun.COM * next ----------------------+ | 3578334SJose.Borrego@Sun.COM * top -----------------------------------+ 3588334SJose.Borrego@Sun.COM * 3598334SJose.Borrego@Sun.COM */ 3608334SJose.Borrego@Sun.COM 3618334SJose.Borrego@Sun.COM /* 3628334SJose.Borrego@Sun.COM * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes 3638334SJose.Borrego@Sun.COM * of the first heap block. 3648334SJose.Borrego@Sun.COM */ 3658334SJose.Borrego@Sun.COM #define NDR_HEAP_MAXIOV 384 3668334SJose.Borrego@Sun.COM #define NDR_HEAP_BLKSZ 8192 3678334SJose.Borrego@Sun.COM 3688334SJose.Borrego@Sun.COM typedef struct ndr_heap { 3698334SJose.Borrego@Sun.COM struct iovec iovec[NDR_HEAP_MAXIOV]; 3708334SJose.Borrego@Sun.COM struct iovec *iov; 3718334SJose.Borrego@Sun.COM int iovcnt; 3728334SJose.Borrego@Sun.COM char *top; 3738334SJose.Borrego@Sun.COM char *next; 3748334SJose.Borrego@Sun.COM } ndr_heap_t; 3758334SJose.Borrego@Sun.COM 3768334SJose.Borrego@Sun.COM /* 3778334SJose.Borrego@Sun.COM * Alternate varying/conformant string definition 3788334SJose.Borrego@Sun.COM * - for non-null-terminated strings. 3798334SJose.Borrego@Sun.COM */ 3808334SJose.Borrego@Sun.COM typedef struct ndr_vcs { 3818334SJose.Borrego@Sun.COM /* 3828334SJose.Borrego@Sun.COM * size_is (actually a copy of length_is) will 3838334SJose.Borrego@Sun.COM * be inserted here by the marshalling library. 3848334SJose.Borrego@Sun.COM */ 3858334SJose.Borrego@Sun.COM uint32_t vc_first_is; 3868334SJose.Borrego@Sun.COM uint32_t vc_length_is; 3878334SJose.Borrego@Sun.COM uint16_t buffer[ANY_SIZE_ARRAY]; 3888334SJose.Borrego@Sun.COM } ndr_vcs_t; 3898334SJose.Borrego@Sun.COM 3908334SJose.Borrego@Sun.COM typedef struct ndr_vcstr { 3918334SJose.Borrego@Sun.COM uint16_t wclen; 3928334SJose.Borrego@Sun.COM uint16_t wcsize; 3938334SJose.Borrego@Sun.COM ndr_vcs_t *vcs; 3948334SJose.Borrego@Sun.COM } ndr_vcstr_t; 3958334SJose.Borrego@Sun.COM 3968334SJose.Borrego@Sun.COM typedef struct ndr_vcb { 3978334SJose.Borrego@Sun.COM /* 3988334SJose.Borrego@Sun.COM * size_is (actually a copy of length_is) will 3998334SJose.Borrego@Sun.COM * be inserted here by the marshalling library. 4008334SJose.Borrego@Sun.COM */ 4018334SJose.Borrego@Sun.COM uint32_t vc_first_is; 4028334SJose.Borrego@Sun.COM uint32_t vc_length_is; 4038334SJose.Borrego@Sun.COM uint8_t buffer[ANY_SIZE_ARRAY]; 4048334SJose.Borrego@Sun.COM } ndr_vcb_t; 4058334SJose.Borrego@Sun.COM 4068334SJose.Borrego@Sun.COM typedef struct ndr_vcbuf { 4078334SJose.Borrego@Sun.COM uint16_t len; 4088334SJose.Borrego@Sun.COM uint16_t size; 4098334SJose.Borrego@Sun.COM ndr_vcb_t *vcb; 4108334SJose.Borrego@Sun.COM } ndr_vcbuf_t; 4118334SJose.Borrego@Sun.COM 4128334SJose.Borrego@Sun.COM ndr_heap_t *ndr_heap_create(void); 4138334SJose.Borrego@Sun.COM void ndr_heap_destroy(ndr_heap_t *); 4148334SJose.Borrego@Sun.COM void *ndr_heap_malloc(ndr_heap_t *, unsigned); 4158334SJose.Borrego@Sun.COM void *ndr_heap_strdup(ndr_heap_t *, const char *); 4168334SJose.Borrego@Sun.COM int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *); 4178334SJose.Borrego@Sun.COM void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *); 4188334SJose.Borrego@Sun.COM void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *); 4198334SJose.Borrego@Sun.COM smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *); 4208334SJose.Borrego@Sun.COM int ndr_heap_used(ndr_heap_t *); 4218334SJose.Borrego@Sun.COM int ndr_heap_avail(ndr_heap_t *); 4228334SJose.Borrego@Sun.COM 4238334SJose.Borrego@Sun.COM #define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ) 4248334SJose.Borrego@Sun.COM #define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T)) 4258334SJose.Borrego@Sun.COM #define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N)) 4268334SJose.Borrego@Sun.COM #define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S)) 4278334SJose.Borrego@Sun.COM #define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT)) 4288334SJose.Borrego@Sun.COM #define NDR_SIDDUP(XA, S) ndr_heap_siddup((XA)->heap, (S)) 4298334SJose.Borrego@Sun.COM 4308334SJose.Borrego@Sun.COM typedef struct ndr_xa { 4318334SJose.Borrego@Sun.COM int fid; 4328334SJose.Borrego@Sun.COM unsigned short ptype; /* high bits special */ 4338334SJose.Borrego@Sun.COM unsigned short opnum; 4348334SJose.Borrego@Sun.COM ndr_stream_t recv_nds; 4358334SJose.Borrego@Sun.COM ndr_hdr_t recv_hdr; 4368334SJose.Borrego@Sun.COM ndr_stream_t send_nds; 4378334SJose.Borrego@Sun.COM ndr_hdr_t send_hdr; 4388334SJose.Borrego@Sun.COM ndr_binding_t *binding; /* what we're using */ 4398334SJose.Borrego@Sun.COM ndr_binding_t *binding_list; /* from connection */ 4408334SJose.Borrego@Sun.COM ndr_heap_t *heap; 4418334SJose.Borrego@Sun.COM ndr_pipe_t *pipe; 4428334SJose.Borrego@Sun.COM } ndr_xa_t; 4438334SJose.Borrego@Sun.COM 4448334SJose.Borrego@Sun.COM /* 4458334SJose.Borrego@Sun.COM * 20-byte opaque id used by various RPC services. 4468334SJose.Borrego@Sun.COM */ 4478334SJose.Borrego@Sun.COM CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t; 4488334SJose.Borrego@Sun.COM 4498334SJose.Borrego@Sun.COM typedef struct ndr_client { 4508334SJose.Borrego@Sun.COM int (*xa_init)(struct ndr_client *, ndr_xa_t *); 4518334SJose.Borrego@Sun.COM int (*xa_exchange)(struct ndr_client *, ndr_xa_t *); 4528334SJose.Borrego@Sun.COM int (*xa_read)(struct ndr_client *, ndr_xa_t *); 4538334SJose.Borrego@Sun.COM void (*xa_preserve)(struct ndr_client *, ndr_xa_t *); 4548334SJose.Borrego@Sun.COM void (*xa_destruct)(struct ndr_client *, ndr_xa_t *); 4558334SJose.Borrego@Sun.COM void (*xa_release)(struct ndr_client *); 4568334SJose.Borrego@Sun.COM 4578334SJose.Borrego@Sun.COM int fid; 4588334SJose.Borrego@Sun.COM ndr_hdid_t *handle; 4598334SJose.Borrego@Sun.COM ndr_binding_t *binding; 4608334SJose.Borrego@Sun.COM ndr_binding_t *binding_list; 4618334SJose.Borrego@Sun.COM ndr_binding_t binding_pool[NDR_N_BINDING_POOL]; 4628334SJose.Borrego@Sun.COM 46311337SWilliam.Krier@Sun.COM boolean_t nonull; 4648334SJose.Borrego@Sun.COM boolean_t heap_preserved; 4658334SJose.Borrego@Sun.COM ndr_heap_t *heap; 4668334SJose.Borrego@Sun.COM ndr_stream_t *recv_nds; 4678334SJose.Borrego@Sun.COM ndr_stream_t *send_nds; 4688334SJose.Borrego@Sun.COM 4698334SJose.Borrego@Sun.COM uint32_t next_call_id; 4708334SJose.Borrego@Sun.COM unsigned next_p_cont_id; 4718334SJose.Borrego@Sun.COM } ndr_client_t; 4728334SJose.Borrego@Sun.COM 4738334SJose.Borrego@Sun.COM typedef struct ndr_handle { 4748334SJose.Borrego@Sun.COM ndr_hdid_t nh_id; 4758334SJose.Borrego@Sun.COM struct ndr_handle *nh_next; 4768334SJose.Borrego@Sun.COM int nh_fid; 4778334SJose.Borrego@Sun.COM const ndr_service_t *nh_svc; 4788334SJose.Borrego@Sun.COM ndr_client_t *nh_clnt; 4798474SJose.Borrego@Sun.COM void *nh_data; 4808474SJose.Borrego@Sun.COM void (*nh_data_free)(void *); 4818334SJose.Borrego@Sun.COM } ndr_handle_t; 4828334SJose.Borrego@Sun.COM 4839914Samw@Sun.COM #define NDR_PDU_SIZE_HINT_DEFAULT (16*1024) 4849914Samw@Sun.COM #define NDR_BUF_MAGIC 0x4E425546 /* NBUF */ 4859914Samw@Sun.COM 4869914Samw@Sun.COM typedef struct ndr_buf { 4879914Samw@Sun.COM uint32_t nb_magic; 4889914Samw@Sun.COM ndr_stream_t nb_nds; 4899914Samw@Sun.COM ndr_heap_t *nb_heap; 4909914Samw@Sun.COM ndr_typeinfo_t *nb_ti; 4919914Samw@Sun.COM } ndr_buf_t; 4929914Samw@Sun.COM 4938334SJose.Borrego@Sun.COM /* ndr_ops.c */ 49411337SWilliam.Krier@Sun.COM int nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *); 4958334SJose.Borrego@Sun.COM void nds_finalize(ndr_stream_t *, ndr_fraglist_t *); 4968334SJose.Borrego@Sun.COM void nds_destruct(ndr_stream_t *); 49710475Samw@Sun.COM void nds_show_state(ndr_stream_t *); 4988334SJose.Borrego@Sun.COM 4998334SJose.Borrego@Sun.COM /* ndr_client.c */ 5008334SJose.Borrego@Sun.COM int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **); 5018334SJose.Borrego@Sun.COM int ndr_clnt_call(ndr_binding_t *, int, void *); 5028334SJose.Borrego@Sun.COM void ndr_clnt_free_heap(ndr_client_t *); 5038334SJose.Borrego@Sun.COM 5048334SJose.Borrego@Sun.COM /* ndr_marshal.c */ 5059914Samw@Sun.COM ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *); 5069914Samw@Sun.COM void ndr_buf_fini(ndr_buf_t *); 507*12065SKeyur.Desai@Sun.COM int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t, 508*12065SKeyur.Desai@Sun.COM void *); 5098334SJose.Borrego@Sun.COM int ndr_decode_call(ndr_xa_t *, void *); 5108334SJose.Borrego@Sun.COM int ndr_encode_return(ndr_xa_t *, void *); 5118334SJose.Borrego@Sun.COM int ndr_encode_call(ndr_xa_t *, void *); 5128334SJose.Borrego@Sun.COM int ndr_decode_return(ndr_xa_t *, void *); 5138334SJose.Borrego@Sun.COM int ndr_decode_pdu_hdr(ndr_xa_t *); 5148334SJose.Borrego@Sun.COM int ndr_encode_pdu_hdr(ndr_xa_t *); 5158334SJose.Borrego@Sun.COM void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *); 51611963SAfshin.Ardakani@Sun.COM void ndr_remove_frag_hdr(ndr_stream_t *); 51710475Samw@Sun.COM void ndr_show_hdr(ndr_common_header_t *); 5188334SJose.Borrego@Sun.COM unsigned ndr_bind_ack_hdr_size(ndr_xa_t *); 5198334SJose.Borrego@Sun.COM unsigned ndr_alter_context_rsp_hdr_size(void); 5208334SJose.Borrego@Sun.COM 5218334SJose.Borrego@Sun.COM /* ndr_server.c */ 5228334SJose.Borrego@Sun.COM int ndr_pipe_open(int, uint8_t *, uint32_t); 5238334SJose.Borrego@Sun.COM int ndr_pipe_close(int); 5248334SJose.Borrego@Sun.COM int ndr_pipe_read(int, uint8_t *, uint32_t *, uint32_t *); 5258334SJose.Borrego@Sun.COM int ndr_pipe_write(int, uint8_t *, uint32_t); 52611963SAfshin.Ardakani@Sun.COM void *ndr_pipe_transact(void *); 5278334SJose.Borrego@Sun.COM 5288334SJose.Borrego@Sun.COM int ndr_generic_call_stub(ndr_xa_t *); 5298334SJose.Borrego@Sun.COM 5308334SJose.Borrego@Sun.COM boolean_t ndr_is_admin(ndr_xa_t *); 5318334SJose.Borrego@Sun.COM boolean_t ndr_is_poweruser(ndr_xa_t *); 5328334SJose.Borrego@Sun.COM int32_t ndr_native_os(ndr_xa_t *); 5338334SJose.Borrego@Sun.COM 5348334SJose.Borrego@Sun.COM /* ndr_svc.c */ 5358334SJose.Borrego@Sun.COM ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int); 5368334SJose.Borrego@Sun.COM ndr_service_t *ndr_svc_lookup_name(const char *); 5378334SJose.Borrego@Sun.COM ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int); 5388334SJose.Borrego@Sun.COM int ndr_svc_register(ndr_service_t *); 5398334SJose.Borrego@Sun.COM void ndr_svc_unregister(ndr_service_t *); 5408334SJose.Borrego@Sun.COM void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int); 5418334SJose.Borrego@Sun.COM ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t); 5428334SJose.Borrego@Sun.COM ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *); 5438334SJose.Borrego@Sun.COM 5448334SJose.Borrego@Sun.COM int ndr_uuid_parse(char *, ndr_uuid_t *); 5458334SJose.Borrego@Sun.COM void ndr_uuid_unparse(ndr_uuid_t *, char *); 5468334SJose.Borrego@Sun.COM 5478334SJose.Borrego@Sun.COM ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *); 5488334SJose.Borrego@Sun.COM void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *); 5498334SJose.Borrego@Sun.COM ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *); 5508334SJose.Borrego@Sun.COM void ndr_hdclose(int fid); 5518334SJose.Borrego@Sun.COM 5528334SJose.Borrego@Sun.COM ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *); 5535331Samw 5545331Samw #ifdef __cplusplus 5555331Samw } 5565331Samw #endif 5575331Samw 5585331Samw #endif /* _LIBMLRPC_H */ 559