xref: /onnv-gate/usr/src/lib/smbsrv/libmlrpc/common/libmlrpc.h (revision 12065:0e89d02a32ea)
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