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 * +---------------+ +---------------+ +---------------+
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
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 {
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 */
|
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 * +---------------+ +---------------+ +---------------+
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
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 {
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 */
|