Print this page
1575 untangle libmlrpc ... (libmlrpc)


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