2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#ifndef _LIBNDR_H
2N/A#define _LIBNDR_H
2N/A
2N/A#include <sys/types.h>
2N/A#include <sys/uio.h>
2N/A#include <smb/wintypes.h>
2N/A#include <smbsrv/ndr.h>
2N/A#include <smb/smb_sid.h>
2N/A#include <smbsrv/smb_xdr.h>
2N/A
2N/A#ifdef __cplusplus
2N/Aextern "C" {
2N/A#endif
2N/A
2N/A/*
2N/A * An MSRPC compatible implementation of OSF DCE RPC. DCE RPC is derived
2N/A * from the Apollo Network Computing Architecture (NCA) RPC implementation.
2N/A *
2N/A * CAE Specification (1997)
2N/A * DCE 1.1: Remote Procedure Call
2N/A * Document Number: C706
2N/A * The Open Group
2N/A * ogspecs@opengroup.org
2N/A *
2N/A * This implementation is based on the DCE Remote Procedure Call spec with
2N/A * enhancements to support Unicode strings. The diagram below shows the
2N/A * DCE RPC layers compared against ONC SUN RPC.
2N/A *
2N/A * NDR RPC Layers Sun RPC Layers Remark
2N/A * +---------------+ +---------------+ +---------------+
2N/A * +---------------+ +---------------+
2N/A * | Application | | Application | The application
2N/A * +---------------+ +---------------+
2N/A * | Hand coded | | RPCGEN gen'd | Where the real
2N/A * | client/server | | client/server | work happens
2N/A * | srvsvc.ndl | | *_svc.c *_clnt|
2N/A * | srvsvc.c | | |
2N/A * +---------------+ +---------------+
2N/A * | RPC Library | | RPC Library | Calls/Return
2N/A * | ndr_*.c | | | Binding/PMAP
2N/A * +---------------+ +---------------+
2N/A * | RPC Protocol | | RPC Protocol | Headers, Auth,
2N/A * | rpcpdu.ndl | | |
2N/A * +---------------+ +---------------+
2N/A * | IDL gen'd | | RPCGEN gen'd | Aggregate
2N/A * | NDR stubs | | XDR stubs | Composition
2N/A * | *__ndr.c | | *_xdr.c |
2N/A * +---------------+ +---------------+
2N/A * | NDR Represen | | XDR Represen | Byte order, padding
2N/A * +---------------+ +---------------+
2N/A * | Packet Heaps | | Network Conn | DCERPC does not talk
2N/A * | ndo_*.c | | clnt_{tcp,udp}| directly to network.
2N/A * +---------------+ +---------------+
2N/A *
2N/A * There are two major differences between the DCE RPC and ONC RPC:
2N/A *
2N/A * 1. NDR RPC only generates or processes packets from buffers. Other
2N/A * layers must take care of packet transmission and reception.
2N/A * The packet heaps are managed through a simple interface provided
2N/A * by the Network Data Representation (NDR) module called ndr_stream_t.
2N/A * ndo_*.c modules implement the different flavors (operations) of
2N/A * packet heaps.
2N/A *
2N/A * ONC RPC communicates directly with the network. You have to do
2N/A * something special for the RPC packet to be placed in a buffer
2N/A * rather than sent to the wire.
2N/A *
2N/A * 2. NDR RPC uses application provided heaps to support operations.
2N/A * A heap is a single, monolithic chunk of memory that NDR RPC manages
2N/A * as it allocates. When the operation and its result are done, the
2N/A * heap is disposed of as a single item. The transaction, which
2N/A * is the anchor of most operations, contains the necessary book-
2N/A * keeping for the heap.
2N/A *
2N/A * ONC RPC uses malloc() liberally throughout its run-time system.
2N/A * To free results, ONC RPC supports an XDR_FREE operation that
2N/A * traverses data structures freeing memory as it goes, whether
2N/A * it was malloc'd or not.
2N/A */
2N/A
2N/A/*
2N/A * Dispatch Return Code (DRC)
2N/A *
2N/A * 0x8000 15:01 Set to indicate a fault, clear indicates status
2N/A * 0x7F00 08:07 Status/Fault specific
2N/A * 0x00FF 00:08 PTYPE_... of PDU, 0xFF for header
2N/A */
2N/A#define NDR_DRC_OK 0x0000
2N/A#define NDR_DRC_MASK_FAULT 0x8000
2N/A#define NDR_DRC_MASK_SPECIFIER 0xFF00
2N/A#define NDR_DRC_MASK_PTYPE 0x00FF
2N/A
2N/A/* Fake PTYPE DRC discriminators */
2N/A#define NDR_DRC_PTYPE_RPCHDR(DRC) ((DRC) | 0x00FF)
2N/A#define NDR_DRC_PTYPE_API(DRC) ((DRC) | 0x00AA)
2N/A
2N/A/* DRC Recognizers */
2N/A#define NDR_DRC_IS_OK(DRC) (((DRC) & NDR_DRC_MASK_SPECIFIER) == 0)
2N/A#define NDR_DRC_IS_FAULT(DRC) (((DRC) & NDR_DRC_MASK_FAULT) != 0)
2N/A
2N/A/*
2N/A * (Un)Marshalling category specifiers
2N/A */
2N/A#define NDR_DRC_FAULT_MODE_MISMATCH 0x8100
2N/A#define NDR_DRC_RECEIVED 0x0200
2N/A#define NDR_DRC_FAULT_RECEIVED_RUNT 0x8300
2N/A#define NDR_DRC_FAULT_RECEIVED_MALFORMED 0x8400
2N/A#define NDR_DRC_DECODED 0x0500
2N/A#define NDR_DRC_FAULT_DECODE_FAILED 0x8600
2N/A#define NDR_DRC_ENCODED 0x0700
2N/A#define NDR_DRC_FAULT_ENCODE_FAILED 0x8800
2N/A#define NDR_DRC_FAULT_ENCODE_TOO_BIG 0x8900
2N/A#define NDR_DRC_SENT 0x0A00
2N/A#define NDR_DRC_FAULT_SEND_FAILED 0x8B00
2N/A
2N/A/*
2N/A * Resource category specifier
2N/A */
2N/A#define NDR_DRC_FAULT_RESOURCE_1 0x9100
2N/A#define NDR_DRC_FAULT_RESOURCE_2 0x9200
2N/A
2N/A/*
2N/A * Parameters. Usually #define'd with useful alias
2N/A */
2N/A#define NDR_DRC_FAULT_PARAM_0_INVALID 0xC000
2N/A#define NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED 0xD000
2N/A#define NDR_DRC_FAULT_PARAM_1_INVALID 0xC100
2N/A#define NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED 0xD100
2N/A#define NDR_DRC_FAULT_PARAM_2_INVALID 0xC200
2N/A#define NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED 0xD200
2N/A#define NDR_DRC_FAULT_PARAM_3_INVALID 0xC300
2N/A#define NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED 0xD300
2N/A
2N/A#define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000
2N/A
2N/A/* RPCHDR */
2N/A#define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF
2N/A#define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF
2N/A#define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF
2N/A#define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */
2N/A#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */
2N/A
2N/A/* Request */
2N/A#define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */
2N/A#define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */
2N/A
2N/A/* Bind */
2N/A#define NDR_DRC_BINDING_MADE 0x000B /* OK */
2N/A#define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */
2N/A#define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */
2N/A#define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */
2N/A
2N/A/* API */
2N/A#define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */
2N/A#define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA /* RESOURCE_1 */
2N/A#define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA /* PARAM_1_INVALID */
2N/A
2N/Astruct ndr_xa;
2N/Astruct ndr_client;
2N/A
2N/Atypedef struct ndr_stub_table {
2N/A int (*func)(void *, struct ndr_xa *);
2N/A unsigned short opnum;
2N/A} ndr_stub_table_t;
2N/A
2N/Atypedef struct ndr_service {
2N/A char *name;
2N/A char *desc;
2N/A char *endpoint;
2N/A char *sec_addr_port;
2N/A char *abstract_syntax_uuid;
2N/A int abstract_syntax_version;
2N/A char *transfer_syntax_uuid;
2N/A int transfer_syntax_version;
2N/A unsigned bind_instance_size;
2N/A int (*bind_req)();
2N/A int (*unbind_and_close)();
2N/A int (*call_stub)(struct ndr_xa *);
2N/A ndr_typeinfo_t *interface_ti;
2N/A ndr_stub_table_t *stub_table;
2N/A} ndr_service_t;
2N/A
2N/A/*
2N/A * The list of bindings is anchored at a connection. Nothing in the
2N/A * RPC mechanism allocates them. Binding elements which have service==0
2N/A * indicate free elements. When a connection is instantiated, at least
2N/A * one free binding entry should also be established. Something like
2N/A * this should suffice for most (all) situations:
2N/A *
2N/A * struct connection {
2N/A * ....
2N/A * ndr_binding_t *binding_list_head;
2N/A * ndr_binding_t binding_pool[N_BINDING_POOL];
2N/A * ....
2N/A * };
2N/A *
2N/A * init_connection(struct connection *conn) {
2N/A * ....
2N/A * ndr_svc_binding_pool_init(&conn->binding_list_head,
2N/A * conn->binding_pool, N_BINDING_POOL);
2N/A */
2N/Atypedef struct ndr_binding {
2N/A struct ndr_binding *next;
2N/A ndr_p_context_id_t p_cont_id;
2N/A unsigned char which_side;
2N/A struct ndr_client *clnt;
2N/A ndr_service_t *service;
2N/A void *instance_specific;
2N/A} ndr_binding_t;
2N/A
2N/A#define NDR_BIND_SIDE_CLIENT 1
2N/A#define NDR_BIND_SIDE_SERVER 2
2N/A
2N/A#define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \
2N/A ((TYPE *) (BINDING)->instance_specific)
2N/A
2N/A/*
2N/A * The binding list space must be provided by the application library
2N/A * for use by the underlying RPC library. We need at least two binding
2N/A * slots per connection.
2N/A */
2N/A#define NDR_N_BINDING_POOL 2
2N/A
2N/Atypedef struct ndr_pipe {
2N/A int np_fid;
2N/A uint32_t np_txid;
2N/A smb_netuserinfo_t np_user;
2N/A char *np_buf;
2N/A struct uio np_uio;
2N/A iovec_t np_iov;
2N/A ndr_fraglist_t np_frags;
2N/A int np_refcnt;
2N/A uint16_t np_max_xmit_frag;
2N/A uint16_t np_max_recv_frag;
2N/A ndr_binding_t *np_binding;
2N/A ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL];
2N/A} ndr_pipe_t;
2N/A
2N/Atypedef struct ndr_pipe_info {
2N/A uint32_t npi_fid;
2N/A uint32_t npi_permissions;
2N/A uint32_t npi_num_locks;
2N/A char npi_pathname[MAXPATHLEN];
2N/A char npi_username[MAXNAMELEN];
2N/A} ndr_pipe_info_t;
2N/A
2N/A/*
2N/A * Number of bytes required to align SIZE on the next dword/4-byte
2N/A * boundary.
2N/A */
2N/A#define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3);
2N/A
2N/A/*
2N/A * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying
2N/A * and conformant one-dimensional arrays. Characters can be single-byte
2N/A * or multi-byte as long as all characters conform to a fixed element size,
2N/A * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The
2N/A * string is terminated by a null character of the appropriate element size.
2N/A *
2N/A * MSRPC strings should always be varying/conformant and not null terminated.
2N/A * This format uses the size_is, first_is and length_is attributes (CAE
2N/A * section 4.2.18).
2N/A *
2N/A * typedef struct string {
2N/A * DWORD size_is;
2N/A * DWORD first_is;
2N/A * DWORD length_is;
2N/A * wchar_t string[ANY_SIZE_ARRAY];
2N/A * } string_t;
2N/A *
2N/A * The size_is attribute is used to specify the number of data elements in
2N/A * each dimension of an array.
2N/A *
2N/A * The first_is attribute is used to define the lower bound for significant
2N/A * elements in each dimension of an array. For strings this is always 0.
2N/A *
2N/A * The length_is attribute is used to define the number of significant
2N/A * elements in each dimension of an array. For strings this is typically
2N/A * the same as size_is. Although it might be (size_is - 1) if the string
2N/A * is null terminated.
2N/A *
2N/A * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes
2N/A * +---------+---------+---------+------+------+------+------+
2N/A * |size_is |first_is |length_is| char | char | char | char |
2N/A * +---------+---------+---------+------+------+------+------+
2N/A *
2N/A * Unfortunately, not all MSRPC Unicode strings are null terminated, which
2N/A * means that the recipient has to manually null-terminate the string after
2N/A * it has been unmarshalled. There may be a wide-char pad following a
2N/A * string, and it may sometimes contains zero, but it's not guaranteed.
2N/A *
2N/A * To deal with this, MSRPC sometimes uses an additional wrapper with two
2N/A * more fields, as shown below.
2N/A * length: the array length in bytes excluding terminating null bytes
2N/A * maxlen: the array length in bytes including null terminator bytes
2N/A * LPTSTR: converted to a string_t by NDR
2N/A *
2N/A * typedef struct ms_string {
2N/A * WORD length;
2N/A * WORD maxlen;
2N/A * LPTSTR str;
2N/A * } ms_string_t;
2N/A */
2N/Atypedef struct ndr_mstring {
2N/A uint16_t length;
2N/A uint16_t allosize;
2N/A LPTSTR str;
2N/A} ndr_mstring_t;
2N/A
2N/A/*
2N/A * A number of heap areas are used during marshalling and unmarshalling.
2N/A * Under some circumstances these areas can be discarded by the library
2N/A * code, i.e. on the server side before returning to the client and on
2N/A * completion of a client side bind. In the case of a client side RPC
2N/A * call, these areas must be preserved after an RPC returns to give the
2N/A * caller time to take a copy of the data. In this case the client must
2N/A * call ndr_clnt_free_heap to free the memory.
2N/A *
2N/A * The heap management data definition looks a bit like this:
2N/A *
2N/A * heap -> +---------------+ +------------+
2N/A * | iovec[0].base | --> | data block |
2N/A * | iovec[0].len | +------------+
2N/A * +---------------+
2N/A * ::
2N/A * ::
2N/A * iov -> +---------------+ +------------+
2N/A * | iovec[n].base | --> | data block |
2N/A * | iovec[n].len | +------------+
2N/A * +---------------+ ^ ^
2N/A * | |
2N/A * next ----------------------+ |
2N/A * top -----------------------------------+
2N/A *
2N/A */
2N/A
2N/A/*
2N/A * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes
2N/A * of the first heap block.
2N/A */
2N/A#define NDR_HEAP_MAXIOV 384
2N/A#define NDR_HEAP_BLKSZ 8192
2N/A
2N/Atypedef struct ndr_heap {
2N/A struct iovec iovec[NDR_HEAP_MAXIOV];
2N/A struct iovec *iov;
2N/A int iovcnt;
2N/A char *top;
2N/A char *next;
2N/A} ndr_heap_t;
2N/A
2N/A/*
2N/A * Alternate varying/conformant string definition
2N/A * - for non-null-terminated strings.
2N/A */
2N/Atypedef struct ndr_vcs {
2N/A /*
2N/A * size_is (actually a copy of length_is) will
2N/A * be inserted here by the marshalling library.
2N/A */
2N/A uint32_t vc_first_is;
2N/A uint32_t vc_length_is;
2N/A uint16_t buffer[ANY_SIZE_ARRAY];
2N/A} ndr_vcs_t;
2N/A
2N/Atypedef struct ndr_vcstr {
2N/A uint16_t wclen;
2N/A uint16_t wcsize;
2N/A ndr_vcs_t *vcs;
2N/A} ndr_vcstr_t;
2N/A
2N/Atypedef struct ndr_vcb {
2N/A /*
2N/A * size_is (actually a copy of length_is) will
2N/A * be inserted here by the marshalling library.
2N/A */
2N/A uint32_t vc_first_is;
2N/A uint32_t vc_length_is;
2N/A uint8_t buffer[ANY_SIZE_ARRAY];
2N/A} ndr_vcb_t;
2N/A
2N/Atypedef struct ndr_vcbuf {
2N/A uint16_t len;
2N/A uint16_t size;
2N/A ndr_vcb_t *vcb;
2N/A} ndr_vcbuf_t;
2N/A
2N/Andr_heap_t *ndr_heap_create(void);
2N/Avoid ndr_heap_destroy(ndr_heap_t *);
2N/Avoid *ndr_heap_malloc(ndr_heap_t *, unsigned);
2N/Avoid *ndr_heap_strdup(ndr_heap_t *, const char *);
2N/Aint ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
2N/Avoid ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
2N/Avoid ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
2N/Asmb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *);
2N/Aint ndr_heap_used(ndr_heap_t *);
2N/Aint ndr_heap_avail(ndr_heap_t *);
2N/A
2N/A#define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ)
2N/A#define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T))
2N/A#define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
2N/A#define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S))
2N/A#define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT))
2N/A#define NDR_SIDDUP(XA, S) ndr_heap_siddup((XA)->heap, (S))
2N/A
2N/Atypedef struct ndr_xa {
2N/A int fid;
2N/A unsigned short ptype; /* high bits special */
2N/A unsigned short opnum;
2N/A ndr_stream_t recv_nds;
2N/A ndr_hdr_t recv_hdr;
2N/A ndr_stream_t send_nds;
2N/A ndr_hdr_t send_hdr;
2N/A ndr_binding_t *binding; /* what we're using */
2N/A ndr_binding_t *binding_list; /* from connection */
2N/A ndr_heap_t *heap;
2N/A ndr_pipe_t *pipe;
2N/A} ndr_xa_t;
2N/A
2N/A/*
2N/A * 20-byte opaque id used by various RPC services.
2N/A */
2N/ACONTEXT_HANDLE(ndr_hdid) ndr_hdid_t;
2N/A
2N/Atypedef struct ndr_client {
2N/A int (*xa_init)(struct ndr_client *, ndr_xa_t *);
2N/A int (*xa_exchange)(struct ndr_client *, ndr_xa_t *);
2N/A int (*xa_read)(struct ndr_client *, ndr_xa_t *);
2N/A void (*xa_preserve)(struct ndr_client *, ndr_xa_t *);
2N/A void (*xa_destruct)(struct ndr_client *, ndr_xa_t *);
2N/A void (*xa_release)(struct ndr_client *);
2N/A
2N/A int fid;
2N/A ndr_hdid_t *handle;
2N/A ndr_binding_t *binding;
2N/A ndr_binding_t *binding_list;
2N/A ndr_binding_t binding_pool[NDR_N_BINDING_POOL];
2N/A
2N/A boolean_t nonull;
2N/A boolean_t heap_preserved;
2N/A ndr_heap_t *heap;
2N/A ndr_stream_t *recv_nds;
2N/A ndr_stream_t *send_nds;
2N/A
2N/A uint32_t next_call_id;
2N/A unsigned next_p_cont_id;
2N/A} ndr_client_t;
2N/A
2N/Atypedef struct ndr_handle {
2N/A ndr_hdid_t nh_id;
2N/A struct ndr_handle *nh_next;
2N/A int nh_fid;
2N/A const ndr_service_t *nh_svc;
2N/A ndr_client_t *nh_clnt;
2N/A void *nh_data;
2N/A void (*nh_data_free)(void *);
2N/A} ndr_handle_t;
2N/A
2N/A#define NDR_PDU_SIZE_HINT_DEFAULT (16*1024)
2N/A#define NDR_BUF_MAGIC 0x4E425546 /* NBUF */
2N/A
2N/Atypedef struct ndr_buf {
2N/A uint32_t nb_magic;
2N/A ndr_stream_t nb_nds;
2N/A ndr_heap_t *nb_heap;
2N/A ndr_typeinfo_t *nb_ti;
2N/A} ndr_buf_t;
2N/A
2N/A/* ndr_ops.c */
2N/Aint nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *);
2N/Avoid nds_finalize(ndr_stream_t *, ndr_fraglist_t *);
2N/Avoid nds_destruct(ndr_stream_t *);
2N/Avoid nds_show_state(ndr_stream_t *);
2N/A
2N/A/* ndr_client.c */
2N/Aint ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **);
2N/Aint ndr_clnt_call(ndr_binding_t *, int, void *);
2N/Avoid ndr_clnt_free_heap(ndr_client_t *);
2N/A
2N/A/* ndr_marshal.c */
2N/Andr_buf_t *ndr_buf_init(ndr_typeinfo_t *);
2N/Avoid ndr_buf_fini(ndr_buf_t *);
2N/Aint ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t,
2N/A void *);
2N/Aint ndr_decode_call(ndr_xa_t *, void *);
2N/Aint ndr_encode_return(ndr_xa_t *, void *);
2N/Aint ndr_encode_call(ndr_xa_t *, void *);
2N/Aint ndr_decode_return(ndr_xa_t *, void *);
2N/Aint ndr_decode_pdu_hdr(ndr_xa_t *);
2N/Aint ndr_encode_pdu_hdr(ndr_xa_t *);
2N/Avoid ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *);
2N/Avoid ndr_remove_frag_hdr(ndr_stream_t *);
2N/Avoid ndr_show_hdr(ndr_common_header_t *);
2N/Aunsigned ndr_bind_ack_hdr_size(ndr_xa_t *);
2N/Aunsigned ndr_alter_context_rsp_hdr_size(void);
2N/A
2N/A/* ndr_server.c */
2N/Aint ndr_pipe_open(int, uint8_t *, uint32_t);
2N/Aint ndr_pipe_close(int);
2N/Aint ndr_pipe_read(int, uint8_t *, uint32_t *, uint32_t *);
2N/Aint ndr_pipe_write(int, uint8_t *, uint32_t);
2N/Avoid *ndr_pipe_transact(void *);
2N/A
2N/Aint ndr_generic_call_stub(ndr_xa_t *);
2N/A
2N/Aboolean_t ndr_is_admin(ndr_xa_t *);
2N/Aboolean_t ndr_is_poweruser(ndr_xa_t *);
2N/Aint32_t ndr_native_os(ndr_xa_t *);
2N/A
2N/A/* ndr_svc.c */
2N/Andr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
2N/Andr_service_t *ndr_svc_lookup_name(const char *);
2N/Andr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int);
2N/Aint ndr_svc_register(ndr_service_t *);
2N/Avoid ndr_svc_unregister(ndr_service_t *);
2N/Avoid ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int);
2N/Andr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t);
2N/Andr_binding_t *ndr_svc_new_binding(ndr_xa_t *);
2N/A
2N/Aint ndr_uuid_parse(char *, ndr_uuid_t *);
2N/Avoid ndr_uuid_unparse(ndr_uuid_t *, char *);
2N/A
2N/Andr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
2N/Avoid ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
2N/Andr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
2N/Avoid ndr_hdclose(int fid);
2N/A
2N/Assize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
2N/A
2N/A#ifdef __cplusplus
2N/A}
2N/A#endif
2N/A
2N/A#endif /* _LIBNDR_H */