#ifndef _LIBMLRPC_H
#define _LIBMLRPC_H
#include <sys/types.h>
#include <sys/uio.h>
#include <smb/wintypes.h>
#include <libmlrpc/ndr.h>
#ifdef __cplusplus
extern "C" {
#endif
#define NDR_DRC_OK 0x0000
#define NDR_DRC_MASK_FAULT 0x8000
#define NDR_DRC_MASK_SPECIFIER 0xFF00
#define NDR_DRC_MASK_PTYPE 0x00FF
#define NDR_DRC_PTYPE_RPCHDR(DRC) ((DRC) | 0x00FF)
#define NDR_DRC_PTYPE_API(DRC) ((DRC) | 0x00AA)
#define NDR_DRC_PTYPE_SEC(DRC) ((DRC) | 0x00CC)
#define NDR_DRC_IS_OK(DRC) (((DRC) & NDR_DRC_MASK_SPECIFIER) == 0)
#define NDR_DRC_IS_FAULT(DRC) (((DRC) & NDR_DRC_MASK_FAULT) != 0)
#define NDR_DRC_FAULT_MODE_MISMATCH 0x8100
#define NDR_DRC_RECEIVED 0x0200
#define NDR_DRC_FAULT_RECEIVED_RUNT 0x8300
#define NDR_DRC_FAULT_RECEIVED_MALFORMED 0x8400
#define NDR_DRC_DECODED 0x0500
#define NDR_DRC_FAULT_DECODE_FAILED 0x8600
#define NDR_DRC_ENCODED 0x0700
#define NDR_DRC_FAULT_ENCODE_FAILED 0x8800
#define NDR_DRC_FAULT_ENCODE_TOO_BIG 0x8900
#define NDR_DRC_SENT 0x0A00
#define NDR_DRC_FAULT_SEND_FAILED 0x8B00
#define NDR_DRC_FAULT_RESOURCE_1 0x9100
#define NDR_DRC_FAULT_RESOURCE_2 0x9200
#define NDR_DRC_FAULT_PARAM_0_INVALID 0xC000
#define NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED 0xD000
#define NDR_DRC_FAULT_PARAM_1_INVALID 0xC100
#define NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED 0xD100
#define NDR_DRC_FAULT_PARAM_2_INVALID 0xC200
#define NDR_DRC_FAULT_PARAM_2_UNIMPLEMENTED 0xD200
#define NDR_DRC_FAULT_PARAM_3_INVALID 0xC300
#define NDR_DRC_FAULT_PARAM_3_UNIMPLEMENTED 0xD300
#define NDR_DRC_FAULT_PARAM_4_INVALID 0xC400
#define NDR_DRC_FAULT_PARAM_4_UNIMPLEMENTED 0xD400
#define NDR_DRC_FAULT_PARAM_5_INVALID 0xC500
#define NDR_DRC_FAULT_PARAM_5_UNIMPLEMENTED 0xD500
#define NDR_DRC_FAULT_OUT_OF_MEMORY 0xF000
#define NDR_DRC_FAULT_RPCHDR_MODE_MISMATCH 0x81FF
#define NDR_DRC_FAULT_RPCHDR_RECEIVED_RUNT 0x83FF
#define NDR_DRC_FAULT_RPCHDR_DECODE_FAILED 0x86FF
#define NDR_DRC_FAULT_RPCHDR_PTYPE_INVALID 0xC0FF
#define NDR_DRC_FAULT_RPCHDR_PTYPE_UNIMPLEMENTED 0xD0FF
#define NDR_DRC_FAULT_REQUEST_PCONT_INVALID 0xC000
#define NDR_DRC_FAULT_REQUEST_OPNUM_INVALID 0xC100
#define NDR_DRC_BINDING_MADE 0x000B
#define NDR_DRC_FAULT_BIND_PCONT_BUSY 0xC00B
#define NDR_DRC_FAULT_BIND_UNKNOWN_SERVICE 0xC10B
#define NDR_DRC_FAULT_BIND_NO_SLOTS 0x910B
#define NDR_DRC_FAULT_API_SERVICE_INVALID 0xC0AA
#define NDR_DRC_FAULT_API_BIND_NO_SLOTS 0x91AA
#define NDR_DRC_FAULT_API_OPNUM_INVALID 0xC1AA
#define NDR_DRC_FAULT_SEC_TYPE_UNIMPLEMENTED \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED)
#define NDR_DRC_FAULT_SEC_LEVEL_UNIMPLEMENTED \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_1_UNIMPLEMENTED)
#define NDR_DRC_FAULT_SEC_SSP_FAILED \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_RESOURCE_1)
#define NDR_DRC_FAULT_SEC_ENCODE_TOO_BIG \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_ENCODE_TOO_BIG)
#define NDR_DRC_FAULT_SEC_AUTH_LENGTH_INVALID \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_2_INVALID)
#define NDR_DRC_FAULT_SEC_AUTH_TYPE_INVALID \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_0_INVALID)
#define NDR_DRC_FAULT_SEC_AUTH_LEVEL_INVALID \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_1_INVALID)
#define NDR_DRC_FAULT_SEC_OUT_OF_MEMORY \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_OUT_OF_MEMORY)
#define NDR_DRC_FAULT_SEC_ENCODE_FAILED \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_ENCODE_FAILED)
#define NDR_DRC_FAULT_SEC_META_INVALID \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_3_INVALID)
#define NDR_DRC_FAULT_SEC_SEQNUM_INVALID \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_4_INVALID)
#define NDR_DRC_FAULT_SEC_SIG_INVALID \
NDR_DRC_PTYPE_SEC(NDR_DRC_FAULT_PARAM_5_INVALID)
struct ndr_xa;
struct ndr_client;
typedef struct ndr_stub_table {
int (*func)(void *, struct ndr_xa *);
unsigned short opnum;
} ndr_stub_table_t;
typedef struct ndr_service {
char *name;
char *desc;
char *endpoint;
char *sec_addr_port;
char *abstract_syntax_uuid;
int abstract_syntax_version;
char *transfer_syntax_uuid;
int transfer_syntax_version;
unsigned bind_instance_size;
int (*bind_req)();
int (*unbind_and_close)();
int (*call_stub)(struct ndr_xa *);
ndr_typeinfo_t *interface_ti;
ndr_stub_table_t *stub_table;
} ndr_service_t;
typedef struct ndr_binding {
struct ndr_binding *next;
ndr_p_context_id_t p_cont_id;
unsigned char which_side;
struct ndr_client *clnt;
ndr_service_t *service;
void *instance_specific;
} ndr_binding_t;
#define NDR_BIND_SIDE_CLIENT 1
#define NDR_BIND_SIDE_SERVER 2
#define NDR_BINDING_TO_SPECIFIC(BINDING, TYPE) \
((TYPE *) (BINDING)->instance_specific)
#define NDR_N_BINDING_POOL 2
typedef struct ndr_pipe {
void *np_listener;
const char *np_endpoint;
struct smb_netuserinfo *np_user;
int (*np_send)(struct ndr_pipe *, void *, size_t);
int (*np_recv)(struct ndr_pipe *, void *, size_t);
int np_fid;
uint16_t np_max_xmit_frag;
uint16_t np_max_recv_frag;
ndr_binding_t *np_binding;
ndr_binding_t np_binding_pool[NDR_N_BINDING_POOL];
} ndr_pipe_t;
#define NDR_ALIGN4(SIZE) ((4 - (SIZE)) & 3);
typedef struct ndr_mstring {
uint16_t length;
uint16_t allosize;
LPTSTR str;
} ndr_mstring_t;
#define NDR_HEAP_MAXIOV 384
#define NDR_HEAP_BLKSZ 8192
typedef struct ndr_heap {
struct iovec iovec[NDR_HEAP_MAXIOV];
struct iovec *iov;
int iovcnt;
char *top;
char *next;
} ndr_heap_t;
typedef struct ndr_vcs {
uint32_t vc_first_is;
uint32_t vc_length_is;
uint16_t buffer[ANY_SIZE_ARRAY];
} ndr_vcs_t;
typedef struct ndr_vcstr {
uint16_t wclen;
uint16_t wcsize;
ndr_vcs_t *vcs;
} ndr_vcstr_t;
typedef struct ndr_vcb {
uint32_t vc_first_is;
uint32_t vc_length_is;
uint8_t buffer[ANY_SIZE_ARRAY];
} ndr_vcb_t;
typedef struct ndr_vcbuf {
uint16_t len;
uint16_t size;
ndr_vcb_t *vcb;
} ndr_vcbuf_t;
ndr_heap_t *ndr_heap_create(void);
void ndr_heap_destroy(ndr_heap_t *);
void *ndr_heap_dupmem(ndr_heap_t *, const void *, size_t);
void *ndr_heap_malloc(ndr_heap_t *, unsigned);
void *ndr_heap_strdup(ndr_heap_t *, const char *);
int ndr_heap_mstring(ndr_heap_t *, const char *, ndr_mstring_t *);
void ndr_heap_mkvcs(ndr_heap_t *, char *, ndr_vcstr_t *);
void ndr_heap_mkvcb(ndr_heap_t *, uint8_t *, uint32_t, ndr_vcbuf_t *);
int ndr_heap_used(ndr_heap_t *);
int ndr_heap_avail(ndr_heap_t *);
#define NDR_MALLOC(XA, SZ) ndr_heap_malloc((XA)->heap, SZ)
#define NDR_NEW(XA, T) ndr_heap_malloc((XA)->heap, sizeof (T))
#define NDR_NEWN(XA, T, N) ndr_heap_malloc((XA)->heap, sizeof (T)*(N))
#define NDR_STRDUP(XA, S) ndr_heap_strdup((XA)->heap, (S))
#define NDR_MSTRING(XA, S, OUT) ndr_heap_mstring((XA)->heap, (S), (OUT))
#define NDR_SIDDUP(XA, S) ndr_heap_dupmem((XA)->heap, (S), smb_sid_len(S))
typedef struct ndr_xa {
unsigned short ptype;
unsigned short opnum;
ndr_stream_t recv_nds;
ndr_hdr_t recv_hdr;
ndr_sec_t recv_auth;
ndr_stream_t send_nds;
ndr_hdr_t send_hdr;
ndr_sec_t send_auth;
ndr_binding_t *binding;
ndr_binding_t *binding_list;
ndr_heap_t *heap;
ndr_pipe_t *pipe;
} ndr_xa_t;
typedef struct ndr_auth_ops {
int (*nao_init)(void *, ndr_xa_t *);
int (*nao_recv)(void *, ndr_xa_t *);
int (*nao_sign)(void *, ndr_xa_t *);
int (*nao_verify)(void *, ndr_xa_t *, boolean_t);
int (*nao_encrypt)(void *, ndr_xa_t *);
int (*nao_decrypt)(void *, ndr_xa_t *, boolean_t);
} ndr_auth_ops_t;
typedef struct ndr_auth_ctx {
ndr_auth_ops_t auth_ops;
void *auth_ctx;
uint32_t auth_context_id;
uint8_t auth_type;
uint8_t auth_level;
boolean_t auth_verify_resp;
} ndr_auth_ctx_t;
CONTEXT_HANDLE(ndr_hdid) ndr_hdid_t;
typedef struct ndr_client {
int (*xa_init)(struct ndr_client *, ndr_xa_t *);
int (*xa_exchange)(struct ndr_client *, ndr_xa_t *);
int (*xa_read)(struct ndr_client *, ndr_xa_t *);
void (*xa_preserve)(struct ndr_client *, ndr_xa_t *);
void (*xa_destruct)(struct ndr_client *, ndr_xa_t *);
void (*xa_release)(struct ndr_client *);
void *xa_private;
int xa_fd;
ndr_hdid_t *handle;
ndr_binding_t *binding;
ndr_binding_t *binding_list;
ndr_binding_t binding_pool[NDR_N_BINDING_POOL];
boolean_t nonull;
boolean_t heap_preserved;
ndr_heap_t *heap;
ndr_stream_t *recv_nds;
ndr_stream_t *send_nds;
uint32_t next_call_id;
unsigned next_p_cont_id;
ndr_auth_ctx_t auth_ctx;
} ndr_client_t;
typedef struct ndr_handle {
ndr_hdid_t nh_id;
struct ndr_handle *nh_next;
ndr_pipe_t *nh_pipe;
const ndr_service_t *nh_svc;
ndr_client_t *nh_clnt;
void *nh_data;
void (*nh_data_free)(void *);
} ndr_handle_t;
#define NDR_PDU_SIZE_HINT_DEFAULT (16*1024)
#define NDR_BUF_MAGIC 0x4E425546
typedef struct ndr_buf {
uint32_t nb_magic;
ndr_stream_t nb_nds;
ndr_heap_t *nb_heap;
ndr_typeinfo_t *nb_ti;
} ndr_buf_t;
int nds_initialize(ndr_stream_t *, unsigned, int, ndr_heap_t *);
void nds_destruct(ndr_stream_t *);
void nds_show_state(ndr_stream_t *);
int ndr_clnt_bind(ndr_client_t *, ndr_service_t *, ndr_binding_t **);
int ndr_clnt_call(ndr_binding_t *, int, void *);
void ndr_clnt_free_heap(ndr_client_t *);
ndr_buf_t *ndr_buf_init(ndr_typeinfo_t *);
void ndr_buf_fini(ndr_buf_t *);
int ndr_buf_decode(ndr_buf_t *, unsigned, unsigned, const char *data, size_t,
void *);
int ndr_decode_call(ndr_xa_t *, void *);
int ndr_encode_return(ndr_xa_t *, void *);
int ndr_encode_call(ndr_xa_t *, void *);
int ndr_decode_return(ndr_xa_t *, void *);
int ndr_decode_pdu_hdr(ndr_xa_t *);
int ndr_encode_pdu_hdr(ndr_xa_t *);
void ndr_decode_frag_hdr(ndr_stream_t *, ndr_common_header_t *);
void ndr_remove_frag_hdr(ndr_stream_t *);
void ndr_show_hdr(ndr_common_header_t *);
unsigned ndr_bind_ack_hdr_size(ndr_xa_t *);
unsigned ndr_alter_context_rsp_hdr_size(void);
int ndr_decode_pdu_auth(ndr_xa_t *);
int ndr_encode_pdu_auth(ndr_xa_t *);
void ndr_show_auth(ndr_sec_t *);
int ndr_add_sec_context(ndr_auth_ctx_t *, ndr_xa_t *);
int ndr_recv_sec_context(ndr_auth_ctx_t *, ndr_xa_t *);
int ndr_add_auth(ndr_auth_ctx_t *, ndr_xa_t *);
int ndr_check_auth(ndr_auth_ctx_t *, ndr_xa_t *);
void ndr_pipe_worker(ndr_pipe_t *);
int ndr_generic_call_stub(ndr_xa_t *);
ndr_stub_table_t *ndr_svc_find_stub(ndr_service_t *, int);
ndr_service_t *ndr_svc_lookup_name(const char *);
ndr_service_t *ndr_svc_lookup_uuid(ndr_uuid_t *, int, ndr_uuid_t *, int);
int ndr_svc_register(ndr_service_t *);
void ndr_svc_unregister(ndr_service_t *);
void ndr_svc_binding_pool_init(ndr_binding_t **, ndr_binding_t pool[], int);
ndr_binding_t *ndr_svc_find_binding(ndr_xa_t *, ndr_p_context_id_t);
ndr_binding_t *ndr_svc_new_binding(ndr_xa_t *);
int ndr_uuid_parse(char *, ndr_uuid_t *);
void ndr_uuid_unparse(ndr_uuid_t *, char *);
ndr_hdid_t *ndr_hdalloc(const ndr_xa_t *, const void *);
void ndr_hdfree(const ndr_xa_t *, const ndr_hdid_t *);
ndr_handle_t *ndr_hdlookup(const ndr_xa_t *, const ndr_hdid_t *);
void ndr_hdclose(ndr_pipe_t *);
ssize_t ndr_uiomove(caddr_t, size_t, enum uio_rw, struct uio *);
typedef struct mlrpc_handle {
ndr_hdid_t handle;
ndr_client_t *clnt;
} mlrpc_handle_t;
int mlrpc_clh_create(mlrpc_handle_t *, void *);
uint32_t mlrpc_clh_set_auth(mlrpc_handle_t *, ndr_auth_ctx_t *);
uint32_t mlrpc_clh_bind(mlrpc_handle_t *, ndr_service_t *);
void mlrpc_clh_unbind(mlrpc_handle_t *);
void *mlrpc_clh_free(mlrpc_handle_t *);
int ndr_rpc_call(mlrpc_handle_t *, int, void *);
int ndr_rpc_get_ssnkey(mlrpc_handle_t *, unsigned char *, size_t);
void *ndr_rpc_malloc(mlrpc_handle_t *, size_t);
ndr_heap_t *ndr_rpc_get_heap(mlrpc_handle_t *);
void ndr_rpc_release(mlrpc_handle_t *);
void ndr_rpc_set_nonull(mlrpc_handle_t *);
boolean_t ndr_is_null_handle(mlrpc_handle_t *);
boolean_t ndr_is_bind_handle(mlrpc_handle_t *);
void ndr_inherit_handle(mlrpc_handle_t *, mlrpc_handle_t *);
#ifdef __cplusplus
}
#endif
#endif