summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-01-09 08:34:05 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:08:34 -0500
commit6836f5d0b167027908da9a08b9b219520997b563 (patch)
treebe9fcc45bd4cb753a7be128a4b9fed39666ed010 /source4/librpc/rpc
parent3feb4423f3ec35dd3dfa2c358797a4f6a86b2fb5 (diff)
downloadsamba-6836f5d0b167027908da9a08b9b219520997b563.tar.gz
samba-6836f5d0b167027908da9a08b9b219520997b563.tar.bz2
samba-6836f5d0b167027908da9a08b9b219520997b563.zip
r4616: the first phase in the addition of proper support for
dcerpc_alter_context and multiple context_ids in the dcerpc client library. This stage does the following: - split "struct dcerpc_pipe" into two parts, the main part being "struct dcerpc_connection", which contains all the parts not dependent on the context, and "struct dcerpc_pipe" which has the context dependent part. This is similar to the layering in libcli_*() for SMB - disable the current dcerpc_alter code. I've used a #warning until i get the 2nd phase finished. I don't know how portable #warning is, but it won't be long before I add full alter context support anyway, so it won't last long - cleanup the allocation of dcerpc_pipe structures. The previous code was quite awkward. (This used to be commit 4004c69937be7e5dae56f9567ca607f982d395d3)
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r--source4/librpc/rpc/dcerpc.c382
-rw-r--r--source4/librpc/rpc/dcerpc.h53
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c84
-rw-r--r--source4/librpc/rpc/dcerpc_ntlm.c17
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c40
-rw-r--r--source4/librpc/rpc/dcerpc_smb.c123
-rw-r--r--source4/librpc/rpc/dcerpc_sock.c67
-rw-r--r--source4/librpc/rpc/dcerpc_spnego.c27
-rw-r--r--source4/librpc/rpc/dcerpc_util.c292
9 files changed, 560 insertions, 525 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index ee7250a4f9..a29e7f7b6b 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -3,7 +3,7 @@
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
@@ -25,8 +25,11 @@
#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(),
@@ -43,52 +46,92 @@ NTSTATUS librpc_register_interface(const struct dcerpc_interface_table *interfac
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
@@ -124,17 +167,18 @@ void dcerpc_set_auth_length(DATA_BLOB *blob, uint16_t v)
/*
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;
}
@@ -145,12 +189,12 @@ static struct ndr_pull *ndr_pull_init_flags(struct dcerpc_pipe *p, DATA_BLOB *bl
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;
}
@@ -177,7 +221,7 @@ static NTSTATUS dcerpc_connect_verifier(TALLOC_CTX *mem_ctx, DATA_BLOB *blob)
}
/*
- generate a CONNECT level verifier
+ check a CONNECT level verifier
*/
static NTSTATUS dcerpc_check_connect_verifier(DATA_BLOB *blob)
{
@@ -191,7 +235,7 @@ 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)
{
@@ -201,12 +245,12 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
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;
}
@@ -226,7 +270,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
}
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;
}
@@ -243,7 +287,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
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;
}
@@ -259,9 +303,9 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
/* 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,
@@ -274,7 +318,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
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,
@@ -308,7 +352,7 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p,
/*
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)
{
@@ -317,9 +361,9 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
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);
@@ -327,7 +371,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
return NT_STATUS_NO_MEMORY;
}
- if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ if (c->flags & DCERPC_PUSH_BIGENDIAN) {
ndr->flags |= LIBNDR_FLAG_BIGENDIAN;
}
@@ -342,25 +386,25 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
/* 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:
@@ -373,7 +417,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
}
/* 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;
}
@@ -385,18 +429,19 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
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;
@@ -405,13 +450,14 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
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;
@@ -423,7 +469,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
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:
@@ -431,7 +477,7 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
break;
}
- data_blob_free(&p->security_state.auth_info->credentials);
+ data_blob_free(&c->security_state.auth_info->credentials);
return NT_STATUS_OK;
}
@@ -440,11 +486,11 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p,
/*
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;
@@ -465,10 +511,10 @@ struct full_request_state {
/*
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;
@@ -482,7 +528,7 @@ static void full_request_recv(struct dcerpc_pipe *p, DATA_BLOB *blob,
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)
@@ -497,16 +543,16 @@ static NTSTATUS full_request(struct dcerpc_pipe *p,
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;
}
@@ -534,41 +580,41 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
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;
}
@@ -585,117 +631,49 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
}
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;
}
@@ -733,7 +711,7 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p,
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)
{
@@ -743,11 +721,11 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
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);
}
@@ -757,12 +735,12 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
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;
}
@@ -774,7 +752,7 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
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);
}
@@ -782,11 +760,11 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
}
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);
}
@@ -799,7 +777,7 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
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);
}
@@ -816,7 +794,7 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
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);
}
@@ -828,13 +806,13 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
}
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;
@@ -854,12 +832,12 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
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,
@@ -873,7 +851,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
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) {
@@ -881,7 +859,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
}
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);
@@ -889,20 +867,20 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
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) {
@@ -911,7 +889,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
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) {
@@ -933,17 +911,17 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
(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;
}
@@ -961,7 +939,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
*/
struct event_context *dcerpc_event_context(struct dcerpc_pipe *p)
{
- return p->transport.event_context(p);
+ return p->conn->transport.event_context(p->conn);
}
@@ -1020,7 +998,7 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
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,
@@ -1038,7 +1016,7 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_pipe *p,
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;
}
@@ -1084,7 +1062,7 @@ static NTSTATUS dcerpc_ndr_validate_in(struct dcerpc_pipe *p,
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,
@@ -1117,7 +1095,7 @@ static NTSTATUS dcerpc_ndr_validate_out(struct dcerpc_pipe *p,
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;
}
@@ -1182,7 +1160,7 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
return NULL;
}
- if (p->flags & DCERPC_PUSH_BIGENDIAN) {
+ if (p->conn->flags & DCERPC_PUSH_BIGENDIAN) {
push->flags |= LIBNDR_FLAG_BIGENDIAN;
}
@@ -1198,8 +1176,8 @@ struct rpc_request *dcerpc_ndr_request_send(struct dcerpc_pipe *p,
/* 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",
@@ -1256,7 +1234,7 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
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;
}
@@ -1276,8 +1254,8 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
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,
@@ -1329,25 +1307,25 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
*/
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;
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index 1b2feeadb2..00f1fb6488 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -1,9 +1,10 @@
/*
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
@@ -28,17 +29,19 @@ enum dcerpc_transport_t {
/*
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;
@@ -46,35 +49,28 @@ struct dcerpc_pipe {
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;
@@ -82,6 +78,22 @@ struct dcerpc_pipe {
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)
@@ -141,8 +153,7 @@ struct dcerpc_interface_table {
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;
};
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 36e4ba6eea..9d43218e4b 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -45,7 +45,7 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
}
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;
@@ -57,33 +57,34 @@ NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
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);
@@ -91,38 +92,40 @@ NTSTATUS dcerpc_bind_auth3(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
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)
{
@@ -136,13 +139,13 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
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)) {
@@ -150,20 +153,20 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
}
}
- 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);
@@ -171,7 +174,7 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
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)) {
@@ -179,15 +182,15 @@ NTSTATUS dcerpc_bind_alter(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t aut
}
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)) {
@@ -199,12 +202,13 @@ 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;
}
+#endif
diff --git a/source4/librpc/rpc/dcerpc_ntlm.c b/source4/librpc/rpc/dcerpc_ntlm.c
index c236b6c516..8a83cea144 100644
--- a/source4/librpc/rpc/dcerpc_ntlm.c
+++ b/source4/librpc/rpc/dcerpc_ntlm.c
@@ -33,38 +33,39 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
{
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)));
@@ -72,7 +73,7 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p,
}
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)) {
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index 8632a3cf16..92e8d0ca38 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -339,7 +339,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
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;
@@ -424,46 +424,48 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
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;
}
@@ -484,11 +486,11 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
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;
}
diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c
index ab8a60b060..837561981f 100644
--- a/source4/librpc/rpc/dcerpc_smb.c
+++ b/source4/librpc/rpc/dcerpc_smb.c
@@ -35,9 +35,9 @@ struct smb_private {
/*
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);
}
@@ -45,7 +45,7 @@ static void pipe_dead(struct dcerpc_pipe *p, NTSTATUS 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;
@@ -64,12 +64,12 @@ static void smb_read_callback(struct smbcli_request *req)
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;
}
@@ -79,7 +79,7 @@ static void smb_read_callback(struct smbcli_request *req)
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;
}
@@ -88,7 +88,7 @@ static void smb_read_callback(struct smbcli_request *req)
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;
}
@@ -96,14 +96,14 @@ static void smb_read_callback(struct smbcli_request *req)
/* 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;
}
@@ -116,9 +116,9 @@ static void smb_read_callback(struct smbcli_request *req)
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;
@@ -128,7 +128,7 @@ static NTSTATUS send_read_request_continue(struct dcerpc_pipe *p, DATA_BLOB *blo
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);
@@ -171,16 +171,16 @@ static NTSTATUS send_read_request_continue(struct dcerpc_pipe *p, DATA_BLOB *blo
/*
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;
};
@@ -191,33 +191,33 @@ struct smb_trans_state {
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;
@@ -227,7 +227,7 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_pipe *p, DATA_BLOB *blob)
return NT_STATUS_NO_MEMORY;
}
- state->p = p;
+ state->c = c;
state->trans = talloc_p(state, struct smb_trans2);
trans = state->trans;
@@ -263,11 +263,11 @@ static NTSTATUS smb_send_trans_request(struct dcerpc_pipe *p, DATA_BLOB *blob)
*/
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);
@@ -276,14 +276,14 @@ static void smb_write_callback(struct smbcli_request *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;
@@ -300,10 +300,10 @@ static NTSTATUS smb_send_request(struct dcerpc_pipe *p, DATA_BLOB *blob, BOOL tr
}
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;
@@ -313,9 +313,9 @@ static NTSTATUS smb_send_request(struct dcerpc_pipe *p, DATA_BLOB *blob, BOOL tr
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;
}
@@ -324,18 +324,18 @@ static struct event_context *smb_event_context(struct dcerpc_pipe *p)
/*
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);
@@ -345,18 +345,18 @@ static NTSTATUS smb_shutdown_pipe(struct dcerpc_pipe *p)
/*
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;
@@ -368,7 +368,7 @@ static NTSTATUS smb_session_key(struct dcerpc_pipe *p, DATA_BLOB *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)
{
@@ -402,36 +402,31 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
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;
}
@@ -439,11 +434,11 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
/*
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;
}
diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c
index 762a22ad3e..b48fedb0d8 100644
--- a/source4/librpc/rpc/dcerpc_sock.c
+++ b/source4/librpc/rpc/dcerpc_sock.c
@@ -54,7 +54,7 @@ struct sock_private {
/*
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;
@@ -80,7 +80,7 @@ static void sock_dead(struct dcerpc_pipe *p, NTSTATUS status)
/*
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;
@@ -117,7 +117,7 @@ static void sock_process_send(struct dcerpc_pipe *p)
/*
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;
@@ -194,7 +194,7 @@ static void sock_process_recv(struct dcerpc_pipe *p)
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) {
@@ -213,7 +213,7 @@ static void sock_io_handler(struct event_context *ev, struct fd_event *fde,
/*
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;
@@ -227,7 +227,7 @@ static NTSTATUS sock_send_read(struct dcerpc_pipe *p)
/*
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;
@@ -261,7 +261,7 @@ static NTSTATUS sock_send_request(struct dcerpc_pipe *p, DATA_BLOB *data, BOOL t
/*
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;
@@ -271,7 +271,7 @@ static struct event_context *sock_event_context(struct dcerpc_pipe *p)
/*
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);
@@ -281,7 +281,7 @@ static NTSTATUS sock_shutdown_pipe(struct dcerpc_pipe *p)
/*
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;
@@ -290,7 +290,7 @@ static const char *sock_peer_name(struct dcerpc_pipe *p)
/*
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,
@@ -301,45 +301,40 @@ static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
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;
@@ -349,11 +344,11 @@ static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
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);
@@ -364,31 +359,31 @@ static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p,
/*
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;
@@ -398,7 +393,7 @@ NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p, const char *identifier)
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;
diff --git a/source4/librpc/rpc/dcerpc_spnego.c b/source4/librpc/rpc/dcerpc_spnego.c
index d15224b981..cab8865d6b 100644
--- a/source4/librpc/rpc/dcerpc_spnego.c
+++ b/source4/librpc/rpc/dcerpc_spnego.c
@@ -3,7 +3,9 @@
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
@@ -22,6 +24,8 @@
#include "includes.h"
+#warning "this needs dcerpc_alter"
+#if 0
/*
do spnego style authentication on a gensec pipe
*/
@@ -33,49 +37,53 @@ NTSTATUS dcerpc_bind_auth_spnego(struct dcerpc_pipe *p,
{
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)));
@@ -84,3 +92,4 @@ NTSTATUS dcerpc_bind_auth_spnego(struct dcerpc_pipe *p,
return status;
}
+#endif
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index 4adeee7a37..67b0c530bf 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -30,8 +30,8 @@
*/
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;
@@ -45,8 +45,8 @@ const char *idl_pipe_name(const char *uuid, uint32_t if_version)
*/
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;
@@ -61,8 +61,8 @@ int idl_num_calls(const char *uuid, uint32_t if_version)
*/
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;
}
@@ -75,8 +75,8 @@ const struct dcerpc_interface_table *idl_iface_by_name(const char *name)
*/
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;
}
@@ -774,7 +774,7 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind
/* 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,
@@ -782,19 +782,28 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
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));
@@ -803,188 +812,199 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
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,
@@ -994,14 +1014,24 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
{
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));
@@ -1009,34 +1039,37 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
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;
}
@@ -1044,7 +1077,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p,
/* 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,
@@ -1056,18 +1089,20 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
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;
@@ -1079,7 +1114,7 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **p,
/* 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,
@@ -1089,23 +1124,23 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **p,
{
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;
}
@@ -1125,32 +1160,37 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe *
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:
@@ -1158,22 +1198,22 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe *
}
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 ... */
@@ -1188,7 +1228,7 @@ NTSTATUS dcerpc_generic_session_key(struct dcerpc_pipe *p,
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);
}