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 2020 Tintri by DDN, 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 #define NDR_DRC_PTYPE_SEC(DRC) ((DRC) | 0x00CC) 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 #define NDR_DRC_FAULT_PARAM_4_INVALID 0xC400 159 #define NDR_DRC_FAULT_PARAM_4_UNIMPLEMENTED 0xD400 160 #define NDR_DRC_FAULT_PARAM_5_INVALID 0xC500 161 #define NDR_DRC_FAULT_PARAM_5_UNIMPLEMENTED 0xD500 162 163 #define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000 164 165 /* RPCHDR */ 166 #define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF 167 #define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF 168 #define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF 169 #define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF /* PARAM_0_INVALID */ 170 #define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF /* PARAM_0_UNIMP */ 171 172 /* Request */ 173 #define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000 /* PARAM_0_INVALID */ 174 #define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100 /* PARAM_1_INVALID */ 175 176 /* Bind */ 177 #define NDR_DRC_BINDING_MADE 0x000B /* OK */ 178 #define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B /* PARAM_0_INVALID */ 179 #define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B /* PARAM_1_INVALID */ 180 #define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B /* RESOURCE_1 */ 181 182 /* API */ 183 #define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA /* PARAM_0_INVALID */ 184 #define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA /* RESOURCE_1 */ 185 #define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA /* PARAM_1_INVALID */ 186 187 /* Secure RPC and SSPs */ 188 #define NDR_DRC_FAULT_SEC_TYPE_UNIMPLEMENTED \ 189 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED) 190 #define NDR_DRC_FAULT_SEC_LEVEL_UNIMPLEMENTED \ 191 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED) 192 #define NDR_DRC_FAULT_SEC_SSP_FAILED \ 193 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_RESOURCE_1) 194 #define NDR_DRC_FAULT_SEC_ENCODE_TOO_BIG \ 195 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_ENCODE_TOO_BIG) 196 #define NDR_DRC_FAULT_SEC_AUTH_LENGTH_INVALID \ 197 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_2_INVALID) 198 #define NDR_DRC_FAULT_SEC_AUTH_TYPE_INVALID \ 199 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_0_INVALID) 200 #define NDR_DRC_FAULT_SEC_AUTH_LEVEL_INVALID \ 201 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_1_INVALID) 202 #define NDR_DRC_FAULT_SEC_OUT_OF_MEMORY \ 203 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_OUT_OF_MEMORY) 204 #define NDR_DRC_FAULT_SEC_ENCODE_FAILED \ 205 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_ENCODE_FAILED) 206 #define NDR_DRC_FAULT_SEC_META_INVALID \ 207 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_3_INVALID) 208 #define NDR_DRC_FAULT_SEC_SEQNUM_INVALID \ 209 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_4_INVALID) 210 #define NDR_DRC_FAULT_SEC_SIG_INVALID \ 211 NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_5_INVALID) 212 213 struct ndr_xa; 214 struct ndr_client; 215 216 typedef struct ndr_stub_table { 217 int (*func)(void *, struct ndr_xa *); 218 unsigned short opnum; 219 } ndr_stub_table_t; 220 221 typedef struct ndr_service { 222 char *name; 223 char *desc; 224 char *endpoint; 225 char *sec_addr_port; 226 char *abstract_syntax_uuid; 227 int abstract_syntax_version; 228 char *transfer_syntax_uuid; 229 int transfer_syntax_version; 230 unsigned bind_instance_size; 231 int (*bind_req)(); 232 int (*unbind_and_close)(); 233 int (*call_stub)(struct ndr_xa *); 234 ndr_typeinfo_t *interface_ti; 235 ndr_stub_table_t *stub_table; 236 } ndr_service_t; 237 238 /* 239 * The list of bindings is anchored at a connection. Nothing in the 240 * RPC mechanism allocates them. Binding elements which have service==0 241 * indicate free elements. When a connection is instantiated, at least 242 * one free binding entry should also be established. Something like 243 * this should suffice for most (all) situations: 244 * 245 * struct connection { 246 * .... 247 * ndr_binding_t *binding_list_head; 248 * ndr_binding_t binding_pool[N_BINDING_POOL]; 249 * .... 250 * }; 251 * 252 * init_connection(struct connection *conn) { 253 * .... 254 * ndr_svc_binding_pool_init(&conn->binding_list_head, 255 * conn->binding_pool, N_BINDING_POOL); 256 */ 257 typedef struct ndr_binding { 258 struct ndr_binding *next; 259 ndr_p_context_id_t p_cont_id; 260 unsigned char which_side; 261 struct ndr_client *clnt; 262 ndr_service_t *service; 263 void *instance_specific; 264 } ndr_binding_t; 265 266 #define NDR_BIND_SIDE_CLIENT 1 267 #define NDR_BIND_SIDE_SERVER 2 268 269 #define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \ 270 ((TYPE *) (BINDING)->instance_specific) 271 272 /* 273 * The binding list space must be provided by the application library 274 * for use by the underlying RPC library. We need at least two binding 275 * slots per connection. 276 */ 277 #define NDR_N_BINDING_POOL 2 278 279 typedef struct ndr_pipe { 280 void *np_listener; 281 const char *np_endpoint; 282 struct smb_netuserinfo *np_user; 283 int (*np_send)(struct ndr_pipe *, void *, size_t); 284 int (*np_recv)(struct ndr_pipe *, void *, size_t); 285 int np_fid; 286 uint16_t np_max_xmit_frag; 287 uint16_t np_max_recv_frag; 288 ndr_binding_t *np_binding; 289 ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL]; 290 } ndr_pipe_t; 291 292 /* 293 * Number of bytes required to align SIZE on the next dword/4-byte 294 * boundary. 295 */ 296 #define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3); 297 298 /* 299 * DCE RPC strings (CAE section 14.3.4) are represented as varying or varying 300 * and conformant one-dimensional arrays. Characters can be single-byte 301 * or multi-byte as long as all characters conform to a fixed element size, 302 * i.e. UCS-2 is okay but UTF-8 is not a valid DCE RPC string format. The 303 * string is terminated by a null character of the appropriate element size. 304 * 305 * MSRPC strings should always be varying/conformant and not null terminated. 306 * This format uses the size_is, first_is and length_is attributes (CAE 307 * section 4.2.18). 308 * 309 * typedef struct string { 310 * DWORD size_is; 311 * DWORD first_is; 312 * DWORD length_is; 313 * wchar_t string[ANY_SIZE_ARRAY]; 314 * } string_t; 315 * 316 * The size_is attribute is used to specify the number of data elements in 317 * each dimension of an array. 318 * 319 * The first_is attribute is used to define the lower bound for significant 320 * elements in each dimension of an array. For strings this is always 0. 321 * 322 * The length_is attribute is used to define the number of significant 323 * elements in each dimension of an array. For strings this is typically 324 * the same as size_is. Although it might be (size_is - 1) if the string 325 * is null terminated. 326 * 327 * 4 bytes 4 bytes 4 bytes 2bytes 2bytes 2bytes 2bytes 328 * +---------+---------+---------+------+------+------+------+ 329 * |size_is |first_is |length_is| char | char | char | char | 330 * +---------+---------+---------+------+------+------+------+ 331 * 332 * Unfortunately, not all MSRPC Unicode strings are null terminated, which 333 * means that the recipient has to manually null-terminate the string after 334 * it has been unmarshalled. There may be a wide-char pad following a 335 * string, and it may sometimes contains zero, but it's not guaranteed. 336 * 337 * To deal with this, MSRPC sometimes uses an additional wrapper with two 338 * more fields, as shown below. 339 * length: the array length in bytes excluding terminating null bytes 340 * maxlen: the array length in bytes including null terminator bytes 341 * LPTSTR: converted to a string_t by NDR 342 * 343 * typedef struct ms_string { 344 * WORD length; 345 * WORD maxlen; 346 * LPTSTR str; 347 * } ms_string_t; 348 */ 349 typedef struct ndr_mstring { 350 uint16_t length; 351 uint16_t allosize; 352 LPTSTR str; 353 } ndr_mstring_t; 354 355 /* 356 * A number of heap areas are used during marshalling and unmarshalling. 357 * Under some circumstances these areas can be discarded by the library 358 * code, i.e. on the server side before returning to the client and on 359 * completion of a client side bind. In the case of a client side RPC 360 * call, these areas must be preserved after an RPC returns to give the 361 * caller time to take a copy of the data. In this case the client must 362 * call ndr_clnt_free_heap to free the memory. 363 * 364 * The heap management data definition looks a bit like this: 365 * 366 * heap -> +---------------+ +------------+ 367 * | iovec[0].base | --> | data block | 368 * | iovec[0].len | +------------+ 369 * +---------------+ 370 * :: 371 * :: 372 * iov -> +---------------+ +------------+ 373 * | iovec[n].base | --> | data block | 374 * | iovec[n].len | +------------+ 375 * +---------------+ ^ ^ 376 * | | 377 * next ----------------------+ | 378 * top -----------------------------------+ 379 * 380 */ 381 382 /* 383 * Setting MAXIOV to 384 will use ((8 * 384) + 16) = 3088 bytes 384 * of the first heap block. 385 */ 386 #define NDR_HEAP_MAXIOV 384 387 #define NDR_HEAP_BLKSZ 8192 388 389 typedef struct ndr_heap { 390 struct iovec iovec[NDR_HEAP_MAXIOV]; 391 struct iovec *iov; 392 int iovcnt; 393 char *top; 394 char *next; 395 } ndr_heap_t; 396 397 /* 398 * Alternate varying/conformant string definition 399 * - for non-null-terminated strings. 400 */ 401 typedef struct ndr_vcs { 402 /* 403 * size_is (actually a copy of length_is) will 404 * be inserted here by the marshalling library. 405 */ 406 uint32_t vc_first_is; 407 uint32_t vc_length_is; 408 uint16_t buffer[ANY_SIZE_ARRAY]; 409 } ndr_vcs_t; 410 411 typedef struct ndr_vcstr { 412 uint16_t wclen; 413 uint16_t wcsize; 414 ndr_vcs_t *vcs; 415 } ndr_vcstr_t; 416 417 typedef struct ndr_vcb { 418 /* 419 * size_is (actually a copy of length_is) will 420 * be inserted here by the marshalling library. 421 */ 422 uint32_t vc_first_is; 423 uint32_t vc_length_is; 424 uint8_t buffer[ANY_SIZE_ARRAY]; 425 } ndr_vcb_t; 426 427 typedef struct ndr_vcbuf { 428 uint16_t len; 429 uint16_t size; 430 ndr_vcb_t *vcb; 431 } ndr_vcbuf_t; 432 433 ndr_heap_t *ndr_heap_create(void); 434 void ndr_heap_destroy(ndr_heap_t *); 435 void *ndr_heap_dupmem(ndr_heap_t *, const void *, size_t); 436 void *ndr_heap_malloc(ndr_heap_t *, unsigned); 437 void *ndr_heap_strdup(ndr_heap_t *, const char *); 438 int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *); 439 void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *); 440 void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *); 441 int ndr_heap_used(ndr_heap_t *); 442 int ndr_heap_avail(ndr_heap_t *); 443 444 #define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ) 445 #define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T)) 446 #define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N)) 447 #define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S)) 448 #define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT)) 449 #define NDR_SIDDUP(XA, S) ndr_heap_dupmem((XA)->heap, (S), smb_sid_len(S)) 450 451 typedef struct ndr_xa { 452 unsigned short ptype; /* high bits special */ 453 unsigned short opnum; 454 ndr_stream_t recv_nds; 455 ndr_hdr_t recv_hdr; 456 ndr_sec_t recv_auth; 457 ndr_stream_t send_nds; 458 ndr_hdr_t send_hdr; 459 ndr_sec_t send_auth; 460 ndr_binding_t *binding; /* what we're using */ 461 ndr_binding_t *binding_list; /* from connection */ 462 ndr_heap_t *heap; 463 ndr_pipe_t *pipe; 464 } ndr_xa_t; 465 466 typedef struct ndr_auth_ops { 467 int (*nao_init)(void *, ndr_xa_t *); 468 int (*nao_recv)(void *, ndr_xa_t *); 469 int (*nao_sign)(void *, ndr_xa_t *); 470 int (*nao_verify)(void *, ndr_xa_t *, boolean_t); 471 } ndr_auth_ops_t; 472 473 /* 474 * A client provides this structure during bind to indicate 475 * that the RPC runtime should use "Secure RPC" (RPC-level auth). 476 * 477 * Currently, only NETLOGON uses this, and only NETLOGON-based 478 * Integrity protection is supported. 479 */ 480 typedef struct ndr_auth_ctx { 481 ndr_auth_ops_t auth_ops; 482 void *auth_ctx; /* SSP-specific context */ 483 uint32_t auth_context_id; 484 uint8_t auth_type; 485 uint8_t auth_level; 486 boolean_t auth_verify_resp; 487 } ndr_auth_ctx_t; 488 489 /* 490 * 20-byte opaque id used by various RPC services. 491 */ 492 CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t; 493 494 typedef struct ndr_client { 495 /* transport stuff (xa_* members) */ 496 int (*xa_init)(struct ndr_client *, ndr_xa_t *); 497 int (*xa_exchange)(struct ndr_client *, ndr_xa_t *); 498 int (*xa_read)(struct ndr_client *, ndr_xa_t *); 499 void (*xa_preserve)(struct ndr_client *, ndr_xa_t *); 500 void (*xa_destruct)(struct ndr_client *, ndr_xa_t *); 501 void (*xa_release)(struct ndr_client *); 502 void *xa_private; 503 int xa_fd; 504 505 ndr_hdid_t *handle; 506 ndr_binding_t *binding; 507 ndr_binding_t *binding_list; 508 ndr_binding_t binding_pool[NDR_N_BINDING_POOL]; 509 510 boolean_t nonull; 511 boolean_t heap_preserved; 512 ndr_heap_t *heap; 513 ndr_stream_t *recv_nds; 514 ndr_stream_t *send_nds; 515 516 uint32_t next_call_id; 517 unsigned next_p_cont_id; 518 519 ndr_auth_ctx_t auth_ctx; 520 } ndr_client_t; 521 522 typedef struct ndr_handle { 523 ndr_hdid_t nh_id; 524 struct ndr_handle *nh_next; 525 ndr_pipe_t *nh_pipe; 526 const ndr_service_t *nh_svc; 527 ndr_client_t *nh_clnt; 528 void *nh_data; 529 void (*nh_data_free)(void *); 530 } ndr_handle_t; 531 532 #define NDR_PDU_SIZE_HINT_DEFAULT (16*1024) 533 #define NDR_BUF_MAGIC 0x4E425546 /* NBUF */ 534 535 typedef struct ndr_buf { 536 uint32_t nb_magic; 537 ndr_stream_t nb_nds; 538 ndr_heap_t *nb_heap; 539 ndr_typeinfo_t *nb_ti; 540 } ndr_buf_t; 541 542 /* ndr_ops.c */ 543 int nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *); 544 void nds_destruct(ndr_stream_t *); 545 void nds_show_state(ndr_stream_t *); 546 547 /* ndr_client.c */ 548 int ndr_clnt_bind(ndr_client_t *, ndr_service_t *, ndr_binding_t **); 549 int ndr_clnt_call(ndr_binding_t *, int, void *); 550 void ndr_clnt_free_heap(ndr_client_t *); 551 552 /* ndr_marshal.c */ 553 ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *); 554 void ndr_buf_fini(ndr_buf_t *); 555 int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t, 556 void *); 557 int ndr_decode_call(ndr_xa_t *, void *); 558 int ndr_encode_return(ndr_xa_t *, void *); 559 int ndr_encode_call(ndr_xa_t *, void *); 560 int ndr_decode_return(ndr_xa_t *, void *); 561 int ndr_decode_pdu_hdr(ndr_xa_t *); 562 int ndr_encode_pdu_hdr(ndr_xa_t *); 563 void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *); 564 void ndr_remove_frag_hdr(ndr_stream_t *); 565 void ndr_show_hdr(ndr_common_header_t *); 566 unsigned ndr_bind_ack_hdr_size(ndr_xa_t *); 567 unsigned ndr_alter_context_rsp_hdr_size(void); 568 int ndr_decode_pdu_auth(ndr_xa_t *); 569 int ndr_encode_pdu_auth(ndr_xa_t *); 570 void ndr_show_auth(ndr_sec_t *); 571 572 /* 573 * MS-RPCE "Secure RPC" (RPC-level auth). 574 * These call the functions in ndr_auth_ops_t, which should be 575 * GSSAPI (or equivalent) calls. 576 */ 577 int ndr_add_sec_context(ndr_auth_ctx_t *, ndr_xa_t *); 578 int ndr_recv_sec_context(ndr_auth_ctx_t *, ndr_xa_t *); 579 int ndr_add_auth(ndr_auth_ctx_t *, ndr_xa_t *); 580 int ndr_check_auth(ndr_auth_ctx_t *, ndr_xa_t *); 581 582 /* ndr_server.c */ 583 void ndr_pipe_worker(ndr_pipe_t *); 584 585 int ndr_generic_call_stub(ndr_xa_t *); 586 587 /* ndr_svc.c */ 588 ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int); 589 ndr_service_t *ndr_svc_lookup_name(const char *); 590 ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int); 591 int ndr_svc_register(ndr_service_t *); 592 void ndr_svc_unregister(ndr_service_t *); 593 void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int); 594 ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t); 595 ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *); 596 597 int ndr_uuid_parse(char *, ndr_uuid_t *); 598 void ndr_uuid_unparse(ndr_uuid_t *, char *); 599 600 ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *); 601 void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *); 602 ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *); 603 void ndr_hdclose(ndr_pipe_t *); 604 605 ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *); 606 607 /* 608 * An ndr_client_t is created while binding a client connection to hold 609 * the context for calls made using that connection. 610 * 611 * Handles are RPC call specific and we use an inheritance mechanism to 612 * ensure that each handle has a pointer to the client_t. When the top 613 * level (bind) handle is released, we close the connection. 614 * 615 * There are some places in libmlsvc where the code assumes that the 616 * handle member is first in this struct. Careful! 617 * 618 * Note that this entire structure is bzero()'d once the ndr_client_t 619 * has been created. 620 */ 621 typedef struct mlrpc_handle { 622 ndr_hdid_t handle; /* keep first */ 623 ndr_client_t *clnt; 624 } mlrpc_handle_t; 625 626 int mlrpc_clh_create(mlrpc_handle_t *, void *); 627 uint32_t mlrpc_clh_set_auth(mlrpc_handle_t *, ndr_auth_ctx_t *); 628 uint32_t mlrpc_clh_bind(mlrpc_handle_t *, ndr_service_t *); 629 void mlrpc_clh_unbind(mlrpc_handle_t *); 630 void *mlrpc_clh_free(mlrpc_handle_t *); 631 632 int ndr_rpc_call(mlrpc_handle_t *, int, void *); 633 int ndr_rpc_get_ssnkey(mlrpc_handle_t *, unsigned char *, size_t); 634 void *ndr_rpc_malloc(mlrpc_handle_t *, size_t); 635 ndr_heap_t *ndr_rpc_get_heap(mlrpc_handle_t *); 636 void ndr_rpc_release(mlrpc_handle_t *); 637 void ndr_rpc_set_nonull(mlrpc_handle_t *); 638 639 boolean_t ndr_is_null_handle(mlrpc_handle_t *); 640 boolean_t ndr_is_bind_handle(mlrpc_handle_t *); 641 void ndr_inherit_handle(mlrpc_handle_t *, mlrpc_handle_t *); 642 643 #ifdef __cplusplus 644 } 645 #endif 646 647 #endif /* _LIBMLRPC_H */ 648