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