mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
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 4004c69937
)
This commit is contained in:
parent
3feb4423f3
commit
6836f5d0b1
@ -21,7 +21,7 @@ sub ParseFunction($$)
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *
|
||||
|
||||
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);
|
||||
}
|
||||
";
|
||||
|
@ -101,7 +101,7 @@ static struct rpc_request *dcom_proxy_$interface->{NAME}_$name\_send(struct dcom
|
||||
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);
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ static NTSTATUS dcom_proxy_$interface->{NAME}_$name(struct dcom_interface_p *d,
|
||||
|
||||
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);
|
||||
}
|
||||
";
|
||||
|
@ -354,6 +354,8 @@ NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **p)
|
||||
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;
|
||||
@ -365,7 +367,7 @@ NTSTATUS dcom_get_pipe (struct dcom_interface_p *iface, struct dcerpc_pipe **p)
|
||||
*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]);
|
||||
|
@ -76,8 +76,14 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli)
|
||||
}
|
||||
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;
|
||||
|
@ -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,53 +46,93 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* we need to be able to get/set the fragment length without doing a full
|
||||
decode */
|
||||
@ -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
|
||||
*/
|
||||
|
||||
uint32 dcerpc_auth_level(struct dcerpc_pipe *p)
|
||||
/*
|
||||
get the dcerpc auth_level for a open connection
|
||||
*/
|
||||
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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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),
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
c->transport.transport = NCACN_NP;
|
||||
c->transport.private = NULL;
|
||||
c->transport.shutdown_pipe = smb_shutdown_pipe;
|
||||
c->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.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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,48 +37,52 @@ 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),
|
||||
status = dcerpc_bind_alter(p, DCERPC_AUTH_TYPE_SPNEGO,
|
||||
dcerpc_auth_level(p->conn),
|
||||
uuid, version);
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
@ -84,3 +92,4 @@ NTSTATUS dcerpc_bind_auth_spnego(struct dcerpc_pipe *p,
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
@ -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));
|
||||
@ -808,17 +817,17 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
|
||||
}
|
||||
|
||||
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(),
|
||||
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(),
|
||||
status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
|
||||
binding->host, NULL,
|
||||
"ipc$", "?????",
|
||||
username, domain,
|
||||
@ -826,54 +835,48 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
|
||||
}
|
||||
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,
|
||||
static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp,
|
||||
struct dcerpc_binding *binding,
|
||||
const char *pipe_uuid,
|
||||
uint32_t pipe_version,
|
||||
@ -882,52 +885,60 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
|
||||
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);
|
||||
(*pp) = p;
|
||||
talloc_free(tmp_ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -935,7 +946,7 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p,
|
||||
|
||||
/* 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,
|
||||
static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp,
|
||||
struct dcerpc_binding *binding,
|
||||
const char *pipe_uuid,
|
||||
uint32_t pipe_version,
|
||||
@ -944,47 +955,56 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p,
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
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,42 +1039,45 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,7 +105,7 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT
|
||||
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);
|
||||
}
|
||||
|
||||
@ -118,7 +118,8 @@ static NTSTATUS remote_op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CT
|
||||
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);
|
||||
}
|
||||
|
||||
@ -212,9 +213,9 @@ static BOOL remote_fill_interface(struct dcesrv_interface *iface, const struct d
|
||||
|
||||
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);
|
||||
@ -226,9 +227,9 @@ static BOOL remote_op_interface_by_uuid(struct dcesrv_interface *iface, const ch
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ BOOL torture_rpc_mgmt(void)
|
||||
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");
|
||||
@ -196,7 +196,7 @@ BOOL torture_rpc_mgmt(void)
|
||||
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) {
|
||||
|
@ -1110,7 +1110,7 @@ static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
|
||||
int i;
|
||||
BOOL ret = True;
|
||||
|
||||
if (p->transport.transport != NCACN_NP) {
|
||||
if (p->conn->transport.transport != NCACN_NP) {
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -1261,7 +1261,7 @@ BOOL torture_rpc_samlogon(void)
|
||||
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;
|
||||
|
@ -1313,7 +1313,7 @@ BOOL torture_rpc_samsync(void)
|
||||
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;
|
||||
}
|
||||
@ -1342,7 +1342,8 @@ BOOL torture_rpc_samsync(void)
|
||||
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;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ BOOL torture_rpc_scanner(void)
|
||||
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;
|
||||
|
||||
@ -151,7 +151,7 @@ BOOL torture_rpc_scanner(void)
|
||||
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) {
|
||||
|
@ -184,7 +184,7 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
|
||||
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;
|
||||
}
|
||||
|
@ -649,7 +649,7 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
|
||||
BOOL ret = True;
|
||||
|
||||
/* only makes sense on SMB */
|
||||
if (p->transport.transport != NCACN_NP) {
|
||||
if (p->conn->transport.transport != NCACN_NP) {
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -180,14 +180,8 @@ static NTSTATUS anon_ipc(struct smbcli_transport *transport,
|
||||
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,
|
||||
@ -196,7 +190,8 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
|
||||
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)))
|
||||
@ -205,17 +200,20 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
|
||||
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 =
|
||||
@ -226,14 +224,14 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
|
||||
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) &&
|
||||
@ -255,15 +253,15 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **p,
|
||||
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_set_destructor(*p, close_pipe);
|
||||
talloc_steal(*p, tree);
|
||||
talloc_free(tmp_ctx);
|
||||
(*pp) = p;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -284,7 +282,7 @@ static NTSTATUS test_enumtrusts(struct smbcli_transport *transport)
|
||||
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);
|
||||
|
||||
@ -355,7 +353,7 @@ static NTSTATUS test_lookupnames(struct smbcli_transport *transport,
|
||||
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);
|
||||
|
||||
@ -462,7 +460,7 @@ static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
|
||||
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);
|
||||
|
||||
@ -621,7 +619,7 @@ static NTSTATUS test_getgroups(struct smbcli_transport *transport,
|
||||
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);
|
||||
|
||||
@ -785,7 +783,7 @@ static NTSTATUS test_getallsids(struct smbcli_transport *transport,
|
||||
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);
|
||||
|
||||
@ -984,7 +982,7 @@ static NTSTATUS test_remoteTOD(struct smbcli_transport *transport)
|
||||
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);
|
||||
|
||||
@ -1054,14 +1052,14 @@ static BOOL xp_login(const char *dcname, const char *wksname,
|
||||
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,
|
||||
|
@ -46,14 +46,14 @@ static const struct dcerpc_interface_call *find_function(
|
||||
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user