$res .= "
struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r)
{
- if (p->flags & DCERPC_DEBUG_PRINT_IN) {
+ if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
NDR_PRINT_IN_DEBUG($name, r);
}
status = dcerpc_ndr_request_recv(req);
- if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
+ if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
NDR_PRINT_OUT_DEBUG($name, r);
}
";
r->in.ORPCthis.version.MajorVersion = COM_MAJOR_VERSION;
r->in.ORPCthis.version.MinorVersion = COM_MINOR_VERSION;
- if (p->flags & DCERPC_DEBUG_PRINT_IN) {
+ if (p->conn->flags & DCERPC_DEBUG_PRINT_IN) {
NDR_PRINT_IN_DEBUG($name, r);
}
status = dcerpc_ndr_request_recv(req);
- if (NT_STATUS_IS_OK(status) && (p->flags & DCERPC_DEBUG_PRINT_OUT)) {
+ if (NT_STATUS_IS_OK(status) && (p->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
NDR_PRINT_OUT_DEBUG($name, r);
}
";
oxid = iface->ox->oxid;
iid = iface->interface->iid;
+#warning "dcerpc_alter needed"
+#if 0
if (iface->ox->pipe) {
if (!GUID_equal(&iface->ox->pipe->syntax.uuid, &iid)) {
iface->ox->pipe->syntax.uuid = iid;
*p = iface->ox->pipe;
return NT_STATUS_OK;
}
-
+#endif
i = 0;
do {
status = dcerpc_binding_from_STRINGBINDING(iface->ctx, &binding, iface->ox->bindings.stringbindings[i]);
}
lsa->ipc_tree->tid = tcon.tconx.out.cnum;
+ lsa->pipe = dcerpc_pipe_init(lsa);
+ if (lsa->pipe == NULL) {
+ talloc_free(lsa);
+ return NT_STATUS_NO_MEMORY;
+ }
+
/* open the LSA pipe */
- status = dcerpc_pipe_open_smb(&lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME);
+ status = dcerpc_pipe_open_smb(lsa->pipe->conn, lsa->ipc_tree, DCERPC_LSARPC_NAME);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(lsa);
return status;
raw dcerpc operations
Copyright (C) Tim Potter 2003
- Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Andrew Tridgell 2003-2005
Copyright (C) Jelmer Vernooij 2004
This program is free software; you can redistribute it and/or modify
#include "dlinklist.h"
#include "librpc/gen_ndr/ndr_epmapper.h"
-struct dcerpc_interface_list *dcerpc_pipes = NULL;
+static struct dcerpc_interface_list *dcerpc_pipes = NULL;
+/*
+ register a dcerpc client interface
+*/
NTSTATUS librpc_register_interface(const struct dcerpc_interface_table *interface)
{
struct dcerpc_interface_list *l = talloc_p(talloc_autofree_context(),
return NT_STATUS_OK;
}
+/*
+ return the list of registered dcerpc_pipes
+*/
+const struct dcerpc_interface_list *librpc_dcerpc_pipes(void)
+{
+ return dcerpc_pipes;
+}
+
+/* destroy a dcerpc connection */
+static int dcerpc_connection_destructor(void *ptr)
+{
+ struct dcerpc_connection *c = ptr;
+ if (c->transport.shutdown_pipe) {
+ c->transport.shutdown_pipe(c);
+ }
+ return 0;
+}
+
+
+/* initialise a dcerpc connection. */
+struct dcerpc_connection *dcerpc_connection_init(TALLOC_CTX *mem_ctx)
+{
+ struct dcerpc_connection *c;
+
+ c = talloc_zero(mem_ctx, struct dcerpc_connection);
+ if (!c) {
+ return NULL;
+ }
+
+ c->call_id = 1;
+ c->security_state.auth_info = NULL;
+ c->security_state.session_key = dcerpc_generic_session_key;
+ c->security_state.generic_state = NULL;
+ c->binding_string = NULL;
+ c->flags = 0;
+ c->srv_max_xmit_frag = 0;
+ c->srv_max_recv_frag = 0;
+ c->pending = NULL;
+
+ talloc_set_destructor(c, dcerpc_connection_destructor);
+
+ return c;
+}
+
/* initialise a dcerpc pipe. */
-struct dcerpc_pipe *dcerpc_pipe_init(void)
+struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx)
{
struct dcerpc_pipe *p;
- p = talloc_p(NULL, struct dcerpc_pipe);
+ p = talloc_p(mem_ctx, struct dcerpc_pipe);
if (!p) {
return NULL;
}
- p->reference_count = 0;
- p->call_id = 1;
- p->security_state.auth_info = NULL;
- p->security_state.session_key = dcerpc_generic_session_key;
- p->security_state.generic_state = NULL;
- p->binding_string = NULL;
- p->flags = 0;
- p->srv_max_xmit_frag = 0;
- p->srv_max_recv_frag = 0;
+ p->conn = dcerpc_connection_init(p);
+ if (p->conn == NULL) {
+ talloc_free(p);
+ return NULL;
+ }
+
p->last_fault_code = 0;
- p->pending = NULL;
+ p->context_id = 0;
+
+ ZERO_STRUCT(p->syntax);
+ ZERO_STRUCT(p->transfer_syntax);
return p;
}
+
/*
choose the next call id to use
*/
-static uint32_t next_call_id(struct dcerpc_pipe *p)
+static uint32_t next_call_id(struct dcerpc_connection *c)
{
- p->call_id++;
- if (p->call_id == 0) {
- p->call_id++;
+ c->call_id++;
+ if (c->call_id == 0) {
+ c->call_id++;
}
- return p->call_id;
+ return c->call_id;
}
/* close down a dcerpc over SMB pipe */
void dcerpc_pipe_close(struct dcerpc_pipe *p)
{
- if (!p) return;
- p->reference_count--;
- if (p->reference_count <= 0) {
- p->transport.shutdown_pipe(p);
- talloc_free(p);
- }
+ talloc_free(p);
}
/* we need to be able to get/set the fragment length without doing a full
/*
setup for a ndr pull, also setting up any flags from the binding string
*/
-static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_pipe *p, DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
+static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_connection *c,
+ DATA_BLOB *blob, TALLOC_CTX *mem_ctx)
{
struct ndr_pull *ndr = ndr_pull_init_blob(blob, mem_ctx);
if (ndr == NULL) return ndr;
- if (p->flags & DCERPC_DEBUG_PAD_CHECK) {
+ if (c->flags & DCERPC_DEBUG_PAD_CHECK) {
ndr->flags |= LIBNDR_FLAG_PAD_CHECK;
}
- if (p->flags & DCERPC_NDR_REF_ALLOC) {
+ if (c->flags & DCERPC_NDR_REF_ALLOC) {
ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
}
parse a data blob into a dcerpc_packet structure. This handles both
input and output packets
*/
-static NTSTATUS dcerpc_pull(struct dcerpc_pipe *p, DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+static NTSTATUS dcerpc_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
struct dcerpc_packet *pkt)
{
struct ndr_pull *ndr;
- ndr = ndr_pull_init_flags(p, blob, mem_ctx);
+ ndr = ndr_pull_init_flags(c, blob, mem_ctx);
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
}
/*
- generate a CONNECT level verifier
+ check a CONNECT level verifier
*/
static NTSTATUS dcerpc_check_connect_verifier(DATA_BLOB *blob)
{
/*
parse a possibly signed blob into a dcerpc request packet structure
*/
-static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
+static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_connection *c,
DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
struct dcerpc_packet *pkt)
{
DATA_BLOB auth_blob;
/* non-signed packets are simpler */
- if (!p->security_state.auth_info ||
- !p->security_state.generic_state) {
- return dcerpc_pull(p, blob, mem_ctx, pkt);
+ if (!c->security_state.auth_info ||
+ !c->security_state.generic_state) {
+ return dcerpc_pull(c, blob, mem_ctx, pkt);
}
- ndr = ndr_pull_init_flags(p, blob, mem_ctx);
+ ndr = ndr_pull_init_flags(c, blob, mem_ctx);
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
}
if (pkt->auth_length == 0 &&
- p->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
+ c->security_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
return NT_STATUS_OK;
}
pkt->u.response.stub_and_verifier.length -= auth_blob.length;
/* pull the auth structure */
- ndr = ndr_pull_init_flags(p, &auth_blob, mem_ctx);
+ ndr = ndr_pull_init_flags(c, &auth_blob, mem_ctx);
if (!ndr) {
return NT_STATUS_NO_MEMORY;
}
/* check signature or unseal the packet */
- switch (p->security_state.auth_info->auth_level) {
+ switch (c->security_state.auth_info->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
- status = gensec_unseal_packet(p->security_state.generic_state,
+ status = gensec_unseal_packet(c->security_state.generic_state,
mem_ctx,
blob->data + DCERPC_REQUEST_LENGTH,
pkt->u.response.stub_and_verifier.length,
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = gensec_check_packet(p->security_state.generic_state,
+ status = gensec_check_packet(c->security_state.generic_state,
mem_ctx,
pkt->u.response.stub_and_verifier.data,
pkt->u.response.stub_and_verifier.length,
/*
push a dcerpc request packet into a blob, possibly signing it.
*/
-static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
+static NTSTATUS dcerpc_push_request_sign(struct dcerpc_connection *c,
DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
struct dcerpc_packet *pkt)
{
DATA_BLOB creds2;
/* non-signed packets are simpler */
- if (!p->security_state.auth_info ||
- !p->security_state.generic_state) {
- return dcerpc_push_auth(blob, mem_ctx, pkt, p->security_state.auth_info);
+ if (!c->security_state.auth_info ||
+ !c->security_state.generic_state) {
+ return dcerpc_push_auth(blob, mem_ctx, pkt, c->security_state.auth_info);
}
ndr = ndr_push_init_ctx(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
- if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ if (c->flags & DCERPC_PUSH_BIGENDIAN) {
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
/* pad to 16 byte multiple in the payload portion of the
packet. This matches what w2k3 does */
- p->security_state.auth_info->auth_pad_length =
+ c->security_state.auth_info->auth_pad_length =
(16 - (pkt->u.request.stub_and_verifier.length & 15)) & 15;
- ndr_push_zero(ndr, p->security_state.auth_info->auth_pad_length);
+ ndr_push_zero(ndr, c->security_state.auth_info->auth_pad_length);
/* sign or seal the packet */
- switch (p->security_state.auth_info->auth_level) {
+ switch (c->security_state.auth_info->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
case DCERPC_AUTH_LEVEL_INTEGRITY:
- p->security_state.auth_info->credentials
- = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(p->security_state.generic_state));
- data_blob_clear(&p->security_state.auth_info->credentials);
+ c->security_state.auth_info->credentials
+ = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(c->security_state.generic_state));
+ data_blob_clear(&c->security_state.auth_info->credentials);
break;
case DCERPC_AUTH_LEVEL_CONNECT:
- status = dcerpc_connect_verifier(mem_ctx, &p->security_state.auth_info->credentials);
+ status = dcerpc_connect_verifier(mem_ctx, &c->security_state.auth_info->credentials);
break;
case DCERPC_AUTH_LEVEL_NONE:
- p->security_state.auth_info->credentials = data_blob(NULL, 0);
+ c->security_state.auth_info->credentials = data_blob(NULL, 0);
break;
default:
}
/* add the auth verifier */
- status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, p->security_state.auth_info);
+ status = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, c->security_state.auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
in these earlier as we don't know the signature length (it
could be variable length) */
dcerpc_set_frag_length(blob, blob->length);
- dcerpc_set_auth_length(blob, p->security_state.auth_info->credentials.length);
+ dcerpc_set_auth_length(blob, c->security_state.auth_info->credentials.length);
/* sign or seal the packet */
- switch (p->security_state.auth_info->auth_level) {
+ switch (c->security_state.auth_info->auth_level) {
case DCERPC_AUTH_LEVEL_PRIVACY:
- status = gensec_seal_packet(p->security_state.generic_state,
+ status = gensec_seal_packet(c->security_state.generic_state,
mem_ctx,
blob->data + DCERPC_REQUEST_LENGTH,
- pkt->u.request.stub_and_verifier.length+p->security_state.auth_info->auth_pad_length,
+ pkt->u.request.stub_and_verifier.length +
+ c->security_state.auth_info->auth_pad_length,
blob->data,
blob->length -
- p->security_state.auth_info->credentials.length,
+ c->security_state.auth_info->credentials.length,
&creds2);
if (!NT_STATUS_IS_OK(status)) {
return status;
break;
case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = gensec_sign_packet(p->security_state.generic_state,
+ status = gensec_sign_packet(c->security_state.generic_state,
mem_ctx,
blob->data + DCERPC_REQUEST_LENGTH,
- pkt->u.request.stub_and_verifier.length+p->security_state.auth_info->auth_pad_length,
+ pkt->u.request.stub_and_verifier.length +
+ c->security_state.auth_info->auth_pad_length,
blob->data,
blob->length -
- p->security_state.auth_info->credentials.length,
+ c->security_state.auth_info->credentials.length,
&creds2);
if (!NT_STATUS_IS_OK(status)) {
return status;
break;
case DCERPC_AUTH_LEVEL_NONE:
- p->security_state.auth_info->credentials = data_blob(NULL, 0);
+ c->security_state.auth_info->credentials = data_blob(NULL, 0);
break;
default:
break;
}
- data_blob_free(&p->security_state.auth_info->credentials);
+ data_blob_free(&c->security_state.auth_info->credentials);
return NT_STATUS_OK;
}
/*
fill in the fixed values in a dcerpc header
*/
-static void init_dcerpc_hdr(struct dcerpc_pipe *p, struct dcerpc_packet *pkt)
+static void init_dcerpc_hdr(struct dcerpc_connection *c, struct dcerpc_packet *pkt)
{
pkt->rpc_vers = 5;
pkt->rpc_vers_minor = 0;
- if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ if (c->flags & DCERPC_PUSH_BIGENDIAN) {
pkt->drep[0] = 0;
} else {
pkt->drep[0] = DCERPC_DREP_LE;
/*
receive a reply to a full request
*/
-static void full_request_recv(struct dcerpc_pipe *p, DATA_BLOB *blob,
+static void full_request_recv(struct dcerpc_connection *c, DATA_BLOB *blob,
NTSTATUS status)
{
- struct full_request_state *state = p->full_request_private;
+ struct full_request_state *state = c->full_request_private;
if (!NT_STATUS_IS_OK(status)) {
state->status = status;
perform a single pdu synchronous request - used for the bind code
this cannot be mixed with normal async requests
*/
-static NTSTATUS full_request(struct dcerpc_pipe *p,
+static NTSTATUS full_request(struct dcerpc_connection *c,
TALLOC_CTX *mem_ctx,
DATA_BLOB *request_blob,
DATA_BLOB *reply_blob)
state->reply_blob = reply_blob;
state->status = NT_STATUS_OK;
- p->transport.recv_data = full_request_recv;
- p->full_request_private = state;
+ c->transport.recv_data = full_request_recv;
+ c->full_request_private = state;
- status = p->transport.send_request(p, request_blob, True);
+ status = c->transport.send_request(c, request_blob, True);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
while (NT_STATUS_IS_OK(state->status) && state->reply_blob) {
- struct event_context *ctx = p->transport.event_context(p);
+ struct event_context *ctx = c->transport.event_context(c);
if (event_loop_once(ctx) != 0) {
return NT_STATUS_CONNECTION_DISCONNECTED;
}
p->syntax = *syntax;
p->transfer_syntax = *transfer_syntax;
- init_dcerpc_hdr(p, &pkt);
+ init_dcerpc_hdr(p->conn, &pkt);
pkt.ptype = DCERPC_PKT_BIND;
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
- pkt.call_id = p->call_id;
+ pkt.call_id = p->conn->call_id;
pkt.auth_length = 0;
pkt.u.bind.max_xmit_frag = 5840;
pkt.u.bind.max_recv_frag = 5840;
pkt.u.bind.assoc_group_id = 0;
pkt.u.bind.num_contexts = 1;
- pkt.u.bind.ctx_list = talloc_p(mem_ctx, struct dcerpc_ctx_list);
+ pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1);
if (!pkt.u.bind.ctx_list) {
return NT_STATUS_NO_MEMORY;
}
- pkt.u.bind.ctx_list[0].context_id = 0;
+ pkt.u.bind.ctx_list[0].context_id = p->context_id;
pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1;
pkt.u.bind.ctx_list[0].abstract_syntax = p->syntax;
pkt.u.bind.ctx_list[0].transfer_syntaxes = &p->transfer_syntax;
pkt.u.bind.auth_info = data_blob(NULL, 0);
/* construct the NDR form of the packet */
- status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->security_state.auth_info);
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->conn->security_state.auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* send it on its way */
- status = full_request(p, mem_ctx, &blob, &blob);
+ status = full_request(p->conn, mem_ctx, &blob, &blob);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* unmarshall the NDR */
- status = dcerpc_pull(p, &blob, mem_ctx, &pkt);
+ status = dcerpc_pull(p->conn, &blob, mem_ctx, &pkt);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
if (pkt.ptype == DCERPC_PKT_BIND_ACK) {
- p->srv_max_xmit_frag = pkt.u.bind_ack.max_xmit_frag;
- p->srv_max_recv_frag = pkt.u.bind_ack.max_recv_frag;
+ p->conn->srv_max_xmit_frag = pkt.u.bind_ack.max_xmit_frag;
+ p->conn->srv_max_recv_frag = pkt.u.bind_ack.max_recv_frag;
}
/* the bind_ack might contain a reply set of credentials */
- if (p->security_state.auth_info && pkt.u.bind_ack.auth_info.length) {
+ if (p->conn->security_state.auth_info && pkt.u.bind_ack.auth_info.length) {
status = ndr_pull_struct_blob(&pkt.u.bind_ack.auth_info,
mem_ctx,
- p->security_state.auth_info,
+ p->conn->security_state.auth_info,
(ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
}
return status;
}
-/*
- perform a alter context using the given syntax
-
- the auth_info structure is updated with the reply authentication info
- on success
-*/
-NTSTATUS dcerpc_alter(struct dcerpc_pipe *p,
- TALLOC_CTX *mem_ctx)
-{
- struct dcerpc_packet pkt;
- NTSTATUS status;
- DATA_BLOB blob;
-
- init_dcerpc_hdr(p, &pkt);
-
- pkt.ptype = DCERPC_PKT_ALTER;
- pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
- pkt.call_id = p->call_id;
- pkt.auth_length = 0;
-
- pkt.u.alter.max_xmit_frag = 0x2000;
- pkt.u.alter.max_recv_frag = 0x2000;
- pkt.u.alter.assoc_group_id = 0;
- pkt.u.alter.num_contexts = 1;
- pkt.u.alter.ctx_list = talloc_p(mem_ctx, struct dcerpc_ctx_list);
- if (!pkt.u.alter.ctx_list) {
- return NT_STATUS_NO_MEMORY;
- }
- pkt.u.alter.ctx_list[0].context_id = 0;
- pkt.u.alter.ctx_list[0].num_transfer_syntaxes = 1;
- pkt.u.alter.ctx_list[0].abstract_syntax = p->syntax;
- pkt.u.alter.ctx_list[0].transfer_syntaxes = &p->transfer_syntax;
- pkt.u.alter.auth_info = data_blob(NULL, 0);
-
- /* construct the NDR form of the packet */
- status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->security_state.auth_info);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- /* send it on its way */
- status = full_request(p, mem_ctx, &blob, &blob);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- /* unmarshall the NDR */
- status = dcerpc_pull(p, &blob, mem_ctx, &pkt);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- if ((pkt.ptype != DCERPC_PKT_ALTER_ACK) ||
- pkt.u.alter_ack.num_results == 0 ||
- pkt.u.alter_ack.ctx_list[0].result != 0) {
- status = NT_STATUS_UNSUCCESSFUL;
- }
-
- /* the bind_ack might contain a reply set of credentials */
- if (p->security_state.auth_info && pkt.u.alter_ack.auth_info.length) {
- status = ndr_pull_struct_blob(&pkt.u.alter_ack.auth_info,
- mem_ctx,
- p->security_state.auth_info,
- (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth);
- }
-
- return status;
-}
/*
perform a continued bind (and auth3)
*/
-NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
+NTSTATUS dcerpc_auth3(struct dcerpc_connection *c,
TALLOC_CTX *mem_ctx)
{
struct dcerpc_packet pkt;
NTSTATUS status;
DATA_BLOB blob;
- init_dcerpc_hdr(p, &pkt);
+ init_dcerpc_hdr(c, &pkt);
pkt.ptype = DCERPC_PKT_AUTH3;
pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
- pkt.call_id = next_call_id(p);
+ pkt.call_id = next_call_id(c);
pkt.auth_length = 0;
pkt.u.auth3._pad = 0;
pkt.u.auth3.auth_info = data_blob(NULL, 0);
/* construct the NDR form of the packet */
- status = dcerpc_push_auth(&blob, mem_ctx, &pkt, p->security_state.auth_info);
+ status = dcerpc_push_auth(&blob, mem_ctx, &pkt, c->security_state.auth_info);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
/* send it on its way */
- status = p->transport.send_request(p, &blob, False);
+ status = c->transport.send_request(c, &blob, False);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
process a fragment received from the transport layer during a
request
*/
-static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
+static void dcerpc_request_recv_data(struct dcerpc_connection *c,
DATA_BLOB *data,
NTSTATUS status)
{
if (!NT_STATUS_IS_OK(status)) {
/* all pending requests get the error */
- while (p->pending) {
- req = p->pending;
+ while (c->pending) {
+ req = c->pending;
req->state = RPC_REQUEST_DONE;
req->status = status;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(c->pending, req);
if (req->async.callback) {
req->async.callback(req);
}
pkt.call_id = 0;
- status = dcerpc_pull_request_sign(p, data, (TALLOC_CTX *)data->data, &pkt);
+ status = dcerpc_pull_request_sign(c, data, (TALLOC_CTX *)data->data, &pkt);
/* find the matching request. Notice we match before we check
the status. this is ok as a pending call_id can never be
zero */
- for (req=p->pending;req;req=req->next) {
+ for (req=c->pending;req;req=req->next) {
if (pkt.call_id == req->call_id) break;
}
if (!NT_STATUS_IS_OK(status)) {
req->status = status;
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(c->pending, req);
if (req->async.callback) {
req->async.callback(req);
}
}
if (pkt.ptype == DCERPC_PKT_FAULT) {
- DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(p, pkt.u.fault.status)));
+ DEBUG(5,("rpc fault: %s\n", dcerpc_errstr(c, pkt.u.fault.status)));
req->fault_code = pkt.u.fault.status;
req->status = NT_STATUS_NET_WRITE_FAULT;
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(c->pending, req);
if (req->async.callback) {
req->async.callback(req);
}
req->fault_code = DCERPC_FAULT_OTHER;
req->status = NT_STATUS_NET_WRITE_FAULT;
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(c->pending, req);
if (req->async.callback) {
req->async.callback(req);
}
if (!req->payload.data) {
req->status = NT_STATUS_NO_MEMORY;
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(c->pending, req);
if (req->async.callback) {
req->async.callback(req);
}
}
if (!(pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
- p->transport.send_read(p);
+ c->transport.send_read(c);
return;
}
/* we've got the full payload */
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(c->pending, req);
if (!(pkt.drep[0] & DCERPC_DREP_LE)) {
req->flags |= DCERPC_PULL_BIGENDIAN;
static int dcerpc_req_destructor(void *ptr)
{
struct rpc_request *req = ptr;
- DLIST_REMOVE(req->p->pending, req);
+ DLIST_REMOVE(req->p->conn->pending, req);
return 0;
}
/*
- perform the send size of a async dcerpc request
+ perform the send side of a async dcerpc request
*/
struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
const struct GUID *object,
uint32_t remaining, chunk_size;
BOOL first_packet = True;
- p->transport.recv_data = dcerpc_request_recv_data;
+ p->conn->transport.recv_data = dcerpc_request_recv_data;
req = talloc_p(mem_ctx, struct rpc_request);
if (req == NULL) {
}
req->p = p;
- req->call_id = next_call_id(p);
+ req->call_id = next_call_id(p->conn);
req->status = NT_STATUS_OK;
req->state = RPC_REQUEST_PENDING;
req->payload = data_blob(NULL, 0);
req->fault_code = 0;
req->async.callback = NULL;
- init_dcerpc_hdr(p, &pkt);
+ init_dcerpc_hdr(p->conn, &pkt);
remaining = stub_data->length;
/* we can write a full max_recv_frag size, minus the dcerpc
request header size */
- chunk_size = p->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
+ chunk_size = p->conn->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
pkt.ptype = DCERPC_PKT_REQUEST;
pkt.call_id = req->call_id;
pkt.auth_length = 0;
pkt.pfc_flags = 0;
pkt.u.request.alloc_hint = remaining;
- pkt.u.request.context_id = 0;
+ pkt.u.request.context_id = p->context_id;
pkt.u.request.opnum = opnum;
if (object) {
chunk_size -= ndr_size_GUID(object,0);
}
- DLIST_ADD(p->pending, req);
+ DLIST_ADD(p->conn->pending, req);
/* we send a series of pdus without waiting for a reply */
while (remaining > 0 || first_packet) {
(stub_data->length - remaining);
pkt.u.request.stub_and_verifier.length = chunk;
- req->status = dcerpc_push_request_sign(p, &blob, mem_ctx, &pkt);
+ req->status = dcerpc_push_request_sign(p->conn, &blob, mem_ctx, &pkt);
if (!NT_STATUS_IS_OK(req->status)) {
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(p->conn->pending, req);
return req;
}
- req->status = p->transport.send_request(p, &blob, last_frag);
+ req->status = p->conn->transport.send_request(p->conn, &blob, last_frag);
if (!NT_STATUS_IS_OK(req->status)) {
req->state = RPC_REQUEST_DONE;
- DLIST_REMOVE(p->pending, req);
+ DLIST_REMOVE(p->conn->pending, req);
return req;
}
*/
struct event_context *dcerpc_event_context(struct dcerpc_pipe *p)
{
- return p->transport.event_context(p);
+ return p->conn->transport.event_context(p->conn);
}
for that to the NDR we initially generated. If they don't match then we know
we must have a bug in either the pull or push side of our code
*/
-static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_pipe *p,
+static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_connection *c,
TALLOC_CTX *mem_ctx,
DATA_BLOB blob,
size_t struct_size,
return NT_STATUS_NO_MEMORY;
}
- pull = ndr_pull_init_flags(p, &blob, mem_ctx);
+ pull = ndr_pull_init_flags(c, &blob, mem_ctx);
if (!pull) {
return NT_STATUS_NO_MEMORY;
}
initially generated. If they don't match then we know we must have a
bug in either the pull or push side of our code
*/
-static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_pipe *p,
+static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_connection *c,
TALLOC_CTX *mem_ctx,
void *struct_ptr,
size_t struct_size,
blob = ndr_push_blob(push);
- pull = ndr_pull_init_flags(p, &blob, mem_ctx);
+ pull = ndr_pull_init_flags(c, &blob, mem_ctx);
if (!pull) {
return NT_STATUS_NO_MEMORY;
}
return NULL;
}
- if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ if (p->conn->flags & DCERPC_PUSH_BIGENDIAN) {
push->flags |= LIBNDR_FLAG_BIGENDIAN;
}
/* retrieve the blob */
request = ndr_push_blob(push);
- if (p->flags & DCERPC_DEBUG_VALIDATE_IN) {
- status = dcerpc_ndr_validate_in(p, mem_ctx, request, call->struct_size,
+ if (p->conn->flags & DCERPC_DEBUG_VALIDATE_IN) {
+ status = dcerpc_ndr_validate_in(p->conn, mem_ctx, request, call->struct_size,
call->ndr_push, call->ndr_pull);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(2,("Validation failed in dcerpc_ndr_request_send - %s\n",
talloc_free(req);
/* prepare for ndr_pull_* */
- pull = ndr_pull_init_flags(p, &response, mem_ctx);
+ pull = ndr_pull_init_flags(p->conn, &response, mem_ctx);
if (!pull) {
return NT_STATUS_NO_MEMORY;
}
return status;
}
- if (p->flags & DCERPC_DEBUG_VALIDATE_OUT) {
- status = dcerpc_ndr_validate_out(p, mem_ctx, r, call->struct_size,
+ if (p->conn->flags & DCERPC_DEBUG_VALIDATE_OUT) {
+ status = dcerpc_ndr_validate_out(p->conn, mem_ctx, r, call->struct_size,
call->ndr_push, call->ndr_pull);
if (!NT_STATUS_IS_OK(status)) {
dcerpc_log_packet(table, opnum, NDR_OUT,
*/
const char *dcerpc_server_name(struct dcerpc_pipe *p)
{
- if (!p->transport.peer_name) {
+ if (!p->conn->transport.peer_name) {
return "";
}
- return p->transport.peer_name(p);
+ return p->conn->transport.peer_name(p->conn);
}
+
/*
- a useful function to get the auth_level
+ get the dcerpc auth_level for a open connection
*/
-
-uint32 dcerpc_auth_level(struct dcerpc_pipe *p)
+uint32 dcerpc_auth_level(struct dcerpc_connection *c)
{
uint8_t auth_level;
- if (p->flags & DCERPC_SEAL) {
+ if (c->flags & DCERPC_SEAL) {
auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
- } else if (p->flags & DCERPC_SIGN) {
+ } else if (c->flags & DCERPC_SIGN) {
auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
- } else if (p->flags & DCERPC_CONNECT) {
+ } else if (c->flags & DCERPC_CONNECT) {
auth_level = DCERPC_AUTH_LEVEL_CONNECT;
} else {
auth_level = DCERPC_AUTH_LEVEL_NONE;
/*
Unix SMB/CIFS implementation.
- DCERPC interface structures
+
+ DCERPC client side interface structures
Copyright (C) Tim Potter 2003
- Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Andrew Tridgell 2003-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/*
this defines a generic security context for signed/sealed dcerpc pipes.
*/
-struct dcerpc_pipe;
+struct dcerpc_connection;
struct dcerpc_security {
struct dcerpc_auth *auth_info;
struct gensec_security *generic_state;
/* get the session key */
- NTSTATUS (*session_key)(struct dcerpc_pipe *, DATA_BLOB *);
+ NTSTATUS (*session_key)(struct dcerpc_connection *, DATA_BLOB *);
};
-struct dcerpc_pipe {
- int reference_count;
+/*
+ this holds the information that is not specific to a particular rpc context_id
+*/
+struct dcerpc_connection {
uint32_t call_id;
uint32_t srv_max_xmit_frag;
uint32_t srv_max_recv_frag;
struct dcerpc_security security_state;
const char *binding_string;
- struct dcerpc_syntax_id syntax;
- struct dcerpc_syntax_id transfer_syntax;
-
struct dcerpc_transport {
enum dcerpc_transport_t transport;
void *private;
- NTSTATUS (*shutdown_pipe)(struct dcerpc_pipe *);
+ NTSTATUS (*shutdown_pipe)(struct dcerpc_connection *);
- const char *(*peer_name)(struct dcerpc_pipe *);
+ const char *(*peer_name)(struct dcerpc_connection *);
/* send a request to the server */
- NTSTATUS (*send_request)(struct dcerpc_pipe *, DATA_BLOB *, BOOL trigger_read);
+ NTSTATUS (*send_request)(struct dcerpc_connection *, DATA_BLOB *, BOOL trigger_read);
/* send a read request to the server */
- NTSTATUS (*send_read)(struct dcerpc_pipe *);
+ NTSTATUS (*send_read)(struct dcerpc_connection *);
/* get an event context for the connection */
- struct event_context *(*event_context)(struct dcerpc_pipe *);
+ struct event_context *(*event_context)(struct dcerpc_connection *);
/* a callback to the dcerpc code when a full fragment
has been received */
- void (*recv_data)(struct dcerpc_pipe *, DATA_BLOB *, NTSTATUS status);
-
+ void (*recv_data)(struct dcerpc_connection *, DATA_BLOB *, NTSTATUS status);
} transport;
- /* the last fault code from a DCERPC fault */
- uint32_t last_fault_code;
-
/* pending requests */
struct rpc_request *pending;
void *full_request_private;
};
+/*
+ this encapsulates a full dcerpc client side pipe
+*/
+struct dcerpc_pipe {
+ uint32_t context_id;
+
+ struct dcerpc_syntax_id syntax;
+ struct dcerpc_syntax_id transfer_syntax;
+
+ struct dcerpc_connection *conn;
+
+ /* the last fault code from a DCERPC fault */
+ uint32_t last_fault_code;
+};
+
+
/* dcerpc pipe flags */
#define DCERPC_DEBUG_PRINT_IN (1<<0)
#define DCERPC_DEBUG_PRINT_OUT (1<<1)
const struct dcerpc_endpoint_list *endpoints;
};
-struct dcerpc_interface_list
-{
+struct dcerpc_interface_list {
struct dcerpc_interface_list *prev, *next;
const struct dcerpc_interface_table *table;
};
}
NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
- const char *uuid, uint_t version)
+ const char *uuid, uint_t version)
{
NTSTATUS status;
TALLOC_CTX *mem_ctx;
return NT_STATUS_NO_MEMORY;
}
- if (!p->security_state.generic_state) {
- status = gensec_client_start(p, &p->security_state.generic_state);
+ if (!p->conn->security_state.generic_state) {
+ status = gensec_client_start(p, &p->conn->security_state.generic_state);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = gensec_start_mech_by_authtype(p->security_state.generic_state, auth_type, auth_level);
+ status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
+ auth_type, auth_level);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
- p->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
- if (!p->security_state.auth_info) {
+ p->conn->security_state.auth_info = talloc(p, struct dcerpc_auth);
+ if (!p->conn->security_state.auth_info) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
- p->security_state.auth_info->auth_type = auth_type;
- p->security_state.auth_info->auth_level = auth_level;
- p->security_state.auth_info->auth_pad_length = 0;
- p->security_state.auth_info->auth_reserved = 0;
- p->security_state.auth_info->auth_context_id = random();
- p->security_state.auth_info->credentials = null_data_blob;
+ p->conn->security_state.auth_info->auth_type = auth_type;
+ p->conn->security_state.auth_info->auth_level = auth_level;
+ p->conn->security_state.auth_info->auth_pad_length = 0;
+ p->conn->security_state.auth_info->auth_reserved = 0;
+ p->conn->security_state.auth_info->auth_context_id = random();
+ p->conn->security_state.auth_info->credentials = null_data_blob;
- status = gensec_update(p->security_state.generic_state, mem_ctx,
+ status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
null_data_blob,
&credentials);
goto done;
}
- p->security_state.auth_info->credentials = credentials;
+ p->conn->security_state.auth_info->credentials = credentials;
status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
if (!NT_STATUS_IS_OK(status)) {
goto done;
}
- status = gensec_update(p->security_state.generic_state, mem_ctx,
- p->security_state.auth_info->credentials,
+ status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
+ p->conn->security_state.auth_info->credentials,
&credentials);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto done;
}
- p->security_state.auth_info->credentials = credentials;
+ p->conn->security_state.auth_info->credentials = credentials;
- status = dcerpc_auth3(p, mem_ctx);
+ status = dcerpc_auth3(p->conn, mem_ctx);
done:
talloc_destroy(mem_ctx);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(p->security_state.generic_state);
- ZERO_STRUCT(p->security_state);
+ talloc_free(p->conn->security_state.generic_state);
+ ZERO_STRUCT(p->conn->security_state);
} else {
/* Authenticated connections use the generic session key */
- p->security_state.session_key = dcerpc_generic_session_key;
+ p->conn->security_state.session_key = dcerpc_generic_session_key;
}
return status;
}
+#warning "bind_alter not implemented"
+#if 0
NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level,
const char *uuid, uint_t version)
{
return NT_STATUS_NO_MEMORY;
}
- if (!p->security_state.generic_state) {
- status = gensec_client_start(p, &p->security_state.generic_state);
+ if (!p->conn->security_state.generic_state) {
+ status = gensec_client_start(p, &p->conn->security_state.generic_state);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = gensec_start_mech_by_authtype(p->security_state.generic_state,
+ status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
auth_type, auth_level);
if (!NT_STATUS_IS_OK(status)) {
}
}
- p->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
- if (!p->security_state.auth_info) {
+ p->conn->security_state.auth_info = talloc_p(p, struct dcerpc_auth);
+ if (!p->conn->security_state.auth_info) {
status = NT_STATUS_NO_MEMORY;
goto done;
}
- p->security_state.auth_info->auth_type = auth_type;
- p->security_state.auth_info->auth_level = auth_level;
- p->security_state.auth_info->auth_pad_length = 0;
- p->security_state.auth_info->auth_reserved = 0;
- p->security_state.auth_info->auth_context_id = random();
- p->security_state.auth_info->credentials = null_data_blob;
+ p->conn->security_state.auth_info->auth_type = auth_type;
+ p->conn->security_state.auth_info->auth_level = auth_level;
+ p->conn->security_state.auth_info->auth_pad_length = 0;
+ p->conn->security_state.auth_info->auth_reserved = 0;
+ p->conn->security_state.auth_info->auth_context_id = random();
+ p->conn->security_state.auth_info->credentials = null_data_blob;
- status = gensec_update(p->security_state.generic_state, mem_ctx,
+ status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
null_data_blob,
&credentials);
goto done;
}
- p->security_state.auth_info->credentials = credentials;
+ p->conn->security_state.auth_info->credentials = credentials;
status = dcerpc_bind_byuuid(p, mem_ctx, uuid, version);
if (!NT_STATUS_IS_OK(status)) {
}
while(1) {
- status = gensec_update(p->security_state.generic_state, mem_ctx,
- p->security_state.auth_info->credentials,
+ status = gensec_update(p->conn->security_state.generic_state, mem_ctx,
+ p->conn->security_state.auth_info->credentials,
&credentials);
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
goto done;
}
- p->security_state.auth_info->credentials = credentials;
+ p->conn->security_state.auth_info->credentials = credentials;
status = dcerpc_alter(p, mem_ctx);
if (!NT_STATUS_IS_OK(status)) {
talloc_destroy(mem_ctx);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(p->security_state.generic_state);
- ZERO_STRUCT(p->security_state);
+ talloc_free(p->conn->security_state.generic_state);
+ ZERO_STRUCT(p->conn->security_state);
} else {
/* Authenticated connections use the generic session key */
- p->security_state.session_key = dcerpc_generic_session_key;
+ p->conn->security_state.session_key = dcerpc_generic_session_key;
}
return status;
}
+#endif
{
NTSTATUS status;
- if (!(p->flags & (DCERPC_SIGN | DCERPC_SEAL))) {
- p->flags |= DCERPC_CONNECT;
+ if (!(p->conn->flags & (DCERPC_SIGN | DCERPC_SEAL))) {
+ p->conn->flags |= DCERPC_CONNECT;
}
- status = gensec_client_start(p, &p->security_state.generic_state);
+ status = gensec_client_start(p, &p->conn->security_state.generic_state);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));
return status;
}
- status = gensec_set_domain(p->security_state.generic_state, domain);
+ status = gensec_set_domain(p->conn->security_state.generic_state, domain);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n",
domain, nt_errstr(status)));
return status;
}
- status = gensec_set_username(p->security_state.generic_state, username);
+ status = gensec_set_username(p->conn->security_state.generic_state, username);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n",
username, nt_errstr(status)));
return status;
}
- status = gensec_set_password(p->security_state.generic_state, password);
+ status = gensec_set_password(p->conn->security_state.generic_state, password);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client password: %s\n",
nt_errstr(status)));
return status;
}
- status = gensec_start_mech_by_authtype(p->security_state.generic_state, DCERPC_AUTH_TYPE_NTLMSSP, dcerpc_auth_level(p));
+ status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
+ DCERPC_AUTH_TYPE_NTLMSSP, dcerpc_auth_level(p->conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client NTLMSSP mechanism: %s\n",
nt_errstr(status)));
}
status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_NTLMSSP,
- dcerpc_auth_level(p),
+ dcerpc_auth_level(p->conn),
uuid, version);
if (!NT_STATUS_IS_OK(status)) {
const char *workgroup, *workstation;
uint32_t negotiate_flags;
- if (p->flags & DCERPC_SCHANNEL_128) {
+ if (p->conn->flags & DCERPC_SCHANNEL_128) {
negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
} else {
negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
NTSTATUS status;
struct dcerpc_schannel_state *dce_schan_state;
- status = gensec_client_start(p, &p->security_state.generic_state);
+ status = gensec_client_start(p, &p->conn->security_state.generic_state);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = gensec_set_username(p->security_state.generic_state, username);
+ status = gensec_set_username(p->conn->security_state.generic_state, username);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status)));
- talloc_free(p->security_state.generic_state);
- p->security_state.generic_state = NULL;
+ talloc_free(p->conn->security_state.generic_state);
+ p->conn->security_state.generic_state = NULL;
return status;
}
- status = gensec_set_domain(p->security_state.generic_state, domain);
+ status = gensec_set_domain(p->conn->security_state.generic_state, domain);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to set schannel domain to %s: %s\n", domain, nt_errstr(status)));
- talloc_free(p->security_state.generic_state);
- p->security_state.generic_state = NULL;
+ talloc_free(p->conn->security_state.generic_state);
+ p->conn->security_state.generic_state = NULL;
return status;
}
- status = gensec_start_mech_by_authtype(p->security_state.generic_state, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p));
+ status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
+ DCERPC_AUTH_TYPE_SCHANNEL,
+ dcerpc_auth_level(p->conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start SCHANNEL GENSEC backend: %s\n", nt_errstr(status)));
- talloc_free(p->security_state.generic_state);
- p->security_state.generic_state = NULL;
+ talloc_free(p->conn->security_state.generic_state);
+ p->conn->security_state.generic_state = NULL;
return status;
}
- dce_schan_state = p->security_state.generic_state->private_data;
+ dce_schan_state = p->conn->security_state.generic_state->private_data;
dce_schan_state->creds = talloc_reference(dce_schan_state, creds);
- status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p),
- uuid, version);
+ status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p->conn),
+ uuid, version);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to bind to pipe with SCHANNEL: %s\n", nt_errstr(status)));
- talloc_free(p->security_state.generic_state);
- p->security_state.generic_state = NULL;
+ talloc_free(p->conn->security_state.generic_state);
+ p->conn->security_state.generic_state = NULL;
return status;
}
return NT_STATUS_NO_MEMORY;
}
- if (p->flags & DCERPC_SCHANNEL_BDC) {
+ if (p->conn->flags & DCERPC_SCHANNEL_BDC) {
chan_type = SEC_CHAN_BDC;
- } else if (p->flags & DCERPC_SCHANNEL_WORKSTATION) {
+ } else if (p->conn->flags & DCERPC_SCHANNEL_WORKSTATION) {
chan_type = SEC_CHAN_WKSTA;
- } else if (p->flags & DCERPC_SCHANNEL_DOMAIN) {
+ } else if (p->conn->flags & DCERPC_SCHANNEL_DOMAIN) {
chan_type = SEC_CHAN_DOMAIN;
}
/*
tell the dcerpc layer that the transport is dead
*/
-static void pipe_dead(struct dcerpc_pipe *p, NTSTATUS status)
+static void pipe_dead(struct dcerpc_connection *c, NTSTATUS status)
{
- p->transport.recv_data(p, NULL, status);
+ c->transport.recv_data(c, NULL, status);
}
this holds the state of an in-flight call
*/
struct smb_read_state {
- struct dcerpc_pipe *p;
+ struct dcerpc_connection *c;
struct smbcli_request *req;
size_t received;
DATA_BLOB data;
NTSTATUS status;
state = req->async.private;
- smb = state->p->transport.private;
+ smb = state->c->transport.private;
io = state->io;
status = smb_raw_read_recv(state->req, io);
if (NT_STATUS_IS_ERR(status)) {
- pipe_dead(state->p, status);
+ pipe_dead(state->c, status);
talloc_free(state);
return;
}
if (state->received < 16) {
DEBUG(0,("dcerpc_smb: short packet (length %d) in read callback!\n",
state->received));
- pipe_dead(state->p, NT_STATUS_INFO_LENGTH_MISMATCH);
+ pipe_dead(state->c, NT_STATUS_INFO_LENGTH_MISMATCH);
talloc_free(state);
return;
}
if (frag_length <= state->received) {
state->data.length = state->received;
- state->p->transport.recv_data(state->p, &state->data, NT_STATUS_OK);
+ state->c->transport.recv_data(state->c, &state->data, NT_STATUS_OK);
talloc_free(state);
return;
}
/* initiate another read request, as we only got part of a fragment */
state->data.data = talloc_realloc(state, state->data.data, uint8_t, frag_length);
- io->readx.in.mincnt = MIN(state->p->srv_max_xmit_frag,
+ io->readx.in.mincnt = MIN(state->c->srv_max_xmit_frag,
frag_length - state->received);
io->readx.in.maxcnt = io->readx.in.mincnt;
io->readx.out.data = state->data.data + state->received;
state->req = smb_raw_read_send(smb->tree, io);
if (state->req == NULL) {
- pipe_dead(state->p, NT_STATUS_NO_MEMORY);
+ pipe_dead(state->c, NT_STATUS_NO_MEMORY);
talloc_free(state);
return;
}
trigger a read request from the server, possibly with some initial
data in the read buffer
*/
-static NTSTATUS send_read_request_continue(struct dcerpc_pipe *p, DATA_BLOB *blob)
+static NTSTATUS send_read_request_continue(struct dcerpc_connection *c, DATA_BLOB *blob)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
union smb_read *io;
struct smb_read_state *state;
struct smbcli_request *req;
return NT_STATUS_NO_MEMORY;
}
- state->p = p;
+ state->c = c;
if (blob == NULL) {
state->received = 0;
state->data = data_blob_talloc(state, NULL, 0x2000);
/*
trigger a read request from the server
*/
-static NTSTATUS send_read_request(struct dcerpc_pipe *p)
+static NTSTATUS send_read_request(struct dcerpc_connection *c)
{
- return send_read_request_continue(p, NULL);
+ return send_read_request_continue(c, NULL);
}
/*
this holds the state of an in-flight trans call
*/
struct smb_trans_state {
- struct dcerpc_pipe *p;
+ struct dcerpc_connection *c;
struct smbcli_request *req;
struct smb_trans2 *trans;
};
static void smb_trans_callback(struct smbcli_request *req)
{
struct smb_trans_state *state = req->async.private;
- struct dcerpc_pipe *p = state->p;
+ struct dcerpc_connection *c = state->c;
NTSTATUS status;
status = smb_raw_trans_recv(req, state, state->trans);
if (NT_STATUS_IS_ERR(status)) {
- pipe_dead(p, status);
+ pipe_dead(c, status);
return;
}
if (!NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW)) {
- p->transport.recv_data(p, &state->trans->out.data, NT_STATUS_OK);
+ c->transport.recv_data(c, &state->trans->out.data, NT_STATUS_OK);
talloc_free(state);
return;
}
/* there is more to receive - setup a readx */
- send_read_request_continue(p, &state->trans->out.data);
+ send_read_request_continue(c, &state->trans->out.data);
talloc_free(state);
}
/*
send a SMBtrans style request
*/
-static NTSTATUS smb_send_trans_request(struct dcerpc_pipe *p, DATA_BLOB *blob)
+static NTSTATUS smb_send_trans_request(struct dcerpc_connection *c, DATA_BLOB *blob)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
struct smb_trans2 *trans;
uint16 setup[2];
struct smb_trans_state *state;
return NT_STATUS_NO_MEMORY;
}
- state->p = p;
+ state->c = c;
state->trans = talloc_p(state, struct smb_trans2);
trans = state->trans;
*/
static void smb_write_callback(struct smbcli_request *req)
{
- struct dcerpc_pipe *p = req->async.private;
+ struct dcerpc_connection *c = req->async.private;
if (!NT_STATUS_IS_OK(req->status)) {
DEBUG(0,("dcerpc_smb: write callback error\n"));
- pipe_dead(p, req->status);
+ pipe_dead(c, req->status);
}
smbcli_request_destroy(req);
/*
send a packet to the server
*/
-static NTSTATUS smb_send_request(struct dcerpc_pipe *p, DATA_BLOB *blob, BOOL trigger_read)
+static NTSTATUS smb_send_request(struct dcerpc_connection *c, DATA_BLOB *blob, BOOL trigger_read)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
union smb_write io;
struct smbcli_request *req;
if (trigger_read) {
- return smb_send_trans_request(p, blob);
+ return smb_send_trans_request(c, blob);
}
io.generic.level = RAW_WRITE_WRITEX;
}
req->async.fn = smb_write_callback;
- req->async.private = p;
+ req->async.private = c;
if (trigger_read) {
- send_read_request(p);
+ send_read_request(c);
}
return NT_STATUS_OK;
return the event context for the pipe, so the caller can wait
for events asynchronously
*/
-static struct event_context *smb_event_context(struct dcerpc_pipe *p)
+static struct event_context *smb_event_context(struct dcerpc_connection *c)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
return smb->tree->session->transport->event.ctx;
}
/*
shutdown SMB pipe connection
*/
-static NTSTATUS smb_shutdown_pipe(struct dcerpc_pipe *p)
+static NTSTATUS smb_shutdown_pipe(struct dcerpc_connection *c)
{
- struct smb_private *smb = p->transport.private;
- union smb_close c;
+ struct smb_private *smb = c->transport.private;
+ union smb_close io;
/* maybe we're still starting up */
if (!smb) return NT_STATUS_OK;
- c.close.level = RAW_CLOSE_CLOSE;
- c.close.in.fnum = smb->fnum;
- c.close.in.write_time = 0;
- smb_raw_close(smb->tree, &c);
+ io.close.level = RAW_CLOSE_CLOSE;
+ io.close.in.fnum = smb->fnum;
+ io.close.in.write_time = 0;
+ smb_raw_close(smb->tree, &io);
talloc_free(smb);
/*
return SMB server name
*/
-static const char *smb_peer_name(struct dcerpc_pipe *p)
+static const char *smb_peer_name(struct dcerpc_connection *c)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
return smb->tree->session->transport->called.name;
}
/*
fetch the user session key
*/
-static NTSTATUS smb_session_key(struct dcerpc_pipe *p, DATA_BLOB *session_key)
+static NTSTATUS smb_session_key(struct dcerpc_connection *c, DATA_BLOB *session_key)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
if (smb->tree->session->user_session_key.data) {
*session_key = smb->tree->session->user_session_key;
/*
open a rpc connection to a named pipe
*/
-NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
+NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c,
struct smbcli_tree *tree,
const char *pipe_name)
{
return status;
}
- if (!(*p = dcerpc_pipe_init())) {
- return NT_STATUS_NO_MEMORY;
- }
-
/*
fill in the transport methods
*/
- (*p)->transport.transport = NCACN_NP;
- (*p)->transport.private = NULL;
- (*p)->transport.shutdown_pipe = smb_shutdown_pipe;
- (*p)->transport.peer_name = smb_peer_name;
-
- (*p)->transport.send_request = smb_send_request;
- (*p)->transport.send_read = send_read_request;
- (*p)->transport.event_context = smb_event_context;
- (*p)->transport.recv_data = NULL;
+ c->transport.transport = NCACN_NP;
+ c->transport.private = NULL;
+ c->transport.shutdown_pipe = smb_shutdown_pipe;
+ c->transport.peer_name = smb_peer_name;
+
+ c->transport.send_request = smb_send_request;
+ c->transport.send_read = send_read_request;
+ c->transport.event_context = smb_event_context;
+ c->transport.recv_data = NULL;
/* Over-ride the default session key with the SMB session key */
- (*p)->security_state.session_key = smb_session_key;
+ c->security_state.session_key = smb_session_key;
- smb = talloc_p((*p), struct smb_private);
- if (!smb) {
- dcerpc_pipe_close(*p);
+ smb = talloc_p(c, struct smb_private);
+ if (smb == NULL) {
return NT_STATUS_NO_MEMORY;
}
smb->fnum = io.ntcreatex.out.fnum;
smb->tree = tree;
- (*p)->transport.private = smb;
+ c->transport.private = smb;
return NT_STATUS_OK;
}
/*
return the SMB tree used for a dcerpc over SMB pipe
*/
-struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_pipe *p)
+struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c)
{
- struct smb_private *smb = p->transport.private;
+ struct smb_private *smb = c->transport.private;
- if (p->transport.transport != NCACN_NP) {
+ if (c->transport.transport != NCACN_NP) {
return NULL;
}
/*
mark the socket dead
*/
-static void sock_dead(struct dcerpc_pipe *p, NTSTATUS status)
+static void sock_dead(struct dcerpc_connection *p, NTSTATUS status)
{
struct sock_private *sock = p->transport.private;
/*
process send requests
*/
-static void sock_process_send(struct dcerpc_pipe *p)
+static void sock_process_send(struct dcerpc_connection *p)
{
struct sock_private *sock = p->transport.private;
/*
process recv requests
*/
-static void sock_process_recv(struct dcerpc_pipe *p)
+static void sock_process_recv(struct dcerpc_connection *p)
{
struct sock_private *sock = p->transport.private;
NTSTATUS status;
static void sock_io_handler(struct event_context *ev, struct fd_event *fde,
struct timeval t, uint16_t flags)
{
- struct dcerpc_pipe *p = fde->private;
+ struct dcerpc_connection *p = fde->private;
struct sock_private *sock = p->transport.private;
if (flags & EVENT_FD_WRITE) {
/*
initiate a read request
*/
-static NTSTATUS sock_send_read(struct dcerpc_pipe *p)
+static NTSTATUS sock_send_read(struct dcerpc_connection *p)
{
struct sock_private *sock = p->transport.private;
/*
send an initial pdu in a multi-pdu sequence
*/
-static NTSTATUS sock_send_request(struct dcerpc_pipe *p, DATA_BLOB *data, BOOL trigger_read)
+static NTSTATUS sock_send_request(struct dcerpc_connection *p, DATA_BLOB *data, BOOL trigger_read)
{
struct sock_private *sock = p->transport.private;
struct sock_blob *blob;
/*
return the event context so the caller can process asynchronously
*/
-static struct event_context *sock_event_context(struct dcerpc_pipe *p)
+static struct event_context *sock_event_context(struct dcerpc_connection *p)
{
struct sock_private *sock = p->transport.private;
/*
shutdown sock pipe connection
*/
-static NTSTATUS sock_shutdown_pipe(struct dcerpc_pipe *p)
+static NTSTATUS sock_shutdown_pipe(struct dcerpc_connection *p)
{
sock_dead(p, NT_STATUS_OK);
/*
return sock server name
*/
-static const char *sock_peer_name(struct dcerpc_pipe *p)
+static const char *sock_peer_name(struct dcerpc_connection *p)
{
struct sock_private *sock = p->transport.private;
return sock->server_name;
/*
open a rpc connection using the generic socket library
*/
-static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
+static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *c,
const char *server,
uint32_t port,
const char *type,
struct fd_event fde;
NTSTATUS status;
- if (!(*p = dcerpc_pipe_init())) {
- return NT_STATUS_NO_MEMORY;
- }
-
- sock = talloc_p((*p), struct sock_private);
+ sock = talloc_p(c, struct sock_private);
if (!sock) {
- talloc_free(*p);
return NT_STATUS_NO_MEMORY;
}
status = socket_create(type, SOCKET_TYPE_STREAM, &socket_ctx, 0);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(*p);
+ talloc_free(sock);
return status;
}
talloc_steal(sock, socket_ctx);
status = socket_connect(socket_ctx, NULL, 0, server, port, 0);
if (!NT_STATUS_IS_OK(status)) {
- talloc_free(*p);
+ talloc_free(sock);
return status;
}
/*
fill in the transport methods
*/
- (*p)->transport.transport = transport;
- (*p)->transport.private = NULL;
+ c->transport.transport = transport;
+ c->transport.private = NULL;
- (*p)->transport.send_request = sock_send_request;
- (*p)->transport.send_read = sock_send_read;
- (*p)->transport.event_context = sock_event_context;
- (*p)->transport.recv_data = NULL;
+ c->transport.send_request = sock_send_request;
+ c->transport.send_read = sock_send_read;
+ c->transport.event_context = sock_event_context;
+ c->transport.recv_data = NULL;
- (*p)->transport.shutdown_pipe = sock_shutdown_pipe;
- (*p)->transport.peer_name = sock_peer_name;
+ c->transport.shutdown_pipe = sock_shutdown_pipe;
+ c->transport.peer_name = sock_peer_name;
sock->sock = socket_ctx;
- sock->server_name = talloc_strdup((*p), server);
+ sock->server_name = talloc_strdup(sock, server);
sock->event_ctx = event_context_init(sock);
sock->pending_send = NULL;
sock->recv.received = 0;
fde.fd = socket_get_fd(sock->sock);
fde.flags = 0;
fde.handler = sock_io_handler;
- fde.private = *p;
+ fde.private = c;
sock->fde = event_add_fd(sock->event_ctx, &fde);
- (*p)->transport.private = sock;
+ c->transport.private = sock;
/* ensure we don't get SIGPIPE */
BlockSignals(True,SIGPIPE);
/*
open a rpc connection using tcp
*/
-NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, const char *server, uint32_t port)
+NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_connection *c, const char *server, uint32_t port)
{
NTSTATUS status;
/* Try IPv6 first */
- status = dcerpc_pipe_open_socket(p, server, port, "ipv6", NCACN_IP_TCP);
+ status = dcerpc_pipe_open_socket(c, server, port, "ipv6", NCACN_IP_TCP);
if (NT_STATUS_IS_OK(status)) {
return status;
}
- return dcerpc_pipe_open_socket(p, server, port, "ipv4", NCACN_IP_TCP);
+ return dcerpc_pipe_open_socket(c, server, port, "ipv4", NCACN_IP_TCP);
}
/*
open a rpc connection to a unix socket
*/
-NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_pipe **p, const char *path)
+NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_connection *c, const char *path)
{
- return dcerpc_pipe_open_socket(p, path, 0, "unix", NCACN_UNIX_STREAM);
+ return dcerpc_pipe_open_socket(c, path, 0, "unix", NCACN_UNIX_STREAM);
}
/*
open a rpc connection to a named pipe
*/
-NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p, const char *identifier)
+NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_connection *c, const char *identifier)
{
NTSTATUS status;
char *canon, *full_path;
string_replace(canon, '/', '\\');
full_path = talloc_asprintf(canon, "%s/%s", lp_ncalrpc_dir(), canon);
- status = dcerpc_pipe_open_socket(p, full_path, 0, "unix", NCALRPC);
+ status = dcerpc_pipe_open_socket(c, full_path, 0, "unix", NCALRPC);
talloc_free(canon);
return status;
dcerpc authentication operations
- Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Stefan Metzmacher 2004
+ Copyright (C) Andrew Tridgell 2003-2005
+ Copyright (C) Andrew Bartlett 2004
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "includes.h"
+#warning "this needs dcerpc_alter"
+#if 0
/*
do spnego style authentication on a gensec pipe
*/
{
NTSTATUS status;
- status = gensec_client_start(p, &p->security_state.generic_state);
+ status = gensec_client_start(p, &p->conn->security_state.generic_state);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));
return status;
}
- status = gensec_set_domain(p->security_state.generic_state, domain);
+ status = gensec_set_domain(p->conn->security_state.generic_state, domain);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n",
domain, nt_errstr(status)));
return status;
}
- status = gensec_set_username(p->security_state.generic_state, username);
+ status = gensec_set_username(p->conn->security_state.generic_state, username);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client username to %s: %s\n",
username, nt_errstr(status)));
return status;
}
- status = gensec_set_password(p->security_state.generic_state, password);
+ status = gensec_set_password(p->conn->security_state.generic_state, password);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client password: %s\n",
nt_errstr(status)));
return status;
}
- status = gensec_set_target_hostname(p->security_state.generic_state, p->transport.peer_name(p));
+ status = gensec_set_target_hostname(p->conn->security_state.generic_state,
+ p->conn->transport.peer_name(p->conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n",
nt_errstr(status)));
return status;
}
- status = gensec_start_mech_by_authtype(p->security_state.generic_state, DCERPC_AUTH_TYPE_SPNEGO, dcerpc_auth_level(p));
+ status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state,
+ DCERPC_AUTH_TYPE_SPNEGO,
+ dcerpc_auth_level(p->conn));
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client SPNEGO mechanism: %s\n",
nt_errstr(status)));
return status;
}
- status = dcerpc_bind_alter(p, DCERPC_AUTH_TYPE_SPNEGO, dcerpc_auth_level(p),
- uuid, version);
+ status = dcerpc_bind_alter(p, DCERPC_AUTH_TYPE_SPNEGO,
+ dcerpc_auth_level(p->conn),
+ uuid, version);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(2, ("Failed to bind to pipe with SPNEGO: %s\n", nt_errstr(status)));
return status;
}
+#endif
*/
const char *idl_pipe_name(const char *uuid, uint32_t if_version)
{
- struct dcerpc_interface_list *l;
- for (l=dcerpc_pipes;l;l=l->next) {
+ const struct dcerpc_interface_list *l;
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
if (strcasecmp(l->table->uuid, uuid) == 0 &&
l->table->if_version == if_version) {
return l->table->name;
*/
int idl_num_calls(const char *uuid, uint32_t if_version)
{
- struct dcerpc_interface_list *l;
- for (l=dcerpc_pipes;l;l=l->next){
+ const struct dcerpc_interface_list *l;
+ for (l=librpc_dcerpc_pipes();l;l=l->next){
if (strcasecmp(l->table->uuid, uuid) == 0 &&
l->table->if_version == if_version) {
return l->table->num_calls;
*/
const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
{
- struct dcerpc_interface_list *l;
- for (l=dcerpc_pipes;l;l=l->next) {
+ const struct dcerpc_interface_list *l;
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
if (strcasecmp(l->table->name, name) == 0) {
return l->table;
}
*/
const struct dcerpc_interface_table *idl_iface_by_uuid(const char *uuid)
{
- struct dcerpc_interface_list *l;
- for (l=dcerpc_pipes;l;l=l->next) {
+ const struct dcerpc_interface_list *l;
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
if (strcasecmp(l->table->uuid, uuid) == 0) {
return l->table;
}
/* open a rpc connection to a rpc pipe on SMB using the binding
structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
+static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *username,
const char *password)
{
+ struct dcerpc_pipe *p;
NTSTATUS status;
BOOL retry;
struct smbcli_state *cli;
const char *pipe_name = NULL;
- TALLOC_CTX *mem_ctx = talloc_init("dcerpc_pipe_connect_ncacn_np");
+ TALLOC_CTX *tmp_ctx;
+
+ *pp = NULL;
+
+ p = dcerpc_pipe_init(NULL);
+ if (p == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ tmp_ctx = talloc_new(p);
/* Look up identifier using the epmapper */
if (!binding->endpoint) {
- status = dcerpc_epm_map_binding(mem_ctx, binding, pipe_uuid, pipe_version);
+ status = dcerpc_epm_map_binding(tmp_ctx, binding, pipe_uuid, pipe_version);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n",
pipe_uuid, nt_errstr(status)));
- talloc_destroy(mem_ctx);
+ talloc_free(p);
return status;
}
DEBUG(1,("Mapped to DCERPC/NP pipe %s\n", binding->endpoint));
pipe_name = binding->endpoint;
if (!strncasecmp(pipe_name, "/pipe/", 6) ||
- !strncasecmp(pipe_name, "\\pipe\\", 6)) {
- pipe_name+=6;
+ !strncasecmp(pipe_name, "\\pipe\\", 6)) {
+ pipe_name += 6;
}
if (pipe_name[0] != '\\') {
- pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
+ pipe_name = talloc_asprintf(tmp_ctx, "\\%s", pipe_name);
}
if (!username || !username[0] ||
(binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = smbcli_full_connection(NULL, &cli, lp_netbios_name(),
- binding->host, NULL,
- "ipc$", "?????",
- "", "", NULL, 0, &retry);
+ status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
+ binding->host, NULL,
+ "ipc$", "?????",
+ "", "", NULL, 0, &retry);
} else {
- status = smbcli_full_connection(NULL, &cli, lp_netbios_name(),
- binding->host, NULL,
- "ipc$", "?????",
- username, domain,
- password, 0, &retry);
+ status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
+ binding->host, NULL,
+ "ipc$", "?????",
+ username, domain,
+ password, 0, &retry);
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to connect to %s - %s\n", binding->host, nt_errstr(status)));
- talloc_destroy(mem_ctx);
+ talloc_free(p);
return status;
}
- status = dcerpc_pipe_open_smb(p, cli->tree, pipe_name);
+ status = dcerpc_pipe_open_smb(p->conn, cli->tree, pipe_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to open pipe %s - %s\n", pipe_name, nt_errstr(status)));
- smbcli_tdis(cli);
- smbcli_shutdown(cli);
- talloc_destroy(mem_ctx);
+ talloc_free(p);
return status;
}
- /* this ensures that the reference count is decremented so
- a pipe close will really close the link */
- talloc_steal(*p, cli);
-
- (*p)->flags = binding->flags;
+ p->conn->flags = binding->flags;
/* remember the binding string for possible secondary connections */
- (*p)->binding_string = dcerpc_binding_string((*p), binding);
-
- talloc_destroy(mem_ctx);
+ p->conn->binding_string = dcerpc_binding_string(p, binding);
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
+ status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
domain, username, password);
} else if (username && username[0] &&
(binding->flags & (DCERPC_CONNECT|DCERPC_SIGN|DCERPC_SEAL))) {
- status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
} else {
- status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+ status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
- dcerpc_pipe_close(*p);
- *p = NULL;
+ talloc_free(p);
return status;
}
+ (*pp) = p;
+ talloc_free(tmp_ctx);
+
return NT_STATUS_OK;
}
/* open a rpc connection to a rpc pipe on SMP using the binding
structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
- struct dcerpc_binding *binding,
- const char *pipe_uuid,
- uint32_t pipe_version,
- const char *domain,
- const char *username,
- const char *password)
+static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp,
+ struct dcerpc_binding *binding,
+ const char *pipe_uuid,
+ uint32_t pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
{
NTSTATUS status;
- TALLOC_CTX *mem_ctx = talloc_init("dcerpc_pipe_connect_ncalrpc");
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *tmp_ctx;
+
+ (*pp) = NULL;
+
+ p = dcerpc_pipe_init(NULL);
+ if (p == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ tmp_ctx = talloc_new(p);
/* Look up identifier using the epmapper */
if (!binding->endpoint) {
- status = dcerpc_epm_map_binding(mem_ctx, binding, pipe_uuid, pipe_version);
+ status = dcerpc_epm_map_binding(tmp_ctx, binding, pipe_uuid, pipe_version);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to map DCERPC/TCP NCALRPC identifier for '%s' - %s\n",
pipe_uuid, nt_errstr(status)));
- talloc_destroy(mem_ctx);
+ talloc_free(p);
return status;
}
DEBUG(1,("Mapped to DCERPC/LRPC identifier %s\n", binding->endpoint));
}
- status = dcerpc_pipe_open_pipe(p, binding->endpoint);
-
+ status = dcerpc_pipe_open_pipe(p->conn, binding->endpoint);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to open ncalrpc pipe '%s' - %s\n", binding->endpoint, nt_errstr(status)));
- talloc_destroy(mem_ctx);
+ DEBUG(0,("Failed to open ncalrpc pipe '%s' - %s\n",
+ binding->endpoint, nt_errstr(status)));
+ talloc_free(p);
return status;
- }
+ }
- (*p)->flags = binding->flags;
+ p->conn->flags = binding->flags;
/* remember the binding string for possible secondary connections */
- (*p)->binding_string = dcerpc_binding_string((*p), binding);
+ p->conn->binding_string = dcerpc_binding_string(p, binding);
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
+ status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
domain, username, password);
} else if (username && username[0]) {
- status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
} else {
- status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+ status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
}
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n",
- pipe_uuid, nt_errstr(status)));
- dcerpc_pipe_close(*p);
- *p = NULL;
- talloc_destroy(mem_ctx);
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+ talloc_free(p);
return status;
}
-
- talloc_destroy(mem_ctx);
- return status;
+
+ (*pp) = p;
+ talloc_free(tmp_ctx);
+
+ return status;
}
/* open a rpc connection to a rpc pipe on SMP using the binding
structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p,
- struct dcerpc_binding *binding,
- const char *pipe_uuid,
- uint32_t pipe_version,
- const char *domain,
- const char *username,
- const char *password)
+static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp,
+ struct dcerpc_binding *binding,
+ const char *pipe_uuid,
+ uint32_t pipe_version,
+ const char *domain,
+ const char *username,
+ const char *password)
{
NTSTATUS status;
+ struct dcerpc_pipe *p;
+
+ (*pp) = NULL;
if (!binding->endpoint) {
DEBUG(0, ("Path to unix socket not specified\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- status = dcerpc_pipe_open_unix_stream(p, binding->endpoint);
+ p = dcerpc_pipe_init(NULL);
+ if (p == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = dcerpc_pipe_open_unix_stream(p->conn, binding->endpoint);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to open unix socket %s - %s\n",
binding->endpoint, nt_errstr(status)));
+ talloc_free(p);
return status;
}
- (*p)->flags = binding->flags;
+ p->conn->flags = binding->flags;
/* remember the binding string for possible secondary connections */
- (*p)->binding_string = dcerpc_binding_string((*p), binding);
+ p->conn->binding_string = dcerpc_binding_string(p, binding);
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
+ status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
domain, username, password);
} else if (username && username[0]) {
- status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
} else {
- status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+ status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
}
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("Failed to bind to uuid %s - %s\n",
- pipe_uuid, nt_errstr(status)));
- dcerpc_pipe_close(*p);
- *p = NULL;
+ DEBUG(0,("Failed to bind to uuid %s - %s\n", pipe_uuid, nt_errstr(status)));
+ talloc_free(p);
return status;
}
+
+ (*pp) = p;
- return status;
+ return status;
}
/* open a rpc connection to a rpc pipe on SMP using the binding
structure to determine the endpoint and options */
-static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
+static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
{
NTSTATUS status;
uint32_t port = 0;
- TALLOC_CTX *mem_ctx = talloc_init("connect_ncacn_ip_tcp");
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *tmp_ctx;
+
+ (*pp) = NULL;
+
+ p = dcerpc_pipe_init(NULL);
+ if (p == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ tmp_ctx = talloc_new(p);
if (!binding->endpoint) {
- status = dcerpc_epm_map_binding(mem_ctx, binding,
- pipe_uuid, pipe_version);
+ status = dcerpc_epm_map_binding(tmp_ctx, binding,
+ pipe_uuid, pipe_version);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to map DCERPC/TCP port for '%s' - %s\n",
pipe_uuid, nt_errstr(status)));
+ talloc_free(p);
return status;
}
DEBUG(1,("Mapped to DCERPC/TCP port %s\n", binding->endpoint));
port = atoi(binding->endpoint);
- status = dcerpc_pipe_open_tcp(p, binding->host, port);
+ status = dcerpc_pipe_open_tcp(p->conn, binding->host, port);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to connect to %s:%d - %s\n",
binding->host, port, nt_errstr(status)));
+ talloc_free(p);
return status;
}
- (*p)->flags = binding->flags;
+ p->conn->flags = binding->flags;
/* remember the binding string for possible secondary connections */
- (*p)->binding_string = dcerpc_binding_string((*p), binding);
+ p->conn->binding_string = dcerpc_binding_string(p, binding);
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
- status = dcerpc_bind_auth_schannel(*p, pipe_uuid, pipe_version,
+ status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
domain, username, password);
} else if (username && username[0]) {
- status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_bind_auth_ntlm(p, pipe_uuid, pipe_version, domain, username, password);
} else {
- status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
+ status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
}
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to uuid %s - %s\n",
pipe_uuid, nt_errstr(status)));
- dcerpc_pipe_close(*p);
- *p = NULL;
+ talloc_free(p);
return status;
}
+
+ (*pp) = p;
+ talloc_free(tmp_ctx);
return status;
}
/* open a rpc connection to a rpc pipe, using the specified
binding structure to determine the endpoint and options */
-NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
+NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
switch (binding->transport) {
case NCACN_NP:
- status = dcerpc_pipe_connect_ncacn_np(p, binding, pipe_uuid, pipe_version,
+ status = dcerpc_pipe_connect_ncacn_np(pp, binding, pipe_uuid, pipe_version,
domain, username, password);
break;
case NCACN_IP_TCP:
- status = dcerpc_pipe_connect_ncacn_ip_tcp(p, binding, pipe_uuid, pipe_version,
+ status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version,
domain, username, password);
break;
case NCACN_UNIX_STREAM:
- status = dcerpc_pipe_connect_ncacn_unix_stream(p, binding, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version,
+ domain, username, password);
break;
case NCALRPC:
- status = dcerpc_pipe_connect_ncalrpc(p, binding, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version,
+ domain, username, password);
break;
default:
return NT_STATUS_NOT_SUPPORTED;
/* open a rpc connection to a rpc pipe, using the specified string
binding to determine the endpoint and options */
-NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
+NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp,
const char *binding,
const char *pipe_uuid,
uint32_t pipe_version,
{
struct dcerpc_binding b;
NTSTATUS status;
- TALLOC_CTX *mem_ctx;
+ TALLOC_CTX *tmp_ctx;
- mem_ctx = talloc_init("dcerpc_pipe_connect");
- if (!mem_ctx) return NT_STATUS_NO_MEMORY;
+ tmp_ctx = talloc_new(NULL);
- status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ status = dcerpc_parse_binding(tmp_ctx, binding, &b);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
- talloc_destroy(mem_ctx);
+ talloc_free(tmp_ctx);
return status;
}
- DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
+ DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
- status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version, domain, username, password);
+ status = dcerpc_pipe_connect_b(pp, &b, pipe_uuid, pipe_version, domain, username, password);
+
+ talloc_free(tmp_ctx);
- talloc_destroy(mem_ctx);
return status;
}
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
struct dcerpc_binding b;
- switch (p->transport.transport) {
+ (*p2) = dcerpc_pipe_init(p);
+ if (*p2 == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ switch (p->conn->transport.transport) {
case NCACN_NP:
- tree = dcerpc_smb_tree(p);
+ tree = dcerpc_smb_tree(p->conn);
if (!tree) {
return NT_STATUS_INVALID_PARAMETER;
}
- status = dcerpc_pipe_open_smb(p2, tree, pipe_name);
+ status = dcerpc_pipe_open_smb((*p2)->conn, tree, pipe_name);
break;
case NCACN_IP_TCP:
- status = dcerpc_parse_binding(p, p->binding_string, &b);
+ status = dcerpc_parse_binding(p, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
b.flags &= ~DCERPC_AUTH_OPTIONS;
- status = dcerpc_pipe_open_tcp(p2, b.host, atoi(b.endpoint));
+ status = dcerpc_pipe_open_tcp((*p2)->conn, b.host, atoi(b.endpoint));
break;
case NCALRPC:
- status = dcerpc_parse_binding(p, p->binding_string, &b);
+ status = dcerpc_parse_binding(p, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
b.flags &= ~DCERPC_AUTH_OPTIONS;
- status = dcerpc_pipe_open_pipe(p2, b.endpoint);
+ status = dcerpc_pipe_open_pipe((*p2)->conn, b.endpoint);
break;
default:
}
if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(*p2);
return status;
}
- talloc_steal(p, *p2);
-
- (*p2)->flags = p->flags;
+ (*p2)->conn->flags = p->conn->flags;
status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version);
if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(*p2);
return status;
}
return NT_STATUS_OK;
}
-NTSTATUS dcerpc_generic_session_key(struct dcerpc_pipe *p,
+NTSTATUS dcerpc_generic_session_key(struct dcerpc_connection *c,
DATA_BLOB *session_key)
{
/* this took quite a few CPU cycles to find ... */
NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
DATA_BLOB *session_key)
{
- return p->security_state.session_key(p, session_key);
+ return p->conn->security_state.session_key(p->conn, session_key);
}
name = table->calls[opnum].name;
call = &table->calls[opnum];
- if (private->c_pipe->flags & DCERPC_DEBUG_PRINT_IN) {
+ if (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_IN) {
ndr_print_function_debug(call->ndr_print, name, NDR_IN | NDR_SET_VALUES, r);
}
return NT_STATUS_NET_WRITE_FAULT;
}
- if ((dce_call->fault_code == 0) && (private->c_pipe->flags & DCERPC_DEBUG_PRINT_OUT)) {
+ if ((dce_call->fault_code == 0) &&
+ (private->c_pipe->conn->flags & DCERPC_DEBUG_PRINT_OUT)) {
ndr_print_function_debug(call->ndr_print, name, NDR_OUT, r);
}
static BOOL remote_op_interface_by_uuid(struct dcesrv_interface *iface, const char *uuid, uint32_t if_version)
{
- struct dcerpc_interface_list *l;
+ const struct dcerpc_interface_list *l;
- for (l=dcerpc_pipes;l;l=l->next) {
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
if (l->table->if_version == if_version &&
strcmp(l->table->uuid, uuid)==0) {
return remote_fill_interface(iface, l->table);
static BOOL remote_op_interface_by_name(struct dcesrv_interface *iface, const char *name)
{
- struct dcerpc_interface_list *l;
+ const struct dcerpc_interface_list *l;
- for (l=dcerpc_pipes;l;l=l->next) {
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
if (strcmp(l->table->name, name)==0) {
return remote_fill_interface(iface, l->table);
}
TALLOC_CTX *mem_ctx;
BOOL ret = True;
const char *binding = lp_parm_string(-1, "torture", "binding");
- struct dcerpc_interface_list *l;
+ const struct dcerpc_interface_list *l;
struct dcerpc_binding b;
mem_ctx = talloc_init("torture_rpc_mgmt");
return False;
}
- for (l=dcerpc_pipes;l;l=l->next) {
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
/* some interfaces are not mappable */
if (l->table->num_calls == 0 ||
strcmp(l->table->name, "mgmt") == 0) {
int i;
BOOL ret = True;
- if (p->transport.transport != NCACN_NP) {
+ if (p->conn->transport.transport != NCACN_NP) {
return True;
}
goto failed;
}
- status = dcerpc_schannel_creds(p->security_state.generic_state, mem_ctx, &creds);
+ status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds);
if (!NT_STATUS_IS_OK(status)) {
ret = False;
goto failed;
goto failed;
}
- status = dcerpc_schannel_creds(samsync_state->p->security_state.generic_state, mem_ctx, &samsync_state->creds);
+ status = dcerpc_schannel_creds(samsync_state->p->conn->security_state.generic_state, mem_ctx, &samsync_state->creds);
if (!NT_STATUS_IS_OK(status)) {
ret = False;
}
goto failed;
}
- status = dcerpc_schannel_creds(samsync_state->p_netlogon_wksta->security_state.generic_state, mem_ctx, &samsync_state->creds_netlogon_wksta);
+ status = dcerpc_schannel_creds(samsync_state->p_netlogon_wksta->conn->security_state.generic_state,
+ mem_ctx, &samsync_state->creds_netlogon_wksta);
if (!NT_STATUS_IS_OK(status)) {
ret = False;
}
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
- struct dcerpc_interface_list *l;
+ const struct dcerpc_interface_list *l;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
return False;
}
- for (l=dcerpc_pipes;l;l=l->next) {
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
/* some interfaces are not mappable */
if (l->table->num_calls == 0 ||
strcmp(l->table->name, "mgmt") == 0) {
goto failed;
}
- status = dcerpc_schannel_creds(p_netlogon->security_state.generic_state, mem_ctx, &creds);
+ status = dcerpc_schannel_creds(p_netlogon->conn->security_state.generic_state, mem_ctx, &creds);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
BOOL ret = True;
/* only makes sense on SMB */
- if (p->transport.transport != NCACN_NP) {
+ if (p->conn->transport.transport != NCACN_NP) {
return True;
}
return NT_STATUS_OK;
}
-static int close_pipe(void *ptr)
-{
- struct dcerpc_pipe *p = ptr;
- dcerpc_pipe_close(p);
- return 0;
-}
-
-static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
+static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
+ TALLOC_CTX *mem_ctx,
struct smbcli_transport *transport,
const char *pipe_name,
const char *pipe_uuid,
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
NTSTATUS status;
- TALLOC_CTX *mem_ctx;
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *tmp_ctx;
struct smbcli_tree *tree;
-
+
if (!NT_STATUS_IS_OK(status = anon_ipc(transport, &tree)))
return status;
if (binding == NULL)
return NT_STATUS_INVALID_PARAMETER;
- mem_ctx = talloc_init("dcerpc_pipe_connect");
- if (!mem_ctx) return NT_STATUS_NO_MEMORY;
+ p = dcerpc_pipe_init(mem_ctx);
+ if (p == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ tmp_ctx = talloc_new(p);
- status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ status = dcerpc_parse_binding(tmp_ctx, binding, &b);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
- talloc_destroy(mem_ctx);
+ talloc_free(p);
return status;
}
- DEBUG(3,("Using binding %s\n", dcerpc_binding_string(mem_ctx, &b)));
+ DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
if (b.endpoint == NULL) {
const struct dcerpc_interface_table *table =
if (!table) {
DEBUG(0,("Unknown interface endpoint '%s'\n",
pipe_uuid));
- talloc_destroy(mem_ctx);
+ talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
/* Find one of the default pipes for this interface */
for (i = 0; i < table->endpoints->count; i++) {
const char * const *names = table->endpoints->names;
- status = dcerpc_parse_binding(mem_ctx, names[i],
+ status = dcerpc_parse_binding(tmp_ctx, names[i],
&default_binding);
if (NT_STATUS_IS_OK(status) &&
if (!strncasecmp(pipe_name, "/pipe/", 6) ||
!strncasecmp(pipe_name, "\\pipe\\", 6)) {
- pipe_name+=6;
+ pipe_name += 6;
}
if (pipe_name[0] != '\\') {
pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
}
- status = dcerpc_pipe_open_smb(p, tree, pipe_name);
+ status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name);
- if (!NT_STATUS_IS_OK(status))
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(p);
return status;
+ }
- talloc_destroy(mem_ctx);
+ talloc_free(tmp_ctx);
+ (*pp) = p;
- talloc_set_destructor(*p, close_pipe);
- talloc_steal(*p, tree);
-
return NT_STATUS_OK;
}
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
- status = connect_to_pipe(&p, transport, DCERPC_LSARPC_NAME,
+ status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
DCERPC_LSARPC_UUID,
DCERPC_LSARPC_VERSION);
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
- status = connect_to_pipe(&p, transport, DCERPC_LSARPC_NAME,
+ status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_LSARPC_NAME,
DCERPC_LSARPC_UUID,
DCERPC_LSARPC_VERSION);
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
- status = connect_to_pipe(p, transport, DCERPC_NETLOGON_NAME,
+ status = connect_to_pipe(p, mem_ctx, transport, DCERPC_NETLOGON_NAME,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION);
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
- status = connect_to_pipe(&p, transport, DCERPC_SAMR_NAME,
+ status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
DCERPC_SAMR_UUID,
DCERPC_SAMR_VERSION);
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
- status = connect_to_pipe(&p, transport, DCERPC_SAMR_NAME,
+ status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SAMR_NAME,
DCERPC_SAMR_UUID,
DCERPC_SAMR_VERSION);
if (mem_ctx == NULL)
return NT_STATUS_NO_MEMORY;
- status = connect_to_pipe(&p, transport, DCERPC_SRVSVC_NAME,
+ status = connect_to_pipe(&p, mem_ctx, transport, DCERPC_SRVSVC_NAME,
DCERPC_SRVSVC_UUID,
DCERPC_SRVSVC_VERSION);
return False;
status = connect_to_pipe(&netlogon_schannel_pipe,
- transport, DCERPC_NETLOGON_NAME,
+ mem_ctx, transport, DCERPC_NETLOGON_NAME,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION);
if (!NT_STATUS_IS_OK(status))
return False;
- netlogon_schannel_pipe->flags |= DCERPC_SEAL;
+ netlogon_schannel_pipe->conn->flags |= DCERPC_SEAL;
status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
DCERPC_NETLOGON_UUID,
static void show_pipes(void)
{
- struct dcerpc_interface_list *p;
+ const struct dcerpc_interface_list *l;
printf("\nYou must specify a pipe\n");
printf("known pipes are:\n");
- for (p=dcerpc_pipes;p;p=p->next) {
- if(p->table->helpstring) {
- printf("\t%s - %s\n", p->table->name, p->table->helpstring);
+ for (l=librpc_dcerpc_pipes();l;l=l->next) {
+ if(l->table->helpstring) {
+ printf("\t%s - %s\n", l->table->name, l->table->helpstring);
} else {
- printf("\t%s\n", p->table->name);
+ printf("\t%s\n", l->table->name);
}
}
exit(1);