Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef	_LIBMLRPC_H
     27 #define	_LIBMLRPC_H
     28 
     29 #include <sys/types.h>
     30 #include <sys/uio.h>
     31 #include <smbsrv/wintypes.h>
     32 #include <smbsrv/ndr.h>
     33 #include <smbsrv/smb_sid.h>
     34 #include <smbsrv/smb_xdr.h>
     35 
     36 #ifdef	__cplusplus
     37 extern "C" {
     38 #endif
     39 
     40 /*
     41  * An MSRPC compatible implementation of OSF DCE RPC.  DCE RPC is derived
     42  * from the Apollo Network Computing Architecture (NCA) RPC implementation.
     43  *
     44  * CAE Specification (1997)
     45  * DCE 1.1: Remote Procedure Call
     46  * Document Number: C706
     47  * The Open Group
     48  * ogspecs (at) opengroup.org
     49  *
     50  * This implementation is based on the DCE Remote Procedure Call spec with
     51  * enhancements to support Unicode strings.  The diagram below shows the
     52  * DCE RPC layers compared against ONC SUN RPC.
     53  *
     54  *	NDR RPC Layers		Sun RPC Layers		Remark
     55  *	+---------------+	+---------------+	+---------------+
     56  *	+---------------+	+---------------+
     57  *	| Application	|	| Application	|	The application
     58  *	+---------------+	+---------------+
     59  *	| Hand coded    |	| RPCGEN gen'd  |	Where the real
     60  *	| client/server |	| client/server |	work happens
     61  *	| srvsvc.ndl	|	| *_svc.c *_clnt|
     62  *	| srvsvc.c	|	|               |
     63  *	+---------------+	+---------------+
     64  *	| RPC Library	|	| RPC Library   |	Calls/Return
     65  *	| ndr_*.c       |	|               |	Binding/PMAP
     66  *	+---------------+	+---------------+
     67  *	| RPC Protocol	|	| RPC Protocol  |	Headers, Auth,
     68  *	| rpcpdu.ndl    |	|               |
     69  *	+---------------+	+---------------+
     70  *	| IDL gen'd	|	| RPCGEN gen'd  |	Aggregate
     71  *	| NDR stubs	|	| XDR stubs     |	Composition
     72  *	| *__ndr.c      |	| *_xdr.c       |
     73  *	+---------------+	+---------------+
     74  *	| NDR Represen	|	| XDR Represen  |	Byte order, padding
     75  *	+---------------+	+---------------+
     76  *	| Packet Heaps  |	| Network Conn  |	DCERPC does not talk
     77  *	| ndo_*.c       |	| clnt_{tcp,udp}|	directly to network.
     78  *	+---------------+	+---------------+
     79  *
     80  * There are two major differences between the DCE RPC and ONC RPC:
     81  *
     82  * 1. NDR RPC only generates or processes packets from buffers.  Other
     83  *    layers must take care of packet transmission and reception.
     84  *    The packet heaps are managed through a simple interface provided
     85  *    by the Network Data Representation (NDR) module called ndr_stream_t.
     86  *    ndo_*.c modules implement the different flavors (operations) of
     87  *    packet heaps.
     88  *
     89  *    ONC RPC communicates directly with the network.  You have to do
     90  *    something special for the RPC packet to be placed in a buffer
     91  *    rather than sent to the wire.
     92  *
     93  * 2. NDR RPC uses application provided heaps to support operations.
     94  *    A heap is a single, monolithic chunk of memory that NDR RPC manages
     95  *    as it allocates.  When the operation and its result are done, the
     96  *    heap is disposed of as a single item.  The transaction, which
     97  *    is the anchor of most operations, contains the necessary book-
     98  *    keeping for the heap.
     99  *
    100  *    ONC RPC uses malloc() liberally throughout its run-time system.
    101  *    To free results, ONC RPC supports an XDR_FREE operation that
    102  *    traverses data structures freeing memory as it goes, whether
    103  *    it was malloc'd or not.
    104  */
    105 
    106 /*
    107  * Dispatch Return Code (DRC)
    108  *
    109  *	0x8000	15:01	Set to indicate a fault, clear indicates status
    110  *	0x7F00	08:07	Status/Fault specific
    111  *	0x00FF	00:08	PTYPE_... of PDU, 0xFF for header
    112  */
    113 #define	NDR_DRC_OK				0x0000
    114 #define	NDR_DRC_MASK_FAULT			0x8000
    115 #define	NDR_DRC_MASK_SPECIFIER			0xFF00
    116 #define	NDR_DRC_MASK_PTYPE			0x00FF
    117 
    118 /* Fake PTYPE DRC discriminators */
    119 #define	NDR_DRC_PTYPE_RPCHDR(DRC)		((DRC) | 0x00FF)
    120 #define	NDR_DRC_PTYPE_API(DRC)			((DRC) | 0x00AA)
    121 
    122 /* DRC Recognizers */
    123 #define	NDR_DRC_IS_OK(DRC)	(((DRC) & NDR_DRC_MASK_SPECIFIER) == 0)
    124 #define	NDR_DRC_IS_FAULT(DRC)	(((DRC) & NDR_DRC_MASK_FAULT) != 0)
    125 
    126 /*
    127  * (Un)Marshalling category specifiers
    128  */
    129 #define	NDR_DRC_FAULT_MODE_MISMATCH		0x8100
    130 #define	NDR_DRC_RECEIVED			0x0200
    131 #define	NDR_DRC_FAULT_RECEIVED_RUNT		0x8300
    132 #define	NDR_DRC_FAULT_RECEIVED_MALFORMED	0x8400
    133 #define	NDR_DRC_DECODED				0x0500
    134 #define	NDR_DRC_FAULT_DECODE_FAILED		0x8600
    135 #define	NDR_DRC_ENCODED				0x0700
    136 #define	NDR_DRC_FAULT_ENCODE_FAILED		0x8800
    137 #define	NDR_DRC_FAULT_ENCODE_TOO_BIG		0x8900
    138 #define	NDR_DRC_SENT				0x0A00
    139 #define	NDR_DRC_FAULT_SEND_FAILED		0x8B00
    140 
    141 /*
    142  * Resource category specifier
    143  */
    144 #define	NDR_DRC_FAULT_RESOURCE_1		0x9100
    145 #define	NDR_DRC_FAULT_RESOURCE_2		0x9200
    146 
    147 /*
    148  * Parameters. Usually #define'd with useful alias
    149  */
    150 #define	NDR_DRC_FAULT_PARAM_0_INVALID		0xC000
    151 #define	NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED	0xD000
    152 #define	NDR_DRC_FAULT_PARAM_1_INVALID		0xC100
    153 #define	NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED	0xD100
    154 #define	NDR_DRC_FAULT_PARAM_2_INVALID		0xC200
    155 #define	NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED	0xD200
    156 #define	NDR_DRC_FAULT_PARAM_3_INVALID		0xC300
    157 #define	NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED	0xD300
    158 
    159 #define	NDR_DRC_FAULT_OUT_OF_MEMORY		0xF000
    160 
    161 /* RPCHDR */
    162 #define	NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID	0xC0FF	/* PARAM_0_INVALID */
    163 #define	NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */
    164 
    165 /* Request */
    166 #define	NDR_DRC_FAULT_REQUEST_PCONT_INVALID	0xC000	/* PARAM_0_INVALID */
    167 #define	NDR_DRC_FAULT_REQUEST_OPNUM_INVALID	0xC100	/* PARAM_1_INVALID */
    168 
    169 /* Bind */
    170 #define	NDR_DRC_FAULT_BIND_PCONT_BUSY		0xC00B	/* PARAM_0_INVALID */
    171 #define	NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE	0xC10B	/* PARAM_1_INVALID */
    172 #define	NDR_DRC_FAULT_BIND_NO_SLOTS		0x910B	/* RESOURCE_1 */
    173 #define	NDR_DRC_BINDING_MADE			0x000B	/* OK */
    174 
    175 /* API */
    176 #define	NDR_DRC_FAULT_API_SERVICE_INVALID	0xC0AA	/* PARAM_0_INVALID */
    177 #define	NDR_DRC_FAULT_API_BIND_NO_SLOTS		0x91AA	/* RESOURCE_1 */
    178 #define	NDR_DRC_FAULT_API_OPNUM_INVALID		0xC1AA	/* PARAM_1_INVALID */
    179 
    180 struct ndr_xa;
    181 struct ndr_client;
    182 
    183 typedef struct ndr_stub_table {
    184 	int		(*func)(void *, struct ndr_xa *);
    185 	unsigned short	opnum;
    186 } ndr_stub_table_t;
    187 
    188 typedef struct ndr_service {
    189 	char		*name;
    190 	char		*desc;
    191 	char		*endpoint;
    192 	char		*sec_addr_port;
    193 	char		*abstract_syntax_uuid;
    194 	int		abstract_syntax_version;
    195 	char		*transfer_syntax_uuid;
    196 	int		transfer_syntax_version;
    197 	unsigned	bind_instance_size;
    198 	int		(*bind_req)();
    199 	int		(*unbind_and_close)();
    200 	int		(*call_stub)(struct ndr_xa *);
    201 	ndr_typeinfo_t	*interface_ti;
    202 	ndr_stub_table_t *stub_table;
    203 } ndr_service_t;
    204 
    205 /*
    206  * The list of bindings is anchored at a connection.  Nothing in the
    207  * RPC mechanism allocates them.  Binding elements which have service==0
    208  * indicate free elements.  When a connection is instantiated, at least
    209  * one free binding entry should also be established.  Something like
    210  * this should suffice for most (all) situations:
    211  *
    212  *	struct connection {
    213  *		....
    214  *		ndr_binding_t *binding_list_head;
    215  *		ndr_binding_t binding_pool[N_BINDING_POOL];
    216  *		....
    217  *	};
    218  *
    219  *	init_connection(struct connection *conn) {
    220  *		....
    221  *		ndr_svc_binding_pool_init(&conn->binding_list_head,
    222  *		    conn->binding_pool, N_BINDING_POOL);
    223  */
    224 typedef struct ndr_binding {
    225 	struct ndr_binding 	*next;
    226 	ndr_p_context_id_t	p_cont_id;
    227 	unsigned char		which_side;
    228 	struct ndr_client	*clnt;
    229 	ndr_service_t		*service;
    230 	void 			*instance_specific;
    231 } ndr_binding_t;
    232 
    233 #define	NDR_BIND_SIDE_CLIENT	1
    234 #define	NDR_BIND_SIDE_SERVER	2
    235 
    236 #define	NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \
    237 	((TYPE *) (BINDING)->instance_specific)
    238 
    239 /*
    240  * The binding list space must be provided by the application library
    241  * for use by the underlying RPC library.  We need at least two binding
    242  * slots per connection.
    243  */
    244 #define	NDR_N_BINDING_POOL	2
    245 
    246 typedef struct ndr_pipe {
    247 	int			np_fid;
    248 	smb_netuserinfo_t	np_user;
    249 	char			*np_buf;
    250 	struct uio		np_uio;
    251 	iovec_t			np_iov;
    252 	ndr_fraglist_t		np_frags;
    253 	int			np_refcnt;
    254 	uint16_t		np_max_xmit_frag;
    255 	uint16_t		np_max_recv_frag;
    256 	ndr_binding_t		*np_binding;
    257 	ndr_binding_t		np_binding_pool[NDR_N_BINDING_POOL];
    258 } ndr_pipe_t;
    259 
    260 typedef struct ndr_pipe_info {
    261 	uint32_t		npi_fid;
    262 	uint32_t		npi_permissions;
    263 	uint32_t		npi_num_locks;
    264 	char			npi_pathname[MAXPATHLEN];
    265 	char			npi_username[MAXNAMELEN];
    266 } ndr_pipe_info_t;
    267 
    268 /*
    269  * Number of bytes required to align SIZE on the next dword/4-byte
    270  * boundary.
    271  */
    272 #define	NDR_ALIGN4(SIZE)	((4 - (SIZE)) & 3);
    273 
    274 /*
    275  * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying
    276  * and conformant one-dimensional arrays. Characters can be single-byte
    277  * or multi-byte as long as all characters conform to a fixed element size,
    278  * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The
    279  * string is terminated by a null character of the appropriate element size.
    280  *
    281  * MSRPC strings should always be varying/conformant and not null terminated.
    282  * This format uses the size_is, first_is and length_is attributes (CAE
    283  * section 4.2.18).
    284  *
    285  *	typedef struct string {
    286  *		DWORD size_is;
    287  *		DWORD first_is;
    288  *		DWORD length_is;
    289  *		wchar_t string[ANY_SIZE_ARRAY];
    290  *	} string_t;
    291  *
    292  * The size_is attribute is used to specify the number of data elements in
    293  * each dimension of an array.
    294  *
    295  * The first_is attribute is used to define the lower bound for significant
    296  * elements in each dimension of an array. For strings this is always 0.
    297  *
    298  * The length_is attribute is used to define the number of significant
    299  * elements in each dimension of an array. For strings this is typically
    300  * the same as size_is. Although it might be (size_is - 1) if the string
    301  * is null terminated.
    302  *
    303  *   4 bytes   4 bytes   4 bytes  2bytes 2bytes 2bytes 2bytes
    304  * +---------+---------+---------+------+------+------+------+
    305  * |size_is  |first_is |length_is| char | char | char | char |
    306  * +---------+---------+---------+------+------+------+------+
    307  *
    308  * Unfortunately, not all MSRPC Unicode strings are null terminated, which
    309  * means that the recipient has to manually null-terminate the string after
    310  * it has been unmarshalled.  There may be a wide-char pad following a
    311  * string, and it may sometimes contains zero, but it's not guaranteed.
    312  *
    313  * To deal with this, MSRPC sometimes uses an additional wrapper with two
    314  * more fields, as shown below.
    315  *	length: the array length in bytes excluding terminating null bytes
    316  *	maxlen: the array length in bytes including null terminator bytes
    317  *	LPTSTR: converted to a string_t by NDR
    318  *
    319  * typedef struct ms_string {
    320  *		WORD length;
    321  *		WORD maxlen;
    322  *		LPTSTR str;
    323  * } ms_string_t;
    324  */
    325 typedef struct ndr_mstring {
    326 	uint16_t length;
    327 	uint16_t allosize;
    328 	LPTSTR str;
    329 } ndr_mstring_t;
    330 
    331 /*
    332  * A number of heap areas are used during marshalling and unmarshalling.
    333  * Under some circumstances these areas can be discarded by the library
    334  * code, i.e. on the server side before returning to the client and on
    335  * completion of a client side bind.  In the case of a client side RPC
    336  * call, these areas must be preserved after an RPC returns to give the
    337  * caller time to take a copy of the data.  In this case the client must
    338  * call ndr_clnt_free_heap to free the memory.
    339  *
    340  * The heap management data definition looks a bit like this:
    341  *
    342  * heap -> +---------------+     +------------+
    343  *         | iovec[0].base | --> | data block |
    344  *         | iovec[0].len  |     +------------+
    345  *         +---------------+
    346  *                ::
    347  *                ::
    348  * iov  -> +---------------+     +------------+
    349  *         | iovec[n].base | --> | data block |
    350  *         | iovec[n].len  |     +------------+
    351  *         +---------------+     ^            ^
    352  *                               |            |
    353  *    next ----------------------+            |
    354  *    top  -----------------------------------+
    355  *
    356  */
    357 
    358 /*
    359  * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes
    360  * of the first heap block.
    361  */
    362 #define	NDR_HEAP_MAXIOV		384
    363 #define	NDR_HEAP_BLKSZ		8192
    364 
    365 typedef struct ndr_heap {
    366 	struct iovec iovec[NDR_HEAP_MAXIOV];
    367 	struct iovec *iov;
    368 	int iovcnt;
    369 	char *top;
    370 	char *next;
    371 } ndr_heap_t;
    372 
    373 /*
    374  * Alternate varying/conformant string definition
    375  * - for non-null-terminated strings.
    376  */
    377 typedef struct ndr_vcs {
    378 	/*
    379 	 * size_is (actually a copy of length_is) will
    380 	 * be inserted here by the marshalling library.
    381 	 */
    382 	uint32_t vc_first_is;
    383 	uint32_t vc_length_is;
    384 	uint16_t buffer[ANY_SIZE_ARRAY];
    385 } ndr_vcs_t;
    386 
    387 typedef struct ndr_vcstr {
    388 	uint16_t wclen;
    389 	uint16_t wcsize;
    390 	ndr_vcs_t *vcs;
    391 } ndr_vcstr_t;
    392 
    393 typedef struct ndr_vcb {
    394 	/*
    395 	 * size_is (actually a copy of length_is) will
    396 	 * be inserted here by the marshalling library.
    397 	 */
    398 	uint32_t vc_first_is;
    399 	uint32_t vc_length_is;
    400 	uint8_t buffer[ANY_SIZE_ARRAY];
    401 } ndr_vcb_t;
    402 
    403 typedef struct ndr_vcbuf {
    404 	uint16_t len;
    405 	uint16_t size;
    406 	ndr_vcb_t *vcb;
    407 } ndr_vcbuf_t;
    408 
    409 ndr_heap_t *ndr_heap_create(void);
    410 void ndr_heap_destroy(ndr_heap_t *);
    411 void *ndr_heap_malloc(ndr_heap_t *, unsigned);
    412 void *ndr_heap_strdup(ndr_heap_t *, const char *);
    413 int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
    414 void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
    415 void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
    416 smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *);
    417 int ndr_heap_used(ndr_heap_t *);
    418 int ndr_heap_avail(ndr_heap_t *);
    419 
    420 #define	NDR_MALLOC(XA, SZ)	ndr_heap_malloc((XA)->heap, SZ)
    421 #define	NDR_NEW(XA, T)		ndr_heap_malloc((XA)->heap, sizeof (T))
    422 #define	NDR_NEWN(XA, T, N)	ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
    423 #define	NDR_STRDUP(XA, S)	ndr_heap_strdup((XA)->heap, (S))
    424 #define	NDR_MSTRING(XA, S, OUT)	ndr_heap_mstring((XA)->heap, (S), (OUT))
    425 #define	NDR_SIDDUP(XA, S)	ndr_heap_siddup((XA)->heap, (S))
    426 
    427 typedef struct ndr_xa {
    428 	int			fid;
    429 	unsigned short		ptype;		/* high bits special */
    430 	unsigned short		opnum;
    431 	ndr_stream_t		recv_nds;
    432 	ndr_hdr_t		recv_hdr;
    433 	ndr_stream_t		send_nds;
    434 	ndr_hdr_t		send_hdr;
    435 	ndr_binding_t		*binding;	/* what we're using */
    436 	ndr_binding_t		*binding_list;	/* from connection */
    437 	ndr_heap_t		*heap;
    438 	ndr_pipe_t		*pipe;
    439 } ndr_xa_t;
    440 
    441 /*
    442  * 20-byte opaque id used by various RPC services.
    443  */
    444 CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t;
    445 
    446 typedef struct ndr_client {
    447 	int (*xa_init)(struct ndr_client *, ndr_xa_t *);
    448 	int (*xa_exchange)(struct ndr_client *, ndr_xa_t *);
    449 	int (*xa_read)(struct ndr_client *, ndr_xa_t *);
    450 	void (*xa_preserve)(struct ndr_client *, ndr_xa_t *);
    451 	void (*xa_destruct)(struct ndr_client *, ndr_xa_t *);
    452 	void (*xa_release)(struct ndr_client *);
    453 
    454 	int			fid;
    455 	ndr_hdid_t		*handle;
    456 	ndr_binding_t		*binding;
    457 	ndr_binding_t		*binding_list;
    458 	ndr_binding_t		binding_pool[NDR_N_BINDING_POOL];
    459 
    460 	boolean_t		heap_preserved;
    461 	ndr_heap_t		*heap;
    462 	ndr_stream_t		*recv_nds;
    463 	ndr_stream_t		*send_nds;
    464 
    465 	uint32_t		next_call_id;
    466 	unsigned		next_p_cont_id;
    467 } ndr_client_t;
    468 
    469 typedef struct ndr_handle {
    470 	ndr_hdid_t		nh_id;
    471 	struct ndr_handle	*nh_next;
    472 	int			nh_fid;
    473 	int			nh_remote_os;
    474 	const ndr_service_t	*nh_svc;
    475 	ndr_client_t		*nh_clnt;
    476 	void			*nh_data;
    477 	void			(*nh_data_free)(void *);
    478 } ndr_handle_t;
    479 
    480 #define	NDR_PDU_SIZE_HINT_DEFAULT	(16*1024)
    481 #define	NDR_BUF_MAGIC			0x4E425546	/* NBUF */
    482 
    483 typedef struct ndr_buf {
    484 	uint32_t		nb_magic;
    485 	ndr_stream_t		nb_nds;
    486 	ndr_heap_t		*nb_heap;
    487 	ndr_typeinfo_t		*nb_ti;
    488 } ndr_buf_t;
    489 
    490 /* ndr_ops.c */
    491 void nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *);
    492 void nds_finalize(ndr_stream_t *, ndr_fraglist_t *);
    493 void nds_destruct(ndr_stream_t *);
    494 void nds_show_state(ndr_stream_t *);
    495 
    496 /* ndr_client.c */
    497 int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **);
    498 int ndr_clnt_call(ndr_binding_t *, int, void *);
    499 void ndr_clnt_free_heap(ndr_client_t *);
    500 
    501 /* ndr_marshal.c */
    502 ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *);
    503 void ndr_buf_fini(ndr_buf_t *);
    504 int ndr_buf_decode(ndr_buf_t *, unsigned, const char *data, size_t, void *);
    505 int ndr_decode_call(ndr_xa_t *, void *);
    506 int ndr_encode_return(ndr_xa_t *, void *);
    507 int ndr_encode_call(ndr_xa_t *, void *);
    508 int ndr_decode_return(ndr_xa_t *, void *);
    509 int ndr_decode_pdu_hdr(ndr_xa_t *);
    510 int ndr_encode_pdu_hdr(ndr_xa_t *);
    511 void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *);
    512 void ndr_show_hdr(ndr_common_header_t *);
    513 unsigned ndr_bind_ack_hdr_size(ndr_xa_t *);
    514 unsigned ndr_alter_context_rsp_hdr_size(void);
    515 
    516 /* ndr_server.c */
    517 int ndr_pipe_open(int, uint8_t *, uint32_t);
    518 int ndr_pipe_close(int);
    519 int ndr_pipe_read(int, uint8_t *, uint32_t *, uint32_t *);
    520 int ndr_pipe_write(int, uint8_t *, uint32_t);
    521 
    522 int ndr_generic_call_stub(ndr_xa_t *);
    523 
    524 boolean_t ndr_is_admin(ndr_xa_t *);
    525 boolean_t ndr_is_poweruser(ndr_xa_t *);
    526 int32_t ndr_native_os(ndr_xa_t *);
    527 
    528 /* ndr_svc.c */
    529 ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
    530 ndr_service_t *ndr_svc_lookup_name(const char *);
    531 ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int);
    532 int ndr_svc_register(ndr_service_t *);
    533 void ndr_svc_unregister(ndr_service_t *);
    534 void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int);
    535 ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t);
    536 ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *);
    537 
    538 int ndr_uuid_parse(char *, ndr_uuid_t *);
    539 void ndr_uuid_unparse(ndr_uuid_t *, char *);
    540 
    541 ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
    542 void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
    543 ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
    544 void ndr_hdclose(int fid);
    545 
    546 ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
    547 
    548 #ifdef	__cplusplus
    549 }
    550 #endif
    551 
    552 #endif	/* _LIBMLRPC_H */
    553