1da6c28aaSamw /* 2da6c28aaSamw * CDDL HEADER START 3da6c28aaSamw * 4da6c28aaSamw * The contents of this file are subject to the terms of the 5da6c28aaSamw * Common Development and Distribution License (the "License"). 6da6c28aaSamw * You may not use this file except in compliance with the License. 7da6c28aaSamw * 8da6c28aaSamw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9da6c28aaSamw * or http://www.opensolaris.org/os/licensing. 10da6c28aaSamw * See the License for the specific language governing permissions 11da6c28aaSamw * and limitations under the License. 12da6c28aaSamw * 13da6c28aaSamw * When distributing Covered Code, include this CDDL HEADER in each 14da6c28aaSamw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15da6c28aaSamw * If applicable, add the following below this CDDL HEADER, with the 16da6c28aaSamw * fields enclosed by brackets "[]" replaced with your own identifying 17da6c28aaSamw * information: Portions Copyright [yyyy] [name of copyright owner] 18da6c28aaSamw * 19da6c28aaSamw * CDDL HEADER END 20da6c28aaSamw */ 21da6c28aaSamw /* 22c5866007SKeyur Desai * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 2368b2bbf2SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 24da6c28aaSamw */ 25da6c28aaSamw 26da6c28aaSamw #ifndef _LIBMLRPC_H 27da6c28aaSamw #define _LIBMLRPC_H 28da6c28aaSamw 293db3f65cSamw #include <sys/types.h> 308d7e4166Sjose borrego #include <sys/uio.h> 31*3299f39fSGordon Ross 32*3299f39fSGordon Ross #include <smb/wintypes.h> 33*3299f39fSGordon Ross #include <libmlrpc/ndr.h> 343db3f65cSamw 35da6c28aaSamw #ifdef __cplusplus 36da6c28aaSamw extern "C" { 37da6c28aaSamw #endif 38da6c28aaSamw 398d7e4166Sjose borrego /* 408d7e4166Sjose borrego * An MSRPC compatible implementation of OSF DCE RPC. DCE RPC is derived 418d7e4166Sjose borrego * from the Apollo Network Computing Architecture (NCA) RPC implementation. 428d7e4166Sjose borrego * 438d7e4166Sjose borrego * CAE Specification (1997) 448d7e4166Sjose borrego * DCE 1.1: Remote Procedure Call 458d7e4166Sjose borrego * Document Number: C706 468d7e4166Sjose borrego * The Open Group 478d7e4166Sjose borrego * ogspecs@opengroup.org 488d7e4166Sjose borrego * 498d7e4166Sjose borrego * This implementation is based on the DCE Remote Procedure Call spec with 508d7e4166Sjose borrego * enhancements to support Unicode strings. The diagram below shows the 518d7e4166Sjose borrego * DCE RPC layers compared against ONC SUN RPC. 528d7e4166Sjose borrego * 538d7e4166Sjose borrego * NDR RPC Layers Sun RPC Layers Remark 548d7e4166Sjose borrego * +---------------+ +---------------+ +---------------+ 558d7e4166Sjose borrego * +---------------+ +---------------+ 568d7e4166Sjose borrego * | Application | | Application | The application 578d7e4166Sjose borrego * +---------------+ +---------------+ 588d7e4166Sjose borrego * | Hand coded | | RPCGEN gen'd | Where the real 598d7e4166Sjose borrego * | client/server | | client/server | work happens 608d7e4166Sjose borrego * | srvsvc.ndl | | *_svc.c *_clnt| 618d7e4166Sjose borrego * | srvsvc.c | | | 628d7e4166Sjose borrego * +---------------+ +---------------+ 638d7e4166Sjose borrego * | RPC Library | | RPC Library | Calls/Return 648d7e4166Sjose borrego * | ndr_*.c | | | Binding/PMAP 658d7e4166Sjose borrego * +---------------+ +---------------+ 668d7e4166Sjose borrego * | RPC Protocol | | RPC Protocol | Headers, Auth, 678d7e4166Sjose borrego * | rpcpdu.ndl | | | 688d7e4166Sjose borrego * +---------------+ +---------------+ 698d7e4166Sjose borrego * | IDL gen'd | | RPCGEN gen'd | Aggregate 708d7e4166Sjose borrego * | NDR stubs | | XDR stubs | Composition 718d7e4166Sjose borrego * | *__ndr.c | | *_xdr.c | 728d7e4166Sjose borrego * +---------------+ +---------------+ 738d7e4166Sjose borrego * | NDR Represen | | XDR Represen | Byte order, padding 748d7e4166Sjose borrego * +---------------+ +---------------+ 758d7e4166Sjose borrego * | Packet Heaps | | Network Conn | DCERPC does not talk 768d7e4166Sjose borrego * | ndo_*.c | | clnt_{tcp,udp}| directly to network. 778d7e4166Sjose borrego * +---------------+ +---------------+ 788d7e4166Sjose borrego * 798d7e4166Sjose borrego * There are two major differences between the DCE RPC and ONC RPC: 808d7e4166Sjose borrego * 818d7e4166Sjose borrego * 1. NDR RPC only generates or processes packets from buffers. Other 828d7e4166Sjose borrego * layers must take care of packet transmission and reception. 838d7e4166Sjose borrego * The packet heaps are managed through a simple interface provided 848d7e4166Sjose borrego * by the Network Data Representation (NDR) module called ndr_stream_t. 858d7e4166Sjose borrego * ndo_*.c modules implement the different flavors (operations) of 868d7e4166Sjose borrego * packet heaps. 878d7e4166Sjose borrego * 888d7e4166Sjose borrego * ONC RPC communicates directly with the network. You have to do 898d7e4166Sjose borrego * something special for the RPC packet to be placed in a buffer 908d7e4166Sjose borrego * rather than sent to the wire. 918d7e4166Sjose borrego * 928d7e4166Sjose borrego * 2. NDR RPC uses application provided heaps to support operations. 938d7e4166Sjose borrego * A heap is a single, monolithic chunk of memory that NDR RPC manages 948d7e4166Sjose borrego * as it allocates. When the operation and its result are done, the 958d7e4166Sjose borrego * heap is disposed of as a single item. The transaction, which 968d7e4166Sjose borrego * is the anchor of most operations, contains the necessary book- 978d7e4166Sjose borrego * keeping for the heap. 988d7e4166Sjose borrego * 998d7e4166Sjose borrego * ONC RPC uses malloc() liberally throughout its run-time system. 1008d7e4166Sjose borrego * To free results, ONC RPC supports an XDR_FREE operation that 1018d7e4166Sjose borrego * traverses data structures freeing memory as it goes, whether 1028d7e4166Sjose borrego * it was malloc'd or not. 1038d7e4166Sjose borrego */ 1048d7e4166Sjose borrego 1058d7e4166Sjose borrego /* 1068d7e4166Sjose borrego * Dispatch Return Code (DRC) 1078d7e4166Sjose borrego * 1088d7e4166Sjose borrego * 0x8000 15:01 Set to indicate a fault, clear indicates status 1098d7e4166Sjose borrego * 0x7F00 08:07 Status/Fault specific 1108d7e4166Sjose borrego * 0x00FF 00:08 PTYPE_... of PDU, 0xFF for header 1118d7e4166Sjose borrego */ 1128d7e4166Sjose borrego #define NDR_DRC_OK 0x0000 1138d7e4166Sjose borrego #define NDR_DRC_MASK_FAULT 0x8000 1148d7e4166Sjose borrego #define NDR_DRC_MASK_SPECIFIER 0xFF00 1158d7e4166Sjose borrego #define NDR_DRC_MASK_PTYPE 0x00FF 1168d7e4166Sjose borrego 1178d7e4166Sjose borrego /* Fake PTYPE DRC discriminators */ 1188d7e4166Sjose borrego #define NDR_DRC_PTYPE_RPCHDR(DRC) ((DRC) | 0x00FF) 1198d7e4166Sjose borrego #define NDR_DRC_PTYPE_API(DRC) ((DRC) | 0x00AA) 1208d7e4166Sjose borrego 1218d7e4166Sjose borrego /* DRC Recognizers */ 1228d7e4166Sjose borrego #define NDR_DRC_IS_OK(DRC) (((DRC) & NDR_DRC_MASK_SPECIFIER) == 0) 1238d7e4166Sjose borrego #define NDR_DRC_IS_FAULT(DRC) (((DRC) & NDR_DRC_MASK_FAULT) != 0) 1248d7e4166Sjose borrego 1258d7e4166Sjose borrego /* 1268d7e4166Sjose borrego * (Un)Marshalling category specifiers 1278d7e4166Sjose borrego */ 1288d7e4166Sjose borrego #define NDR_DRC_FAULT_MODE_MISMATCH 0x8100 1298d7e4166Sjose borrego #define NDR_DRC_RECEIVED 0x0200 1308d7e4166Sjose borrego #define NDR_DRC_FAULT_RECEIVED_RUNT 0x8300 1318d7e4166Sjose borrego #define NDR_DRC_FAULT_RECEIVED_MALFORMED 0x8400 1328d7e4166Sjose borrego #define NDR_DRC_DECODED 0x0500 1338d7e4166Sjose borrego #define NDR_DRC_FAULT_DECODE_FAILED 0x8600 1348d7e4166Sjose borrego #define NDR_DRC_ENCODED 0x0700 1358d7e4166Sjose borrego #define NDR_DRC_FAULT_ENCODE_FAILED 0x8800 1368d7e4166Sjose borrego #define NDR_DRC_FAULT_ENCODE_TOO_BIG 0x8900 1378d7e4166Sjose borrego #define NDR_DRC_SENT 0x0A00 1388d7e4166Sjose borrego #define NDR_DRC_FAULT_SEND_FAILED 0x8B00 1398d7e4166Sjose borrego 1408d7e4166Sjose borrego /* 1418d7e4166Sjose borrego * Resource category specifier 1428d7e4166Sjose borrego */ 1438d7e4166Sjose borrego #define NDR_DRC_FAULT_RESOURCE_1 0x9100 1448d7e4166Sjose borrego #define NDR_DRC_FAULT_RESOURCE_2 0x9200 1458d7e4166Sjose borrego 1468d7e4166Sjose borrego /* 1478d7e4166Sjose borrego * Parameters. Usually #define'd with useful alias 1488d7e4166Sjose borrego */ 1498d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_0_INVALID 0xC000 1508d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED 0xD000 1518d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_1_INVALID 0xC100 1528d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED 0xD100 1538d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_2_INVALID 0xC200 1548d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED 0xD200 1558d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_3_INVALID 0xC300 1568d7e4166Sjose borrego #define NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED 0xD300 1578d7e4166Sjose borrego 1588d7e4166Sjose borrego #define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 1598d7e4166Sjose borrego 1608d7e4166Sjose borrego /* RPCHDR */ 161c5866007SKeyur Desai #define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF 162c5866007SKeyur Desai #define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF 163c5866007SKeyur Desai #define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF 1648d7e4166Sjose borrego #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ 165c5866007SKeyur Desai #define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ 1668d7e4166Sjose borrego 1678d7e4166Sjose borrego /* Request */ 1688d7e4166Sjose borrego #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */ 1698d7e4166Sjose borrego #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */ 1708d7e4166Sjose borrego 1718d7e4166Sjose borrego /* Bind */ 172c5866007SKeyur Desai #define NDR_DRC_BINDING_MADE 0x000B /* OK */ 1738d7e4166Sjose borrego #define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */ 1748d7e4166Sjose borrego #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */ 1758d7e4166Sjose borrego #define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */ 1768d7e4166Sjose borrego 1778d7e4166Sjose borrego /* API */ 1788d7e4166Sjose borrego #define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */ 1798d7e4166Sjose borrego #define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA /* RESOURCE_1 */ 1808d7e4166Sjose borrego #define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA /* PARAM_1_INVALID */ 1818d7e4166Sjose borrego 1828d7e4166Sjose borrego struct ndr_xa; 1838d7e4166Sjose borrego struct ndr_client; 1848d7e4166Sjose borrego 1858d7e4166Sjose borrego typedef struct ndr_stub_table { 1868d7e4166Sjose borrego int (*func)(void *, struct ndr_xa *); 1878d7e4166Sjose borrego unsigned short opnum; 1888d7e4166Sjose borrego } ndr_stub_table_t; 1898d7e4166Sjose borrego 1908d7e4166Sjose borrego typedef struct ndr_service { 1918d7e4166Sjose borrego char *name; 1928d7e4166Sjose borrego char *desc; 1938d7e4166Sjose borrego char *endpoint; 1948d7e4166Sjose borrego char *sec_addr_port; 1958d7e4166Sjose borrego char *abstract_syntax_uuid; 1968d7e4166Sjose borrego int abstract_syntax_version; 1978d7e4166Sjose borrego char *transfer_syntax_uuid; 1988d7e4166Sjose borrego int transfer_syntax_version; 1998d7e4166Sjose borrego unsigned bind_instance_size; 2008d7e4166Sjose borrego int (*bind_req)(); 2018d7e4166Sjose borrego int (*unbind_and_close)(); 2028d7e4166Sjose borrego int (*call_stub)(struct ndr_xa *); 2038d7e4166Sjose borrego ndr_typeinfo_t *interface_ti; 2048d7e4166Sjose borrego ndr_stub_table_t *stub_table; 2058d7e4166Sjose borrego } ndr_service_t; 2068d7e4166Sjose borrego 2078d7e4166Sjose borrego /* 2088d7e4166Sjose borrego * The list of bindings is anchored at a connection. Nothing in the 2098d7e4166Sjose borrego * RPC mechanism allocates them. Binding elements which have service==0 2108d7e4166Sjose borrego * indicate free elements. When a connection is instantiated, at least 2118d7e4166Sjose borrego * one free binding entry should also be established. Something like 2128d7e4166Sjose borrego * this should suffice for most (all) situations: 2138d7e4166Sjose borrego * 2148d7e4166Sjose borrego * struct connection { 2158d7e4166Sjose borrego * .... 2168d7e4166Sjose borrego * ndr_binding_t *binding_list_head; 2178d7e4166Sjose borrego * ndr_binding_t binding_pool[N_BINDING_POOL]; 2188d7e4166Sjose borrego * .... 2198d7e4166Sjose borrego * }; 2208d7e4166Sjose borrego * 2218d7e4166Sjose borrego * init_connection(struct connection *conn) { 2228d7e4166Sjose borrego * .... 2238d7e4166Sjose borrego * ndr_svc_binding_pool_init(&conn->binding_list_head, 2248d7e4166Sjose borrego * conn->binding_pool, N_BINDING_POOL); 2258d7e4166Sjose borrego */ 2268d7e4166Sjose borrego typedef struct ndr_binding { 2278d7e4166Sjose borrego struct ndr_binding *next; 2288d7e4166Sjose borrego ndr_p_context_id_t p_cont_id; 2298d7e4166Sjose borrego unsigned char which_side; 2308d7e4166Sjose borrego struct ndr_client *clnt; 2318d7e4166Sjose borrego ndr_service_t *service; 2328d7e4166Sjose borrego void *instance_specific; 2338d7e4166Sjose borrego } ndr_binding_t; 2348d7e4166Sjose borrego 2358d7e4166Sjose borrego #define NDR_BIND_SIDE_CLIENT 1 2368d7e4166Sjose borrego #define NDR_BIND_SIDE_SERVER 2 2378d7e4166Sjose borrego 2388d7e4166Sjose borrego #define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \ 2398d7e4166Sjose borrego ((TYPE *) (BINDING)->instance_specific) 2408d7e4166Sjose borrego 2418d7e4166Sjose borrego /* 2428d7e4166Sjose borrego * The binding list space must be provided by the application library 2438d7e4166Sjose borrego * for use by the underlying RPC library. We need at least two binding 2448d7e4166Sjose borrego * slots per connection. 2458d7e4166Sjose borrego */ 2468d7e4166Sjose borrego #define NDR_N_BINDING_POOL 2 2478d7e4166Sjose borrego 2488d7e4166Sjose borrego typedef struct ndr_pipe { 249*3299f39fSGordon Ross void *np_listener; 25068b2bbf2SGordon Ross const char *np_endpoint; 251*3299f39fSGordon Ross struct smb_netuserinfo *np_user; 25268b2bbf2SGordon Ross int (*np_send)(struct ndr_pipe *, void *, size_t); 25368b2bbf2SGordon Ross int (*np_recv)(struct ndr_pipe *, void *, size_t); 2548d7e4166Sjose borrego int np_fid; 2558d7e4166Sjose borrego uint16_t np_max_xmit_frag; 2568d7e4166Sjose borrego uint16_t np_max_recv_frag; 2578d7e4166Sjose borrego ndr_binding_t *np_binding; 2588d7e4166Sjose borrego ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL]; 2598d7e4166Sjose borrego } ndr_pipe_t; 2608d7e4166Sjose borrego 2618d7e4166Sjose borrego /* 2628d7e4166Sjose borrego * Number of bytes required to align SIZE on the next dword/4-byte 2638d7e4166Sjose borrego * boundary. 2648d7e4166Sjose borrego */ 2658d7e4166Sjose borrego #define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3); 2668d7e4166Sjose borrego 2678d7e4166Sjose borrego /* 2688d7e4166Sjose borrego * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying 2698d7e4166Sjose borrego * and conformant one-dimensional arrays. Characters can be single-byte 2708d7e4166Sjose borrego * or multi-byte as long as all characters conform to a fixed element size, 2718d7e4166Sjose borrego * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The 2728d7e4166Sjose borrego * string is terminated by a null character of the appropriate element size. 2738d7e4166Sjose borrego * 2748d7e4166Sjose borrego * MSRPC strings should always be varying/conformant and not null terminated. 2758d7e4166Sjose borrego * This format uses the size_is, first_is and length_is attributes (CAE 2768d7e4166Sjose borrego * section 4.2.18). 2778d7e4166Sjose borrego * 2788d7e4166Sjose borrego * typedef struct string { 2798d7e4166Sjose borrego * DWORD size_is; 2808d7e4166Sjose borrego * DWORD first_is; 2818d7e4166Sjose borrego * DWORD length_is; 2828d7e4166Sjose borrego * wchar_t string[ANY_SIZE_ARRAY]; 2838d7e4166Sjose borrego * } string_t; 2848d7e4166Sjose borrego * 2858d7e4166Sjose borrego * The size_is attribute is used to specify the number of data elements in 2868d7e4166Sjose borrego * each dimension of an array. 2878d7e4166Sjose borrego * 2888d7e4166Sjose borrego * The first_is attribute is used to define the lower bound for significant 2898d7e4166Sjose borrego * elements in each dimension of an array. For strings this is always 0. 2908d7e4166Sjose borrego * 2918d7e4166Sjose borrego * The length_is attribute is used to define the number of significant 2928d7e4166Sjose borrego * elements in each dimension of an array. For strings this is typically 2938d7e4166Sjose borrego * the same as size_is. Although it might be (size_is - 1) if the string 2948d7e4166Sjose borrego * is null terminated. 2958d7e4166Sjose borrego * 2968d7e4166Sjose borrego * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes 2978d7e4166Sjose borrego * +---------+---------+---------+------+------+------+------+ 2988d7e4166Sjose borrego * |size_is |first_is |length_is| char | char | char | char | 2998d7e4166Sjose borrego * +---------+---------+---------+------+------+------+------+ 3008d7e4166Sjose borrego * 3018d7e4166Sjose borrego * Unfortunately, not all MSRPC Unicode strings are null terminated, which 3028d7e4166Sjose borrego * means that the recipient has to manually null-terminate the string after 3038d7e4166Sjose borrego * it has been unmarshalled. There may be a wide-char pad following a 3048d7e4166Sjose borrego * string, and it may sometimes contains zero, but it's not guaranteed. 3058d7e4166Sjose borrego * 3068d7e4166Sjose borrego * To deal with this, MSRPC sometimes uses an additional wrapper with two 3078d7e4166Sjose borrego * more fields, as shown below. 3088d7e4166Sjose borrego * length: the array length in bytes excluding terminating null bytes 3098d7e4166Sjose borrego * maxlen: the array length in bytes including null terminator bytes 3108d7e4166Sjose borrego * LPTSTR: converted to a string_t by NDR 3118d7e4166Sjose borrego * 3128d7e4166Sjose borrego * typedef struct ms_string { 3138d7e4166Sjose borrego * WORD length; 3148d7e4166Sjose borrego * WORD maxlen; 3158d7e4166Sjose borrego * LPTSTR str; 3168d7e4166Sjose borrego * } ms_string_t; 3178d7e4166Sjose borrego */ 3188d7e4166Sjose borrego typedef struct ndr_mstring { 3198d7e4166Sjose borrego uint16_t length; 3208d7e4166Sjose borrego uint16_t allosize; 3218d7e4166Sjose borrego LPTSTR str; 3228d7e4166Sjose borrego } ndr_mstring_t; 3238d7e4166Sjose borrego 3248d7e4166Sjose borrego /* 3258d7e4166Sjose borrego * A number of heap areas are used during marshalling and unmarshalling. 3268d7e4166Sjose borrego * Under some circumstances these areas can be discarded by the library 3278d7e4166Sjose borrego * code, i.e. on the server side before returning to the client and on 3288d7e4166Sjose borrego * completion of a client side bind. In the case of a client side RPC 3298d7e4166Sjose borrego * call, these areas must be preserved after an RPC returns to give the 3308d7e4166Sjose borrego * caller time to take a copy of the data. In this case the client must 3318d7e4166Sjose borrego * call ndr_clnt_free_heap to free the memory. 3328d7e4166Sjose borrego * 3338d7e4166Sjose borrego * The heap management data definition looks a bit like this: 3348d7e4166Sjose borrego * 3358d7e4166Sjose borrego * heap -> +---------------+ +------------+ 3368d7e4166Sjose borrego * | iovec[0].base | --> | data block | 3378d7e4166Sjose borrego * | iovec[0].len | +------------+ 3388d7e4166Sjose borrego * +---------------+ 3398d7e4166Sjose borrego * :: 3408d7e4166Sjose borrego * :: 3418d7e4166Sjose borrego * iov -> +---------------+ +------------+ 3428d7e4166Sjose borrego * | iovec[n].base | --> | data block | 3438d7e4166Sjose borrego * | iovec[n].len | +------------+ 3448d7e4166Sjose borrego * +---------------+ ^ ^ 3458d7e4166Sjose borrego * | | 3468d7e4166Sjose borrego * next ----------------------+ | 3478d7e4166Sjose borrego * top -----------------------------------+ 3488d7e4166Sjose borrego * 3498d7e4166Sjose borrego */ 3508d7e4166Sjose borrego 3518d7e4166Sjose borrego /* 3528d7e4166Sjose borrego * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes 3538d7e4166Sjose borrego * of the first heap block. 3548d7e4166Sjose borrego */ 3558d7e4166Sjose borrego #define NDR_HEAP_MAXIOV 384 3568d7e4166Sjose borrego #define NDR_HEAP_BLKSZ 8192 3578d7e4166Sjose borrego 3588d7e4166Sjose borrego typedef struct ndr_heap { 3598d7e4166Sjose borrego struct iovec iovec[NDR_HEAP_MAXIOV]; 3608d7e4166Sjose borrego struct iovec *iov; 3618d7e4166Sjose borrego int iovcnt; 3628d7e4166Sjose borrego char *top; 3638d7e4166Sjose borrego char *next; 3648d7e4166Sjose borrego } ndr_heap_t; 3658d7e4166Sjose borrego 3668d7e4166Sjose borrego /* 3678d7e4166Sjose borrego * Alternate varying/conformant string definition 3688d7e4166Sjose borrego * - for non-null-terminated strings. 3698d7e4166Sjose borrego */ 3708d7e4166Sjose borrego typedef struct ndr_vcs { 3718d7e4166Sjose borrego /* 3728d7e4166Sjose borrego * size_is (actually a copy of length_is) will 3738d7e4166Sjose borrego * be inserted here by the marshalling library. 3748d7e4166Sjose borrego */ 3758d7e4166Sjose borrego uint32_t vc_first_is; 3768d7e4166Sjose borrego uint32_t vc_length_is; 3778d7e4166Sjose borrego uint16_t buffer[ANY_SIZE_ARRAY]; 3788d7e4166Sjose borrego } ndr_vcs_t; 3798d7e4166Sjose borrego 3808d7e4166Sjose borrego typedef struct ndr_vcstr { 3818d7e4166Sjose borrego uint16_t wclen; 3828d7e4166Sjose borrego uint16_t wcsize; 3838d7e4166Sjose borrego ndr_vcs_t *vcs; 3848d7e4166Sjose borrego } ndr_vcstr_t; 3858d7e4166Sjose borrego 3868d7e4166Sjose borrego typedef struct ndr_vcb { 3878d7e4166Sjose borrego /* 3888d7e4166Sjose borrego * size_is (actually a copy of length_is) will 3898d7e4166Sjose borrego * be inserted here by the marshalling library. 3908d7e4166Sjose borrego */ 3918d7e4166Sjose borrego uint32_t vc_first_is; 3928d7e4166Sjose borrego uint32_t vc_length_is; 3938d7e4166Sjose borrego uint8_t buffer[ANY_SIZE_ARRAY]; 3948d7e4166Sjose borrego } ndr_vcb_t; 3958d7e4166Sjose borrego 3968d7e4166Sjose borrego typedef struct ndr_vcbuf { 3978d7e4166Sjose borrego uint16_t len; 3988d7e4166Sjose borrego uint16_t size; 3998d7e4166Sjose borrego ndr_vcb_t *vcb; 4008d7e4166Sjose borrego } ndr_vcbuf_t; 4018d7e4166Sjose borrego 4028d7e4166Sjose borrego ndr_heap_t *ndr_heap_create(void); 4038d7e4166Sjose borrego void ndr_heap_destroy(ndr_heap_t *); 404*3299f39fSGordon Ross void *ndr_heap_dupmem(ndr_heap_t *, const void *, size_t); 4058d7e4166Sjose borrego void *ndr_heap_malloc(ndr_heap_t *, unsigned); 4068d7e4166Sjose borrego void *ndr_heap_strdup(ndr_heap_t *, const char *); 4078d7e4166Sjose borrego int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *); 4088d7e4166Sjose borrego void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *); 4098d7e4166Sjose borrego void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *); 4108d7e4166Sjose borrego int ndr_heap_used(ndr_heap_t *); 4118d7e4166Sjose borrego int ndr_heap_avail(ndr_heap_t *); 4128d7e4166Sjose borrego 4138d7e4166Sjose borrego #define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ) 4148d7e4166Sjose borrego #define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T)) 4158d7e4166Sjose borrego #define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N)) 4168d7e4166Sjose borrego #define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S)) 4178d7e4166Sjose borrego #define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT)) 418*3299f39fSGordon Ross #define NDR_SIDDUP(XA, S) ndr_heap_dupmem((XA)->heap, (S), smb_sid_len(S)) 4198d7e4166Sjose borrego 4208d7e4166Sjose borrego typedef struct ndr_xa { 4218d7e4166Sjose borrego unsigned short ptype; /* high bits special */ 4228d7e4166Sjose borrego unsigned short opnum; 4238d7e4166Sjose borrego ndr_stream_t recv_nds; 4248d7e4166Sjose borrego ndr_hdr_t recv_hdr; 4258d7e4166Sjose borrego ndr_stream_t send_nds; 4268d7e4166Sjose borrego ndr_hdr_t send_hdr; 4278d7e4166Sjose borrego ndr_binding_t *binding; /* what we're using */ 4288d7e4166Sjose borrego ndr_binding_t *binding_list; /* from connection */ 4298d7e4166Sjose borrego ndr_heap_t *heap; 4308d7e4166Sjose borrego ndr_pipe_t *pipe; 4318d7e4166Sjose borrego } ndr_xa_t; 4328d7e4166Sjose borrego 4338d7e4166Sjose borrego /* 4348d7e4166Sjose borrego * 20-byte opaque id used by various RPC services. 4358d7e4166Sjose borrego */ 4368d7e4166Sjose borrego CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t; 4378d7e4166Sjose borrego 4388d7e4166Sjose borrego typedef struct ndr_client { 439ed9aabc7SGordon Ross /* transport stuff (xa_* members) */ 4408d7e4166Sjose borrego int (*xa_init)(struct ndr_client *, ndr_xa_t *); 4418d7e4166Sjose borrego int (*xa_exchange)(struct ndr_client *, ndr_xa_t *); 4428d7e4166Sjose borrego int (*xa_read)(struct ndr_client *, ndr_xa_t *); 4438d7e4166Sjose borrego void (*xa_preserve)(struct ndr_client *, ndr_xa_t *); 4448d7e4166Sjose borrego void (*xa_destruct)(struct ndr_client *, ndr_xa_t *); 4458d7e4166Sjose borrego void (*xa_release)(struct ndr_client *); 446ed9aabc7SGordon Ross void *xa_private; 447ed9aabc7SGordon Ross int xa_fd; 4488d7e4166Sjose borrego 4498d7e4166Sjose borrego ndr_hdid_t *handle; 4508d7e4166Sjose borrego ndr_binding_t *binding; 4518d7e4166Sjose borrego ndr_binding_t *binding_list; 4528d7e4166Sjose borrego ndr_binding_t binding_pool[NDR_N_BINDING_POOL]; 4538d7e4166Sjose borrego 454fe1c642dSBill Krier boolean_t nonull; 4558d7e4166Sjose borrego boolean_t heap_preserved; 4568d7e4166Sjose borrego ndr_heap_t *heap; 4578d7e4166Sjose borrego ndr_stream_t *recv_nds; 4588d7e4166Sjose borrego ndr_stream_t *send_nds; 4598d7e4166Sjose borrego 4608d7e4166Sjose borrego uint32_t next_call_id; 4618d7e4166Sjose borrego unsigned next_p_cont_id; 4628d7e4166Sjose borrego } ndr_client_t; 4638d7e4166Sjose borrego 4648d7e4166Sjose borrego typedef struct ndr_handle { 4658d7e4166Sjose borrego ndr_hdid_t nh_id; 4668d7e4166Sjose borrego struct ndr_handle *nh_next; 46768b2bbf2SGordon Ross ndr_pipe_t *nh_pipe; 4688d7e4166Sjose borrego const ndr_service_t *nh_svc; 4698d7e4166Sjose borrego ndr_client_t *nh_clnt; 47089dc44ceSjose borrego void *nh_data; 47189dc44ceSjose borrego void (*nh_data_free)(void *); 4728d7e4166Sjose borrego } ndr_handle_t; 4738d7e4166Sjose borrego 474b1352070SAlan Wright #define NDR_PDU_SIZE_HINT_DEFAULT (16*1024) 475b1352070SAlan Wright #define NDR_BUF_MAGIC 0x4E425546 /* NBUF */ 476b1352070SAlan Wright 477b1352070SAlan Wright typedef struct ndr_buf { 478b1352070SAlan Wright uint32_t nb_magic; 479b1352070SAlan Wright ndr_stream_t nb_nds; 480b1352070SAlan Wright ndr_heap_t *nb_heap; 481b1352070SAlan Wright ndr_typeinfo_t *nb_ti; 482b1352070SAlan Wright } ndr_buf_t; 483b1352070SAlan Wright 4848d7e4166Sjose borrego /* ndr_ops.c */ 485fe1c642dSBill Krier int nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *); 4868d7e4166Sjose borrego void nds_destruct(ndr_stream_t *); 4870658b32dSAlan Wright void nds_show_state(ndr_stream_t *); 4888d7e4166Sjose borrego 4898d7e4166Sjose borrego /* ndr_client.c */ 490*3299f39fSGordon Ross int ndr_clnt_bind(ndr_client_t *, ndr_service_t *, ndr_binding_t **); 4918d7e4166Sjose borrego int ndr_clnt_call(ndr_binding_t *, int, void *); 4928d7e4166Sjose borrego void ndr_clnt_free_heap(ndr_client_t *); 4938d7e4166Sjose borrego 4948d7e4166Sjose borrego /* ndr_marshal.c */ 495b1352070SAlan Wright ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *); 496b1352070SAlan Wright void ndr_buf_fini(ndr_buf_t *); 497c5866007SKeyur Desai int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t, 498c5866007SKeyur Desai void *); 4998d7e4166Sjose borrego int ndr_decode_call(ndr_xa_t *, void *); 5008d7e4166Sjose borrego int ndr_encode_return(ndr_xa_t *, void *); 5018d7e4166Sjose borrego int ndr_encode_call(ndr_xa_t *, void *); 5028d7e4166Sjose borrego int ndr_decode_return(ndr_xa_t *, void *); 5038d7e4166Sjose borrego int ndr_decode_pdu_hdr(ndr_xa_t *); 5048d7e4166Sjose borrego int ndr_encode_pdu_hdr(ndr_xa_t *); 5058d7e4166Sjose borrego void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *); 5069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void ndr_remove_frag_hdr(ndr_stream_t *); 5070658b32dSAlan Wright void ndr_show_hdr(ndr_common_header_t *); 5088d7e4166Sjose borrego unsigned ndr_bind_ack_hdr_size(ndr_xa_t *); 5098d7e4166Sjose borrego unsigned ndr_alter_context_rsp_hdr_size(void); 5108d7e4166Sjose borrego 5118d7e4166Sjose borrego /* ndr_server.c */ 51268b2bbf2SGordon Ross void ndr_pipe_worker(ndr_pipe_t *); 5138d7e4166Sjose borrego 5148d7e4166Sjose borrego int ndr_generic_call_stub(ndr_xa_t *); 5158d7e4166Sjose borrego 5168d7e4166Sjose borrego /* ndr_svc.c */ 5178d7e4166Sjose borrego ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int); 5188d7e4166Sjose borrego ndr_service_t *ndr_svc_lookup_name(const char *); 5198d7e4166Sjose borrego ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int); 5208d7e4166Sjose borrego int ndr_svc_register(ndr_service_t *); 5218d7e4166Sjose borrego void ndr_svc_unregister(ndr_service_t *); 5228d7e4166Sjose borrego void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int); 5238d7e4166Sjose borrego ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t); 5248d7e4166Sjose borrego ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *); 5258d7e4166Sjose borrego 5268d7e4166Sjose borrego int ndr_uuid_parse(char *, ndr_uuid_t *); 5278d7e4166Sjose borrego void ndr_uuid_unparse(ndr_uuid_t *, char *); 5288d7e4166Sjose borrego 5298d7e4166Sjose borrego ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *); 5308d7e4166Sjose borrego void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *); 5318d7e4166Sjose borrego ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *); 53268b2bbf2SGordon Ross void ndr_hdclose(ndr_pipe_t *); 5338d7e4166Sjose borrego 5348d7e4166Sjose borrego ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *); 535da6c28aaSamw 536*3299f39fSGordon Ross /* 537*3299f39fSGordon Ross * An ndr_client_t is created while binding a client connection to hold 538*3299f39fSGordon Ross * the context for calls made using that connection. 539*3299f39fSGordon Ross * 540*3299f39fSGordon Ross * Handles are RPC call specific and we use an inheritance mechanism to 541*3299f39fSGordon Ross * ensure that each handle has a pointer to the client_t. When the top 542*3299f39fSGordon Ross * level (bind) handle is released, we close the connection. 543*3299f39fSGordon Ross * 544*3299f39fSGordon Ross * There are some places in libmlsvc where the code assumes that the 545*3299f39fSGordon Ross * handle member is first in this struct. careful 546*3299f39fSGordon Ross */ 547*3299f39fSGordon Ross typedef struct mlrpc_handle { 548*3299f39fSGordon Ross ndr_hdid_t handle; /* keep first */ 549*3299f39fSGordon Ross ndr_client_t *clnt; 550*3299f39fSGordon Ross } mlrpc_handle_t; 551*3299f39fSGordon Ross 552*3299f39fSGordon Ross int mlrpc_clh_create(mlrpc_handle_t *, void *); 553*3299f39fSGordon Ross uint32_t mlrpc_clh_bind(mlrpc_handle_t *, ndr_service_t *); 554*3299f39fSGordon Ross void mlrpc_clh_unbind(mlrpc_handle_t *); 555*3299f39fSGordon Ross void *mlrpc_clh_free(mlrpc_handle_t *); 556*3299f39fSGordon Ross 557*3299f39fSGordon Ross int ndr_rpc_call(mlrpc_handle_t *, int, void *); 558*3299f39fSGordon Ross int ndr_rpc_get_ssnkey(mlrpc_handle_t *, unsigned char *, size_t); 559*3299f39fSGordon Ross void *ndr_rpc_malloc(mlrpc_handle_t *, size_t); 560*3299f39fSGordon Ross ndr_heap_t *ndr_rpc_get_heap(mlrpc_handle_t *); 561*3299f39fSGordon Ross void ndr_rpc_release(mlrpc_handle_t *); 562*3299f39fSGordon Ross void ndr_rpc_set_nonull(mlrpc_handle_t *); 563*3299f39fSGordon Ross 564*3299f39fSGordon Ross boolean_t ndr_is_null_handle(mlrpc_handle_t *); 565*3299f39fSGordon Ross boolean_t ndr_is_bind_handle(mlrpc_handle_t *); 566*3299f39fSGordon Ross void ndr_inherit_handle(mlrpc_handle_t *, mlrpc_handle_t *); 567*3299f39fSGordon Ross 568da6c28aaSamw #ifdef __cplusplus 569da6c28aaSamw } 570da6c28aaSamw #endif 571da6c28aaSamw 572da6c28aaSamw #endif /* _LIBMLRPC_H */ 573