13299f39fSGordon Ross /*
23299f39fSGordon Ross  * CDDL HEADER START
33299f39fSGordon Ross  *
43299f39fSGordon Ross  * The contents of this file are subject to the terms of the
53299f39fSGordon Ross  * Common Development and Distribution License (the "License").
63299f39fSGordon Ross  * You may not use this file except in compliance with the License.
73299f39fSGordon Ross  *
83299f39fSGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93299f39fSGordon Ross  * or http://www.opensolaris.org/os/licensing.
103299f39fSGordon Ross  * See the License for the specific language governing permissions
113299f39fSGordon Ross  * and limitations under the License.
123299f39fSGordon Ross  *
133299f39fSGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
143299f39fSGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153299f39fSGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
163299f39fSGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
173299f39fSGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
183299f39fSGordon Ross  *
193299f39fSGordon Ross  * CDDL HEADER END
203299f39fSGordon Ross  */
213299f39fSGordon Ross /*
223299f39fSGordon Ross  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23ce8560eeSMatt Barden  * Copyright 2020 Tintri by DDN, Inc. All rights reserved.
24*0ccfe583SMatt Barden  * Copyright 2023 RackTop Systems, Inc.
253299f39fSGordon Ross  */
263299f39fSGordon Ross 
273299f39fSGordon Ross #ifndef	_LIBMLRPC_H
283299f39fSGordon Ross #define	_LIBMLRPC_H
293299f39fSGordon Ross 
303299f39fSGordon Ross #include <sys/types.h>
313299f39fSGordon Ross #include <sys/uio.h>
323299f39fSGordon Ross 
333299f39fSGordon Ross #include <smb/wintypes.h>
343299f39fSGordon Ross #include <libmlrpc/ndr.h>
353299f39fSGordon Ross 
363299f39fSGordon Ross #ifdef	__cplusplus
373299f39fSGordon Ross extern "C" {
383299f39fSGordon Ross #endif
393299f39fSGordon Ross 
403299f39fSGordon Ross /*
413299f39fSGordon Ross  * An MSRPC compatible implementation of OSF DCE RPC.  DCE RPC is derived
423299f39fSGordon Ross  * from the Apollo Network Computing Architecture (NCA) RPC implementation.
433299f39fSGordon Ross  *
443299f39fSGordon Ross  * CAE Specification (1997)
453299f39fSGordon Ross  * DCE 1.1: Remote Procedure Call
463299f39fSGordon Ross  * Document Number: C706
473299f39fSGordon Ross  * The Open Group
483299f39fSGordon Ross  * ogspecs@opengroup.org
493299f39fSGordon Ross  *
503299f39fSGordon Ross  * This implementation is based on the DCE Remote Procedure Call spec with
513299f39fSGordon Ross  * enhancements to support Unicode strings.  The diagram below shows the
523299f39fSGordon Ross  * DCE RPC layers compared against ONC SUN RPC.
533299f39fSGordon Ross  *
543299f39fSGordon Ross  *	NDR RPC Layers		Sun RPC Layers		Remark
553299f39fSGordon Ross  *	+---------------+	+---------------+	+---------------+
563299f39fSGordon Ross  *	+---------------+	+---------------+
573299f39fSGordon Ross  *	| Application	|	| Application	|	The application
583299f39fSGordon Ross  *	+---------------+	+---------------+
593299f39fSGordon Ross  *	| Hand coded    |	| RPCGEN gen'd  |	Where the real
603299f39fSGordon Ross  *	| client/server |	| client/server |	work happens
613299f39fSGordon Ross  *	| srvsvc.ndl	|	| *_svc.c *_clnt|
623299f39fSGordon Ross  *	| srvsvc.c	|	|               |
633299f39fSGordon Ross  *	+---------------+	+---------------+
643299f39fSGordon Ross  *	| RPC Library	|	| RPC Library   |	Calls/Return
653299f39fSGordon Ross  *	| ndr_*.c       |	|               |	Binding/PMAP
663299f39fSGordon Ross  *	+---------------+	+---------------+
673299f39fSGordon Ross  *	| RPC Protocol	|	| RPC Protocol  |	Headers, Auth,
683299f39fSGordon Ross  *	| rpcpdu.ndl    |	|               |
693299f39fSGordon Ross  *	+---------------+	+---------------+
703299f39fSGordon Ross  *	| IDL gen'd	|	| RPCGEN gen'd  |	Aggregate
713299f39fSGordon Ross  *	| NDR stubs	|	| XDR stubs     |	Composition
723299f39fSGordon Ross  *	| *__ndr.c      |	| *_xdr.c       |
733299f39fSGordon Ross  *	+---------------+	+---------------+
743299f39fSGordon Ross  *	| NDR Represen	|	| XDR Represen  |	Byte order, padding
753299f39fSGordon Ross  *	+---------------+	+---------------+
763299f39fSGordon Ross  *	| Packet Heaps  |	| Network Conn  |	DCERPC does not talk
773299f39fSGordon Ross  *	| ndo_*.c       |	| clnt_{tcp,udp}|	directly to network.
783299f39fSGordon Ross  *	+---------------+	+---------------+
793299f39fSGordon Ross  *
803299f39fSGordon Ross  * There are two major differences between the DCE RPC and ONC RPC:
813299f39fSGordon Ross  *
823299f39fSGordon Ross  * 1. NDR RPC only generates or processes packets from buffers.  Other
833299f39fSGordon Ross  *    layers must take care of packet transmission and reception.
843299f39fSGordon Ross  *    The packet heaps are managed through a simple interface provided
853299f39fSGordon Ross  *    by the Network Data Representation (NDR) module called ndr_stream_t.
863299f39fSGordon Ross  *    ndo_*.c modules implement the different flavors (operations) of
873299f39fSGordon Ross  *    packet heaps.
883299f39fSGordon Ross  *
893299f39fSGordon Ross  *    ONC RPC communicates directly with the network.  You have to do
903299f39fSGordon Ross  *    something special for the RPC packet to be placed in a buffer
913299f39fSGordon Ross  *    rather than sent to the wire.
923299f39fSGordon Ross  *
933299f39fSGordon Ross  * 2. NDR RPC uses application provided heaps to support operations.
943299f39fSGordon Ross  *    A heap is a single, monolithic chunk of memory that NDR RPC manages
953299f39fSGordon Ross  *    as it allocates.  When the operation and its result are done, the
963299f39fSGordon Ross  *    heap is disposed of as a single item.  The transaction, which
973299f39fSGordon Ross  *    is the anchor of most operations, contains the necessary book-
983299f39fSGordon Ross  *    keeping for the heap.
993299f39fSGordon Ross  *
1003299f39fSGordon Ross  *    ONC RPC uses malloc() liberally throughout its run-time system.
1013299f39fSGordon Ross  *    To free results, ONC RPC supports an XDR_FREE operation that
1023299f39fSGordon Ross  *    traverses data structures freeing memory as it goes, whether
1033299f39fSGordon Ross  *    it was malloc'd or not.
1043299f39fSGordon Ross  */
1053299f39fSGordon Ross 
1063299f39fSGordon Ross /*
1073299f39fSGordon Ross  * Dispatch Return Code (DRC)
1083299f39fSGordon Ross  *
1093299f39fSGordon Ross  *	0x8000	15:01	Set to indicate a fault, clear indicates status
1103299f39fSGordon Ross  *	0x7F00	08:07	Status/Fault specific
1113299f39fSGordon Ross  *	0x00FF	00:08	PTYPE_... of PDU, 0xFF for header
1123299f39fSGordon Ross  */
1133299f39fSGordon Ross #define	NDR_DRC_OK				0x0000
1143299f39fSGordon Ross #define	NDR_DRC_MASK_FAULT			0x8000
1153299f39fSGordon Ross #define	NDR_DRC_MASK_SPECIFIER			0xFF00
1163299f39fSGordon Ross #define	NDR_DRC_MASK_PTYPE			0x00FF
1173299f39fSGordon Ross 
1183299f39fSGordon Ross /* Fake PTYPE DRC discriminators */
1193299f39fSGordon Ross #define	NDR_DRC_PTYPE_RPCHDR(DRC)		((DRC) | 0x00FF)
1203299f39fSGordon Ross #define	NDR_DRC_PTYPE_API(DRC)			((DRC) | 0x00AA)
121ce8560eeSMatt Barden #define	NDR_DRC_PTYPE_SEC(DRC)			((DRC) | 0x00CC)
1223299f39fSGordon Ross 
1233299f39fSGordon Ross /* DRC Recognizers */
1243299f39fSGordon Ross #define	NDR_DRC_IS_OK(DRC)	(((DRC) & NDR_DRC_MASK_SPECIFIER) == 0)
1253299f39fSGordon Ross #define	NDR_DRC_IS_FAULT(DRC)	(((DRC) & NDR_DRC_MASK_FAULT) != 0)
1263299f39fSGordon Ross 
1273299f39fSGordon Ross /*
1283299f39fSGordon Ross  * (Un)Marshalling category specifiers
1293299f39fSGordon Ross  */
1303299f39fSGordon Ross #define	NDR_DRC_FAULT_MODE_MISMATCH		0x8100
1313299f39fSGordon Ross #define	NDR_DRC_RECEIVED			0x0200
1323299f39fSGordon Ross #define	NDR_DRC_FAULT_RECEIVED_RUNT		0x8300
1333299f39fSGordon Ross #define	NDR_DRC_FAULT_RECEIVED_MALFORMED	0x8400
1343299f39fSGordon Ross #define	NDR_DRC_DECODED				0x0500
1353299f39fSGordon Ross #define	NDR_DRC_FAULT_DECODE_FAILED		0x8600
1363299f39fSGordon Ross #define	NDR_DRC_ENCODED				0x0700
1373299f39fSGordon Ross #define	NDR_DRC_FAULT_ENCODE_FAILED		0x8800
1383299f39fSGordon Ross #define	NDR_DRC_FAULT_ENCODE_TOO_BIG		0x8900
1393299f39fSGordon Ross #define	NDR_DRC_SENT				0x0A00
1403299f39fSGordon Ross #define	NDR_DRC_FAULT_SEND_FAILED		0x8B00
1413299f39fSGordon Ross 
1423299f39fSGordon Ross /*
1433299f39fSGordon Ross  * Resource category specifier
1443299f39fSGordon Ross  */
1453299f39fSGordon Ross #define	NDR_DRC_FAULT_RESOURCE_1		0x9100
1463299f39fSGordon Ross #define	NDR_DRC_FAULT_RESOURCE_2		0x9200
1473299f39fSGordon Ross 
1483299f39fSGordon Ross /*
1493299f39fSGordon Ross  * Parameters. Usually #define'd with useful alias
1503299f39fSGordon Ross  */
1513299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_0_INVALID		0xC000
1523299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED	0xD000
1533299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_1_INVALID		0xC100
1543299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED	0xD100
1553299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_2_INVALID		0xC200
1563299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED	0xD200
1573299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_3_INVALID		0xC300
1583299f39fSGordon Ross #define	NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED	0xD300
159ce8560eeSMatt Barden #define	NDR_DRC_FAULT_PARAM_4_INVALID		0xC400
160ce8560eeSMatt Barden #define	NDR_DRC_FAULT_PARAM_4_UNIMPLEMENTED	0xD400
161ce8560eeSMatt Barden #define	NDR_DRC_FAULT_PARAM_5_INVALID		0xC500
162ce8560eeSMatt Barden #define	NDR_DRC_FAULT_PARAM_5_UNIMPLEMENTED	0xD500
1633299f39fSGordon Ross 
1643299f39fSGordon Ross #define	NDR_DRC_FAULT_OUT_OF_MEMORY		0xF000
1653299f39fSGordon Ross 
1663299f39fSGordon Ross /* RPCHDR */
1673299f39fSGordon Ross #define	NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH	0x81FF
1683299f39fSGordon Ross #define	NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT	0x83FF
1693299f39fSGordon Ross #define	NDR_DRC_FAULT_RPCHDR_DECODE_FAILED	0x86FF
1703299f39fSGordon Ross #define	NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID	0xC0FF	/* PARAM_0_INVALID */
1713299f39fSGordon Ross #define	NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF	/* PARAM_0_UNIMP */
1723299f39fSGordon Ross 
1733299f39fSGordon Ross /* Request */
1743299f39fSGordon Ross #define	NDR_DRC_FAULT_REQUEST_PCONT_INVALID	0xC000	/* PARAM_0_INVALID */
1753299f39fSGordon Ross #define	NDR_DRC_FAULT_REQUEST_OPNUM_INVALID	0xC100	/* PARAM_1_INVALID */
1763299f39fSGordon Ross 
1773299f39fSGordon Ross /* Bind */
1783299f39fSGordon Ross #define	NDR_DRC_BINDING_MADE			0x000B	/* OK */
1793299f39fSGordon Ross #define	NDR_DRC_FAULT_BIND_PCONT_BUSY		0xC00B	/* PARAM_0_INVALID */
1803299f39fSGordon Ross #define	NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE	0xC10B	/* PARAM_1_INVALID */
1813299f39fSGordon Ross #define	NDR_DRC_FAULT_BIND_NO_SLOTS		0x910B	/* RESOURCE_1 */
1823299f39fSGordon Ross 
1833299f39fSGordon Ross /* API */
1843299f39fSGordon Ross #define	NDR_DRC_FAULT_API_SERVICE_INVALID	0xC0AA	/* PARAM_0_INVALID */
1853299f39fSGordon Ross #define	NDR_DRC_FAULT_API_BIND_NO_SLOTS		0x91AA	/* RESOURCE_1 */
1863299f39fSGordon Ross #define	NDR_DRC_FAULT_API_OPNUM_INVALID		0xC1AA	/* PARAM_1_INVALID */
1873299f39fSGordon Ross 
188ce8560eeSMatt Barden /* Secure RPC and SSPs */
189ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_TYPE_UNIMPLEMENTED	\
190ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED)
191ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_LEVEL_UNIMPLEMENTED	\
192ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED)
193ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_SSP_FAILED		\
194ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_RESOURCE_1)
195ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_ENCODE_TOO_BIG	\
196ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_ENCODE_TOO_BIG)
197ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_AUTH_LENGTH_INVALID	\
198ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_2_INVALID)
199ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_AUTH_TYPE_INVALID	\
200ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_0_INVALID)
201ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_AUTH_LEVEL_INVALID	\
202ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_1_INVALID)
203ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_OUT_OF_MEMORY		\
204ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_OUT_OF_MEMORY)
205ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_ENCODE_FAILED		\
206ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_ENCODE_FAILED)
207ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_META_INVALID		\
208ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_3_INVALID)
209ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_SEQNUM_INVALID	\
210ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_4_INVALID)
211ce8560eeSMatt Barden #define	NDR_DRC_FAULT_SEC_SIG_INVALID		\
212ce8560eeSMatt Barden     NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_5_INVALID)
213ce8560eeSMatt Barden 
2143299f39fSGordon Ross struct ndr_xa;
2153299f39fSGordon Ross struct ndr_client;
2163299f39fSGordon Ross 
2173299f39fSGordon Ross typedef struct ndr_stub_table {
2183299f39fSGordon Ross 	int		(*func)(void *, struct ndr_xa *);
2193299f39fSGordon Ross 	unsigned short	opnum;
2203299f39fSGordon Ross } ndr_stub_table_t;
2213299f39fSGordon Ross 
2223299f39fSGordon Ross typedef struct ndr_service {
2233299f39fSGordon Ross 	char		*name;
2243299f39fSGordon Ross 	char		*desc;
2253299f39fSGordon Ross 	char		*endpoint;
2263299f39fSGordon Ross 	char		*sec_addr_port;
2273299f39fSGordon Ross 	char		*abstract_syntax_uuid;
2283299f39fSGordon Ross 	int		abstract_syntax_version;
2293299f39fSGordon Ross 	char		*transfer_syntax_uuid;
2303299f39fSGordon Ross 	int		transfer_syntax_version;
2313299f39fSGordon Ross 	unsigned	bind_instance_size;
2323299f39fSGordon Ross 	int		(*bind_req)();
2333299f39fSGordon Ross 	int		(*unbind_and_close)();
2343299f39fSGordon Ross 	int		(*call_stub)(struct ndr_xa *);
2353299f39fSGordon Ross 	ndr_typeinfo_t	*interface_ti;
2363299f39fSGordon Ross 	ndr_stub_table_t *stub_table;
2373299f39fSGordon Ross } ndr_service_t;
2383299f39fSGordon Ross 
2393299f39fSGordon Ross /*
2403299f39fSGordon Ross  * The list of bindings is anchored at a connection.  Nothing in the
2413299f39fSGordon Ross  * RPC mechanism allocates them.  Binding elements which have service==0
2423299f39fSGordon Ross  * indicate free elements.  When a connection is instantiated, at least
2433299f39fSGordon Ross  * one free binding entry should also be established.  Something like
2443299f39fSGordon Ross  * this should suffice for most (all) situations:
2453299f39fSGordon Ross  *
2463299f39fSGordon Ross  *	struct connection {
2473299f39fSGordon Ross  *		....
2483299f39fSGordon Ross  *		ndr_binding_t *binding_list_head;
2493299f39fSGordon Ross  *		ndr_binding_t binding_pool[N_BINDING_POOL];
2503299f39fSGordon Ross  *		....
2513299f39fSGordon Ross  *	};
2523299f39fSGordon Ross  *
2533299f39fSGordon Ross  *	init_connection(struct connection *conn) {
2543299f39fSGordon Ross  *		....
2553299f39fSGordon Ross  *		ndr_svc_binding_pool_init(&conn->binding_list_head,
2563299f39fSGordon Ross  *		    conn->binding_pool, N_BINDING_POOL);
2573299f39fSGordon Ross  */
2583299f39fSGordon Ross typedef struct ndr_binding {
2593299f39fSGordon Ross 	struct ndr_binding	*next;
2603299f39fSGordon Ross 	ndr_p_context_id_t	p_cont_id;
2613299f39fSGordon Ross 	unsigned char		which_side;
2623299f39fSGordon Ross 	struct ndr_client	*clnt;
2633299f39fSGordon Ross 	ndr_service_t		*service;
2643299f39fSGordon Ross 	void			*instance_specific;
2653299f39fSGordon Ross } ndr_binding_t;
2663299f39fSGordon Ross 
2673299f39fSGordon Ross #define	NDR_BIND_SIDE_CLIENT	1
2683299f39fSGordon Ross #define	NDR_BIND_SIDE_SERVER	2
2693299f39fSGordon Ross 
2703299f39fSGordon Ross #define	NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \
2713299f39fSGordon Ross 	((TYPE *) (BINDING)->instance_specific)
2723299f39fSGordon Ross 
2733299f39fSGordon Ross /*
2743299f39fSGordon Ross  * The binding list space must be provided by the application library
2753299f39fSGordon Ross  * for use by the underlying RPC library.  We need at least two binding
2763299f39fSGordon Ross  * slots per connection.
2773299f39fSGordon Ross  */
2783299f39fSGordon Ross #define	NDR_N_BINDING_POOL	2
2793299f39fSGordon Ross 
2803299f39fSGordon Ross typedef struct ndr_pipe {
2813299f39fSGordon Ross 	void			*np_listener;
2823299f39fSGordon Ross 	const char		*np_endpoint;
2833299f39fSGordon Ross 	struct smb_netuserinfo	*np_user;
2843299f39fSGordon Ross 	int			(*np_send)(struct ndr_pipe *, void *, size_t);
2853299f39fSGordon Ross 	int			(*np_recv)(struct ndr_pipe *, void *, size_t);
2863299f39fSGordon Ross 	int			np_fid;
2873299f39fSGordon Ross 	uint16_t		np_max_xmit_frag;
2883299f39fSGordon Ross 	uint16_t		np_max_recv_frag;
2893299f39fSGordon Ross 	ndr_binding_t		*np_binding;
2903299f39fSGordon Ross 	ndr_binding_t		np_binding_pool[NDR_N_BINDING_POOL];
2913299f39fSGordon Ross } ndr_pipe_t;
2923299f39fSGordon Ross 
2933299f39fSGordon Ross /*
2943299f39fSGordon Ross  * Number of bytes required to align SIZE on the next dword/4-byte
2953299f39fSGordon Ross  * boundary.
2963299f39fSGordon Ross  */
2973299f39fSGordon Ross #define	NDR_ALIGN4(SIZE)	((4 - (SIZE)) & 3);
2983299f39fSGordon Ross 
2993299f39fSGordon Ross /*
3003299f39fSGordon Ross  * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying
3013299f39fSGordon Ross  * and conformant one-dimensional arrays. Characters can be single-byte
3023299f39fSGordon Ross  * or multi-byte as long as all characters conform to a fixed element size,
3033299f39fSGordon Ross  * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The
3043299f39fSGordon Ross  * string is terminated by a null character of the appropriate element size.
3053299f39fSGordon Ross  *
3063299f39fSGordon Ross  * MSRPC strings should always be varying/conformant and not null terminated.
3073299f39fSGordon Ross  * This format uses the size_is, first_is and length_is attributes (CAE
3083299f39fSGordon Ross  * section 4.2.18).
3093299f39fSGordon Ross  *
3103299f39fSGordon Ross  *	typedef struct string {
3113299f39fSGordon Ross  *		DWORD size_is;
3123299f39fSGordon Ross  *		DWORD first_is;
3133299f39fSGordon Ross  *		DWORD length_is;
3143299f39fSGordon Ross  *		wchar_t string[ANY_SIZE_ARRAY];
3153299f39fSGordon Ross  *	} string_t;
3163299f39fSGordon Ross  *
3173299f39fSGordon Ross  * The size_is attribute is used to specify the number of data elements in
3183299f39fSGordon Ross  * each dimension of an array.
3193299f39fSGordon Ross  *
3203299f39fSGordon Ross  * The first_is attribute is used to define the lower bound for significant
3213299f39fSGordon Ross  * elements in each dimension of an array. For strings this is always 0.
3223299f39fSGordon Ross  *
3233299f39fSGordon Ross  * The length_is attribute is used to define the number of significant
3243299f39fSGordon Ross  * elements in each dimension of an array. For strings this is typically
3253299f39fSGordon Ross  * the same as size_is. Although it might be (size_is - 1) if the string
3263299f39fSGordon Ross  * is null terminated.
3273299f39fSGordon Ross  *
3283299f39fSGordon Ross  *   4 bytes   4 bytes   4 bytes  2bytes 2bytes 2bytes 2bytes
3293299f39fSGordon Ross  * +---------+---------+---------+------+------+------+------+
3303299f39fSGordon Ross  * |size_is  |first_is |length_is| char | char | char | char |
3313299f39fSGordon Ross  * +---------+---------+---------+------+------+------+------+
3323299f39fSGordon Ross  *
3333299f39fSGordon Ross  * Unfortunately, not all MSRPC Unicode strings are null terminated, which
3343299f39fSGordon Ross  * means that the recipient has to manually null-terminate the string after
3353299f39fSGordon Ross  * it has been unmarshalled.  There may be a wide-char pad following a
3363299f39fSGordon Ross  * string, and it may sometimes contains zero, but it's not guaranteed.
3373299f39fSGordon Ross  *
3383299f39fSGordon Ross  * To deal with this, MSRPC sometimes uses an additional wrapper with two
3393299f39fSGordon Ross  * more fields, as shown below.
3403299f39fSGordon Ross  *	length: the array length in bytes excluding terminating null bytes
3413299f39fSGordon Ross  *	maxlen: the array length in bytes including null terminator bytes
3423299f39fSGordon Ross  *	LPTSTR: converted to a string_t by NDR
3433299f39fSGordon Ross  *
3443299f39fSGordon Ross  * typedef struct ms_string {
3453299f39fSGordon Ross  *		WORD length;
3463299f39fSGordon Ross  *		WORD maxlen;
3473299f39fSGordon Ross  *		LPTSTR str;
3483299f39fSGordon Ross  * } ms_string_t;
3493299f39fSGordon Ross  */
3503299f39fSGordon Ross typedef struct ndr_mstring {
3513299f39fSGordon Ross 	uint16_t length;
3523299f39fSGordon Ross 	uint16_t allosize;
3533299f39fSGordon Ross 	LPTSTR str;
3543299f39fSGordon Ross } ndr_mstring_t;
3553299f39fSGordon Ross 
3563299f39fSGordon Ross /*
3573299f39fSGordon Ross  * A number of heap areas are used during marshalling and unmarshalling.
3583299f39fSGordon Ross  * Under some circumstances these areas can be discarded by the library
3593299f39fSGordon Ross  * code, i.e. on the server side before returning to the client and on
3603299f39fSGordon Ross  * completion of a client side bind.  In the case of a client side RPC
3613299f39fSGordon Ross  * call, these areas must be preserved after an RPC returns to give the
3623299f39fSGordon Ross  * caller time to take a copy of the data.  In this case the client must
3633299f39fSGordon Ross  * call ndr_clnt_free_heap to free the memory.
3643299f39fSGordon Ross  *
3653299f39fSGordon Ross  * The heap management data definition looks a bit like this:
3663299f39fSGordon Ross  *
3673299f39fSGordon Ross  * heap -> +---------------+     +------------+
3683299f39fSGordon Ross  *         | iovec[0].base | --> | data block |
3693299f39fSGordon Ross  *         | iovec[0].len  |     +------------+
3703299f39fSGordon Ross  *         +---------------+
3713299f39fSGordon Ross  *                ::
3723299f39fSGordon Ross  *                ::
3733299f39fSGordon Ross  * iov  -> +---------------+     +------------+
3743299f39fSGordon Ross  *         | iovec[n].base | --> | data block |
3753299f39fSGordon Ross  *         | iovec[n].len  |     +------------+
3763299f39fSGordon Ross  *         +---------------+     ^            ^
3773299f39fSGordon Ross  *                               |            |
3783299f39fSGordon Ross  *    next ----------------------+            |
3793299f39fSGordon Ross  *    top  -----------------------------------+
3803299f39fSGordon Ross  *
3813299f39fSGordon Ross  */
3823299f39fSGordon Ross 
3833299f39fSGordon Ross /*
3843299f39fSGordon Ross  * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes
3853299f39fSGordon Ross  * of the first heap block.
3863299f39fSGordon Ross  */
3873299f39fSGordon Ross #define	NDR_HEAP_MAXIOV		384
3883299f39fSGordon Ross #define	NDR_HEAP_BLKSZ		8192
3893299f39fSGordon Ross 
3903299f39fSGordon Ross typedef struct ndr_heap {
3913299f39fSGordon Ross 	struct iovec iovec[NDR_HEAP_MAXIOV];
3923299f39fSGordon Ross 	struct iovec *iov;
3933299f39fSGordon Ross 	int iovcnt;
3943299f39fSGordon Ross 	char *top;
3953299f39fSGordon Ross 	char *next;
3963299f39fSGordon Ross } ndr_heap_t;
3973299f39fSGordon Ross 
3983299f39fSGordon Ross /*
3993299f39fSGordon Ross  * Alternate varying/conformant string definition
4003299f39fSGordon Ross  * - for non-null-terminated strings.
4013299f39fSGordon Ross  */
4023299f39fSGordon Ross typedef struct ndr_vcs {
4033299f39fSGordon Ross 	/*
4043299f39fSGordon Ross 	 * size_is (actually a copy of length_is) will
4053299f39fSGordon Ross 	 * be inserted here by the marshalling library.
4063299f39fSGordon Ross 	 */
4073299f39fSGordon Ross 	uint32_t vc_first_is;
4083299f39fSGordon Ross 	uint32_t vc_length_is;
4093299f39fSGordon Ross 	uint16_t buffer[ANY_SIZE_ARRAY];
4103299f39fSGordon Ross } ndr_vcs_t;
4113299f39fSGordon Ross 
4123299f39fSGordon Ross typedef struct ndr_vcstr {
4133299f39fSGordon Ross 	uint16_t wclen;
4143299f39fSGordon Ross 	uint16_t wcsize;
4153299f39fSGordon Ross 	ndr_vcs_t *vcs;
4163299f39fSGordon Ross } ndr_vcstr_t;
4173299f39fSGordon Ross 
4183299f39fSGordon Ross typedef struct ndr_vcb {
4193299f39fSGordon Ross 	/*
4203299f39fSGordon Ross 	 * size_is (actually a copy of length_is) will
4213299f39fSGordon Ross 	 * be inserted here by the marshalling library.
4223299f39fSGordon Ross 	 */
4233299f39fSGordon Ross 	uint32_t vc_first_is;
4243299f39fSGordon Ross 	uint32_t vc_length_is;
4253299f39fSGordon Ross 	uint8_t buffer[ANY_SIZE_ARRAY];
4263299f39fSGordon Ross } ndr_vcb_t;
4273299f39fSGordon Ross 
4283299f39fSGordon Ross typedef struct ndr_vcbuf {
4293299f39fSGordon Ross 	uint16_t len;
4303299f39fSGordon Ross 	uint16_t size;
4313299f39fSGordon Ross 	ndr_vcb_t *vcb;
4323299f39fSGordon Ross } ndr_vcbuf_t;
4333299f39fSGordon Ross 
4343299f39fSGordon Ross ndr_heap_t *ndr_heap_create(void);
4353299f39fSGordon Ross void ndr_heap_destroy(ndr_heap_t *);
4363299f39fSGordon Ross void *ndr_heap_dupmem(ndr_heap_t *, const void *, size_t);
4373299f39fSGordon Ross void *ndr_heap_malloc(ndr_heap_t *, unsigned);
4383299f39fSGordon Ross void *ndr_heap_strdup(ndr_heap_t *, const char *);
4393299f39fSGordon Ross int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
4403299f39fSGordon Ross void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
4413299f39fSGordon Ross void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
4423299f39fSGordon Ross int ndr_heap_used(ndr_heap_t *);
4433299f39fSGordon Ross int ndr_heap_avail(ndr_heap_t *);
4443299f39fSGordon Ross 
4453299f39fSGordon Ross #define	NDR_MALLOC(XA, SZ)	ndr_heap_malloc((XA)->heap, SZ)
4463299f39fSGordon Ross #define	NDR_NEW(XA, T)		ndr_heap_malloc((XA)->heap, sizeof (T))
4473299f39fSGordon Ross #define	NDR_NEWN(XA, T, N)	ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
4483299f39fSGordon Ross #define	NDR_STRDUP(XA, S)	ndr_heap_strdup((XA)->heap, (S))
4493299f39fSGordon Ross #define	NDR_MSTRING(XA, S, OUT)	ndr_heap_mstring((XA)->heap, (S), (OUT))
4503299f39fSGordon Ross #define	NDR_SIDDUP(XA, S)	ndr_heap_dupmem((XA)->heap, (S), smb_sid_len(S))
4513299f39fSGordon Ross 
4523299f39fSGordon Ross typedef struct ndr_xa {
4533299f39fSGordon Ross 	unsigned short		ptype;		/* high bits special */
4543299f39fSGordon Ross 	unsigned short		opnum;
4553299f39fSGordon Ross 	ndr_stream_t		recv_nds;
4563299f39fSGordon Ross 	ndr_hdr_t		recv_hdr;
457ce8560eeSMatt Barden 	ndr_sec_t		recv_auth;
4583299f39fSGordon Ross 	ndr_stream_t		send_nds;
4593299f39fSGordon Ross 	ndr_hdr_t		send_hdr;
460ce8560eeSMatt Barden 	ndr_sec_t		send_auth;
4613299f39fSGordon Ross 	ndr_binding_t		*binding;	/* what we're using */
4623299f39fSGordon Ross 	ndr_binding_t		*binding_list;	/* from connection */
4633299f39fSGordon Ross 	ndr_heap_t		*heap;
4643299f39fSGordon Ross 	ndr_pipe_t		*pipe;
4653299f39fSGordon Ross } ndr_xa_t;
4663299f39fSGordon Ross 
467ce8560eeSMatt Barden typedef struct ndr_auth_ops {
468ce8560eeSMatt Barden 	int (*nao_init)(void *, ndr_xa_t *);
469ce8560eeSMatt Barden 	int (*nao_recv)(void *, ndr_xa_t *);
470ce8560eeSMatt Barden 	int (*nao_sign)(void *, ndr_xa_t *);
471ce8560eeSMatt Barden 	int (*nao_verify)(void *, ndr_xa_t *, boolean_t);
472*0ccfe583SMatt Barden 	int (*nao_encrypt)(void *, ndr_xa_t *);
473*0ccfe583SMatt Barden 	int (*nao_decrypt)(void *, ndr_xa_t *, boolean_t);
474ce8560eeSMatt Barden } ndr_auth_ops_t;
475ce8560eeSMatt Barden 
476ce8560eeSMatt Barden /*
477ce8560eeSMatt Barden  * A client provides this structure during bind to indicate
478ce8560eeSMatt Barden  * that the RPC runtime should use "Secure RPC" (RPC-level auth).
479ce8560eeSMatt Barden  *
480ce8560eeSMatt Barden  * Currently, only NETLOGON uses this, and only NETLOGON-based
481ce8560eeSMatt Barden  * Integrity protection is supported.
482ce8560eeSMatt Barden  */
483ce8560eeSMatt Barden typedef struct ndr_auth_ctx {
484ce8560eeSMatt Barden 	ndr_auth_ops_t		auth_ops;
485ce8560eeSMatt Barden 	void			*auth_ctx; /* SSP-specific context */
486ce8560eeSMatt Barden 	uint32_t		auth_context_id;
487ce8560eeSMatt Barden 	uint8_t			auth_type;
488ce8560eeSMatt Barden 	uint8_t			auth_level;
489ce8560eeSMatt Barden 	boolean_t		auth_verify_resp;
490ce8560eeSMatt Barden } ndr_auth_ctx_t;
491ce8560eeSMatt Barden 
4923299f39fSGordon Ross /*
4933299f39fSGordon Ross  * 20-byte opaque id used by various RPC services.
4943299f39fSGordon Ross  */
4953299f39fSGordon Ross CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t;
4963299f39fSGordon Ross 
4973299f39fSGordon Ross typedef struct ndr_client {
4983299f39fSGordon Ross 	/* transport stuff (xa_* members) */
4993299f39fSGordon Ross 	int (*xa_init)(struct ndr_client *, ndr_xa_t *);
5003299f39fSGordon Ross 	int (*xa_exchange)(struct ndr_client *, ndr_xa_t *);
5013299f39fSGordon Ross 	int (*xa_read)(struct ndr_client *, ndr_xa_t *);
5023299f39fSGordon Ross 	void (*xa_preserve)(struct ndr_client *, ndr_xa_t *);
5033299f39fSGordon Ross 	void (*xa_destruct)(struct ndr_client *, ndr_xa_t *);
5043299f39fSGordon Ross 	void (*xa_release)(struct ndr_client *);
5053299f39fSGordon Ross 	void			*xa_private;
5063299f39fSGordon Ross 	int			xa_fd;
5073299f39fSGordon Ross 
5083299f39fSGordon Ross 	ndr_hdid_t		*handle;
5093299f39fSGordon Ross 	ndr_binding_t		*binding;
5103299f39fSGordon Ross 	ndr_binding_t		*binding_list;
5113299f39fSGordon Ross 	ndr_binding_t		binding_pool[NDR_N_BINDING_POOL];
5123299f39fSGordon Ross 
5133299f39fSGordon Ross 	boolean_t		nonull;
5143299f39fSGordon Ross 	boolean_t		heap_preserved;
5153299f39fSGordon Ross 	ndr_heap_t		*heap;
5163299f39fSGordon Ross 	ndr_stream_t		*recv_nds;
5173299f39fSGordon Ross 	ndr_stream_t		*send_nds;
5183299f39fSGordon Ross 
5193299f39fSGordon Ross 	uint32_t		next_call_id;
5203299f39fSGordon Ross 	unsigned		next_p_cont_id;
521ce8560eeSMatt Barden 
522ce8560eeSMatt Barden 	ndr_auth_ctx_t		auth_ctx;
5233299f39fSGordon Ross } ndr_client_t;
5243299f39fSGordon Ross 
5253299f39fSGordon Ross typedef struct ndr_handle {
5263299f39fSGordon Ross 	ndr_hdid_t		nh_id;
5273299f39fSGordon Ross 	struct ndr_handle	*nh_next;
5283299f39fSGordon Ross 	ndr_pipe_t		*nh_pipe;
5293299f39fSGordon Ross 	const ndr_service_t	*nh_svc;
5303299f39fSGordon Ross 	ndr_client_t		*nh_clnt;
5313299f39fSGordon Ross 	void			*nh_data;
5323299f39fSGordon Ross 	void			(*nh_data_free)(void *);
5333299f39fSGordon Ross } ndr_handle_t;
5343299f39fSGordon Ross 
5353299f39fSGordon Ross #define	NDR_PDU_SIZE_HINT_DEFAULT	(16*1024)
5363299f39fSGordon Ross #define	NDR_BUF_MAGIC			0x4E425546	/* NBUF */
5373299f39fSGordon Ross 
5383299f39fSGordon Ross typedef struct ndr_buf {
5393299f39fSGordon Ross 	uint32_t		nb_magic;
5403299f39fSGordon Ross 	ndr_stream_t		nb_nds;
5413299f39fSGordon Ross 	ndr_heap_t		*nb_heap;
5423299f39fSGordon Ross 	ndr_typeinfo_t		*nb_ti;
5433299f39fSGordon Ross } ndr_buf_t;
5443299f39fSGordon Ross 
5453299f39fSGordon Ross /* ndr_ops.c */
5463299f39fSGordon Ross int nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *);
5473299f39fSGordon Ross void nds_destruct(ndr_stream_t *);
5483299f39fSGordon Ross void nds_show_state(ndr_stream_t *);
5493299f39fSGordon Ross 
5503299f39fSGordon Ross /* ndr_client.c */
5513299f39fSGordon Ross int ndr_clnt_bind(ndr_client_t *, ndr_service_t *, ndr_binding_t **);
5523299f39fSGordon Ross int ndr_clnt_call(ndr_binding_t *, int, void *);
5533299f39fSGordon Ross void ndr_clnt_free_heap(ndr_client_t *);
5543299f39fSGordon Ross 
5553299f39fSGordon Ross /* ndr_marshal.c */
5563299f39fSGordon Ross ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *);
5573299f39fSGordon Ross void ndr_buf_fini(ndr_buf_t *);
5583299f39fSGordon Ross int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t,
5593299f39fSGordon Ross     void *);
5603299f39fSGordon Ross int ndr_decode_call(ndr_xa_t *, void *);
5613299f39fSGordon Ross int ndr_encode_return(ndr_xa_t *, void *);
5623299f39fSGordon Ross int ndr_encode_call(ndr_xa_t *, void *);
5633299f39fSGordon Ross int ndr_decode_return(ndr_xa_t *, void *);
5643299f39fSGordon Ross int ndr_decode_pdu_hdr(ndr_xa_t *);
5653299f39fSGordon Ross int ndr_encode_pdu_hdr(ndr_xa_t *);
5663299f39fSGordon Ross void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *);
5673299f39fSGordon Ross void ndr_remove_frag_hdr(ndr_stream_t *);
5683299f39fSGordon Ross void ndr_show_hdr(ndr_common_header_t *);
5693299f39fSGordon Ross unsigned ndr_bind_ack_hdr_size(ndr_xa_t *);
5703299f39fSGordon Ross unsigned ndr_alter_context_rsp_hdr_size(void);
571ce8560eeSMatt Barden int ndr_decode_pdu_auth(ndr_xa_t *);
572ce8560eeSMatt Barden int ndr_encode_pdu_auth(ndr_xa_t *);
573ce8560eeSMatt Barden void ndr_show_auth(ndr_sec_t *);
574ce8560eeSMatt Barden 
575ce8560eeSMatt Barden /*
576ce8560eeSMatt Barden  * MS-RPCE "Secure RPC" (RPC-level auth).
577ce8560eeSMatt Barden  * These call the functions in ndr_auth_ops_t, which should be
578ce8560eeSMatt Barden  * GSSAPI (or equivalent) calls.
579ce8560eeSMatt Barden  */
580ce8560eeSMatt Barden int ndr_add_sec_context(ndr_auth_ctx_t *, ndr_xa_t *);
581ce8560eeSMatt Barden int ndr_recv_sec_context(ndr_auth_ctx_t *, ndr_xa_t *);
582ce8560eeSMatt Barden int ndr_add_auth(ndr_auth_ctx_t *, ndr_xa_t *);
583ce8560eeSMatt Barden int ndr_check_auth(ndr_auth_ctx_t *, ndr_xa_t *);
5843299f39fSGordon Ross 
5853299f39fSGordon Ross /* ndr_server.c */
5863299f39fSGordon Ross void ndr_pipe_worker(ndr_pipe_t *);
5873299f39fSGordon Ross 
5883299f39fSGordon Ross int ndr_generic_call_stub(ndr_xa_t *);
5893299f39fSGordon Ross 
5903299f39fSGordon Ross /* ndr_svc.c */
5913299f39fSGordon Ross ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
5923299f39fSGordon Ross ndr_service_t *ndr_svc_lookup_name(const char *);
5933299f39fSGordon Ross ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int);
5943299f39fSGordon Ross int ndr_svc_register(ndr_service_t *);
5953299f39fSGordon Ross void ndr_svc_unregister(ndr_service_t *);
5963299f39fSGordon Ross void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int);
5973299f39fSGordon Ross ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t);
5983299f39fSGordon Ross ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *);
5993299f39fSGordon Ross 
6003299f39fSGordon Ross int ndr_uuid_parse(char *, ndr_uuid_t *);
6013299f39fSGordon Ross void ndr_uuid_unparse(ndr_uuid_t *, char *);
6023299f39fSGordon Ross 
6033299f39fSGordon Ross ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
6043299f39fSGordon Ross void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
6053299f39fSGordon Ross ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
6063299f39fSGordon Ross void ndr_hdclose(ndr_pipe_t *);
6073299f39fSGordon Ross 
6083299f39fSGordon Ross ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
6093299f39fSGordon Ross 
6103299f39fSGordon Ross /*
6113299f39fSGordon Ross  * An ndr_client_t is created while binding a client connection to hold
6123299f39fSGordon Ross  * the context for calls made using that connection.
6133299f39fSGordon Ross  *
6143299f39fSGordon Ross  * Handles are RPC call specific and we use an inheritance mechanism to
6153299f39fSGordon Ross  * ensure that each handle has a pointer to the client_t.  When the top
6163299f39fSGordon Ross  * level (bind) handle is released, we close the connection.
6173299f39fSGordon Ross  *
6183299f39fSGordon Ross  * There are some places in libmlsvc where the code assumes that the
619ce8560eeSMatt Barden  * handle member is first in this struct. Careful!
620ce8560eeSMatt Barden  *
621ce8560eeSMatt Barden  * Note that this entire structure is bzero()'d once the ndr_client_t
622ce8560eeSMatt Barden  * has been created.
6233299f39fSGordon Ross  */
6243299f39fSGordon Ross typedef struct mlrpc_handle {
6253299f39fSGordon Ross 	ndr_hdid_t	handle;		/* keep first */
6263299f39fSGordon Ross 	ndr_client_t	*clnt;
6273299f39fSGordon Ross } mlrpc_handle_t;
6283299f39fSGordon Ross 
6293299f39fSGordon Ross int mlrpc_clh_create(mlrpc_handle_t *, void *);
630ce8560eeSMatt Barden uint32_t mlrpc_clh_set_auth(mlrpc_handle_t *, ndr_auth_ctx_t *);
6313299f39fSGordon Ross uint32_t mlrpc_clh_bind(mlrpc_handle_t *, ndr_service_t *);
6323299f39fSGordon Ross void mlrpc_clh_unbind(mlrpc_handle_t *);
6333299f39fSGordon Ross void *mlrpc_clh_free(mlrpc_handle_t *);
6343299f39fSGordon Ross 
6353299f39fSGordon Ross int ndr_rpc_call(mlrpc_handle_t *, int, void *);
6363299f39fSGordon Ross int ndr_rpc_get_ssnkey(mlrpc_handle_t *, unsigned char *, size_t);
6373299f39fSGordon Ross void *ndr_rpc_malloc(mlrpc_handle_t *, size_t);
6383299f39fSGordon Ross ndr_heap_t *ndr_rpc_get_heap(mlrpc_handle_t *);
6393299f39fSGordon Ross void ndr_rpc_release(mlrpc_handle_t *);
6403299f39fSGordon Ross void ndr_rpc_set_nonull(mlrpc_handle_t *);
6413299f39fSGordon Ross 
6423299f39fSGordon Ross boolean_t ndr_is_null_handle(mlrpc_handle_t *);
6433299f39fSGordon Ross boolean_t ndr_is_bind_handle(mlrpc_handle_t *);
6443299f39fSGordon Ross void ndr_inherit_handle(mlrpc_handle_t *, mlrpc_handle_t *);
6453299f39fSGordon Ross 
6463299f39fSGordon Ross #ifdef	__cplusplus
6473299f39fSGordon Ross }
6483299f39fSGordon Ross #endif
6493299f39fSGordon Ross 
6503299f39fSGordon Ross #endif	/* _LIBMLRPC_H */
651