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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  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@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_MODE_MISMATCH      0x81FF
 163 #define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT      0x83FF
 164 #define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED      0x86FF
 165 #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID      0xC0FF  /* PARAM_0_INVALID */
 166 #define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */
 167 
 168 /* Request */
 169 #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID     0xC000  /* PARAM_0_INVALID */
 170 #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID     0xC100  /* PARAM_1_INVALID */
 171 
 172 /* Bind */
 173 #define NDR_DRC_BINDING_MADE                    0x000B  /* OK */
 174 #define NDR_DRC_FAULT_BIND_PCONT_BUSY           0xC00B  /* PARAM_0_INVALID */
 175 #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE      0xC10B  /* PARAM_1_INVALID */
 176 #define NDR_DRC_FAULT_BIND_NO_SLOTS             0x910B  /* RESOURCE_1 */
 177 
 178 /* API */
 179 #define NDR_DRC_FAULT_API_SERVICE_INVALID       0xC0AA  /* PARAM_0_INVALID */
 180 #define NDR_DRC_FAULT_API_BIND_NO_SLOTS         0x91AA  /* RESOURCE_1 */
 181 #define NDR_DRC_FAULT_API_OPNUM_INVALID         0xC1AA  /* PARAM_1_INVALID */
 182 
 183 struct ndr_xa;
 184 struct ndr_client;
 185 
 186 typedef struct ndr_stub_table {
 187         int             (*func)(void *, struct ndr_xa *);
 188         unsigned short  opnum;
 189 } ndr_stub_table_t;
 190 
 191 typedef struct ndr_service {
 192         char            *name;
 193         char            *desc;
 194         char            *endpoint;
 195         char            *sec_addr_port;
 196         char            *abstract_syntax_uuid;
 197         int             abstract_syntax_version;
 198         char            *transfer_syntax_uuid;
 199         int             transfer_syntax_version;
 200         unsigned        bind_instance_size;
 201         int             (*bind_req)();
 202         int             (*unbind_and_close)();
 203         int             (*call_stub)(struct ndr_xa *);
 204         ndr_typeinfo_t  *interface_ti;
 205         ndr_stub_table_t *stub_table;
 206 } ndr_service_t;
 207 
 208 /*
 209  * The list of bindings is anchored at a connection.  Nothing in the
 210  * RPC mechanism allocates them.  Binding elements which have service==0
 211  * indicate free elements.  When a connection is instantiated, at least
 212  * one free binding entry should also be established.  Something like
 213  * this should suffice for most (all) situations:
 214  *
 215  *      struct connection {
 216  *              ....
 217  *              ndr_binding_t *binding_list_head;
 218  *              ndr_binding_t binding_pool[N_BINDING_POOL];
 219  *              ....
 220  *      };
 221  *
 222  *      init_connection(struct connection *conn) {
 223  *              ....
 224  *              ndr_svc_binding_pool_init(&conn->binding_list_head,
 225  *                  conn->binding_pool, N_BINDING_POOL);
 226  */
 227 typedef struct ndr_binding {
 228         struct ndr_binding      *next;
 229         ndr_p_context_id_t      p_cont_id;
 230         unsigned char           which_side;
 231         struct ndr_client       *clnt;
 232         ndr_service_t           *service;
 233         void                    *instance_specific;
 234 } ndr_binding_t;
 235 
 236 #define NDR_BIND_SIDE_CLIENT    1
 237 #define NDR_BIND_SIDE_SERVER    2
 238 
 239 #define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \
 240         ((TYPE *) (BINDING)->instance_specific)
 241 
 242 /*
 243  * The binding list space must be provided by the application library
 244  * for use by the underlying RPC library.  We need at least two binding
 245  * slots per connection.
 246  */
 247 #define NDR_N_BINDING_POOL      2
 248 
 249 typedef struct ndr_pipe {
 250         void                    *np_listener;
 251         const char              *np_endpoint;
 252         smb_netuserinfo_t       *np_user;
 253         int                     (*np_send)(struct ndr_pipe *, void *, size_t);
 254         int                     (*np_recv)(struct ndr_pipe *, void *, size_t);
 255         int                     np_fid;
 256         uint16_t                np_max_xmit_frag;
 257         uint16_t                np_max_recv_frag;
 258         ndr_binding_t           *np_binding;
 259         ndr_binding_t           np_binding_pool[NDR_N_BINDING_POOL];
 260 } ndr_pipe_t;
 261 
 262 /*
 263  * Number of bytes required to align SIZE on the next dword/4-byte
 264  * boundary.
 265  */
 266 #define NDR_ALIGN4(SIZE)        ((4 - (SIZE)) & 3);
 267 
 268 /*
 269  * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying
 270  * and conformant one-dimensional arrays. Characters can be single-byte
 271  * or multi-byte as long as all characters conform to a fixed element size,
 272  * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The
 273  * string is terminated by a null character of the appropriate element size.
 274  *
 275  * MSRPC strings should always be varying/conformant and not null terminated.
 276  * This format uses the size_is, first_is and length_is attributes (CAE
 277  * section 4.2.18).
 278  *
 279  *      typedef struct string {
 280  *              DWORD size_is;
 281  *              DWORD first_is;
 282  *              DWORD length_is;
 283  *              wchar_t string[ANY_SIZE_ARRAY];
 284  *      } string_t;
 285  *
 286  * The size_is attribute is used to specify the number of data elements in
 287  * each dimension of an array.
 288  *
 289  * The first_is attribute is used to define the lower bound for significant
 290  * elements in each dimension of an array. For strings this is always 0.
 291  *
 292  * The length_is attribute is used to define the number of significant
 293  * elements in each dimension of an array. For strings this is typically
 294  * the same as size_is. Although it might be (size_is - 1) if the string
 295  * is null terminated.
 296  *
 297  *   4 bytes   4 bytes   4 bytes  2bytes 2bytes 2bytes 2bytes
 298  * +---------+---------+---------+------+------+------+------+
 299  * |size_is  |first_is |length_is| char | char | char | char |
 300  * +---------+---------+---------+------+------+------+------+
 301  *
 302  * Unfortunately, not all MSRPC Unicode strings are null terminated, which
 303  * means that the recipient has to manually null-terminate the string after
 304  * it has been unmarshalled.  There may be a wide-char pad following a
 305  * string, and it may sometimes contains zero, but it's not guaranteed.
 306  *
 307  * To deal with this, MSRPC sometimes uses an additional wrapper with two
 308  * more fields, as shown below.
 309  *      length: the array length in bytes excluding terminating null bytes
 310  *      maxlen: the array length in bytes including null terminator bytes
 311  *      LPTSTR: converted to a string_t by NDR
 312  *
 313  * typedef struct ms_string {
 314  *              WORD length;
 315  *              WORD maxlen;
 316  *              LPTSTR str;
 317  * } ms_string_t;
 318  */
 319 typedef struct ndr_mstring {
 320         uint16_t length;
 321         uint16_t allosize;
 322         LPTSTR str;
 323 } ndr_mstring_t;
 324 
 325 /*
 326  * A number of heap areas are used during marshalling and unmarshalling.
 327  * Under some circumstances these areas can be discarded by the library
 328  * code, i.e. on the server side before returning to the client and on
 329  * completion of a client side bind.  In the case of a client side RPC
 330  * call, these areas must be preserved after an RPC returns to give the
 331  * caller time to take a copy of the data.  In this case the client must
 332  * call ndr_clnt_free_heap to free the memory.
 333  *
 334  * The heap management data definition looks a bit like this:
 335  *
 336  * heap -> +---------------+     +------------+
 337  *         | iovec[0].base | --> | data block |
 338  *         | iovec[0].len  |     +------------+
 339  *         +---------------+
 340  *                ::
 341  *                ::
 342  * iov  -> +---------------+     +------------+
 343  *         | iovec[n].base | --> | data block |
 344  *         | iovec[n].len  |     +------------+
 345  *         +---------------+     ^            ^
 346  *                               |            |
 347  *    next ----------------------+            |
 348  *    top  -----------------------------------+
 349  *
 350  */
 351 
 352 /*
 353  * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes
 354  * of the first heap block.
 355  */
 356 #define NDR_HEAP_MAXIOV         384
 357 #define NDR_HEAP_BLKSZ          8192
 358 
 359 typedef struct ndr_heap {
 360         struct iovec iovec[NDR_HEAP_MAXIOV];
 361         struct iovec *iov;
 362         int iovcnt;
 363         char *top;
 364         char *next;
 365 } ndr_heap_t;
 366 
 367 /*
 368  * Alternate varying/conformant string definition
 369  * - for non-null-terminated strings.
 370  */
 371 typedef struct ndr_vcs {
 372         /*
 373          * size_is (actually a copy of length_is) will
 374          * be inserted here by the marshalling library.
 375          */
 376         uint32_t vc_first_is;
 377         uint32_t vc_length_is;
 378         uint16_t buffer[ANY_SIZE_ARRAY];
 379 } ndr_vcs_t;
 380 
 381 typedef struct ndr_vcstr {
 382         uint16_t wclen;
 383         uint16_t wcsize;
 384         ndr_vcs_t *vcs;
 385 } ndr_vcstr_t;
 386 
 387 typedef struct ndr_vcb {
 388         /*
 389          * size_is (actually a copy of length_is) will
 390          * be inserted here by the marshalling library.
 391          */
 392         uint32_t vc_first_is;
 393         uint32_t vc_length_is;
 394         uint8_t buffer[ANY_SIZE_ARRAY];
 395 } ndr_vcb_t;
 396 
 397 typedef struct ndr_vcbuf {
 398         uint16_t len;
 399         uint16_t size;
 400         ndr_vcb_t *vcb;
 401 } ndr_vcbuf_t;
 402 
 403 ndr_heap_t *ndr_heap_create(void);
 404 void ndr_heap_destroy(ndr_heap_t *);
 405 void *ndr_heap_malloc(ndr_heap_t *, unsigned);
 406 void *ndr_heap_strdup(ndr_heap_t *, const char *);
 407 int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
 408 void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
 409 void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
 410 smb_sid_t *ndr_heap_siddup(ndr_heap_t *, smb_sid_t *);
 411 int ndr_heap_used(ndr_heap_t *);
 412 int ndr_heap_avail(ndr_heap_t *);
 413 
 414 #define NDR_MALLOC(XA, SZ)      ndr_heap_malloc((XA)->heap, SZ)
 415 #define NDR_NEW(XA, T)          ndr_heap_malloc((XA)->heap, sizeof (T))
 416 #define NDR_NEWN(XA, T, N)      ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
 417 #define NDR_STRDUP(XA, S)       ndr_heap_strdup((XA)->heap, (S))
 418 #define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT))
 419 #define NDR_SIDDUP(XA, S)       ndr_heap_siddup((XA)->heap, (S))
 420 
 421 typedef struct ndr_xa {
 422         unsigned short          ptype;          /* high bits special */
 423         unsigned short          opnum;
 424         ndr_stream_t            recv_nds;
 425         ndr_hdr_t               recv_hdr;
 426         ndr_stream_t            send_nds;
 427         ndr_hdr_t               send_hdr;
 428         ndr_binding_t           *binding;       /* what we're using */
 429         ndr_binding_t           *binding_list;  /* from connection */
 430         ndr_heap_t              *heap;
 431         ndr_pipe_t              *pipe;
 432 } ndr_xa_t;
 433 
 434 /*
 435  * 20-byte opaque id used by various RPC services.
 436  */
 437 CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t;
 438 
 439 typedef struct ndr_client {
 440         /* transport stuff (xa_* members) */
 441         int (*xa_init)(struct ndr_client *, ndr_xa_t *);
 442         int (*xa_exchange)(struct ndr_client *, ndr_xa_t *);
 443         int (*xa_read)(struct ndr_client *, ndr_xa_t *);
 444         void (*xa_preserve)(struct ndr_client *, ndr_xa_t *);
 445         void (*xa_destruct)(struct ndr_client *, ndr_xa_t *);
 446         void (*xa_release)(struct ndr_client *);
 447         void                    *xa_private;
 448         int                     xa_fd;
 449 
 450         ndr_hdid_t              *handle;
 451         ndr_binding_t           *binding;
 452         ndr_binding_t           *binding_list;
 453         ndr_binding_t           binding_pool[NDR_N_BINDING_POOL];
 454 
 455         boolean_t               nonull;
 456         boolean_t               heap_preserved;
 457         ndr_heap_t              *heap;
 458         ndr_stream_t            *recv_nds;
 459         ndr_stream_t            *send_nds;
 460 
 461         uint32_t                next_call_id;
 462         unsigned                next_p_cont_id;
 463 } ndr_client_t;
 464 
 465 typedef struct ndr_handle {
 466         ndr_hdid_t              nh_id;
 467         struct ndr_handle       *nh_next;
 468         ndr_pipe_t              *nh_pipe;
 469         const ndr_service_t     *nh_svc;
 470         ndr_client_t            *nh_clnt;
 471         void                    *nh_data;
 472         void                    (*nh_data_free)(void *);
 473 } ndr_handle_t;
 474 
 475 #define NDR_PDU_SIZE_HINT_DEFAULT       (16*1024)
 476 #define NDR_BUF_MAGIC                   0x4E425546      /* NBUF */
 477 
 478 typedef struct ndr_buf {
 479         uint32_t                nb_magic;
 480         ndr_stream_t            nb_nds;
 481         ndr_heap_t              *nb_heap;
 482         ndr_typeinfo_t          *nb_ti;
 483 } ndr_buf_t;
 484 
 485 /* ndr_ops.c */
 486 int nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *);
 487 void nds_destruct(ndr_stream_t *);
 488 void nds_show_state(ndr_stream_t *);
 489 
 490 /* ndr_client.c */
 491 int ndr_clnt_bind(ndr_client_t *, const char *, ndr_binding_t **);
 492 int ndr_clnt_call(ndr_binding_t *, int, void *);
 493 void ndr_clnt_free_heap(ndr_client_t *);
 494 
 495 /* ndr_marshal.c */
 496 ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *);
 497 void ndr_buf_fini(ndr_buf_t *);
 498 int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t,
 499     void *);
 500 int ndr_decode_call(ndr_xa_t *, void *);
 501 int ndr_encode_return(ndr_xa_t *, void *);
 502 int ndr_encode_call(ndr_xa_t *, void *);
 503 int ndr_decode_return(ndr_xa_t *, void *);
 504 int ndr_decode_pdu_hdr(ndr_xa_t *);
 505 int ndr_encode_pdu_hdr(ndr_xa_t *);
 506 void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *);
 507 void ndr_remove_frag_hdr(ndr_stream_t *);
 508 void ndr_show_hdr(ndr_common_header_t *);
 509 unsigned ndr_bind_ack_hdr_size(ndr_xa_t *);
 510 unsigned ndr_alter_context_rsp_hdr_size(void);
 511 
 512 /* ndr_server.c */
 513 void ndr_pipe_worker(ndr_pipe_t *);
 514 
 515 int ndr_generic_call_stub(ndr_xa_t *);
 516 
 517 boolean_t ndr_is_admin(ndr_xa_t *);
 518 boolean_t ndr_is_poweruser(ndr_xa_t *);
 519 int32_t ndr_native_os(ndr_xa_t *);
 520 
 521 /* ndr_svc.c */
 522 ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
 523 ndr_service_t *ndr_svc_lookup_name(const char *);
 524 ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int);
 525 int ndr_svc_register(ndr_service_t *);
 526 void ndr_svc_unregister(ndr_service_t *);
 527 void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int);
 528 ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t);
 529 ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *);
 530 
 531 int ndr_uuid_parse(char *, ndr_uuid_t *);
 532 void ndr_uuid_unparse(ndr_uuid_t *, char *);
 533 
 534 ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
 535 void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
 536 ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
 537 void ndr_hdclose(ndr_pipe_t *);
 538 
 539 ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
 540 
 541 #ifdef  __cplusplus
 542 }
 543 #endif
 544 
 545 #endif  /* _LIBMLRPC_H */