From 188b2054a80ec16e7fb9ed7b6b1e8fce9b52458f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Dec 2003 22:21:04 +0000 Subject: initial rpc server side infrastructure (This used to be commit 3706af7a6cb2090e0baeff5ee54bf49ebda2cce1) --- source4/rpc_server/dcerpc_server.c | 141 +++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 source4/rpc_server/dcerpc_server.c (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c new file mode 100644 index 0000000000..c01dc4d9db --- /dev/null +++ b/source4/rpc_server/dcerpc_server.c @@ -0,0 +1,141 @@ +/* + Unix SMB/CIFS implementation. + + server side dcerpc core code + + Copyright (C) Andrew Tridgell 2003 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + find the set of endpoint operations for an endpoint server +*/ +static const struct dcesrv_endpoint_ops *find_endpoint(struct server_context *smb, + const struct dcesrv_endpoint *endpoint) +{ + struct dce_endpoint *ep; + for (ep=smb->dcesrv.endpoint_list; ep; ep=ep->next) { + if (ep->endpoint_ops->query(endpoint)) { + return ep->endpoint_ops; + } + } + return NULL; +} + + +/* + register an endpoint server +*/ +BOOL dcesrv_endpoint_register(struct server_context *smb, + const struct dcesrv_endpoint_ops *ops) +{ + struct dce_endpoint *ep; + ep = malloc(sizeof(*ep)); + if (!ep) { + return False; + } + ep->endpoint_ops = ops; + DLIST_ADD(smb->dcesrv.endpoint_list, ep); + return True; +} + +/* + connect to a dcerpc endpoint +*/ +NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, + const struct dcesrv_endpoint *endpoint, + struct dcesrv_state **p) +{ + TALLOC_CTX *mem_ctx; + NTSTATUS status; + const struct dcesrv_endpoint_ops *ops; + + /* make sure this endpoint exists */ + ops = find_endpoint(smb, endpoint); + if (!ops) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + mem_ctx = talloc_init("dcesrv_endpoint_connect"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + *p = talloc(mem_ctx, sizeof(struct dcesrv_state)); + if (! *p) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*p)->mem_ctx = mem_ctx; + (*p)->endpoint = *endpoint; + (*p)->ops = ops; + (*p)->private = NULL; + + /* make sure the endpoint server likes the connection */ + status = ops->connect(*p); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + return NT_STATUS_OK; +} + + +/* + disconnect a link to an endpoint +*/ +void dcesrv_endpoint_disconnect(struct dcesrv_state *p) +{ + p->ops->disconnect(p); + talloc_destroy(p->mem_ctx); +} + + + +/* + a useful function for implementing the query endpoint op + */ +BOOL dcesrv_table_query(const struct dcerpc_interface_table *table, + const struct dcesrv_endpoint *ep) +{ + int i; + const struct dcerpc_endpoint_list *endpoints = table->endpoints; + + if (ep->type != ENDPOINT_SMB) { + return False; + } + + for (i=0;icount;i++) { + if (strcasecmp(ep->info.smb_pipe, endpoints->names[i]) == 0) { + return True; + } + } + return False; +} + + +/* + initialise the dcerpc server subsystem +*/ +BOOL dcesrv_init(struct server_context *smb) +{ + rpc_echo_init(smb); + return True; +} -- cgit From fcc4efd1ea637c810eed8444080b87d7f92c837a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Dec 2003 09:07:45 +0000 Subject: the next step in the dcerpc server code. Added the link between the IPC IO routines and the dcerpc endpoint servers. (This used to be commit 4929c53bc8dddda8a763fdfbcf81a79776d01113) --- source4/rpc_server/dcerpc_server.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c01dc4d9db..e1d6da2292 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -108,6 +108,24 @@ void dcesrv_endpoint_disconnect(struct dcesrv_state *p) } +/* + provide some input to a dcerpc endpoint server. This passes data + from a dcerpc client into the server +*/ +NTSTATUS dcesrv_input(struct dcesrv_state *p, const DATA_BLOB *data) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + retrieve some output from a dcerpc server. The amount of data that + is wanted is in data->length +*/ +NTSTATUS dcesrv_output(struct dcesrv_state *p, DATA_BLOB *data) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + /* a useful function for implementing the query endpoint op -- cgit From 16309de71d6c8de96e869aeaab0b879185991d87 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Dec 2003 03:59:09 +0000 Subject: * the RPC-ECHO pipe now works in smbd, as long as the data sizes don't cause fragmented pdus (I'll add fragments shortly) * change data_blob_talloc() to not zero memory when the 2nd argument is NULL. The zeroing just masks bugs, and can't even allow a DOS attack * modified pidl to ensure that [ref] arguments to the out side of functions are allocated when parsing the in side. This allows rpc backends to assume that [ref] variables are all setup. Doesn't work correctly for [ref] arrays yet * changed DLIST_ADD_END() to take the type instead of a tmp variable. This means you don't need to declare a silly tmp variable in the caller (This used to be commit 46e0a358198eeb9af1907ee2a29025d3ab23b6d1) --- source4/rpc_server/dcerpc_server.c | 308 ++++++++++++++++++++++++++++++++++++- 1 file changed, 302 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e1d6da2292..f5e7ff858e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -30,7 +30,7 @@ static const struct dcesrv_endpoint_ops *find_endpoint(struct server_context *sm { struct dce_endpoint *ep; for (ep=smb->dcesrv.endpoint_list; ep; ep=ep->next) { - if (ep->endpoint_ops->query(endpoint)) { + if (ep->endpoint_ops->query_endpoint(endpoint)) { return ep->endpoint_ops; } } @@ -86,6 +86,7 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, (*p)->endpoint = *endpoint; (*p)->ops = ops; (*p)->private = NULL; + (*p)->call_list = NULL; /* make sure the endpoint server likes the connection */ status = ops->connect(*p); @@ -107,23 +108,318 @@ void dcesrv_endpoint_disconnect(struct dcesrv_state *p) talloc_destroy(p->mem_ctx); } +/* + return a dcerpc fault +*/ +static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) +{ + struct ndr_push *push; + struct dcerpc_packet pkt; + NTSTATUS status; + + /* setup a bind_ack */ + pkt.rpc_vers = 5; + pkt.rpc_vers_minor = 0; + pkt.drep[0] = 0x10; /* Little endian */ + pkt.drep[1] = 0; + pkt.drep[2] = 0; + pkt.drep[3] = 0; + pkt.auth_length = 0; + pkt.call_id = call->pkt.call_id; + pkt.ptype = DCERPC_PKT_FAULT; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.u.fault.alloc_hint = 0; + pkt.u.fault.context_id = 0; + pkt.u.fault.cancel_count = 0; + pkt.u.fault.status = fault_code; + + /* now form the NDR for the bind_ack */ + push = ndr_push_init_ctx(call->mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + call->data = ndr_push_blob(push); + SSVAL(call->data.data, DCERPC_FRAG_LEN_OFFSET, call->data.length); + + return NT_STATUS_OK; +} + + +/* + handle a bind request +*/ +static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) +{ + const char *uuid, *transfer_syntax; + uint32 if_version, transfer_syntax_version; + struct dcerpc_packet pkt; + struct ndr_push *push; + NTSTATUS status; + + if (call->pkt.u.bind.num_contexts != 1 || + call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.major_version; + uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); + if (!uuid) { + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].major_version; + transfer_syntax = GUID_string(call->mem_ctx, + &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid); + if (!transfer_syntax || + strcasecmp(NDR_GUID, transfer_syntax) != 0 || + NDR_GUID_VERSION != transfer_syntax_version) { + /* we only do NDR encoded dcerpc */ + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + if (!call->dce->ops->set_interface(call->dce, uuid, if_version)) { + DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); + /* we don't know about that interface */ + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + /* setup a bind_ack */ + pkt.rpc_vers = 5; + pkt.rpc_vers_minor = 0; + pkt.drep[0] = 0x10; /* Little endian */ + pkt.drep[1] = 0; + pkt.drep[2] = 0; + pkt.drep[3] = 0; + pkt.auth_length = 0; + pkt.call_id = call->pkt.call_id; + pkt.ptype = DCERPC_PKT_BIND_ACK; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.u.bind_ack.max_xmit_frag = 0x2000; + pkt.u.bind_ack.max_recv_frag = 0x2000; + pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; + pkt.u.bind_ack.secondary_address = talloc_asprintf(call->mem_ctx, "\\PIPE\\%s", + call->dce->ndr->name); + pkt.u.bind_ack.num_results = 1; + pkt.u.bind_ack.ctx_list = talloc(call->mem_ctx, sizeof(struct dcerpc_ack_ctx)); + if (!pkt.u.bind_ack.ctx_list) { + return NT_STATUS_NO_MEMORY; + } + pkt.u.bind_ack.ctx_list[0].result = 0; + pkt.u.bind_ack.ctx_list[0].reason = 0; + GUID_from_string(uuid, &pkt.u.bind_ack.ctx_list[0].syntax.uuid); + pkt.u.bind_ack.ctx_list[0].syntax.major_version = if_version; + pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0; + pkt.u.bind_ack.auth_info = data_blob(NULL, 0); + + /* now form the NDR for the bind_ack */ + push = ndr_push_init_ctx(call->mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + call->data = ndr_push_blob(push); + SSVAL(call->data.data, DCERPC_FRAG_LEN_OFFSET, call->data.length); + + return NT_STATUS_OK; +} + + +/* + handle a dcerpc request packet +*/ +static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) +{ + struct ndr_pull *pull; + struct ndr_push *push; + uint16 opnum; + void *r; + NTSTATUS status; + DATA_BLOB stub; + struct dcerpc_packet pkt; + + if (call->pkt.pfc_flags != (DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST)) { + /* we don't do fragments in the server yet */ + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + opnum = call->pkt.u.request.opnum; + + if (opnum >= call->dce->ndr->num_calls) { + return dcesrv_fault(call, DCERPC_FAULT_OP_RNG_ERROR); + } + + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call->mem_ctx); + if (!pull) { + return NT_STATUS_NO_MEMORY; + } + + r = talloc(call->mem_ctx, call->dce->ndr->calls[opnum].struct_size); + if (!r) { + return NT_STATUS_NO_MEMORY; + } + + /* unravel the NDR for the packet */ + status = call->dce->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + /* call the dispatch function */ + status = call->dce->dispatch[opnum](call->dce, call->mem_ctx, r); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + /* form the reply NDR */ + push = ndr_push_init_ctx(call->mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = call->dce->ndr->calls[opnum].ndr_push(push, NDR_OUT, r); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault(call, DCERPC_FAULT_TODO); + } + + stub = ndr_push_blob(push); + + /* form the dcerpc response packet */ + pkt.rpc_vers = 5; + pkt.rpc_vers_minor = 0; + pkt.drep[0] = 0x10; /* Little endian */ + pkt.drep[1] = 0; + pkt.drep[2] = 0; + pkt.drep[3] = 0; + pkt.auth_length = 0; + pkt.call_id = call->pkt.call_id; + pkt.ptype = DCERPC_PKT_RESPONSE; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.u.response.alloc_hint = stub.length; + pkt.u.response.context_id = call->pkt.u.request.context_id; + pkt.u.response.cancel_count = 0; + pkt.u.response.stub_and_verifier = stub; + + push = ndr_push_init_ctx(call->mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + call->data = ndr_push_blob(push); + SSVAL(call->data.data, DCERPC_FRAG_LEN_OFFSET, call->data.length); + + return NT_STATUS_OK; +} + /* provide some input to a dcerpc endpoint server. This passes data from a dcerpc client into the server */ -NTSTATUS dcesrv_input(struct dcesrv_state *p, const DATA_BLOB *data) +NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) { - return NT_STATUS_NOT_IMPLEMENTED; + struct ndr_pull *ndr; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + struct dcesrv_call_state *call; + + mem_ctx = talloc_init("dcesrv_input"); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + call = talloc(mem_ctx, sizeof(*call)); + if (!call) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + call->mem_ctx = mem_ctx; + call->dce = dce; + + ndr = ndr_pull_init_blob(data, mem_ctx); + if (!ndr) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + /* TODO: at this point we should see if the packet is a + continuation of an existing call, but I'm too lazy for that + right now ... maybe tomorrow */ + + + switch (call->pkt.ptype) { + case DCERPC_PKT_BIND: + status = dcesrv_bind(call); + break; + case DCERPC_PKT_REQUEST: + status = dcesrv_request(call); + break; + default: + status = NT_STATUS_INVALID_PARAMETER; + break; + } + + /* if we are going to be sending a reply then add + it to the list of pending calls. We add it to the end to keep the call + list in the order we will answer */ + if (NT_STATUS_IS_OK(status)) { + DLIST_ADD_END(dce->call_list, call, struct dcesrv_call_state *); + } else { + talloc_destroy(mem_ctx); + } + + return status; } /* retrieve some output from a dcerpc server. The amount of data that - is wanted is in data->length + is wanted is in data->length and data->data is already allocated + to hold that much data. */ -NTSTATUS dcesrv_output(struct dcesrv_state *p, DATA_BLOB *data) +NTSTATUS dcesrv_output(struct dcesrv_state *dce, DATA_BLOB *data) { - return NT_STATUS_NOT_IMPLEMENTED; + struct dcesrv_call_state *call; + + call = dce->call_list; + if (!call) { + return NT_STATUS_FOOBAR; + } + + if (data->length >= call->data.length) { + data->length = call->data.length; + } + + memcpy(data->data, call->data.data, data->length); + call->data.length -= data->length; + call->data.data += data->length; + + if (call->data.length == 0) { + /* we're done with this call */ + DLIST_REMOVE(dce->call_list, call); + talloc_destroy(call->mem_ctx); + } + + return NT_STATUS_OK; } -- cgit From dab0deae833d1180f61e7d4112966990d4c19600 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Dec 2003 05:01:41 +0000 Subject: added handling of fragmented requests in the rpc server now we just need to handle fragmented replies .... (This used to be commit 14005c95d7c6c68f7da0f1ad7b7d7952a04a125b) --- source4/rpc_server/dcerpc_server.c | 71 +++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f5e7ff858e..0ee5fad3fc 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -37,6 +37,19 @@ static const struct dcesrv_endpoint_ops *find_endpoint(struct server_context *sm return NULL; } +/* + find a call that is pending in our call list +*/ +static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_state *dce, uint16 call_id) +{ + struct dcesrv_call_state *c; + for (c=dce->call_list;c;c=c->next) { + if (c->pkt.call_id == call_id) { + return c; + } + } + return NULL; +} /* register an endpoint server @@ -248,11 +261,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) DATA_BLOB stub; struct dcerpc_packet pkt; - if (call->pkt.pfc_flags != (DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST)) { - /* we don't do fragments in the server yet */ - return dcesrv_fault(call, DCERPC_FAULT_TODO); - } - opnum = call->pkt.u.request.opnum; if (opnum >= call->dce->ndr->num_calls) { @@ -349,6 +357,7 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) } call->mem_ctx = mem_ctx; call->dce = dce; + call->data = data_blob(NULL, 0); ndr = ndr_pull_init_blob(data, mem_ctx); if (!ndr) { @@ -362,10 +371,56 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) return status; } - /* TODO: at this point we should see if the packet is a - continuation of an existing call, but I'm too lazy for that - right now ... maybe tomorrow */ + /* see if this is a continued packet */ + if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { + struct dcesrv_call_state *call2 = call; + uint32 alloc_size; + + /* we only allow fragmented requests, no other packet types */ + if (call->pkt.ptype != DCERPC_PKT_REQUEST) { + return dcesrv_fault(call2, DCERPC_FAULT_TODO); + } + + /* this is a continuation of an existing call - find the call then + tack it on the end */ + call = dcesrv_find_call(dce, call2->pkt.call_id); + if (!call) { + return dcesrv_fault(call2, DCERPC_FAULT_TODO); + } + + if (call->pkt.ptype != call2->pkt.ptype) { + /* trying to play silly buggers are we? */ + return dcesrv_fault(call2, DCERPC_FAULT_TODO); + } + + alloc_size = call->pkt.u.request.stub_and_verifier.length + + call2->pkt.u.request.stub_and_verifier.length; + if (call->pkt.u.request.alloc_hint > alloc_size) { + alloc_size = call->pkt.u.request.alloc_hint; + } + + call->pkt.u.request.stub_and_verifier.data = + talloc_realloc(call->mem_ctx, + call->pkt.u.request.stub_and_verifier.data, alloc_size); + if (!call->pkt.u.request.stub_and_verifier.data) { + return dcesrv_fault(call2, DCERPC_FAULT_TODO); + } + memcpy(call->pkt.u.request.stub_and_verifier.data + + call->pkt.u.request.stub_and_verifier.length, + call2->pkt.u.request.stub_and_verifier.data, + call2->pkt.u.request.stub_and_verifier.length); + call->pkt.u.request.stub_and_verifier.length += + call2->pkt.u.request.stub_and_verifier.length; + + call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); + } + /* this may not be the last pdu in the chain - if its isn't then + just put it on the call_list and wait for the rest */ + if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { + DLIST_ADD_END(dce->call_list, call, struct dcesrv_call_state *); + return NT_STATUS_OK; + } switch (call->pkt.ptype) { case DCERPC_PKT_BIND: -- cgit From 9d8ef74eac5c4f77602d3da76ffdb0526b060c74 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Dec 2003 05:30:00 +0000 Subject: we now support pdu fragmentation on both input and output in the rpc server code (This used to be commit 4dac9517188f2dba06df481071063543ede89495) --- source4/rpc_server/dcerpc_server.c | 135 ++++++++++++++++++++++++++----------- 1 file changed, 95 insertions(+), 40 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 0ee5fad3fc..45e720b8c1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -100,6 +100,7 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, (*p)->ops = ops; (*p)->private = NULL; (*p)->call_list = NULL; + (*p)->cli_max_recv_frag = 0; /* make sure the endpoint server likes the connection */ status = ops->connect(*p); @@ -128,6 +129,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) { struct ndr_push *push; struct dcerpc_packet pkt; + struct dcesrv_call_reply *rep; NTSTATUS status; /* setup a bind_ack */ @@ -157,8 +159,15 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) return status; } - call->data = ndr_push_blob(push); - SSVAL(call->data.data, DCERPC_FRAG_LEN_OFFSET, call->data.length); + rep = talloc(call->mem_ctx, sizeof(*rep)); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } + + rep->data = ndr_push_blob(push); + SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + + DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); return NT_STATUS_OK; } @@ -173,6 +182,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32 if_version, transfer_syntax_version; struct dcerpc_packet pkt; struct ndr_push *push; + struct dcesrv_call_reply *rep; NTSTATUS status; if (call->pkt.u.bind.num_contexts != 1 || @@ -202,6 +212,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_TODO); } + if (call->dce->cli_max_recv_frag == 0) { + call->dce->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag; + } + /* setup a bind_ack */ pkt.rpc_vers = 5; pkt.rpc_vers_minor = 0; @@ -241,8 +255,15 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return status; } - call->data = ndr_push_blob(push); - SSVAL(call->data.data, DCERPC_FRAG_LEN_OFFSET, call->data.length); + rep = talloc(call->mem_ctx, sizeof(*rep)); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } + + rep->data = ndr_push_blob(push); + SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + + DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); return NT_STATUS_OK; } @@ -259,7 +280,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) void *r; NTSTATUS status; DATA_BLOB stub; - struct dcerpc_packet pkt; opnum = call->pkt.u.request.opnum; @@ -302,34 +322,62 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) stub = ndr_push_blob(push); - /* form the dcerpc response packet */ - pkt.rpc_vers = 5; - pkt.rpc_vers_minor = 0; - pkt.drep[0] = 0x10; /* Little endian */ - pkt.drep[1] = 0; - pkt.drep[2] = 0; - pkt.drep[3] = 0; - pkt.auth_length = 0; - pkt.call_id = call->pkt.call_id; - pkt.ptype = DCERPC_PKT_RESPONSE; - pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.u.response.alloc_hint = stub.length; - pkt.u.response.context_id = call->pkt.u.request.context_id; - pkt.u.response.cancel_count = 0; - pkt.u.response.stub_and_verifier = stub; + do { + uint32 length; + struct dcesrv_call_reply *rep; + struct dcerpc_packet pkt; - push = ndr_push_init_ctx(call->mem_ctx); - if (!push) { - return NT_STATUS_NO_MEMORY; - } + rep = talloc(call->mem_ctx, sizeof(*rep)); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } - status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + length = stub.length; + if (length + DCERPC_RESPONSE_LENGTH > call->dce->cli_max_recv_frag) { + length = call->dce->cli_max_recv_frag - DCERPC_RESPONSE_LENGTH; + } - call->data = ndr_push_blob(push); - SSVAL(call->data.data, DCERPC_FRAG_LEN_OFFSET, call->data.length); + /* form the dcerpc response packet */ + pkt.rpc_vers = 5; + pkt.rpc_vers_minor = 0; + pkt.drep[0] = 0x10; /* Little endian */ + pkt.drep[1] = 0; + pkt.drep[2] = 0; + pkt.drep[3] = 0; + pkt.auth_length = 0; + pkt.call_id = call->pkt.call_id; + pkt.ptype = DCERPC_PKT_RESPONSE; + pkt.pfc_flags = 0; + if (!call->replies) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_FIRST; + } + if (length == stub.length) { + pkt.pfc_flags |= DCERPC_PFC_FLAG_LAST; + } + pkt.u.response.alloc_hint = stub.length; + pkt.u.response.context_id = call->pkt.u.request.context_id; + pkt.u.response.cancel_count = 0; + pkt.u.response.stub_and_verifier.data = stub.data; + pkt.u.response.stub_and_verifier.length = length; + + push = ndr_push_init_ctx(call->mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + rep->data = ndr_push_blob(push); + SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + + DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + + stub.data += length; + stub.length -= length; + } while (stub.length != 0); return NT_STATUS_OK; } @@ -357,7 +405,7 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) } call->mem_ctx = mem_ctx; call->dce = dce; - call->data = data_blob(NULL, 0); + call->replies = NULL; ndr = ndr_pull_init_blob(data, mem_ctx); if (!ndr) { @@ -454,22 +502,29 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) NTSTATUS dcesrv_output(struct dcesrv_state *dce, DATA_BLOB *data) { struct dcesrv_call_state *call; + struct dcesrv_call_reply *rep; call = dce->call_list; - if (!call) { + if (!call || !call->replies) { return NT_STATUS_FOOBAR; } - - if (data->length >= call->data.length) { - data->length = call->data.length; + rep = call->replies; + + if (data->length >= rep->data.length) { + data->length = rep->data.length; } - memcpy(data->data, call->data.data, data->length); - call->data.length -= data->length; - call->data.data += data->length; + memcpy(data->data, rep->data.data, data->length); + rep->data.length -= data->length; + rep->data.data += data->length; + + if (rep->data.length == 0) { + /* we're done with this section of the call */ + DLIST_REMOVE(call->replies, rep); + } - if (call->data.length == 0) { - /* we're done with this call */ + if (call->replies == NULL) { + /* we're done with the whole call */ DLIST_REMOVE(dce->call_list, call); talloc_destroy(call->mem_ctx); } -- cgit From fece5b7abae880f839b662aa1ac590f4a997c95e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Dec 2003 06:12:41 +0000 Subject: added support for sending bind_nak replies in the rpc server (This used to be commit 6e7c50bcd9929b6b1400b3155f55e6c9a4a730b3) --- source4/rpc_server/dcerpc_server.c | 89 +++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 16 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 45e720b8c1..4711f4e6ff 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -101,6 +101,8 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, (*p)->private = NULL; (*p)->call_list = NULL; (*p)->cli_max_recv_frag = 0; + (*p)->ndr = NULL; + (*p)->dispatch = NULL; /* make sure the endpoint server likes the connection */ status = ops->connect(*p); @@ -148,7 +150,56 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - /* now form the NDR for the bind_ack */ + /* now form the NDR for the fault */ + push = ndr_push_init_ctx(call->mem_ctx); + if (!push) { + return NT_STATUS_NO_MEMORY; + } + + status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + rep = talloc(call->mem_ctx, sizeof(*rep)); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } + + rep->data = ndr_push_blob(push); + SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + + DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + + return NT_STATUS_OK; +} + + +/* + return a dcerpc bind_nak +*/ +static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) +{ + struct ndr_push *push; + struct dcerpc_packet pkt; + struct dcesrv_call_reply *rep; + NTSTATUS status; + + /* setup a bind_ack */ + pkt.rpc_vers = 5; + pkt.rpc_vers_minor = 0; + pkt.drep[0] = 0x10; /* Little endian */ + pkt.drep[1] = 0; + pkt.drep[2] = 0; + pkt.drep[3] = 0; + pkt.auth_length = 0; + pkt.call_id = call->pkt.call_id; + pkt.ptype = DCERPC_PKT_BIND_NAK; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.u.bind_nak.reject_reason = reason; + pkt.u.bind_nak.num_versions = 0; + + /* now form the NDR for the bind_nak */ push = ndr_push_init_ctx(call->mem_ctx); if (!push) { return NT_STATUS_NO_MEMORY; @@ -184,16 +235,17 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) struct ndr_push *push; struct dcesrv_call_reply *rep; NTSTATUS status; + uint32 result=0, reason=0; if (call->pkt.u.bind.num_contexts != 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { - return dcesrv_fault(call, DCERPC_FAULT_TODO); + return dcesrv_bind_nak(call, 0); } if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.major_version; uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); if (!uuid) { - return dcesrv_fault(call, DCERPC_FAULT_TODO); + return dcesrv_bind_nak(call, 0); } transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].major_version; @@ -203,13 +255,14 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) strcasecmp(NDR_GUID, transfer_syntax) != 0 || NDR_GUID_VERSION != transfer_syntax_version) { /* we only do NDR encoded dcerpc */ - return dcesrv_fault(call, DCERPC_FAULT_TODO); + return dcesrv_bind_nak(call, 0); } if (!call->dce->ops->set_interface(call->dce, uuid, if_version)) { DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); /* we don't know about that interface */ - return dcesrv_fault(call, DCERPC_FAULT_TODO); + result = DCERPC_BIND_PROVIDER_REJECT; + reason = DCERPC_BIND_REASON_ASYNTAX; } if (call->dce->cli_max_recv_frag == 0) { @@ -230,15 +283,19 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; - pkt.u.bind_ack.secondary_address = talloc_asprintf(call->mem_ctx, "\\PIPE\\%s", - call->dce->ndr->name); + if (call->dce->ndr) { + pkt.u.bind_ack.secondary_address = talloc_asprintf(call->mem_ctx, "\\PIPE\\%s", + call->dce->ndr->name); + } else { + pkt.u.bind_ack.secondary_address = ""; + } pkt.u.bind_ack.num_results = 1; pkt.u.bind_ack.ctx_list = talloc(call->mem_ctx, sizeof(struct dcerpc_ack_ctx)); if (!pkt.u.bind_ack.ctx_list) { return NT_STATUS_NO_MEMORY; } - pkt.u.bind_ack.ctx_list[0].result = 0; - pkt.u.bind_ack.ctx_list[0].reason = 0; + pkt.u.bind_ack.ctx_list[0].result = result; + pkt.u.bind_ack.ctx_list[0].reason = reason; GUID_from_string(uuid, &pkt.u.bind_ack.ctx_list[0].syntax.uuid); pkt.u.bind_ack.ctx_list[0].syntax.major_version = if_version; pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0; @@ -300,13 +357,13 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* unravel the NDR for the packet */ status = call->dce->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); if (!NT_STATUS_IS_OK(status)) { - return dcesrv_fault(call, DCERPC_FAULT_TODO); + return dcesrv_fault(call, DCERPC_FAULT_NDR); } /* call the dispatch function */ status = call->dce->dispatch[opnum](call->dce, call->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { - return dcesrv_fault(call, DCERPC_FAULT_TODO); + return dcesrv_fault(call, DCERPC_FAULT_NDR); } /* form the reply NDR */ @@ -317,7 +374,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) status = call->dce->ndr->calls[opnum].ndr_push(push, NDR_OUT, r); if (!NT_STATUS_IS_OK(status)) { - return dcesrv_fault(call, DCERPC_FAULT_TODO); + return dcesrv_fault(call, DCERPC_FAULT_NDR); } stub = ndr_push_blob(push); @@ -426,19 +483,19 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) /* we only allow fragmented requests, no other packet types */ if (call->pkt.ptype != DCERPC_PKT_REQUEST) { - return dcesrv_fault(call2, DCERPC_FAULT_TODO); + return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } /* this is a continuation of an existing call - find the call then tack it on the end */ call = dcesrv_find_call(dce, call2->pkt.call_id); if (!call) { - return dcesrv_fault(call2, DCERPC_FAULT_TODO); + return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } if (call->pkt.ptype != call2->pkt.ptype) { /* trying to play silly buggers are we? */ - return dcesrv_fault(call2, DCERPC_FAULT_TODO); + return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } alloc_size = call->pkt.u.request.stub_and_verifier.length + @@ -451,7 +508,7 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) talloc_realloc(call->mem_ctx, call->pkt.u.request.stub_and_verifier.data, alloc_size); if (!call->pkt.u.request.stub_and_verifier.data) { - return dcesrv_fault(call2, DCERPC_FAULT_TODO); + return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } memcpy(call->pkt.u.request.stub_and_verifier.data + call->pkt.u.request.stub_and_verifier.length, -- cgit From 340d9b71f9e75d634389104da5949ba59669ede2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 02:20:40 +0000 Subject: added a basic dcerpc endpoint mapper to Samba4. Currently only implements the epm_Lookup() call, I'll add the other important calls soon. I was rather pleased to find that epm_Lookup() worked first time, which is particularly surprising given its complexity. This required quite a bit of new infrastructure: * a generic way of handling dcerpc policy handles in the rpc server * added type checked varients of talloc. These are much less error prone. I'd like to move to using these for nearly all uses of talloc. * added more dcerpc fault handling code, and translation from NTSTATUS to a dcerpc fault code * added data_blob_talloc_zero() for allocating an initially zero blob * added a endpoint enumeration hook in the dcerpc endpoint server operations (This used to be commit 3f85f9b782dc17417baf1ca557fcae22f5b6a83a) --- source4/rpc_server/dcerpc_server.c | 64 +++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4711f4e6ff..e2a6ab0132 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -89,12 +89,13 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, return NT_STATUS_NO_MEMORY; } - *p = talloc(mem_ctx, sizeof(struct dcesrv_state)); + *p = talloc_p(mem_ctx, struct dcesrv_state); if (! *p) { talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } + (*p)->smb = smb; (*p)->mem_ctx = mem_ctx; (*p)->endpoint = *endpoint; (*p)->ops = ops; @@ -103,6 +104,7 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, (*p)->cli_max_recv_frag = 0; (*p)->ndr = NULL; (*p)->dispatch = NULL; + (*p)->handles = NULL; /* make sure the endpoint server likes the connection */ status = ops->connect(*p); @@ -121,6 +123,14 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, void dcesrv_endpoint_disconnect(struct dcesrv_state *p) { p->ops->disconnect(p); + + /* destroy any handles */ + while (p->handles) { + TALLOC_CTX *m = p->handles->mem_ctx; + DLIST_REMOVE(p->handles, p->handles); + talloc_destroy(m); + } + talloc_destroy(p->mem_ctx); } @@ -161,7 +171,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) return status; } - rep = talloc(call->mem_ctx, sizeof(*rep)); + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -175,6 +185,22 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) } +/* + return a dcerpc fault from a ntstatus code +*/ +static NTSTATUS dcesrv_fault_nt(struct dcesrv_call_state *call, NTSTATUS status) +{ + uint32 fault_code = DCERPC_FAULT_OTHER; + + /* TODO: we need to expand this table to include more mappings */ + if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { + fault_code = DCERPC_FAULT_CONTEXT_MISMATCH; + } + + return dcesrv_fault(call, fault_code); +} + + /* return a dcerpc bind_nak */ @@ -210,7 +236,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) return status; } - rep = talloc(call->mem_ctx, sizeof(*rep)); + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -290,7 +316,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.secondary_address = ""; } pkt.u.bind_ack.num_results = 1; - pkt.u.bind_ack.ctx_list = talloc(call->mem_ctx, sizeof(struct dcerpc_ack_ctx)); + pkt.u.bind_ack.ctx_list = talloc_p(call->mem_ctx, struct dcerpc_ack_ctx); if (!pkt.u.bind_ack.ctx_list) { return NT_STATUS_NO_MEMORY; } @@ -312,7 +338,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return status; } - rep = talloc(call->mem_ctx, sizeof(*rep)); + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -363,7 +389,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* call the dispatch function */ status = call->dce->dispatch[opnum](call->dce, call->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { - return dcesrv_fault(call, DCERPC_FAULT_NDR); + return dcesrv_fault_nt(call, status); } /* form the reply NDR */ @@ -384,7 +410,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct dcesrv_call_reply *rep; struct dcerpc_packet pkt; - rep = talloc(call->mem_ctx, sizeof(*rep)); + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -455,7 +481,7 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } - call = talloc(mem_ctx, sizeof(*call)); + call = talloc_p(mem_ctx, struct dcesrv_call_state); if (!call) { talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; @@ -612,11 +638,33 @@ BOOL dcesrv_table_query(const struct dcerpc_interface_table *table, } +/* + a useful function for implementing the lookup_endpoints op + */ +int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table, + TALLOC_CTX *mem_ctx, + struct dcesrv_ep_iface **e) +{ + *e = talloc_p(mem_ctx, struct dcesrv_ep_iface); + if (! *e) { + return -1; + } + + (*e)->uuid = table->uuid; + (*e)->if_version = table->if_version; + (*e)->endpoint.type = ENDPOINT_SMB; + (*e)->endpoint.info.smb_pipe = table->endpoints->names[0]; + + return 1; +} + + /* initialise the dcerpc server subsystem */ BOOL dcesrv_init(struct server_context *smb) { rpc_echo_init(smb); + rpc_epmapper_init(smb); return True; } -- cgit From da86d3af3126413e59798bcfb0705c307bc730cb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 03:23:41 +0000 Subject: added the epm_Map() call. the RPC-EPMAPPER torture test now passes (This used to be commit fbdcf9ef548aefb1233cbb22a60bff3eacba996f) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e2a6ab0132..35661d913e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -105,6 +105,7 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, (*p)->ndr = NULL; (*p)->dispatch = NULL; (*p)->handles = NULL; + (*p)->next_handle = 0; /* make sure the endpoint server likes the connection */ status = ops->connect(*p); -- cgit From 8faa77f177833eeee245391840d06771f46e0136 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 04:46:50 +0000 Subject: rpcdump.exe now works fine against a Samba4 server for some reason the epm_Lookup replies can't be parsed by ethereal, although w2k parses then fine as does the Samba4 NDR code. (This used to be commit 097e7ca99d947932df5674c36e628ca6b8f31d3a) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 35661d913e..67b36cdc48 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -651,6 +651,7 @@ int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table, return -1; } + (*e)->name = table->name; (*e)->uuid = table->uuid; (*e)->if_version = table->if_version; (*e)->endpoint.type = ENDPOINT_SMB; -- cgit From d4705378ce88d1bb2f787338c531998d37d078ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 10:58:48 +0000 Subject: dcerpc over tcp in the samba4 server now works to some extent. It needs quite a bit more work to get it finished. The biggest missing feature is the lack of NTLMSSP which is needed for basic authentication over tcp (This used to be commit 9fb0f0369356909c99389e2cbc525be27c08793c) --- source4/rpc_server/dcerpc_server.c | 70 ++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 25 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 67b36cdc48..81c9d4cb8f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -25,11 +25,11 @@ /* find the set of endpoint operations for an endpoint server */ -static const struct dcesrv_endpoint_ops *find_endpoint(struct server_context *smb, +static const struct dcesrv_endpoint_ops *find_endpoint(struct dcesrv_context *dce, const struct dcesrv_endpoint *endpoint) { struct dce_endpoint *ep; - for (ep=smb->dcesrv.endpoint_list; ep; ep=ep->next) { + for (ep=dce->endpoint_list; ep; ep=ep->next) { if (ep->endpoint_ops->query_endpoint(endpoint)) { return ep->endpoint_ops; } @@ -54,7 +54,7 @@ static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_state *dce, uint /* register an endpoint server */ -BOOL dcesrv_endpoint_register(struct server_context *smb, +BOOL dcesrv_endpoint_register(struct dcesrv_context *dce, const struct dcesrv_endpoint_ops *ops) { struct dce_endpoint *ep; @@ -63,26 +63,20 @@ BOOL dcesrv_endpoint_register(struct server_context *smb, return False; } ep->endpoint_ops = ops; - DLIST_ADD(smb->dcesrv.endpoint_list, ep); + DLIST_ADD(dce->endpoint_list, ep); return True; } /* connect to a dcerpc endpoint */ -NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, - const struct dcesrv_endpoint *endpoint, - struct dcesrv_state **p) +NTSTATUS dcesrv_endpoint_connect_ops(struct dcesrv_context *dce, + const struct dcesrv_endpoint *endpoint, + const struct dcesrv_endpoint_ops *ops, + struct dcesrv_state **p) { TALLOC_CTX *mem_ctx; NTSTATUS status; - const struct dcesrv_endpoint_ops *ops; - - /* make sure this endpoint exists */ - ops = find_endpoint(smb, endpoint); - if (!ops) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } mem_ctx = talloc_init("dcesrv_endpoint_connect"); if (!mem_ctx) { @@ -95,7 +89,7 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, return NT_STATUS_NO_MEMORY; } - (*p)->smb = smb; + (*p)->dce = dce; (*p)->mem_ctx = mem_ctx; (*p)->endpoint = *endpoint; (*p)->ops = ops; @@ -117,6 +111,24 @@ NTSTATUS dcesrv_endpoint_connect(struct server_context *smb, return NT_STATUS_OK; } +/* + connect to a dcerpc endpoint +*/ +NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce, + const struct dcesrv_endpoint *endpoint, + struct dcesrv_state **p) +{ + const struct dcesrv_endpoint_ops *ops; + + /* make sure this endpoint exists */ + ops = find_endpoint(dce, endpoint); + if (!ops) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + return dcesrv_endpoint_connect_ops(dce, endpoint, ops, p); +} + /* disconnect a link to an endpoint @@ -646,27 +658,35 @@ int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table, TALLOC_CTX *mem_ctx, struct dcesrv_ep_iface **e) { - *e = talloc_p(mem_ctx, struct dcesrv_ep_iface); + int i; + *e = talloc_array_p(mem_ctx, struct dcesrv_ep_iface, table->endpoints->count); if (! *e) { return -1; } - (*e)->name = table->name; - (*e)->uuid = table->uuid; - (*e)->if_version = table->if_version; - (*e)->endpoint.type = ENDPOINT_SMB; - (*e)->endpoint.info.smb_pipe = table->endpoints->names[0]; + for (i=0;iendpoints->count;i++) { + (*e)[i].name = table->name; + (*e)[i].uuid = table->uuid; + (*e)[i].if_version = table->if_version; + if (strncmp(table->endpoints->names[i], "TCP-", 4) == 0) { + (*e)[i].endpoint.type = ENDPOINT_TCP; + (*e)[i].endpoint.info.tcp_port = atoi(table->endpoints->names[i]+4); + } else { + (*e)[i].endpoint.type = ENDPOINT_SMB; + (*e)[i].endpoint.info.smb_pipe = table->endpoints->names[i]; + } + } - return 1; + return i; } /* initialise the dcerpc server subsystem */ -BOOL dcesrv_init(struct server_context *smb) +BOOL dcesrv_init(struct dcesrv_context *dce) { - rpc_echo_init(smb); - rpc_epmapper_init(smb); + rpc_echo_init(dce); + rpc_epmapper_init(dce); return True; } -- cgit From 8d79eb52f104d023122de3965592b4ea36adbb2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 11:44:28 +0000 Subject: make the IO in the dcerpc over TCP server completely async, handling partial packets on both input and output (This used to be commit 4f46606af880f6dd86c20b8dc5799102a8e80cc9) --- source4/rpc_server/dcerpc_server.c | 56 +++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 81c9d4cb8f..bde7063dcc 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -100,6 +100,7 @@ NTSTATUS dcesrv_endpoint_connect_ops(struct dcesrv_context *dce, (*p)->dispatch = NULL; (*p)->handles = NULL; (*p)->next_handle = 0; + (*p)->partial_input = data_blob(NULL, 0); /* make sure the endpoint server likes the connection */ status = ops->connect(*p); @@ -479,6 +480,40 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } +/* + work out if we have a full packet yet +*/ +static BOOL dce_full_packet(const DATA_BLOB *data) +{ + if (data->length < DCERPC_FRAG_LEN_OFFSET+2) { + return False; + } + if (SVAL(data->data, DCERPC_FRAG_LEN_OFFSET) > data->length) { + return False; + } + return True; +} + +/* + we might have consumed only part of our input - advance past that part +*/ +static void dce_partial_advance(struct dcesrv_state *dce, uint32 offset) +{ + DATA_BLOB blob; + + if (dce->partial_input.length == offset) { + talloc_free(dce->mem_ctx, dce->partial_input.data); + dce->partial_input = data_blob(NULL, 0); + return; + } + + blob = dce->partial_input; + dce->partial_input = data_blob_talloc(dce->mem_ctx, + blob.data + offset, + blob.length - offset); + talloc_free(dce->mem_ctx, blob.data); +} + /* provide some input to a dcerpc endpoint server. This passes data from a dcerpc client into the server @@ -490,12 +525,27 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) NTSTATUS status; struct dcesrv_call_state *call; + dce->partial_input.data = talloc_realloc(dce->mem_ctx, + dce->partial_input.data, + dce->partial_input.length + data->length); + if (!dce->partial_input.data) { + return NT_STATUS_NO_MEMORY; + } + memcpy(dce->partial_input.data + dce->partial_input.length, + data->data, data->length); + dce->partial_input.length += data->length; + + if (!dce_full_packet(&dce->partial_input)) { + return NT_STATUS_OK; + } + mem_ctx = talloc_init("dcesrv_input"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } call = talloc_p(mem_ctx, struct dcesrv_call_state); if (!call) { + talloc_free(dce->mem_ctx, dce->partial_input.data); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -503,18 +553,22 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) call->dce = dce; call->replies = NULL; - ndr = ndr_pull_init_blob(data, mem_ctx); + ndr = ndr_pull_init_blob(&dce->partial_input, mem_ctx); if (!ndr) { + talloc_free(dce->mem_ctx, dce->partial_input.data); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { + talloc_free(dce->mem_ctx, dce->partial_input.data); talloc_destroy(mem_ctx); return status; } + dce_partial_advance(dce, ndr->offset); + /* see if this is a continued packet */ if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; -- cgit From d262b8c3c79b2fbb0bf8c330d765f89210948a26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 23:25:15 +0000 Subject: completed the linkage between the endpoint mapper and the dcerpc server endpoints. We can now successfully setup listening endpoints on high ports, then use our endpoint mapper redirect incoming clients to the right port. also greatly cleanup the rpc over tcp session handling. (This used to be commit 593bc29bbe0e46d356d001160e8a3332a88f2fa8) --- source4/rpc_server/dcerpc_server.c | 43 +++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index bde7063dcc..4493ffdaa5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -55,15 +55,44 @@ static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_state *dce, uint register an endpoint server */ BOOL dcesrv_endpoint_register(struct dcesrv_context *dce, - const struct dcesrv_endpoint_ops *ops) + const struct dcesrv_endpoint_ops *ops, + const struct dcerpc_interface_table *table) { - struct dce_endpoint *ep; - ep = malloc(sizeof(*ep)); - if (!ep) { - return False; + BOOL done_smb=False; + BOOL done_tcp=False; + int i; + + for (i=0;iendpoints->count;i++) { + struct dce_endpoint *ep; + BOOL tcp; + + tcp = (strncasecmp(table->endpoints->names[i], "TCP-", 4) == 0); + + if (tcp) { + if (done_tcp) continue; + done_tcp = True; + } else { + if (done_smb) continue; + done_smb = True; + } + + ep = malloc(sizeof(*ep)); + if (!ep) { + return False; + } + + if (tcp) { + ep->endpoint.type = ENDPOINT_TCP; + ep->endpoint.info.tcp_port = atoi(table->endpoints->names[i]+4); + } else { + ep->endpoint.type = ENDPOINT_SMB; + ep->endpoint.info.smb_pipe = table->endpoints->names[i]; + } + + ep->endpoint_ops = ops; + DLIST_ADD(dce->endpoint_list, ep); } - ep->endpoint_ops = ops; - DLIST_ADD(dce->endpoint_list, ep); + return True; } -- cgit From 8f6b3eb1a9c1e996330b0edfb312b2345e292819 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Dec 2003 01:09:10 +0000 Subject: fixed a bug handling multiple PDUs being read from a socket at one time in the rpc server. started on the framework for the dcerpc authentication server code (This used to be commit 74041b6a0a60d792e1b220496d66ec27b9ee6c25) --- source4/rpc_server/dcerpc_server.c | 121 +++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 59 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4493ffdaa5..81715f038b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -130,6 +130,8 @@ NTSTATUS dcesrv_endpoint_connect_ops(struct dcesrv_context *dce, (*p)->handles = NULL; (*p)->next_handle = 0; (*p)->partial_input = data_blob(NULL, 0); + (*p)->auth_state.ntlmssp_state = NULL; + (*p)->auth_state.auth_info = NULL; /* make sure the endpoint server likes the connection */ status = ops->connect(*p); @@ -182,7 +184,6 @@ void dcesrv_endpoint_disconnect(struct dcesrv_state *p) */ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) { - struct ndr_push *push; struct dcerpc_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; @@ -203,23 +204,16 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - /* now form the NDR for the fault */ - push = ndr_push_init_ctx(call->mem_ctx); - if (!push) { + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); + if (!rep) { return NT_STATUS_NO_MEMORY; } - status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } - - rep->data = ndr_push_blob(push); SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -249,7 +243,6 @@ static NTSTATUS dcesrv_fault_nt(struct dcesrv_call_state *call, NTSTATUS status) */ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) { - struct ndr_push *push; struct dcerpc_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; @@ -268,23 +261,16 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) pkt.u.bind_nak.reject_reason = reason; pkt.u.bind_nak.num_versions = 0; - /* now form the NDR for the bind_nak */ - push = ndr_push_init_ctx(call->mem_ctx); - if (!push) { + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); + if (!rep) { return NT_STATUS_NO_MEMORY; } - status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } - - rep->data = ndr_push_blob(push); SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -301,7 +287,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) const char *uuid, *transfer_syntax; uint32 if_version, transfer_syntax_version; struct dcerpc_packet pkt; - struct ndr_push *push; struct dcesrv_call_reply *rep; NTSTATUS status; uint32 result=0, reason=0; @@ -338,6 +323,11 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) call->dce->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag; } + /* handle any authentication that is being requested */ + if (!dcesrv_auth_bind(call)) { + return dcesrv_bind_nak(call, 0); + } + /* setup a bind_ack */ pkt.rpc_vers = 5; pkt.rpc_vers_minor = 0; @@ -370,15 +360,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0; pkt.u.bind_ack.auth_info = data_blob(NULL, 0); - /* now form the NDR for the bind_ack */ - push = ndr_push_init_ctx(call->mem_ctx); - if (!push) { - return NT_STATUS_NO_MEMORY; - } - - status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (!dcesrv_auth_bind_ack(call, &pkt)) { + return dcesrv_bind_nak(call, 0); } rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); @@ -386,7 +369,11 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - rep->data = ndr_push_blob(push); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -486,17 +473,12 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pkt.u.response.stub_and_verifier.data = stub.data; pkt.u.response.stub_and_verifier.length = length; - push = ndr_push_init_ctx(call->mem_ctx); - if (!push) { - return NT_STATUS_NO_MEMORY; - } - - status = ndr_push_dcerpc_packet(push, NDR_SCALARS|NDR_BUFFERS, &pkt); + + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - - rep->data = ndr_push_blob(push); + SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -544,29 +526,15 @@ static void dce_partial_advance(struct dcesrv_state *dce, uint32 offset) } /* - provide some input to a dcerpc endpoint server. This passes data - from a dcerpc client into the server + process some input to a dcerpc endpoint server. */ -NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) +NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) { struct ndr_pull *ndr; TALLOC_CTX *mem_ctx; NTSTATUS status; struct dcesrv_call_state *call; - - dce->partial_input.data = talloc_realloc(dce->mem_ctx, - dce->partial_input.data, - dce->partial_input.length + data->length); - if (!dce->partial_input.data) { - return NT_STATUS_NO_MEMORY; - } - memcpy(dce->partial_input.data + dce->partial_input.length, - data->data, data->length); - dce->partial_input.length += data->length; - - if (!dce_full_packet(&dce->partial_input)) { - return NT_STATUS_OK; - } + DATA_BLOB blob; mem_ctx = talloc_init("dcesrv_input"); if (!mem_ctx) { @@ -582,7 +550,10 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) call->dce = dce; call->replies = NULL; - ndr = ndr_pull_init_blob(&dce->partial_input, mem_ctx); + blob = dce->partial_input; + blob.length = SVAL(blob.data, DCERPC_FRAG_LEN_OFFSET); + + ndr = ndr_pull_init_blob(&blob, mem_ctx); if (!ndr) { talloc_free(dce->mem_ctx, dce->partial_input.data); talloc_destroy(mem_ctx); @@ -673,6 +644,38 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) return status; } + +/* + provide some input to a dcerpc endpoint server. This passes data + from a dcerpc client into the server +*/ +NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) +{ + struct ndr_pull *ndr; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + struct dcesrv_call_state *call; + + dce->partial_input.data = talloc_realloc(dce->mem_ctx, + dce->partial_input.data, + dce->partial_input.length + data->length); + if (!dce->partial_input.data) { + return NT_STATUS_NO_MEMORY; + } + memcpy(dce->partial_input.data + dce->partial_input.length, + data->data, data->length); + dce->partial_input.length += data->length; + + while (dce_full_packet(&dce->partial_input)) { + status = dcesrv_input_process(dce); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + return NT_STATUS_OK; +} + /* retrieve some output from a dcerpc server. The amount of data that is wanted is in data->length and data->data is already allocated -- cgit From 089ae5e43543a4654dddd42d61eb84a8036c4780 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Dec 2003 03:51:48 +0000 Subject: fixed some memory leaks in the rpc server code (This used to be commit 20458556017f426ab57ca9a9d098cacecefbdcff) --- source4/rpc_server/dcerpc_server.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 81715f038b..7fa7a7aa8b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -513,16 +513,15 @@ static void dce_partial_advance(struct dcesrv_state *dce, uint32 offset) DATA_BLOB blob; if (dce->partial_input.length == offset) { - talloc_free(dce->mem_ctx, dce->partial_input.data); + free(dce->partial_input.data); dce->partial_input = data_blob(NULL, 0); return; } blob = dce->partial_input; - dce->partial_input = data_blob_talloc(dce->mem_ctx, - blob.data + offset, - blob.length - offset); - talloc_free(dce->mem_ctx, blob.data); + dce->partial_input = data_blob(blob.data + offset, + blob.length - offset); + free(blob.data); } /* @@ -567,7 +566,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) return status; } - dce_partial_advance(dce, ndr->offset); + dce_partial_advance(dce, blob.length); /* see if this is a continued packet */ if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { @@ -651,14 +650,10 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) */ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) { - struct ndr_pull *ndr; - TALLOC_CTX *mem_ctx; NTSTATUS status; - struct dcesrv_call_state *call; - dce->partial_input.data = talloc_realloc(dce->mem_ctx, - dce->partial_input.data, - dce->partial_input.length + data->length); + dce->partial_input.data = Realloc(dce->partial_input.data, + dce->partial_input.length + data->length); if (!dce->partial_input.data) { return NT_STATUS_NO_MEMORY; } -- cgit From d009dc61f90e45b695fb9eaaf11899c7572dc9a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Dec 2003 10:45:50 +0000 Subject: ntlmssp over rpc over tcp now fully works I needed to hack the ntlmssp code a little, as the auth code in samba4 is out of date relative to the samba3 auth code. I need to do a merge :) (This used to be commit 6ee0935afe9444bf9bb24eed4e02e8377dc746b7) --- source4/rpc_server/dcerpc_server.c | 44 +++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 7fa7a7aa8b..16b573cfad 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -369,7 +369,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, + call->dce->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -377,7 +378,26 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *); + + return NT_STATUS_OK; +} + + +/* + handle a auth3 request +*/ +static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) +{ + /* handle the auth3 in the auth code */ + if (!dcesrv_auth_auth3(call)) { + return dcesrv_fault(call, DCERPC_FAULT_OTHER); + } + + talloc_destroy(call->mem_ctx); + /* we don't send a reply to a auth3 request, except by a + fault */ return NT_STATUS_OK; } @@ -473,10 +493,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pkt.u.response.stub_and_verifier.data = stub.data; pkt.u.response.stub_and_verifier.length = length; - - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (!dcesrv_auth_response(call, &rep->data, &pkt)) { + return dcesrv_fault(call, DCERPC_FAULT_OTHER); } SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); @@ -487,6 +505,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) stub.length -= length; } while (stub.length != 0); + DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *); + return NT_STATUS_OK; } @@ -568,6 +588,13 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) dce_partial_advance(dce, blob.length); + /* we have to check the signing here, before combining the + pdus */ + if (call->pkt.ptype == DCERPC_PKT_REQUEST && + !dcesrv_auth_request(call)) { + return dcesrv_fault(call, DCERPC_FAULT_OTHER); + } + /* see if this is a continued packet */ if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; @@ -623,6 +650,9 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) case DCERPC_PKT_BIND: status = dcesrv_bind(call); break; + case DCERPC_PKT_AUTH3: + status = dcesrv_auth3(call); + break; case DCERPC_PKT_REQUEST: status = dcesrv_request(call); break; @@ -634,9 +664,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) /* if we are going to be sending a reply then add it to the list of pending calls. We add it to the end to keep the call list in the order we will answer */ - if (NT_STATUS_IS_OK(status)) { - DLIST_ADD_END(dce->call_list, call, struct dcesrv_call_state *); - } else { + if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); } -- cgit From a05882b34beffae26723a6b22a467ab10ee28dfe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Dec 2003 12:21:21 +0000 Subject: fixed fragmented signed connections to our rpc server over SMB (This used to be commit f5df126c254bcb96dfb42096d7247215c7e7a89a) --- source4/rpc_server/dcerpc_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 16b573cfad..a34c00cd58 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -467,7 +467,9 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) length = stub.length; if (length + DCERPC_RESPONSE_LENGTH > call->dce->cli_max_recv_frag) { - length = call->dce->cli_max_recv_frag - DCERPC_RESPONSE_LENGTH; + /* the 32 is to cope with signing data */ + length = call->dce->cli_max_recv_frag - + (DCERPC_MAX_SIGN_SIZE+DCERPC_RESPONSE_LENGTH); } /* form the dcerpc response packet */ -- cgit From f6eb8342cba87c7c8f17471ed9783b567d36b0ed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Dec 2003 13:22:12 +0000 Subject: added auto-generation of the server side boilerplate code for each pipe. The server side code gets generated as librpc/gen_ndr/ndr_NAME_s.c and gets included in the pipe module (This used to be commit bd3dcfe5820489a838e19b244266bd9126af5eb4) --- source4/rpc_server/dcerpc_server.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a34c00cd58..cbde3c9532 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -792,12 +792,28 @@ int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table, } +BOOL dcesrv_set_interface(struct dcesrv_state *dce, + const char *uuid, uint32 if_version, + const struct dcerpc_interface_table *table, + const dcesrv_dispatch_fn_t *dispatch_table) +{ + if (strcasecmp(table->uuid, uuid) != 0 || if_version != table->if_version) { + DEBUG(2,("Attempt to use unknown interface %s/%d\n", uuid, if_version)); + return False; + } + + dce->ndr = table; + dce->dispatch = dispatch_table; + return True; +} + + /* initialise the dcerpc server subsystem */ BOOL dcesrv_init(struct dcesrv_context *dce) { - rpc_echo_init(dce); + rpc_rpcecho_init(dce); rpc_epmapper_init(dce); return True; } -- cgit From 79990c727c700399927d7bc7fd121fc310daa798 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Dec 2003 00:40:57 +0000 Subject: fixed the transfer syntax in the dcerpc bind reply (This used to be commit 39a7c660f4b7cafb0414842329669dd4724b07db) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cbde3c9532..f3c7a63c79 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -355,8 +355,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } pkt.u.bind_ack.ctx_list[0].result = result; pkt.u.bind_ack.ctx_list[0].reason = reason; - GUID_from_string(uuid, &pkt.u.bind_ack.ctx_list[0].syntax.uuid); - pkt.u.bind_ack.ctx_list[0].syntax.major_version = if_version; + GUID_from_string(NDR_GUID, &pkt.u.bind_ack.ctx_list[0].syntax.uuid); + pkt.u.bind_ack.ctx_list[0].syntax.major_version = NDR_GUID_VERSION; pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0; pkt.u.bind_ack.auth_info = data_blob(NULL, 0); -- cgit From 24c22aef90d8534ee2d016b37b2b302f1367d106 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Dec 2003 09:02:58 +0000 Subject: a fairly large commit! This adds support for bigendian rpc in the client. I have installed SUN pcnetlink locally and am using it to test the samba4 rpc code. This allows us to easily find places where we have stuffed up the types (such as 2 uint16 versus a uint32), as testing both big-endian and little-endian easily shows which is correct. I have now used this to fix several bugs like that in the samba4 IDL. In order to make this work I also had to redefine a GUID as a true structure, not a blob. From the pcnetlink wire it is clear that it is indeed defined as a structure (the byte order changes). This required changing lots of Samba code to use a GUID as a structure. I also had to fix the if_version code in dcerpc syntax IDs, as it turns out they are a single uint32 not two uint16s. The big-endian support is a bit ugly at the moment, and breaks the layering in some places. More work is needed, especially on the server side. (This used to be commit bb1af644a5a7b188290ce36232f255da0e5d66d2) --- source4/rpc_server/dcerpc_server.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f3c7a63c79..5780de0c30 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -209,7 +209,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -266,7 +266,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -296,13 +296,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.major_version; + if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); if (!uuid) { return dcesrv_bind_nak(call, 0); } - transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].major_version; + transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version; transfer_syntax = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid); if (!transfer_syntax || @@ -356,8 +356,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.ctx_list[0].result = result; pkt.u.bind_ack.ctx_list[0].reason = reason; GUID_from_string(NDR_GUID, &pkt.u.bind_ack.ctx_list[0].syntax.uuid); - pkt.u.bind_ack.ctx_list[0].syntax.major_version = NDR_GUID_VERSION; - pkt.u.bind_ack.ctx_list[0].syntax.minor_version = 0; + pkt.u.bind_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; pkt.u.bind_ack.auth_info = data_blob(NULL, 0); if (!dcesrv_auth_bind_ack(call, &pkt)) { @@ -370,7 +369,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, - call->dce->auth_state.auth_info); + call->dce->auth_state.auth_info, 0); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 6f12e4ace1609fbf00d42226134b1dbb259f38bc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Dec 2003 09:50:49 +0000 Subject: it turns out that a wire policy handle isn't a blob either, its a uint32 followed by a GUID. I needed to fix this to support running in mixed-mode rpc (where smbtorture is bigendian and w2k3 is little-endian). Otherwise when you send back a policy handle the server doesn't recognise it. (This used to be commit 9b1c76a8e9e953e051072441f8938ee17a674d35) --- source4/rpc_server/dcerpc_server.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5780de0c30..081b5b1d5a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -128,7 +128,6 @@ NTSTATUS dcesrv_endpoint_connect_ops(struct dcesrv_context *dce, (*p)->ndr = NULL; (*p)->dispatch = NULL; (*p)->handles = NULL; - (*p)->next_handle = 0; (*p)->partial_input = data_blob(NULL, 0); (*p)->auth_state.ntlmssp_state = NULL; (*p)->auth_state.auth_info = NULL; -- cgit From 7efa19cd2285617dcb39d67a81a821b5119c3748 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Dec 2003 02:06:44 +0000 Subject: added a smb.conf flag "rpc big endian" that tells our rpc server to send packets in bigendian format. (This used to be commit 44df662960e662a55a9f27627f838771503a7a59) --- source4/rpc_server/dcerpc_server.c | 72 +++++++++++++++++++++----------------- 1 file changed, 39 insertions(+), 33 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 081b5b1d5a..d3e2f1917f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -178,6 +178,20 @@ void dcesrv_endpoint_disconnect(struct dcesrv_state *p) talloc_destroy(p->mem_ctx); } +static void dcesrv_init_hdr(struct dcerpc_packet *pkt) +{ + pkt->rpc_vers = 5; + pkt->rpc_vers_minor = 0; + if (lp_rpc_big_endian()) { + pkt->drep[0] = 0; + } else { + pkt->drep[0] = DCERPC_DREP_LE; + } + pkt->drep[1] = 0; + pkt->drep[2] = 0; + pkt->drep[3] = 0; +} + /* return a dcerpc fault */ @@ -188,12 +202,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) NTSTATUS status; /* setup a bind_ack */ - pkt.rpc_vers = 5; - pkt.rpc_vers_minor = 0; - pkt.drep[0] = 0x10; /* Little endian */ - pkt.drep[1] = 0; - pkt.drep[2] = 0; - pkt.drep[3] = 0; + dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_FAULT; @@ -208,12 +217,12 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -247,12 +256,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) NTSTATUS status; /* setup a bind_ack */ - pkt.rpc_vers = 5; - pkt.rpc_vers_minor = 0; - pkt.drep[0] = 0x10; /* Little endian */ - pkt.drep[1] = 0; - pkt.drep[2] = 0; - pkt.drep[3] = 0; + dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_NAK; @@ -265,12 +269,12 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL, 0); + status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -328,12 +332,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } /* setup a bind_ack */ - pkt.rpc_vers = 5; - pkt.rpc_vers_minor = 0; - pkt.drep[0] = 0x10; /* Little endian */ - pkt.drep[1] = 0; - pkt.drep[2] = 0; - pkt.drep[3] = 0; + dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_ACK; @@ -368,12 +367,12 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, - call->dce->auth_state.auth_info, 0); + call->dce->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } - SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *); @@ -428,6 +427,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } + if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) { + pull->flags |= LIBNDR_FLAG_BIGENDIAN; + } + /* unravel the NDR for the packet */ status = call->dce->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); if (!NT_STATUS_IS_OK(status)) { @@ -446,6 +449,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } + if (lp_rpc_big_endian()) { + push->flags |= LIBNDR_FLAG_BIGENDIAN; + } + status = call->dce->ndr->calls[opnum].ndr_push(push, NDR_OUT, r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, DCERPC_FAULT_NDR); @@ -471,12 +478,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* form the dcerpc response packet */ - pkt.rpc_vers = 5; - pkt.rpc_vers_minor = 0; - pkt.drep[0] = 0x10; /* Little endian */ - pkt.drep[1] = 0; - pkt.drep[2] = 0; - pkt.drep[3] = 0; + dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_RESPONSE; @@ -497,7 +499,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_OTHER); } - SSVAL(rep->data.data, DCERPC_FRAG_LEN_OFFSET, rep->data.length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -519,7 +521,7 @@ static BOOL dce_full_packet(const DATA_BLOB *data) if (data->length < DCERPC_FRAG_LEN_OFFSET+2) { return False; } - if (SVAL(data->data, DCERPC_FRAG_LEN_OFFSET) > data->length) { + if (dcerpc_get_frag_length(data) > data->length) { return False; } return True; @@ -570,7 +572,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) call->replies = NULL; blob = dce->partial_input; - blob.length = SVAL(blob.data, DCERPC_FRAG_LEN_OFFSET); + blob.length = dcerpc_get_frag_length(&blob); ndr = ndr_pull_init_blob(&blob, mem_ctx); if (!ndr) { @@ -579,6 +581,10 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) return NT_STATUS_NO_MEMORY; } + if (!(CVAL(blob.data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) { + ndr->flags |= LIBNDR_FLAG_BIGENDIAN; + } + status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { talloc_free(dce->mem_ctx, dce->partial_input.data); -- cgit From 7e6cf43756b7643e2f0ee7ada5076f36f3a24bb7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Jan 2004 22:55:27 +0000 Subject: This patch adds a better dcerpc server infastructure. 1.) We now register endpoint servers add startup via register_backend() and later use the smb.conf 'dcerpc endpoint servers' parameter to setup the dcesrv_context 2.) each endpoint server can register at context creation time as much interfaces as it wants (multiple interfaces on one endpoint are supported!) (NOTE: there's a difference between 'endpoint server' and 'endpoint'! for details look at rpc_server/dcesrv_server.h) 3.) one endpoint can have a security descriptor registered to it self this will be checked in the future when a client wants to connect to an smb pipe endpoint. 4.) we now have a 'remote' endpoint server, which works like the ntvfs_cifs module it takes this options in the [globals] section: dcerpc remote:interfaces = srvsvc, winreg, w32time, epmapper dcerpc remote:binding = ... dcerpc remote:user = ... dcerpc remote:password = ... 5.) we currently have tree endpoint servers: epmapper, rpcecho and remote the default for the 'dcerpc endpiont servers = epmapper, rpcecho' for testing you can also do dcerpc endpoint servers = rpcecho, remote, epmapper dcerpc remote:interfaces = srvsvc, samr, netlogon 6,) please notice the the epmapper now only returns NO_ENTRIES (but I think we'll find a solution for this too:-) 7.) also there're some other stuff left, but step by step :-) This patch also includes updates for the register_subsystem() , ntvfs_init(), and some other funtions to check for duplicate subsystem registration metze (hmmm, my first large commit...I hope it works as supposed :-) (This used to be commit 917e45dafd5be4c2cd90ff425b8d6f8403122349) --- source4/rpc_server/dcerpc_server.c | 529 ++++++++++++++++++++++++++----------- 1 file changed, 373 insertions(+), 156 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d3e2f1917f..46341e6db1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -4,6 +4,7 @@ server side dcerpc core code Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan (metze) Metzmacher 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 @@ -23,15 +24,105 @@ #include "includes.h" /* - find the set of endpoint operations for an endpoint server + see if two endpoints match */ -static const struct dcesrv_endpoint_ops *find_endpoint(struct dcesrv_context *dce, - const struct dcesrv_endpoint *endpoint) +static BOOL endpoints_match(const struct dcesrv_ep_description *ep1, + const struct dcesrv_ep_description *ep2) { - struct dce_endpoint *ep; - for (ep=dce->endpoint_list; ep; ep=ep->next) { - if (ep->endpoint_ops->query_endpoint(endpoint)) { - return ep->endpoint_ops; + if (ep1->type != ep2->type) { + return False; + } + + switch (ep1->type) { + case ENDPOINT_SMB: + if (strcmp(ep1->info.smb_pipe,ep2->info.smb_pipe)==0) { + return True; + } + break; + case ENDPOINT_TCP: + if (ep1->info.tcp_port == ep2->info.tcp_port) { + return True; + } + break; + } + + return False; +} + +/* + find an endpoint in the dcesrv_context +*/ +static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, + const struct dcesrv_ep_description *ep_description) +{ + struct dcesrv_endpoint *ep; + for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) { + if (endpoints_match(&ep->ep_description, ep_description)) { + return ep; + } + } + return NULL; +} + +/* + see if a uuid and if_version match to an interface +*/ +static BOOL interface_match(const struct dcesrv_interface *if1, + const struct dcesrv_interface *if2) +{ + if (if1->ndr->if_version != if2->ndr->if_version) { + return False; + } + + if (strcmp(if1->ndr->uuid, if2->ndr->uuid)==0) { + return True; + } + + return False; +} + +/* + find the interface operations on an endpoint +*/ +static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint, + const struct dcesrv_interface *iface) +{ + struct dcesrv_if_list *ifl; + for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) { + if (interface_match(&(ifl->iface), iface)) { + return &(ifl->iface); + } + } + return NULL; +} + +/* + see if a uuid and if_version match to an interface +*/ +static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, + const char *uuid, uint32 if_version) +{ + if (iface->ndr->if_version != if_version) { + return False; + } + + if (strcmp(iface->ndr->uuid, uuid)==0) { + return True; + } + + return False; +} + +/* + find the interface operations on an endpoint by uuid +*/ +static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint, + const char *uuid, uint32 if_version) +{ + struct dcesrv_if_list *ifl; + for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) { + if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) { + return &(ifl->iface); } } return NULL; @@ -40,10 +131,10 @@ static const struct dcesrv_endpoint_ops *find_endpoint(struct dcesrv_context *dc /* find a call that is pending in our call list */ -static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_state *dce, uint16 call_id) +static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_conn, uint16 call_id) { struct dcesrv_call_state *c; - for (c=dce->call_list;c;c=c->next) { + for (c=dce_conn->call_list;c;c=c->next) { if (c->pkt.call_id == call_id) { return c; } @@ -52,121 +143,175 @@ static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_state *dce, uint } /* - register an endpoint server + register an interface on an endpoint */ -BOOL dcesrv_endpoint_register(struct dcesrv_context *dce, - const struct dcesrv_endpoint_ops *ops, - const struct dcerpc_interface_table *table) +NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, + const char *ep_name, + const struct dcesrv_interface *iface, + const struct security_descriptor *sd) { - BOOL done_smb=False; - BOOL done_tcp=False; - int i; + struct dcesrv_ep_description ep_description; + struct dcesrv_endpoint *ep; + struct dcesrv_if_list *ifl; + BOOL tcp; + BOOL add_ep = False; - for (i=0;iendpoints->count;i++) { - struct dce_endpoint *ep; - BOOL tcp; + tcp = (strncasecmp(ep_name, "TCP-", 4) == 0); - tcp = (strncasecmp(table->endpoints->names[i], "TCP-", 4) == 0); + if (tcp) { + ep_description.type = ENDPOINT_TCP; + ep_description.info.tcp_port = atoi(ep_name+4); + } else { + ep_description.type = ENDPOINT_SMB; + ep_description.info.smb_pipe = ep_name; + } + /* check if this endpoint exists + */ + if ((ep=find_endpoint(dce_ctx, &ep_description))==NULL) { + ep = talloc(dce_ctx->mem_ctx, sizeof(*ep)); + if (!ep) { + return NT_STATUS_NO_MEMORY; + } + ZERO_STRUCTP(ep); if (tcp) { - if (done_tcp) continue; - done_tcp = True; + ep->ep_description.type = ENDPOINT_TCP; + ep->ep_description.info.tcp_port = atoi(ep_name+4); } else { - if (done_smb) continue; - done_smb = True; + ep->ep_description.type = ENDPOINT_SMB; + ep->ep_description.info.smb_pipe = smb_xstrdup(ep_name); } + add_ep = True; + } - ep = malloc(sizeof(*ep)); - if (!ep) { - return False; + /* see if the interface is already registered on te endpoint */ + if (find_interface(ep, iface)!=NULL) { + DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n", + iface->ndr->name, ep_name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + /* talloc a new interface list element */ + ifl = talloc(dce_ctx->mem_ctx, sizeof(*ifl)); + if (!ifl) { + return NT_STATUS_NO_MEMORY; + } + + /* copy the given interface struct to the one on the endpoints interface list */ + memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface)); + + /* if we have a security descriptor given, + * we should see if we can set it up on the endpoint + */ + if (sd != NULL) { + /* if there's currently no security descriptor given on the endpoint + * we try to set it + */ + if (ep->sd == NULL) { + ep->sd = copy_security_descriptor(dce_ctx->mem_ctx, sd); } - if (tcp) { - ep->endpoint.type = ENDPOINT_TCP; - ep->endpoint.info.tcp_port = atoi(table->endpoints->names[i]+4); - } else { - ep->endpoint.type = ENDPOINT_SMB; - ep->endpoint.info.smb_pipe = table->endpoints->names[i]; + /* if now there's no security descriptor given on the endpoint + * something goes wrong, either we failed to copy the security descriptor + * or there was already one on the endpoint + */ + if (ep->sd != NULL) { + DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n" + " on endpoint '%s'\n", + iface->ndr->name, ep_name)); + if (add_ep) free(ep); + free(ifl); + return NT_STATUS_OBJECT_NAME_COLLISION; } + } - ep->endpoint_ops = ops; - DLIST_ADD(dce->endpoint_list, ep); + /* finally add the interface on the endpoint */ + DLIST_ADD(ep->interface_list, ifl); + + /* if it's a new endpoint add it to the dcesrv_context */ + if (add_ep) { + DLIST_ADD(dce_ctx->endpoint_list, ep); } - return True; + DEBUG(3,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n", + iface->ndr->name, ep_name)); + + return NT_STATUS_OK; } /* connect to a dcerpc endpoint */ -NTSTATUS dcesrv_endpoint_connect_ops(struct dcesrv_context *dce, - const struct dcesrv_endpoint *endpoint, - const struct dcesrv_endpoint_ops *ops, - struct dcesrv_state **p) +NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, + const struct dcesrv_endpoint *ep, + struct dcesrv_connection **p) { TALLOC_CTX *mem_ctx; - NTSTATUS status; mem_ctx = talloc_init("dcesrv_endpoint_connect"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } - *p = talloc_p(mem_ctx, struct dcesrv_state); + *p = talloc_p(mem_ctx, struct dcesrv_connection); if (! *p) { talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } - (*p)->dce = dce; + (*p)->dce_ctx = dce_ctx; (*p)->mem_ctx = mem_ctx; - (*p)->endpoint = *endpoint; - (*p)->ops = ops; + (*p)->endpoint = ep; + (*p)->iface = NULL; (*p)->private = NULL; (*p)->call_list = NULL; (*p)->cli_max_recv_frag = 0; - (*p)->ndr = NULL; - (*p)->dispatch = NULL; (*p)->handles = NULL; (*p)->partial_input = data_blob(NULL, 0); (*p)->auth_state.ntlmssp_state = NULL; (*p)->auth_state.auth_info = NULL; - /* make sure the endpoint server likes the connection */ - status = ops->connect(*p); - if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); - return status; - } - return NT_STATUS_OK; } /* - connect to a dcerpc endpoint + search and connect to a dcerpc endpoint */ -NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce, - const struct dcesrv_endpoint *endpoint, - struct dcesrv_state **p) +NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, + const struct dcesrv_ep_description *ep_description, + struct dcesrv_connection **dce_conn_p) { - const struct dcesrv_endpoint_ops *ops; + NTSTATUS status; + const struct dcesrv_endpoint *ep; /* make sure this endpoint exists */ - ops = find_endpoint(dce, endpoint); - if (!ops) { + ep = find_endpoint(dce_ctx, ep_description); + if (!ep) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - return dcesrv_endpoint_connect_ops(dce, endpoint, ops, p); + status = dcesrv_endpoint_connect(dce_ctx, ep, dce_conn_p); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* TODO: check security descriptor of the endpoint here + * if it's a smb named pipe + * if it's failed free dce_conn_p + */ + + return NT_STATUS_OK; } /* disconnect a link to an endpoint */ -void dcesrv_endpoint_disconnect(struct dcesrv_state *p) +void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) { - p->ops->disconnect(p); + if (p->iface) { + p->iface->unbind(p, p->iface); + } /* destroy any handles */ while (p->handles) { @@ -315,15 +460,16 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - if (!call->dce->ops->set_interface(call->dce, uuid, if_version)) { + call->conn->iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version); + if (!call->conn->iface) { DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); /* we don't know about that interface */ result = DCERPC_BIND_PROVIDER_REJECT; - reason = DCERPC_BIND_REASON_ASYNTAX; + reason = DCERPC_BIND_REASON_ASYNTAX; } - if (call->dce->cli_max_recv_frag == 0) { - call->dce->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag; + if (call->conn->cli_max_recv_frag == 0) { + call->conn->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag; } /* handle any authentication that is being requested */ @@ -340,9 +486,9 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; - if (call->dce->ndr) { + if (call->conn->iface && call->conn->iface->ndr) { pkt.u.bind_ack.secondary_address = talloc_asprintf(call->mem_ctx, "\\PIPE\\%s", - call->dce->ndr->name); + call->conn->iface->ndr->name); } else { pkt.u.bind_ack.secondary_address = ""; } @@ -361,13 +507,21 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } + if (call->conn->iface) { + status = call->conn->iface->bind(call, call->conn->iface); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(2,("Request for dcerpc interface %s/%d rejected\n", uuid, if_version)); + return status; + } + } + rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, - call->dce->auth_state.auth_info); + call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -375,7 +529,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); - DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *); + DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; } @@ -413,7 +567,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) opnum = call->pkt.u.request.opnum; - if (opnum >= call->dce->ndr->num_calls) { + if (opnum >= call->conn->iface->ndr->num_calls) { return dcesrv_fault(call, DCERPC_FAULT_OP_RNG_ERROR); } @@ -422,7 +576,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - r = talloc(call->mem_ctx, call->dce->ndr->calls[opnum].struct_size); + r = talloc(call->mem_ctx, call->conn->iface->ndr->calls[opnum].struct_size); if (!r) { return NT_STATUS_NO_MEMORY; } @@ -432,13 +586,13 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* unravel the NDR for the packet */ - status = call->dce->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); + status = call->conn->iface->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, DCERPC_FAULT_NDR); } /* call the dispatch function */ - status = call->dce->dispatch[opnum](call->dce, call->mem_ctx, r); + status = call->conn->iface->dispatch(call, call->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault_nt(call, status); } @@ -453,7 +607,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) push->flags |= LIBNDR_FLAG_BIGENDIAN; } - status = call->dce->ndr->calls[opnum].ndr_push(push, NDR_OUT, r); + status = call->conn->iface->ndr->calls[opnum].ndr_push(push, NDR_OUT, r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, DCERPC_FAULT_NDR); } @@ -471,9 +625,9 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } length = stub.length; - if (length + DCERPC_RESPONSE_LENGTH > call->dce->cli_max_recv_frag) { + if (length + DCERPC_RESPONSE_LENGTH > call->conn->cli_max_recv_frag) { /* the 32 is to cope with signing data */ - length = call->dce->cli_max_recv_frag - + length = call->conn->cli_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_RESPONSE_LENGTH); } @@ -507,7 +661,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) stub.length -= length; } while (stub.length != 0); - DLIST_ADD_END(call->dce->call_list, call, struct dcesrv_call_state *); + DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; } @@ -530,18 +684,18 @@ static BOOL dce_full_packet(const DATA_BLOB *data) /* we might have consumed only part of our input - advance past that part */ -static void dce_partial_advance(struct dcesrv_state *dce, uint32 offset) +static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32 offset) { DATA_BLOB blob; - if (dce->partial_input.length == offset) { - free(dce->partial_input.data); - dce->partial_input = data_blob(NULL, 0); + if (dce_conn->partial_input.length == offset) { + free(dce_conn->partial_input.data); + dce_conn->partial_input = data_blob(NULL, 0); return; } - blob = dce->partial_input; - dce->partial_input = data_blob(blob.data + offset, + blob = dce_conn->partial_input; + dce_conn->partial_input = data_blob(blob.data + offset, blob.length - offset); free(blob.data); } @@ -549,7 +703,7 @@ static void dce_partial_advance(struct dcesrv_state *dce, uint32 offset) /* process some input to a dcerpc endpoint server. */ -NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) +NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) { struct ndr_pull *ndr; TALLOC_CTX *mem_ctx; @@ -563,20 +717,20 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) } call = talloc_p(mem_ctx, struct dcesrv_call_state); if (!call) { - talloc_free(dce->mem_ctx, dce->partial_input.data); + talloc_free(dce_conn->mem_ctx, dce_conn->partial_input.data); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } call->mem_ctx = mem_ctx; - call->dce = dce; + call->conn = dce_conn; call->replies = NULL; - blob = dce->partial_input; + blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); ndr = ndr_pull_init_blob(&blob, mem_ctx); if (!ndr) { - talloc_free(dce->mem_ctx, dce->partial_input.data); + talloc_free(dce_conn->mem_ctx, dce_conn->partial_input.data); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -587,12 +741,12 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { - talloc_free(dce->mem_ctx, dce->partial_input.data); + talloc_free(dce_conn->mem_ctx, dce_conn->partial_input.data); talloc_destroy(mem_ctx); return status; } - dce_partial_advance(dce, blob.length); + dce_partial_advance(dce_conn, blob.length); /* we have to check the signing here, before combining the pdus */ @@ -613,7 +767,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) /* this is a continuation of an existing call - find the call then tack it on the end */ - call = dcesrv_find_call(dce, call2->pkt.call_id); + call = dcesrv_find_call(dce_conn, call2->pkt.call_id); if (!call) { return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } @@ -648,7 +802,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) /* this may not be the last pdu in the chain - if its isn't then just put it on the call_list and wait for the rest */ if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { - DLIST_ADD_END(dce->call_list, call, struct dcesrv_call_state *); + DLIST_ADD_END(dce_conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; } @@ -682,21 +836,21 @@ NTSTATUS dcesrv_input_process(struct dcesrv_state *dce) provide some input to a dcerpc endpoint server. This passes data from a dcerpc client into the server */ -NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) +NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; - dce->partial_input.data = Realloc(dce->partial_input.data, - dce->partial_input.length + data->length); - if (!dce->partial_input.data) { + dce_conn->partial_input.data = Realloc(dce_conn->partial_input.data, + dce_conn->partial_input.length + data->length); + if (!dce_conn->partial_input.data) { return NT_STATUS_NO_MEMORY; } - memcpy(dce->partial_input.data + dce->partial_input.length, + memcpy(dce_conn->partial_input.data + dce_conn->partial_input.length, data->data, data->length); - dce->partial_input.length += data->length; + dce_conn->partial_input.length += data->length; - while (dce_full_packet(&dce->partial_input)) { - status = dcesrv_input_process(dce); + while (dce_full_packet(&dce_conn->partial_input)) { + status = dcesrv_input_process(dce_conn); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -710,12 +864,12 @@ NTSTATUS dcesrv_input(struct dcesrv_state *dce, const DATA_BLOB *data) is wanted is in data->length and data->data is already allocated to hold that much data. */ -NTSTATUS dcesrv_output(struct dcesrv_state *dce, DATA_BLOB *data) +NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, DATA_BLOB *data) { struct dcesrv_call_state *call; struct dcesrv_call_reply *rep; - call = dce->call_list; + call = dce_conn->call_list; if (!call || !call->replies) { return NT_STATUS_FOOBAR; } @@ -736,88 +890,151 @@ NTSTATUS dcesrv_output(struct dcesrv_state *dce, DATA_BLOB *data) if (call->replies == NULL) { /* we're done with the whole call */ - DLIST_REMOVE(dce->call_list, call); + DLIST_REMOVE(dce_conn->call_list, call); talloc_destroy(call->mem_ctx); } return NT_STATUS_OK; } - /* - a useful function for implementing the query endpoint op - */ -BOOL dcesrv_table_query(const struct dcerpc_interface_table *table, - const struct dcesrv_endpoint *ep) + initialise the dcerpc server context +*/ +NTSTATUS dcesrv_init_context(struct dcesrv_context *dce_ctx) { int i; - const struct dcerpc_endpoint_list *endpoints = table->endpoints; + const char **endpoint_servers = lp_dcerpc_endpoint_servers(); - if (ep->type != ENDPOINT_SMB) { - return False; + dce_ctx->mem_ctx = talloc_init("struct dcesrv_context"); + if (!dce_ctx->mem_ctx) { + DEBUG(3,("dcesrv_init_context: talloc_init failed\n")); + return NT_STATUS_NO_MEMORY; } - for (i=0;icount;i++) { - if (strcasecmp(ep->info.smb_pipe, endpoints->names[i]) == 0) { - return True; + dce_ctx->endpoint_list = NULL; + + if (!endpoint_servers) { + DEBUG(3,("dcesrv_init_context: no endpoint servers configured\n")); + return NT_STATUS_OK; + } + + for (i=0;endpoint_servers[i];i++) { + NTSTATUS ret; + const struct dcesrv_endpoint_server *ep_server; + + ep_server = dcesrv_ep_server_byname(endpoint_servers[i]); + if (!ep_server) { + DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i])); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = ep_server->init_server(dce_ctx, ep_server); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s'\n", endpoint_servers[i])); + return ret; } } - return False; + + return NT_STATUS_OK; } +/* the list of currently registered DCERPC endpoint servers. + */ +static struct { + struct dcesrv_endpoint_server *ep_server; +} *ep_servers = NULL; +static int num_ep_servers; /* - a useful function for implementing the lookup_endpoints op - */ -int dcesrv_lookup_endpoints(const struct dcerpc_interface_table *table, - TALLOC_CTX *mem_ctx, - struct dcesrv_ep_iface **e) + register a DCERPC endpoint server. + + The 'name' can be later used by other backends to find the operations + structure for this backend. + + The 'type' is used to specify whether this is for a disk, printer or IPC$ share +*/ +static NTSTATUS decrpc_register_ep_server(void *_ep_server) { - int i; - *e = talloc_array_p(mem_ctx, struct dcesrv_ep_iface, table->endpoints->count); - if (! *e) { - return -1; - } - - for (i=0;iendpoints->count;i++) { - (*e)[i].name = table->name; - (*e)[i].uuid = table->uuid; - (*e)[i].if_version = table->if_version; - if (strncmp(table->endpoints->names[i], "TCP-", 4) == 0) { - (*e)[i].endpoint.type = ENDPOINT_TCP; - (*e)[i].endpoint.info.tcp_port = atoi(table->endpoints->names[i]+4); - } else { - (*e)[i].endpoint.type = ENDPOINT_SMB; - (*e)[i].endpoint.info.smb_pipe = table->endpoints->names[i]; - } + const struct dcesrv_endpoint_server *ep_server = _ep_server; + + if (dcesrv_ep_server_byname(ep_server->name) != NULL) { + /* its already registered! */ + DEBUG(1,("DCERPC endpoint server '%s' already registered\n", + ep_server->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; } - return i; -} + ep_servers = Realloc(ep_servers, sizeof(ep_servers[0]) * (num_ep_servers+1)); + if (!ep_servers) { + smb_panic("out of memory in decrpc_register"); + } + + ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server)); + ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name); + + num_ep_servers++; + + DEBUG(1,("DCERPC module '%s' registered\n", + ep_server->name)); + return NT_STATUS_OK; +} -BOOL dcesrv_set_interface(struct dcesrv_state *dce, - const char *uuid, uint32 if_version, - const struct dcerpc_interface_table *table, - const dcesrv_dispatch_fn_t *dispatch_table) +/* + return the operations structure for a named backend of the specified type +*/ +const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name) { - if (strcasecmp(table->uuid, uuid) != 0 || if_version != table->if_version) { - DEBUG(2,("Attempt to use unknown interface %s/%d\n", uuid, if_version)); - return False; + int i; + + for (i=0;iname, name) == 0) { + return ep_servers[i].ep_server; + } } - dce->ndr = table; - dce->dispatch = dispatch_table; - return True; + return NULL; } +/* + return the DCERPC module version, and the size of some critical types + This can be used by endpoint server modules to either detect compilation errors, or provide + multiple implementations for different smbd compilation options in one module +*/ +const struct dcesrv_critical_sizes *dcerpc_module_version(void) +{ + static const struct dcesrv_critical_sizes critical_sizes = { + DCERPC_MODULE_VERSION, + sizeof(struct dcesrv_context), + sizeof(struct dcesrv_endpoint), + sizeof(struct dcesrv_endpoint_server), + sizeof(struct dcesrv_ep_description), + sizeof(struct dcesrv_interface), + sizeof(struct dcesrv_if_list), + sizeof(struct dcesrv_connection), + sizeof(struct dcesrv_call_state), + sizeof(struct dcesrv_auth), + sizeof(struct dcesrv_handle) + }; + + return &critical_sizes; +} /* - initialise the dcerpc server subsystem + initialise the DCERPC subsystem */ -BOOL dcesrv_init(struct dcesrv_context *dce) +BOOL dcesrv_init(void) { - rpc_rpcecho_init(dce); - rpc_epmapper_init(dce); + NTSTATUS status; + + status = register_subsystem("dcerpc", decrpc_register_ep_server); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + /* FIXME: Perhaps panic if a basic endpoint server, such as EPMAPER, fails to initialise? */ + static_init_dcerpc; + + DEBUG(1,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); return True; } -- cgit From 4d39861f991254aa381b8823476825e26a4d6da3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Jan 2004 04:32:17 +0000 Subject: avoid a copy of the data being input to the dcerpc server in the most common case of there being no pending partial data and a full dcerpc packet being received. We should use this same model for the smb server. It gives us efficient memory usage while allowing for completely async socket operations. (This used to be commit 9aab321fb6e2f3499efd8ca5bc88ce2cb8e68219) --- source4/rpc_server/dcerpc_server.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 46341e6db1..a4f5fb9768 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -689,15 +689,14 @@ static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32 offse DATA_BLOB blob; if (dce_conn->partial_input.length == offset) { - free(dce_conn->partial_input.data); - dce_conn->partial_input = data_blob(NULL, 0); + data_blob_free(&dce_conn->partial_input); return; } blob = dce_conn->partial_input; dce_conn->partial_input = data_blob(blob.data + offset, - blob.length - offset); - free(blob.data); + blob.length - offset); + data_blob_free(&blob); } /* @@ -840,6 +839,32 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; + /* handle the very common case that the input contains a full packet and there + is no partial packet pending. In this case we can avoid a copy of the + data */ + if (dce_conn->partial_input.length == 0) { + dce_conn->partial_input = *data; + /* make sure that dce_partial_advance doesn't free this data */ + dce_conn->partial_input.free = NULL; + while (dce_full_packet(&dce_conn->partial_input)) { + status = dcesrv_input_process(dce_conn); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + if (dce_conn->partial_input.length) { + /* there was some data left over. We have to copy this + as the caller may free the data */ + dce_conn->partial_input = + data_blob(dce_conn->partial_input.data, + dce_conn->partial_input.length); + if (!dce_conn->partial_input.data) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; + } + dce_conn->partial_input.data = Realloc(dce_conn->partial_input.data, dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { -- cgit From 7a4da9654e30ea96b326448c3e9111c2a5604f58 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Jan 2004 05:54:17 +0000 Subject: dcerpc server output now copes with the client blocking part way through a read. This happens to also avoid a memcpy on output for dcerpc over tcp. (This used to be commit e7c53ad1856e299d82d84b5837189ae3191c32de) --- source4/rpc_server/dcerpc_server.c | 53 +++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 9 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a4f5fb9768..0553537cb5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -885,14 +885,23 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) } /* - retrieve some output from a dcerpc server. The amount of data that - is wanted is in data->length and data->data is already allocated - to hold that much data. + retrieve some output from a dcerpc server + The caller supplies a function that will be called to do the + actual output. + + The first argument to write_fn() will be 'private', the second will + be a pointer to a buffer containing the data to be sent and the 3rd + will be the number of bytes to be sent. + + write_fn() should return the number of bytes successfully written. */ -NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, DATA_BLOB *data) +NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, + void *private, + ssize_t (*write_fn)(void *, const void *, size_t)) { struct dcesrv_call_state *call; struct dcesrv_call_reply *rep; + ssize_t nwritten; call = dce_conn->call_list; if (!call || !call->replies) { @@ -900,13 +909,15 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, DATA_BLOB *data) } rep = call->replies; - if (data->length >= rep->data.length) { - data->length = rep->data.length; + nwritten = write_fn(private, rep->data.data, rep->data.length); + if (nwritten == -1) { + /* TODO: hmm, how do we cope with this? destroy the + connection perhaps? */ + return NT_STATUS_UNSUCCESSFUL; } - memcpy(data->data, rep->data.data, data->length); - rep->data.length -= data->length; - rep->data.data += data->length; + rep->data.length -= nwritten; + rep->data.data += nwritten; if (rep->data.length == 0) { /* we're done with this section of the call */ @@ -922,6 +933,30 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, DATA_BLOB *data) return NT_STATUS_OK; } + +/* + write_fn() for dcesrv_output_blob() +*/ +static ssize_t dcesrv_output_blob_write_fn(void *private, const void *buf, size_t count) +{ + DATA_BLOB *blob = private; + if (count < blob->length) { + blob->length = count; + } + memcpy(blob->data, buf, blob->length); + return blob->length; +} + +/* + a simple wrapper for dcesrv_output() for when we want to output + into a data blob +*/ +NTSTATUS dcesrv_output_blob(struct dcesrv_connection *dce_conn, + DATA_BLOB *blob) +{ + return dcesrv_output(dce_conn, blob, dcesrv_output_blob_write_fn); +} + /* initialise the dcerpc server context */ -- cgit From 894e02f80c254da4edca5dbae99561d205c63fbe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 2 Feb 2004 13:28:29 +0000 Subject: some DEBUG and comment fixes metze (This used to be commit 5ac4f878687eb0fa95a2e5830a8372168a27d3b3) --- source4/rpc_server/dcerpc_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 0553537cb5..a17910e1d5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -233,7 +233,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, DLIST_ADD(dce_ctx->endpoint_list, ep); } - DEBUG(3,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n", + DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n", iface->ndr->name, ep_name)); return NT_STATUS_OK; @@ -1019,7 +1019,7 @@ static NTSTATUS decrpc_register_ep_server(void *_ep_server) if (dcesrv_ep_server_byname(ep_server->name) != NULL) { /* its already registered! */ - DEBUG(1,("DCERPC endpoint server '%s' already registered\n", + DEBUG(0,("DCERPC endpoint server '%s' already registered\n", ep_server->name)); return NT_STATUS_OBJECT_NAME_COLLISION; } @@ -1034,7 +1034,7 @@ static NTSTATUS decrpc_register_ep_server(void *_ep_server) num_ep_servers++; - DEBUG(1,("DCERPC module '%s' registered\n", + DEBUG(3,("DCERPC endpoint server '%s' registered\n", ep_server->name)); return NT_STATUS_OK; @@ -1095,6 +1095,6 @@ BOOL dcesrv_init(void) /* FIXME: Perhaps panic if a basic endpoint server, such as EPMAPER, fails to initialise? */ static_init_dcerpc; - DEBUG(1,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); + DEBUG(3,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); return True; } -- cgit From 1c5de896bc0aa58c4463dca3675b299c2555fddf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Apr 2004 08:07:07 +0000 Subject: r67: added a destroy hook in the policy handle -> wire handle code to allow backends to cleanup handle data (This used to be commit af0c21c1e175ca2ebb687dc6dff83da919280271) --- source4/rpc_server/dcerpc_server.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a17910e1d5..2d448f61de 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -315,9 +315,7 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) /* destroy any handles */ while (p->handles) { - TALLOC_CTX *m = p->handles->mem_ctx; - DLIST_REMOVE(p->handles, p->handles); - talloc_destroy(m); + dcesrv_handle_destroy(p, p->handles); } talloc_destroy(p->mem_ctx); -- cgit From cac54feea80f512bf6b74185025cbe4cdade7702 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 May 2004 10:07:25 +0000 Subject: r445: fixed the bind_nak code (This used to be commit f3799e7720e13e12b59168cf4afbf2dfe87868f7) --- source4/rpc_server/dcerpc_server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 2d448f61de..844df37b0e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -398,7 +398,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) struct dcesrv_call_reply *rep; NTSTATUS status; - /* setup a bind_ack */ + /* setup a bind_nak */ dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; @@ -420,6 +420,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; } @@ -472,6 +473,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) /* handle any authentication that is being requested */ if (!dcesrv_auth_bind(call)) { + /* TODO: work out the right reject code */ return dcesrv_bind_nak(call, 0); } @@ -562,6 +564,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) void *r; NTSTATUS status; DATA_BLOB stub; + uint32 total_length; opnum = call->pkt.u.request.opnum; @@ -612,6 +615,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) stub = ndr_push_blob(push); + total_length = stub.length; + do { uint32 length; struct dcesrv_call_reply *rep; @@ -635,7 +640,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_RESPONSE; pkt.pfc_flags = 0; - if (!call->replies) { + if (stub.length == total_length) { pkt.pfc_flags |= DCERPC_PFC_FLAG_FIRST; } if (length == stub.length) { -- cgit From 21e6b1531b4e656af5962fdbeb671350f653fc26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 May 2004 06:07:52 +0000 Subject: r464: a big improvement to the API for writing server-side RPC servers. Previously the server pipe code needed to return the RPC level status (nearly always "OK") and separately set the function call return using r->out.result. All the programmers writing servers (metze, jelmer and me) were often getting this wrong, by doing things like "return NT_STATUS_NO_MEMORY" which was really quite meaningless as there is no code like that at the dcerpc level. I have now modified pidl to generate the necessary boilerplate so that just returning the status you want from the function will work. So for a NTSTATUS function you return NT_STATUS_XXX and from a WERROR function you return WERR_XXX. If you really want to generate a DCERPC level fault rather than just a return value in your function then you should use the DCESRV_FAULT() macro which will correctly generate a fault for you. As a side effect, this also adds automatic type checking of all of our server side rpc functions, which was impossible with the old API. When I changed the API I found and fixed quite a few functions with the wrong type information, so this is definately useful. I have also changed the server side template generation to generate a DCERPC "operation range error" by default when you have not yet filled in a server side function. This allows us to correctly implement functions in any order in our rpc pipe servers and give the client the right information about the fault. (This used to be commit a4df5c7cf88891a78d82c8d6d7f058d8485e73f0) --- source4/rpc_server/dcerpc_server.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 844df37b0e..463cb4fe39 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -368,27 +368,12 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; } -/* - return a dcerpc fault from a ntstatus code -*/ -static NTSTATUS dcesrv_fault_nt(struct dcesrv_call_state *call, NTSTATUS status) -{ - uint32 fault_code = DCERPC_FAULT_OTHER; - - /* TODO: we need to expand this table to include more mappings */ - if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_HANDLE)) { - fault_code = DCERPC_FAULT_CONTEXT_MISMATCH; - } - - return dcesrv_fault(call, fault_code); -} - - /* return a dcerpc bind_nak */ @@ -592,10 +577,12 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_NDR); } + call->fault_code = 0; + /* call the dispatch function */ status = call->conn->iface->dispatch(call, call->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { - return dcesrv_fault_nt(call, status); + return dcesrv_fault(call, call->fault_code); } /* form the reply NDR */ -- cgit From 0f581e4af943a7e5dfd71d1c308ac668f287aed3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 May 2004 11:23:50 +0000 Subject: r623: setUserInfo level 24 (password set) now works in the SAMR server. This includes all of the password complexity, password history and other password restrictions. (This used to be commit cb070b9084d95cf5178edbef951b75eab62b7220) --- source4/rpc_server/dcerpc_server.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 463cb4fe39..22a6e1e625 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -270,16 +270,25 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->partial_input = data_blob(NULL, 0); (*p)->auth_state.ntlmssp_state = NULL; (*p)->auth_state.auth_info = NULL; + (*p)->session_key = data_blob(NULL, 0); return NT_STATUS_OK; } +/* + set the transport level session key +*/ +void dcesrv_set_session_key(struct dcesrv_connection *p, DATA_BLOB key) +{ + p->session_key = data_blob_talloc(p->mem_ctx, key.data, key.length); +} + /* search and connect to a dcerpc endpoint */ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, - const struct dcesrv_ep_description *ep_description, - struct dcesrv_connection **dce_conn_p) + const struct dcesrv_ep_description *ep_description, + struct dcesrv_connection **dce_conn_p) { NTSTATUS status; const struct dcesrv_endpoint *ep; -- cgit From b5edc0fc05e567fe2ec1a13bd49073f9496db14d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 May 2004 15:39:23 +0000 Subject: r649: return unknown interface when the client not yet binds succesful to an interface metze (This used to be commit c39e450702cfa2b577c64e14ba1428fd95db7ade) --- source4/rpc_server/dcerpc_server.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 22a6e1e625..b89bec40bb 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -560,6 +560,11 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) DATA_BLOB stub; uint32 total_length; + + if (!call->conn->iface) { + return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); + } + opnum = call->pkt.u.request.opnum; if (opnum >= call->conn->iface->ndr->num_calls) { -- cgit From f9d8f8843dc0ab8c9d59abde7222e0f118b86b5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 16:24:13 +0000 Subject: r884: convert samba4 to use [u]int32_t instead of [u]int32 metze (This used to be commit 0e5517d937a2eb7cf707991d1c7498c1ab456095) --- source4/rpc_server/dcerpc_server.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b89bec40bb..350621aa6b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -100,7 +100,7 @@ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoin see if a uuid and if_version match to an interface */ static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, - const char *uuid, uint32 if_version) + const char *uuid, uint32_t if_version) { if (iface->ndr->if_version != if_version) { return False; @@ -117,7 +117,7 @@ static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, find the interface operations on an endpoint by uuid */ static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint, - const char *uuid, uint32 if_version) + const char *uuid, uint32_t if_version) { struct dcesrv_if_list *ifl; for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) { @@ -347,7 +347,7 @@ static void dcesrv_init_hdr(struct dcerpc_packet *pkt) /* return a dcerpc fault */ -static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) +static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) { struct dcerpc_packet pkt; struct dcesrv_call_reply *rep; @@ -386,7 +386,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32 fault_code) /* return a dcerpc bind_nak */ -static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) +static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) { struct dcerpc_packet pkt; struct dcesrv_call_reply *rep; @@ -426,11 +426,11 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32 reason) static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) { const char *uuid, *transfer_syntax; - uint32 if_version, transfer_syntax_version; + uint32_t if_version, transfer_syntax_version; struct dcerpc_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; - uint32 result=0, reason=0; + uint32_t result=0, reason=0; if (call->pkt.u.bind.num_contexts != 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { @@ -558,7 +558,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) void *r; NTSTATUS status; DATA_BLOB stub; - uint32 total_length; + uint32_t total_length; if (!call->conn->iface) { @@ -619,7 +619,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) total_length = stub.length; do { - uint32 length; + uint32_t length; struct dcesrv_call_reply *rep; struct dcerpc_packet pkt; @@ -688,7 +688,7 @@ static BOOL dce_full_packet(const DATA_BLOB *data) /* we might have consumed only part of our input - advance past that part */ -static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32 offset) +static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32_t offset) { DATA_BLOB blob; @@ -761,7 +761,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) /* see if this is a continued packet */ if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; - uint32 alloc_size; + uint32_t alloc_size; /* we only allow fragmented requests, no other packet types */ if (call->pkt.ptype != DCERPC_PKT_REQUEST) { -- cgit From f88bf54c7f6d1c2ef833047eb8327953c304b5ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:24:24 +0000 Subject: r889: convert samba4 to use [u]int16_t instead of [u]int16 metze (This used to be commit af6f1f8a01bebbecd99bc8c066519e89966e65e3) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 350621aa6b..4191c42edc 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -131,7 +131,7 @@ static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv /* find a call that is pending in our call list */ -static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_conn, uint16 call_id) +static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_conn, uint16_t call_id) { struct dcesrv_call_state *c; for (c=dce_conn->call_list;c;c=c->next) { @@ -554,7 +554,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { struct ndr_pull *pull; struct ndr_push *push; - uint16 opnum; + uint16_t opnum; void *r; NTSTATUS status; DATA_BLOB stub; -- cgit From 7a6d86fbc9610d57e7386f969743b8451cae9351 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 May 2004 05:24:32 +0000 Subject: r918: - dcerpc endpoint name are case insensitive this fix allows samba3 to join a samba4 domain using "net rpc join" (This used to be commit 876a6eecc3db99a137b58993ce7cf69f277e7499) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4191c42edc..683be7225b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -35,7 +35,7 @@ static BOOL endpoints_match(const struct dcesrv_ep_description *ep1, switch (ep1->type) { case ENDPOINT_SMB: - if (strcmp(ep1->info.smb_pipe,ep2->info.smb_pipe)==0) { + if (strcasecmp(ep1->info.smb_pipe,ep2->info.smb_pipe)==0) { return True; } break; -- cgit From 8087d844ef59a82617be51f7c887b9bafe362f80 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Jun 2004 23:15:16 +0000 Subject: r995: - renamed many of our crypto routines to use the industry standard names rather than our crazy naming scheme. So DES is now called des_crypt() rather than smbhash() - added the code from the solution of the ADS crypto challenge that allows Samba to correctly handle a 128 bit session key in all of the netr_ServerAuthenticateX() varients. A huge thanks to Luke Howard from PADL for solving this one! - restructured the server side rpc authentication to allow for other than NTLMSSP sign and seal. This commit just adds the structure, the next commit will add schannel server side support. - added 128 bit session key support to our client side code, and testing against w2k3 with smbtorture. Works well. (This used to be commit 729b2f41c924a0b435d44a14209e6dacc2304cee) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 683be7225b..fd806c5289 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -268,7 +268,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->cli_max_recv_frag = 0; (*p)->handles = NULL; (*p)->partial_input = data_blob(NULL, 0); - (*p)->auth_state.ntlmssp_state = NULL; + (*p)->auth_state.crypto_state = NULL; (*p)->auth_state.auth_info = NULL; (*p)->session_key = data_blob(NULL, 0); -- cgit From 5165fec02e0e489ac63c3cb71bed31dea9fde644 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Jun 2004 09:46:46 +0000 Subject: r1004: continue tridge's work on dcerpc server auth/crypto code I made it much more generic, and we should be able to add a module interface to this code, so that other DCERPC_AUTH types can be added via modules... metze (This used to be commit d09abeb686c43c62322205689273d1b417113004) --- source4/rpc_server/dcerpc_server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fd806c5289..2c0db15081 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -268,8 +268,9 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->cli_max_recv_frag = 0; (*p)->handles = NULL; (*p)->partial_input = data_blob(NULL, 0); - (*p)->auth_state.crypto_state = NULL; (*p)->auth_state.auth_info = NULL; + (*p)->auth_state.crypto_ctx.private_data = NULL; + (*p)->auth_state.crypto_ctx.ops = NULL; (*p)->session_key = data_blob(NULL, 0); return NT_STATUS_OK; @@ -326,7 +327,11 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) while (p->handles) { dcesrv_handle_destroy(p, p->handles); } - + + if (p->auth_state.crypto_ctx.ops) { + p->auth_state.crypto_ctx.ops->end(&p->auth_state); + } + talloc_destroy(p->mem_ctx); } -- cgit From f5108651ee95f16128be1b0cfb36c38fac8b5348 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 7 Jun 2004 03:13:38 +0000 Subject: r1057: added rpc packet logging for packets that generate rpc faults. This makes it much easier to develop the IDL for new requests, especially for sealed pipes, where ethereal cannot easily extract the data. (This used to be commit 0cde043592d2d2439cf0cd8bf113545e78be5dfd) --- source4/rpc_server/dcerpc_server.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 2c0db15081..a084477b36 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -552,6 +552,40 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) } +/* + log a rpc packet in a format suitable for ndrdump. This is especially useful + for sealed packets, where ethereal cannot easily see the contents + + this triggers on a debug level of >= 10 +*/ +static void log_rpc_packet(const struct dcesrv_interface *iface, + uint32_t opnum, uint32_t flags, DATA_BLOB *pkt) +{ + const int num_examples = 20; + int i; + + if (DEBUGLEVEL < 10) return; + + for (i=0;indr->name, opnum, i, + (flags&NDR_IN)?"in":"out"); + if (name == NULL) { + return; + } + if (!file_exist(name, NULL)) { + if (file_save(name, pkt->data, pkt->length)) { + DEBUG(10,("Logged rpc packet to %s\n", name)); + } + free(name); + break; + } + free(name); + } +} + + /* handle a dcerpc request packet */ @@ -593,6 +627,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* unravel the NDR for the packet */ status = call->conn->iface->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); if (!NT_STATUS_IS_OK(status)) { + log_rpc_packet(call->conn->iface, opnum, NDR_IN, + &call->pkt.u.request.stub_and_verifier); return dcesrv_fault(call, DCERPC_FAULT_NDR); } @@ -601,6 +637,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* call the dispatch function */ status = call->conn->iface->dispatch(call, call->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { + log_rpc_packet(call->conn->iface, opnum, NDR_IN, + &call->pkt.u.request.stub_and_verifier); return dcesrv_fault(call, call->fault_code); } -- cgit From b717b40235b2433b26b20ced36142c250f9c411e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Jun 2004 21:34:32 +0000 Subject: r1078: the dxesrv_crypto_* implementations should now explicit set the dce_conn->auth_state.session_info ( the ntlmssp one works fine, but the schannel one isn't implemented yet) this is also set by the ntvfs_ipc backend on the endpoint connect. metze (This used to be commit ad3dd1789e9f124493519cb4731d9f5a563fd051) --- source4/rpc_server/dcerpc_server.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a084477b36..20ed50d128 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -271,24 +271,17 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->auth_state.auth_info = NULL; (*p)->auth_state.crypto_ctx.private_data = NULL; (*p)->auth_state.crypto_ctx.ops = NULL; - (*p)->session_key = data_blob(NULL, 0); + (*p)->auth_state.session_info = NULL; return NT_STATUS_OK; } -/* - set the transport level session key -*/ -void dcesrv_set_session_key(struct dcesrv_connection *p, DATA_BLOB key) -{ - p->session_key = data_blob_talloc(p->mem_ctx, key.data, key.length); -} - /* search and connect to a dcerpc endpoint */ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_ep_description *ep_description, + struct auth_session_info *session_info, struct dcesrv_connection **dce_conn_p) { NTSTATUS status; @@ -305,6 +298,8 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return status; } + (*dce_conn_p)->auth_state.session_info = session_info; + /* TODO: check security descriptor of the endpoint here * if it's a smb named pipe * if it's failed free dce_conn_p -- cgit From bccac81d8792f85ae37d4a6617a92e2fae75aa50 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Jun 2004 08:12:50 +0000 Subject: r1136: - added IDL for netr_LogonGetDomainInfo() - added workstation to auth_session_info in rpc servers - added session key fetch hook in crypto backends in dcesrv - store and fetch seed as well as a session key in schannel ldb - when a client uses schannel to setup a netlogon pipe connection we also need to setup the credentials from the schannel negotiation so credentials chaining works - added server side netr_LogonGetDomainInfo() call (This used to be commit a35459387de3b6a422c5af6f658338fc7e4314b0) --- source4/rpc_server/dcerpc_server.c | 42 ++++---------------------------------- 1 file changed, 4 insertions(+), 38 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 20ed50d128..d5d291dab5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -547,40 +547,6 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) } -/* - log a rpc packet in a format suitable for ndrdump. This is especially useful - for sealed packets, where ethereal cannot easily see the contents - - this triggers on a debug level of >= 10 -*/ -static void log_rpc_packet(const struct dcesrv_interface *iface, - uint32_t opnum, uint32_t flags, DATA_BLOB *pkt) -{ - const int num_examples = 20; - int i; - - if (DEBUGLEVEL < 10) return; - - for (i=0;indr->name, opnum, i, - (flags&NDR_IN)?"in":"out"); - if (name == NULL) { - return; - } - if (!file_exist(name, NULL)) { - if (file_save(name, pkt->data, pkt->length)) { - DEBUG(10,("Logged rpc packet to %s\n", name)); - } - free(name); - break; - } - free(name); - } -} - - /* handle a dcerpc request packet */ @@ -622,8 +588,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* unravel the NDR for the packet */ status = call->conn->iface->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); if (!NT_STATUS_IS_OK(status)) { - log_rpc_packet(call->conn->iface, opnum, NDR_IN, - &call->pkt.u.request.stub_and_verifier); + dcerpc_log_packet(call->conn->iface->ndr, opnum, NDR_IN, + &call->pkt.u.request.stub_and_verifier); return dcesrv_fault(call, DCERPC_FAULT_NDR); } @@ -632,8 +598,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* call the dispatch function */ status = call->conn->iface->dispatch(call, call->mem_ctx, r); if (!NT_STATUS_IS_OK(status)) { - log_rpc_packet(call->conn->iface, opnum, NDR_IN, - &call->pkt.u.request.stub_and_verifier); + dcerpc_log_packet(call->conn->iface->ndr, opnum, NDR_IN, + &call->pkt.u.request.stub_and_verifier); return dcesrv_fault(call, call->fault_code); } -- cgit From b00103dac1bf9e559e132c62e768dba9408b94eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Jun 2004 06:49:24 +0000 Subject: r1165: fixed handling of SMBtrans replies that should return STATUS_BUFFER_OVERFLOW when more data is present. (This used to be commit 0e557fe85748558affd20a58455c4b75fee69e27) --- source4/rpc_server/dcerpc_server.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d5d291dab5..b6584f812f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -902,6 +902,9 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) will be the number of bytes to be sent. write_fn() should return the number of bytes successfully written. + + this will return STATUS_BUFFER_OVERFLOW if there is more to be read + from the current fragment */ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, void *private, @@ -910,6 +913,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, struct dcesrv_call_state *call; struct dcesrv_call_reply *rep; ssize_t nwritten; + NTSTATUS status = NT_STATUS_OK; call = dce_conn->call_list; if (!call || !call->replies) { @@ -930,6 +934,8 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (rep->data.length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); + } else { + status = STATUS_BUFFER_OVERFLOW; } if (call->replies == NULL) { @@ -938,7 +944,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, talloc_destroy(call->mem_ctx); } - return NT_STATUS_OK; + return status; } -- cgit From 62aabf5630b57090dfb1ca3d924459c3b44123c9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 20 Jun 2004 10:00:32 +0000 Subject: r1204: decrpc -> dcerpc (This used to be commit a5e3a26fc9a7e2c616302ed3b4a021f5755a4a13) --- source4/rpc_server/dcerpc_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b6584f812f..90ebaf285c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1027,7 +1027,7 @@ static int num_ep_servers; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -static NTSTATUS decrpc_register_ep_server(void *_ep_server) +static NTSTATUS dcerpc_register_ep_server(void *_ep_server) { const struct dcesrv_endpoint_server *ep_server = _ep_server; @@ -1040,7 +1040,7 @@ static NTSTATUS decrpc_register_ep_server(void *_ep_server) ep_servers = Realloc(ep_servers, sizeof(ep_servers[0]) * (num_ep_servers+1)); if (!ep_servers) { - smb_panic("out of memory in decrpc_register"); + smb_panic("out of memory in dcerpc_register"); } ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server)); @@ -1101,7 +1101,7 @@ BOOL dcesrv_init(void) { NTSTATUS status; - status = register_subsystem("dcerpc", decrpc_register_ep_server); + status = register_subsystem("dcerpc", dcerpc_register_ep_server); if (!NT_STATUS_IS_OK(status)) { return False; } -- cgit From dc9f55dbec5f892b39d924d5fd033b5eec1e14e4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 Jun 2004 09:40:10 +0000 Subject: r1294: A nice, large, commit... This implements gensec for Samba's server side, and brings gensec up to the standards of a full subsystem. This means that use of the subsystem is by gensec_* functions, not function pointers in structures (this is internal). This causes changes in all the existing gensec users. Our RPC server no longer contains it's own generalised security scheme, and now calls gensec directly. Gensec has also taken over the role of auth/auth_ntlmssp.c An important part of gensec, is the output of the 'session_info' struct. This is now reference counted, so that we can correctly free it when a pipe is closed, no matter if it was inherited, or created by per-pipe authentication. The schannel code is reworked, to be in the same file for client and server. ntlm_auth is reworked to use gensec. The major problem with this code is the way it relies on subsystem auto-initialisation. The primary reason for this commit now.is to allow these problems to be looked at, and fixed. There are problems with the new code: - I've tested it with smbtorture, but currently don't have VMware and valgrind working (this I'll fix soon). - The SPNEGO code is client-only at this point. - We still do not do kerberos. Andrew Bartlett (This used to be commit 07fd885fd488fd1051eacc905a2d4962f8a018ec) --- source4/rpc_server/dcerpc_server.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 90ebaf285c..e5c4c120a5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -146,9 +146,9 @@ static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_ register an interface on an endpoint */ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, - const char *ep_name, - const struct dcesrv_interface *iface, - const struct security_descriptor *sd) + const char *ep_name, + const struct dcesrv_interface *iface, + const struct security_descriptor *sd) { struct dcesrv_ep_description ep_description; struct dcesrv_endpoint *ep; @@ -269,8 +269,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->handles = NULL; (*p)->partial_input = data_blob(NULL, 0); (*p)->auth_state.auth_info = NULL; - (*p)->auth_state.crypto_ctx.private_data = NULL; - (*p)->auth_state.crypto_ctx.ops = NULL; + (*p)->auth_state.gensec_security = NULL; (*p)->auth_state.session_info = NULL; return NT_STATUS_OK; @@ -298,6 +297,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return status; } + session_info->refcount++; (*dce_conn_p)->auth_state.session_info = session_info; /* TODO: check security descriptor of the endpoint here @@ -323,8 +323,12 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) dcesrv_handle_destroy(p, p->handles); } - if (p->auth_state.crypto_ctx.ops) { - p->auth_state.crypto_ctx.ops->end(&p->auth_state); + if (p->auth_state.gensec_security) { + gensec_end(&p->auth_state.gensec_security); + } + + if (p->auth_state.session_info) { + free_session_info(&p->auth_state.session_info); } talloc_destroy(p->mem_ctx); @@ -1027,7 +1031,7 @@ static int num_ep_servers; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -static NTSTATUS dcerpc_register_ep_server(void *_ep_server) +static NTSTATUS dcerpc_register_ep_server(const void *_ep_server) { const struct dcesrv_endpoint_server *ep_server = _ep_server; -- cgit From 45a85bdd353418828df8017a9d7eb7c14f6f0cd3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Jul 2004 21:04:56 +0000 Subject: r1486: commit the start of the generic server infastructure the idea is to have services as modules (smb, dcerpc, swat, ...) the process_model don't know about the service it self anymore. TODO: - the smbsrv should use the smbsrv_send function - the service subsystem init should be done like for other modules - we need to have a generic socket subsystem, which handle stream, datagram, and virtuell other sockets( e.g. for the ntvfs_ipc module to connect to the dcerpc server , or for smb or dcerpc or whatever to connect to a server wide auth service) - and other fixes... NOTE: process model pthread seems to be broken( but also before this patch!) metze (This used to be commit bbe5e00715ca4013ff0dbc345aa97adc6b5c2458) --- source4/rpc_server/dcerpc_server.c | 105 ++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e5c4c120a5..34756349c6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -271,6 +271,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->auth_state.auth_info = NULL; (*p)->auth_state.gensec_security = NULL; (*p)->auth_state.session_info = NULL; + (*p)->srv_conn = NULL; return NT_STATUS_OK; } @@ -1016,6 +1017,87 @@ NTSTATUS dcesrv_init_context(struct dcesrv_context *dce_ctx) return NT_STATUS_OK; } +static void dcesrv_init(struct server_service *service, const struct model_ops *model_ops) +{ + TALLOC_CTX *mem_ctx; + struct dcesrv_context *dce_ctx; + int i; + const char **endpoint_servers = lp_dcerpc_endpoint_servers(); + + DEBUG(0,("dcesrv_init\n")); + + + if (!endpoint_servers) { + DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n")); + return; + } + + mem_ctx = talloc_init("struct dcesrv_context"); + + dce_ctx = talloc_p(mem_ctx, struct dcesrv_context); + if (!dce_ctx) { + DEBUG(0,("talloc_p(mem_ctx, struct dcesrv_context) failed\n")); + return; + } + + ZERO_STRUCTP(dce_ctx); + dce_ctx->mem_ctx = mem_ctx; + dce_ctx->endpoint_list = NULL; + + for (i=0;endpoint_servers[i];i++) { + NTSTATUS ret; + const struct dcesrv_endpoint_server *ep_server; + + ep_server = dcesrv_ep_server_byname(endpoint_servers[i]); + if (!ep_server) { + DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i])); + return; + } + + ret = ep_server->init_server(dce_ctx, ep_server); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s'\n", endpoint_servers[i])); + return; + } + } + + dcesrv_tcp_init(service, model_ops, dce_ctx); + + return; +} + +static void dcesrv_accept(struct server_connection *srv_conn) +{ + dcesrv_tcp_accept(srv_conn); +} + +static void dcesrv_recv(struct server_connection *srv_conn, time_t t, uint16_t flags) +{ + dcesrv_tcp_recv(srv_conn, t, flags); +} + +static void dcesrv_send(struct server_connection *srv_conn, time_t t, uint16_t flags) +{ + dcesrv_tcp_send(srv_conn, t, flags); +} + +static void dcesrv_idle(struct server_connection *srv_conn, time_t t) +{ + dcesrv_tcp_idle(srv_conn, t); +} + +static void dcesrv_close(struct server_connection *srv_conn, const char *reason) +{ + dcesrv_tcp_close(srv_conn, reason); + return; +} + +static void dcesrv_exit(struct server_service *service, const char *reason) +{ + dcesrv_tcp_exit(service, reason); + return; +} + /* the list of currently registered DCERPC endpoint servers. */ static struct { @@ -1101,7 +1183,7 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) /* initialise the DCERPC subsystem */ -BOOL dcesrv_init(void) +BOOL subsystem_dcerpc_init(void) { NTSTATUS status; @@ -1116,3 +1198,24 @@ BOOL dcesrv_init(void) DEBUG(3,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); return True; } + +static const struct server_service_ops dcesrv_ops = { + .name = "rpc", + .service_init = dcesrv_init, + .accept_connection = dcesrv_accept, + .recv_handler = dcesrv_recv, + .send_handler = dcesrv_send, + .idle_handler = dcesrv_idle, + .close_connection = dcesrv_close, + .service_exit = dcesrv_exit, +}; + +const struct server_service_ops *dcesrv_get_ops(void) +{ + return &dcesrv_ops; +} + +NTSTATUS server_service_rpc_init(void) +{ + return NT_STATUS_OK; +} -- cgit From 3d4879fdc9c88ddde7b4ae2f7347f8fd1853971a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 15 Jul 2004 08:26:41 +0000 Subject: r1513: change DEBUG level to 1 metze (This used to be commit d7dd5347dd9414cfa604eeb24cb2f6dc5f99e703) --- source4/rpc_server/dcerpc_server.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 34756349c6..b04591cf3b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1024,8 +1024,7 @@ static void dcesrv_init(struct server_service *service, const struct model_ops * int i; const char **endpoint_servers = lp_dcerpc_endpoint_servers(); - DEBUG(0,("dcesrv_init\n")); - + DEBUG(1,("dcesrv_init\n")); if (!endpoint_servers) { DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n")); -- cgit From e2357c67f5afbfeacafab6997b57ea262cd3c05a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Aug 2004 05:15:41 +0000 Subject: r1757: much simpler (and smaller, faster etc) way of doing relative pointers in pidl. This mechanism should be much easier to extend to the "retrospective subcontexts" that jelmer needs. also produced more standards complient full-pointer offsets. This keeps ethereal happy with decoding our epmapper frames. (This used to be commit ecb7378bbcd86727aedfa04a9e302e06b0a2ccd9) --- source4/rpc_server/dcerpc_server.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b04591cf3b..000dc27fad 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -614,6 +614,11 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } + /* carry over the pointer count to the reply in case we are + using full pointer. See NDR specification for full + pointers */ + push->ptr_count = pull->ptr_count; + if (lp_rpc_big_endian()) { push->flags |= LIBNDR_FLAG_BIGENDIAN; } -- cgit From b1be11a13b94fd8b3f12c25588973d4782382a6b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Aug 2004 07:45:42 +0000 Subject: r1843: return DCERPC_FAULT_LOGON_FAILURE when the auth fails metze (This used to be commit a6ce6ee878c896cfc256989894fd2b35707e3da0) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 000dc27fad..f83916f3c9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -769,7 +769,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) pdus */ if (call->pkt.ptype == DCERPC_PKT_REQUEST && !dcesrv_auth_request(call)) { - return dcesrv_fault(call, DCERPC_FAULT_OTHER); + return dcesrv_fault(call, DCERPC_FAULT_LOGON_FAILURE); } /* see if this is a continued packet */ -- cgit From b83ba93eaeb2dcb0bf11615591d886fda84e4162 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 01:54:46 +0000 Subject: r1983: a completely new implementation of talloc This version does the following: 1) talloc_free(), talloc_realloc() and talloc_steal() lose their (redundent) first arguments 2) you can use _any_ talloc pointer as a talloc context to allocate more memory. This allows you to create complex data structures where the top level structure is the logical parent of the next level down, and those are the parents of the level below that. Then destroy either the lot with a single talloc_free() or destroy any sub-part with a talloc_free() of that part 3) you can name any pointer. Use talloc_named() which is just like talloc() but takes the printf style name argument as well as the parent context and the size. The whole thing ends up being a very simple piece of code, although some of the pointer walking gets hairy. So far, I'm just using the new talloc() like the old one. The next step is to actually take advantage of the new interface properly. Expect some new commits soon that simplify some common coding styles in samba4 by using the new talloc(). (This used to be commit e35bb094c52e550b3105dd1638d8d90de71d854f) --- source4/rpc_server/dcerpc_server.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f83916f3c9..ab61ba3911 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -734,7 +734,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) } call = talloc_p(mem_ctx, struct dcesrv_call_state); if (!call) { - talloc_free(dce_conn->mem_ctx, dce_conn->partial_input.data); + talloc_free(dce_conn->partial_input.data); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -747,7 +747,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) ndr = ndr_pull_init_blob(&blob, mem_ctx); if (!ndr) { - talloc_free(dce_conn->mem_ctx, dce_conn->partial_input.data); + talloc_free(dce_conn->partial_input.data); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -758,7 +758,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { - talloc_free(dce_conn->mem_ctx, dce_conn->partial_input.data); + talloc_free(dce_conn->partial_input.data); talloc_destroy(mem_ctx); return status; } @@ -801,8 +801,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) } call->pkt.u.request.stub_and_verifier.data = - talloc_realloc(call->mem_ctx, - call->pkt.u.request.stub_and_verifier.data, alloc_size); + talloc_realloc(call->pkt.u.request.stub_and_verifier.data, alloc_size); if (!call->pkt.u.request.stub_and_verifier.data) { return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } -- cgit From aca6a1e1ee46fea49a5290613347d2f1d4b235c8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 23 Aug 2004 05:51:38 +0000 Subject: r1993: Allow WinXP domain logon to progress a bit further (it seems broken for me). Fix indent, and add a few more useful debug messages. Send a fault, if the bind is not accepted - don't just leave the client hanging. Andrew Bartlett (This used to be commit 486215edc1148ad754632be37760dc0d38b0340d) --- source4/rpc_server/dcerpc_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ab61ba3911..c243d7e4f9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -100,7 +100,7 @@ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoin see if a uuid and if_version match to an interface */ static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, - const char *uuid, uint32_t if_version) + const char *uuid, uint32_t if_version) { if (iface->ndr->if_version != if_version) { return False; @@ -117,7 +117,7 @@ static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, find the interface operations on an endpoint by uuid */ static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint, - const char *uuid, uint32_t if_version) + const char *uuid, uint32_t if_version) { struct dcesrv_if_list *ifl; for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) { @@ -509,8 +509,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) if (call->conn->iface) { status = call->conn->iface->bind(call, call->conn->iface); if (!NT_STATUS_IS_OK(status)) { - DEBUG(2,("Request for dcerpc interface %s/%d rejected\n", uuid, if_version)); - return status; + DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n", uuid, if_version, nt_errstr(status))); + return dcesrv_bind_nak(call, 0); } } -- cgit From 2ed3ab021deb8e091a6a1a077010824f31b6d5bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2004 02:06:08 +0000 Subject: r2038: get rid of the optimisation in the dcerpc server that tries to avoid a data copy by playing internal games with DATA_BLOB and free(). (This used to be commit 5894b5c0f32f75734151c6c915b296204b7825ac) --- source4/rpc_server/dcerpc_server.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c243d7e4f9..f7c4689590 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -856,32 +856,6 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; - /* handle the very common case that the input contains a full packet and there - is no partial packet pending. In this case we can avoid a copy of the - data */ - if (dce_conn->partial_input.length == 0) { - dce_conn->partial_input = *data; - /* make sure that dce_partial_advance doesn't free this data */ - dce_conn->partial_input.free = NULL; - while (dce_full_packet(&dce_conn->partial_input)) { - status = dcesrv_input_process(dce_conn); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - } - if (dce_conn->partial_input.length) { - /* there was some data left over. We have to copy this - as the caller may free the data */ - dce_conn->partial_input = - data_blob(dce_conn->partial_input.data, - dce_conn->partial_input.length); - if (!dce_conn->partial_input.data) { - return NT_STATUS_NO_MEMORY; - } - } - return NT_STATUS_OK; - } - dce_conn->partial_input.data = Realloc(dce_conn->partial_input.data, dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { -- cgit From 294f6f16947c56d3fac5b24e5c95e8df522e18d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 25 Aug 2004 06:42:08 +0000 Subject: r2050: fixed a case where code assumed you could Realloc the result of a data_blob() (This used to be commit 1fdccf8dc79ea19a37be7fb047130a7c8e2407e5) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f7c4689590..5cadeb254f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -856,8 +856,8 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; - dce_conn->partial_input.data = Realloc(dce_conn->partial_input.data, - dce_conn->partial_input.length + data->length); + dce_conn->partial_input.data = talloc_realloc(dce_conn->partial_input.data, + dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { return NT_STATUS_NO_MEMORY; } -- cgit From 8293df91bcec574fb4a2b290cc11dd83353264ae Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 8 Sep 2004 00:00:56 +0000 Subject: r2247: talloc_destroy -> talloc_free (This used to be commit 6c1a72c5d667245b1eec94f58e68acd22dd720ce) --- source4/rpc_server/dcerpc_server.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5cadeb254f..891462214c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -255,7 +255,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, *p = talloc_p(mem_ctx, struct dcesrv_connection); if (! *p) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -332,7 +332,7 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) free_session_info(&p->auth_state.session_info); } - talloc_destroy(p->mem_ctx); + talloc_free(p->mem_ctx); } static void dcesrv_init_hdr(struct dcerpc_packet *pkt) @@ -544,7 +544,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_OTHER); } - talloc_destroy(call->mem_ctx); + talloc_free(call->mem_ctx); /* we don't send a reply to a auth3 request, except by a fault */ @@ -735,7 +735,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) call = talloc_p(mem_ctx, struct dcesrv_call_state); if (!call) { talloc_free(dce_conn->partial_input.data); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } call->mem_ctx = mem_ctx; @@ -748,7 +748,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) ndr = ndr_pull_init_blob(&blob, mem_ctx); if (!ndr) { talloc_free(dce_conn->partial_input.data); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -759,7 +759,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { talloc_free(dce_conn->partial_input.data); - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); return status; } @@ -841,7 +841,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) it to the list of pending calls. We add it to the end to keep the call list in the order we will answer */ if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); + talloc_free(mem_ctx); } return status; @@ -924,7 +924,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (call->replies == NULL) { /* we're done with the whole call */ DLIST_REMOVE(dce_conn->call_list, call); - talloc_destroy(call->mem_ctx); + talloc_free(call->mem_ctx); } return status; -- cgit From fa419c925524d05ef220c6442759961d28fb5771 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Sep 2004 12:32:05 +0000 Subject: r2280: fixed the session key choice for ncacn_np and ncacn_ip_tcp in the rpc server (This used to be commit 3b4ed24f4ba467a77bef8d6c25695fdbdb42b2ac) --- source4/rpc_server/dcerpc_server.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 891462214c..ba8d2bd835 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -300,6 +300,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, session_info->refcount++; (*dce_conn_p)->auth_state.session_info = session_info; + (*dce_conn_p)->transport_session_key = session_info->session_key; /* TODO: check security descriptor of the endpoint here * if it's a smb named pipe @@ -763,15 +764,16 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) return status; } - dce_partial_advance(dce_conn, blob.length); - /* we have to check the signing here, before combining the pdus */ if (call->pkt.ptype == DCERPC_PKT_REQUEST && - !dcesrv_auth_request(call)) { + !dcesrv_auth_request(call, &blob)) { + dce_partial_advance(dce_conn, blob.length); return dcesrv_fault(call, DCERPC_FAULT_LOGON_FAILURE); } + dce_partial_advance(dce_conn, blob.length); + /* see if this is a continued packet */ if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; -- cgit From 15a96c42985c9bb4778a16160290220a935d99bd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 12 Sep 2004 03:18:24 +0000 Subject: r2290: Fix 'lsakey' for the server-side, it is static for 'authenticated' connections. Fix kerberos session key issues - we need to call the routine for extracting the session key, not just read the cache. Andrew Bartlett (This used to be commit b80d849b6b586869fc7d3d4153db1a316f2867a9) --- source4/rpc_server/dcerpc_server.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ba8d2bd835..4c460d377a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -239,6 +239,35 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, return NT_STATUS_OK; } +static NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, + DATA_BLOB *session_key) +{ + if (p->auth_state.session_info->session_key.length) { + *session_key = p->auth_state.session_info->session_key; + return NT_STATUS_OK; + } + return NT_STATUS_NO_USER_SESSION_KEY; +} + +NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, + DATA_BLOB *session_key) +{ + /* this took quite a few CPU cycles to find ... */ + session_key->data = "SystemLibraryDTC"; + session_key->length = 16; + return NT_STATUS_OK; +} + +/* + fetch the user session key - may be default (above) or the SMB session key +*/ +NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, + DATA_BLOB *session_key) +{ + return p->auth_state.session_key(p, session_key); +} + + /* connect to a dcerpc endpoint */ @@ -271,6 +300,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->auth_state.auth_info = NULL; (*p)->auth_state.gensec_security = NULL; (*p)->auth_state.session_info = NULL; + (*p)->auth_state.session_key = dcesrv_generic_session_key; (*p)->srv_conn = NULL; return NT_STATUS_OK; @@ -300,7 +330,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, session_info->refcount++; (*dce_conn_p)->auth_state.session_info = session_info; - (*dce_conn_p)->transport_session_key = session_info->session_key; + (*dce_conn_p)->auth_state.session_key = dcesrv_inherited_session_key; /* TODO: check security descriptor of the endpoint here * if it's a smb named pipe -- cgit From 2d5ca36872d10138ac997a0d91916abb9b637c6e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Sep 2004 01:23:09 +0000 Subject: r2301: add a server side warning when we receive more RPC data than we expect. It isn't an error as w2k3 does this on its first packet when NTLM2 signing is used. (This used to be commit daaee86d1441afec9915e5f2ffc10b200a1ff564) --- source4/rpc_server/dcerpc_server.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4c460d377a..e619053f6a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -629,6 +629,12 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_NDR); } + if (pull->offset != pull->data_size) { + DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n", + pull->data_size - pull->offset)); + dump_data(10, pull->data+pull->offset, pull->data_size - pull->offset); + } + call->fault_code = 0; /* call the dispatch function */ -- cgit From 7d06a06584e5163b69f712e38dc46afc2668389c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Sep 2004 12:31:07 +0000 Subject: r2447: let the server code use the new lib/socket/ stuff metze (This used to be commit 2fd577d2417e117a7e8c1a56feb147eae805df34) --- source4/rpc_server/dcerpc_server.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e619053f6a..14b7c14d2a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -929,7 +929,7 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) */ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, void *private, - ssize_t (*write_fn)(void *, const void *, size_t)) + ssize_t (*write_fn)(void *, DATA_BLOB *)) { struct dcesrv_call_state *call; struct dcesrv_call_reply *rep; @@ -942,7 +942,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, } rep = call->replies; - nwritten = write_fn(private, rep->data.data, rep->data.length); + nwritten = write_fn(private, &rep->data); if (nwritten == -1) { /* TODO: hmm, how do we cope with this? destroy the connection perhaps? */ @@ -972,13 +972,13 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, /* write_fn() for dcesrv_output_blob() */ -static ssize_t dcesrv_output_blob_write_fn(void *private, const void *buf, size_t count) +static ssize_t dcesrv_output_blob_write_fn(void *private, DATA_BLOB *out) { DATA_BLOB *blob = private; - if (count < blob->length) { - blob->length = count; + if (out->length < blob->length) { + blob->length = out->length; } - memcpy(blob->data, buf, blob->length); + memcpy(blob->data, out->data, blob->length); return blob->length; } -- cgit From d79c7d41da373dea7f95506c178b18f0dd896043 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 11:24:10 +0000 Subject: r2627: use the new talloc capabilities in a bunch more places in the rpc server code. This fixes a number of memory leaks I found when testing with valgrind and smbtorture, as the cascading effect of a talloc_free() ensures that anything derived from the top level object is destroyed on disconnect. (This used to be commit 76d0b8206ce64d6ff4a192979c43dddbec726d6e) --- source4/rpc_server/dcerpc_server.c | 93 +++++++++++++++----------------------- 1 file changed, 37 insertions(+), 56 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 14b7c14d2a..22e677acd8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -27,7 +27,7 @@ see if two endpoints match */ static BOOL endpoints_match(const struct dcesrv_ep_description *ep1, - const struct dcesrv_ep_description *ep2) + const struct dcesrv_ep_description *ep2) { if (ep1->type != ep2->type) { return False; @@ -53,7 +53,7 @@ static BOOL endpoints_match(const struct dcesrv_ep_description *ep1, find an endpoint in the dcesrv_context */ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, - const struct dcesrv_ep_description *ep_description) + const struct dcesrv_ep_description *ep_description) { struct dcesrv_endpoint *ep; for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) { @@ -169,7 +169,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* check if this endpoint exists */ if ((ep=find_endpoint(dce_ctx, &ep_description))==NULL) { - ep = talloc(dce_ctx->mem_ctx, sizeof(*ep)); + ep = talloc_p(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } @@ -192,7 +192,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } /* talloc a new interface list element */ - ifl = talloc(dce_ctx->mem_ctx, sizeof(*ifl)); + ifl = talloc_p(dce_ctx, struct dcesrv_if_list); if (!ifl) { return NT_STATUS_NO_MEMORY; } @@ -208,7 +208,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, * we try to set it */ if (ep->sd == NULL) { - ep->sd = copy_security_descriptor(dce_ctx->mem_ctx, sd); + ep->sd = copy_security_descriptor(dce_ctx, sd); } /* if now there's no security descriptor given on the endpoint @@ -275,21 +275,12 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint *ep, struct dcesrv_connection **p) { - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("dcesrv_endpoint_connect"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - *p = talloc_p(mem_ctx, struct dcesrv_connection); + *p = talloc_p(dce_ctx, struct dcesrv_connection); if (! *p) { - talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } (*p)->dce_ctx = dce_ctx; - (*p)->mem_ctx = mem_ctx; (*p)->endpoint = ep; (*p)->iface = NULL; (*p)->private = NULL; @@ -363,7 +354,7 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) free_session_info(&p->auth_state.session_info); } - talloc_free(p->mem_ctx); + talloc_free(p); } static void dcesrv_init_hdr(struct dcerpc_packet *pkt) @@ -400,12 +391,12 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); + rep = talloc_p(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); + status = dcerpc_push_auth(&rep->data, call, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -437,12 +428,12 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.reject_reason = reason; pkt.u.bind_nak.num_versions = 0; - rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); + rep = talloc_p(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, NULL); + status = dcerpc_push_auth(&rep->data, call, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -474,13 +465,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; - uuid = GUID_string(call->mem_ctx, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); + uuid = GUID_string(call, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); if (!uuid) { return dcesrv_bind_nak(call, 0); } transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version; - transfer_syntax = GUID_string(call->mem_ctx, + transfer_syntax = GUID_string(call, &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid); if (!transfer_syntax || strcasecmp(NDR_GUID, transfer_syntax) != 0 || @@ -517,13 +508,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_recv_frag = 0x2000; pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; if (call->conn->iface && call->conn->iface->ndr) { - pkt.u.bind_ack.secondary_address = talloc_asprintf(call->mem_ctx, "\\PIPE\\%s", + pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", call->conn->iface->ndr->name); } else { pkt.u.bind_ack.secondary_address = ""; } pkt.u.bind_ack.num_results = 1; - pkt.u.bind_ack.ctx_list = talloc_p(call->mem_ctx, struct dcerpc_ack_ctx); + pkt.u.bind_ack.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); if (!pkt.u.bind_ack.ctx_list) { return NT_STATUS_NO_MEMORY; } @@ -545,12 +536,12 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } } - rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); + rep = talloc_p(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call->mem_ctx, &pkt, + status = dcerpc_push_auth(&rep->data, call, &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; @@ -575,7 +566,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_OTHER); } - talloc_free(call->mem_ctx); + talloc_free(call); /* we don't send a reply to a auth3 request, except by a fault */ @@ -607,12 +598,12 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_OP_RNG_ERROR); } - pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call->mem_ctx); + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); if (!pull) { return NT_STATUS_NO_MEMORY; } - r = talloc(call->mem_ctx, call->conn->iface->ndr->calls[opnum].struct_size); + r = talloc(call, call->conn->iface->ndr->calls[opnum].struct_size); if (!r) { return NT_STATUS_NO_MEMORY; } @@ -638,7 +629,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) call->fault_code = 0; /* call the dispatch function */ - status = call->conn->iface->dispatch(call, call->mem_ctx, r); + status = call->conn->iface->dispatch(call, call, r); if (!NT_STATUS_IS_OK(status)) { dcerpc_log_packet(call->conn->iface->ndr, opnum, NDR_IN, &call->pkt.u.request.stub_and_verifier); @@ -646,7 +637,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* form the reply NDR */ - push = ndr_push_init_ctx(call->mem_ctx); + push = ndr_push_init_ctx(call); if (!push) { return NT_STATUS_NO_MEMORY; } @@ -674,7 +665,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct dcesrv_call_reply *rep; struct dcerpc_packet pkt; - rep = talloc_p(call->mem_ctx, struct dcesrv_call_reply); + rep = talloc_p(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -760,32 +751,25 @@ static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32_t off NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) { struct ndr_pull *ndr; - TALLOC_CTX *mem_ctx; NTSTATUS status; struct dcesrv_call_state *call; DATA_BLOB blob; - mem_ctx = talloc_init("dcesrv_input"); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - call = talloc_p(mem_ctx, struct dcesrv_call_state); + call = talloc_p(dce_conn, struct dcesrv_call_state); if (!call) { talloc_free(dce_conn->partial_input.data); - talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; } - call->mem_ctx = mem_ctx; call->conn = dce_conn; call->replies = NULL; blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); - ndr = ndr_pull_init_blob(&blob, mem_ctx); + ndr = ndr_pull_init_blob(&blob, call); if (!ndr) { talloc_free(dce_conn->partial_input.data); - talloc_free(mem_ctx); + talloc_free(call); return NT_STATUS_NO_MEMORY; } @@ -796,7 +780,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { talloc_free(dce_conn->partial_input.data); - talloc_free(mem_ctx); + talloc_free(call); return status; } @@ -879,7 +863,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) it to the list of pending calls. We add it to the end to keep the call list in the order we will answer */ if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); + talloc_free(call); } return status; @@ -962,7 +946,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (call->replies == NULL) { /* we're done with the whole call */ DLIST_REMOVE(dce_conn->call_list, call); - talloc_free(call->mem_ctx); + talloc_free(call); } return status; @@ -995,18 +979,18 @@ NTSTATUS dcesrv_output_blob(struct dcesrv_connection *dce_conn, /* initialise the dcerpc server context */ -NTSTATUS dcesrv_init_context(struct dcesrv_context *dce_ctx) +NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **dce_ctx) { int i; const char **endpoint_servers = lp_dcerpc_endpoint_servers(); - dce_ctx->mem_ctx = talloc_init("struct dcesrv_context"); - if (!dce_ctx->mem_ctx) { - DEBUG(3,("dcesrv_init_context: talloc_init failed\n")); + (*dce_ctx) = talloc_p(mem_ctx, struct dcesrv_context); + if (! *dce_ctx) { return NT_STATUS_NO_MEMORY; } + talloc_set_name(*dce_ctx, "struct dcesrv_context"); - dce_ctx->endpoint_list = NULL; + (*dce_ctx)->endpoint_list = NULL; if (!endpoint_servers) { DEBUG(3,("dcesrv_init_context: no endpoint servers configured\n")); @@ -1023,7 +1007,7 @@ NTSTATUS dcesrv_init_context(struct dcesrv_context *dce_ctx) return NT_STATUS_UNSUCCESSFUL; } - ret = ep_server->init_server(dce_ctx, ep_server); + ret = ep_server->init_server(*dce_ctx, ep_server); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s'\n", endpoint_servers[i])); return ret; @@ -1035,7 +1019,6 @@ NTSTATUS dcesrv_init_context(struct dcesrv_context *dce_ctx) static void dcesrv_init(struct server_service *service, const struct model_ops *model_ops) { - TALLOC_CTX *mem_ctx; struct dcesrv_context *dce_ctx; int i; const char **endpoint_servers = lp_dcerpc_endpoint_servers(); @@ -1047,16 +1030,14 @@ static void dcesrv_init(struct server_service *service, const struct model_ops * return; } - mem_ctx = talloc_init("struct dcesrv_context"); - - dce_ctx = talloc_p(mem_ctx, struct dcesrv_context); + dce_ctx = talloc_p(NULL, struct dcesrv_context); if (!dce_ctx) { DEBUG(0,("talloc_p(mem_ctx, struct dcesrv_context) failed\n")); return; } + talloc_set_name(dce_ctx, "dcesrv_init"); ZERO_STRUCTP(dce_ctx); - dce_ctx->mem_ctx = mem_ctx; dce_ctx->endpoint_list = NULL; for (i=0;endpoint_servers[i];i++) { -- cgit From 764eddb69647681f784f343a122251ca1ecf62df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 03:05:04 +0000 Subject: r2646: - use a talloc destructor to ensure that sockets from the new socket library are closed on abnormal termination - convert the service.h structures to the new talloc methods (This used to be commit 2dc334a3284858eb1c7190f9687c9b6c879ecc9d) --- source4/rpc_server/dcerpc_server.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 22e677acd8..17e629d81e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -988,7 +988,6 @@ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **dce_ct if (! *dce_ctx) { return NT_STATUS_NO_MEMORY; } - talloc_set_name(*dce_ctx, "struct dcesrv_context"); (*dce_ctx)->endpoint_list = NULL; @@ -1030,12 +1029,11 @@ static void dcesrv_init(struct server_service *service, const struct model_ops * return; } - dce_ctx = talloc_p(NULL, struct dcesrv_context); + dce_ctx = talloc_p(service, struct dcesrv_context); if (!dce_ctx) { DEBUG(0,("talloc_p(mem_ctx, struct dcesrv_context) failed\n")); return; } - talloc_set_name(dce_ctx, "dcesrv_init"); ZERO_STRUCTP(dce_ctx); dce_ctx->endpoint_list = NULL; -- cgit From e3880fa759cfa03222262327854fe7bbe585fe01 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 11:30:20 +0000 Subject: r2660: - converted the libcli/raw/ library to use talloc_increase_ref_count() rather than manual reference counts - properly support SMBexit in the cifs and posix backends - added a logoff method to all backends With these changes the RAW-CONTEXT test now passes against the posix backend (This used to be commit c315d6ac1cc40546fde1474702a6d66d07ee13c8) --- source4/rpc_server/dcerpc_server.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 17e629d81e..46029ce8dc 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -350,10 +350,6 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) gensec_end(&p->auth_state.gensec_security); } - if (p->auth_state.session_info) { - free_session_info(&p->auth_state.session_info); - } - talloc_free(p); } -- cgit From 5b44130afad1bb1764d986de3ef0e8e04b0e7357 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 01:36:19 +0000 Subject: r2671: we're getting too many errors caused by the talloc_realloc() API not taking a context (so when you pass a NULL pointer you end up with memory in a top level context). Fixed it by changing the API to take a context. The context is only used if the pointer you are reallocing is NULL. (This used to be commit 8dc23821c9f54b2f13049b5e608a0cafb81aa540) --- source4/rpc_server/dcerpc_server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 46029ce8dc..5ab434baed 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -819,7 +819,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) } call->pkt.u.request.stub_and_verifier.data = - talloc_realloc(call->pkt.u.request.stub_and_verifier.data, alloc_size); + talloc_realloc(call, call->pkt.u.request.stub_and_verifier.data, alloc_size); if (!call->pkt.u.request.stub_and_verifier.data) { return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } @@ -874,7 +874,8 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; - dce_conn->partial_input.data = talloc_realloc(dce_conn->partial_input.data, + dce_conn->partial_input.data = talloc_realloc(dce_conn, + dce_conn->partial_input.data, dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { return NT_STATUS_NO_MEMORY; -- cgit From 0be5523afbd9fcc2c08afab708fa6df19035f16e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 04:11:37 +0000 Subject: r2673: in the rpc server, free up the old call when we decide to extend an existing call rather than creating a new one. This prevents call structures hanging around on the rpc connection context until it is closed (This used to be commit c51ca7c0e73b97435c245cd440a4fb979cf6a4f3) --- source4/rpc_server/dcerpc_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5ab434baed..9536fd6894 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -250,7 +250,7 @@ static NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p, } NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, - DATA_BLOB *session_key) + DATA_BLOB *session_key) { /* this took quite a few CPU cycles to find ... */ session_key->data = "SystemLibraryDTC"; @@ -831,6 +831,8 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) call2->pkt.u.request.stub_and_verifier.length; call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); + + talloc_free(call2); } /* this may not be the last pdu in the chain - if its isn't then -- cgit From b2f1a29e4348a5bc34a87d72d526e23e421ed9d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Sep 2004 05:44:59 +0000 Subject: r2710: continue with the new style of providing a parent context whenever possible to a structure creation routine. This makes for much easier global cleanup. (This used to be commit e14ee428ec357fab76a960387a9820a673786e27) --- source4/rpc_server/dcerpc_server.c | 46 +++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9536fd6894..220c730790 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -268,6 +268,29 @@ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, } +/* + destroy a link to an endpoint +*/ +static int dcesrv_endpoint_destructor(void *ptr) +{ + struct dcesrv_connection *p = ptr; + if (p->iface) { + p->iface->unbind(p, p->iface); + } + + /* destroy any handles */ + while (p->handles) { + dcesrv_handle_destroy(p, p->handles); + } + + if (p->auth_state.gensec_security) { + gensec_end(&p->auth_state.gensec_security); + } + + return 0; +} + + /* connect to a dcerpc endpoint */ @@ -294,6 +317,8 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->auth_state.session_key = dcesrv_generic_session_key; (*p)->srv_conn = NULL; + talloc_set_destructor(*p, dcesrv_endpoint_destructor); + return NT_STATUS_OK; } @@ -332,27 +357,6 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, } -/* - disconnect a link to an endpoint -*/ -void dcesrv_endpoint_disconnect(struct dcesrv_connection *p) -{ - if (p->iface) { - p->iface->unbind(p, p->iface); - } - - /* destroy any handles */ - while (p->handles) { - dcesrv_handle_destroy(p, p->handles); - } - - if (p->auth_state.gensec_security) { - gensec_end(&p->auth_state.gensec_security); - } - - talloc_free(p); -} - static void dcesrv_init_hdr(struct dcerpc_packet *pkt) { pkt->rpc_vers = 5; -- cgit From 31403d548e95ee6047009b78ed72e7144ece199a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Oct 2004 15:18:05 +0000 Subject: r3043: Use binding strings for specifying endpoints. The property for specifying a endpoint is now also 'endpoint' instead of 'endpoints'. The default endpoint (if none is specified) is still "ncacn_np:[\\pipe\\ifacename]", where ifacename is the name of the interface. Examples: [ uuid(60a15ec5-4de8-11d7-a637-005056a20182), endpoint("ncacn_np:[\\pipe\\rpcecho]", "ncacn_ip_tcp:") ] interface rpcecho { void dummy(); } dcerpc_binding is now converted to ep_description in the server, but I hope to completely eliminate ep_description later on. The eventual goal of all these changes is to make it easier to add transports as I'm going to add support for ncalrpc (local RPC over named pipes) and ncacn_unix_stream (Unix sockets). (This used to be commit f3da7c8b443a29b0c656c687a277384ae1353792) --- source4/rpc_server/dcerpc_server.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 220c730790..b4cf7094aa 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -153,17 +153,30 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, struct dcesrv_ep_description ep_description; struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; - BOOL tcp; + struct dcerpc_binding binding; BOOL add_ep = False; + NTSTATUS status; + + status = dcerpc_parse_binding(dce_ctx, ep_name, &binding); - tcp = (strncasecmp(ep_name, "TCP-", 4) == 0); + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name)); + return status; + } - if (tcp) { + if (binding.transport == NCACN_IP_TCP) { ep_description.type = ENDPOINT_TCP; - ep_description.info.tcp_port = atoi(ep_name+4); - } else { + ep_description.info.tcp_port = 0; + + if (binding.options && binding.options[0]) { + ep_description.info.tcp_port = atoi(binding.options[0]); + } + } else if (binding.transport == NCACN_NP) { ep_description.type = ENDPOINT_SMB; - ep_description.info.smb_pipe = ep_name; + ep_description.info.smb_pipe = binding.options[0]; + } else { + DEBUG(0, ("Unknown transport type '%d'\n", binding.transport)); + return NT_STATUS_INVALID_PARAMETER; } /* check if this endpoint exists @@ -174,12 +187,16 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(ep); - if (tcp) { + if (binding.transport == NCACN_IP_TCP) { ep->ep_description.type = ENDPOINT_TCP; - ep->ep_description.info.tcp_port = atoi(ep_name+4); + ep->ep_description.info.tcp_port = 0; + + if (binding.options && binding.options[0]) { + ep->ep_description.info.tcp_port = atoi(binding.options[0]); + } } else { ep->ep_description.type = ENDPOINT_SMB; - ep->ep_description.info.smb_pipe = smb_xstrdup(ep_name); + ep->ep_description.info.smb_pipe = binding.options[0]; } add_ep = True; } @@ -508,6 +525,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_recv_frag = 0x2000; pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; if (call->conn->iface && call->conn->iface->ndr) { + /* FIXME: Use pipe name as specified by endpoint instead of interface name */ pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", call->conn->iface->ndr->name); } else { -- cgit From ac989eda6d981ce47c7b345d5397450a3706f4d7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Oct 2004 12:47:02 +0000 Subject: r3114: - More work on merging the various structs that describe endpoints - Add protocol sequence to dcerpc transports (will be used later on) - Add more transports to the list (This used to be commit ab110192e6e2c1e5a3b2befe7b61158744f15d18) --- source4/rpc_server/dcerpc_server.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b4cf7094aa..1ccb8f4ef2 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -34,16 +34,19 @@ static BOOL endpoints_match(const struct dcesrv_ep_description *ep1, } switch (ep1->type) { - case ENDPOINT_SMB: + case NCACN_NP: if (strcasecmp(ep1->info.smb_pipe,ep2->info.smb_pipe)==0) { return True; } break; - case ENDPOINT_TCP: + case NCACN_IP_TCP: if (ep1->info.tcp_port == ep2->info.tcp_port) { return True; } break; + default: + /* Not supported yet */ + return False; } return False; @@ -164,19 +167,21 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, return status; } - if (binding.transport == NCACN_IP_TCP) { - ep_description.type = ENDPOINT_TCP; + ep_description.type = binding.transport; + switch (binding.transport) { + case NCACN_IP_TCP: ep_description.info.tcp_port = 0; if (binding.options && binding.options[0]) { ep_description.info.tcp_port = atoi(binding.options[0]); } - } else if (binding.transport == NCACN_NP) { - ep_description.type = ENDPOINT_SMB; + break; + case NCACN_NP: ep_description.info.smb_pipe = binding.options[0]; - } else { - DEBUG(0, ("Unknown transport type '%d'\n", binding.transport)); - return NT_STATUS_INVALID_PARAMETER; + break; + default: + DEBUG(0, ("Unsupported transport type '%d'\n", binding.transport)); + return NT_STATUS_NOT_SUPPORTED; } /* check if this endpoint exists @@ -187,16 +192,20 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(ep); - if (binding.transport == NCACN_IP_TCP) { - ep->ep_description.type = ENDPOINT_TCP; + ep->ep_description.type = binding.transport; + switch (binding.transport) { + case NCACN_IP_TCP: ep->ep_description.info.tcp_port = 0; if (binding.options && binding.options[0]) { ep->ep_description.info.tcp_port = atoi(binding.options[0]); } - } else { - ep->ep_description.type = ENDPOINT_SMB; + break; + case NCACN_NP: ep->ep_description.info.smb_pipe = binding.options[0]; + break; + default: + return NT_STATUS_NOT_SUPPORTED; } add_ep = True; } -- cgit From a9081b527b33d536ca36d61ad2f7f34a6e6e69e5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Oct 2004 17:40:55 +0000 Subject: r3118: Eliminate struct dcesrv_ep_description and replace it with struct dcerpc_binding. (This used to be commit 2046e14cf8d010d4e715124859df2c1c3c782266) --- source4/rpc_server/dcerpc_server.c | 72 +++++++++----------------------------- 1 file changed, 17 insertions(+), 55 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1ccb8f4ef2..a4e31712bd 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -26,37 +26,32 @@ /* see if two endpoints match */ -static BOOL endpoints_match(const struct dcesrv_ep_description *ep1, - const struct dcesrv_ep_description *ep2) +static BOOL endpoints_match(const struct dcerpc_binding *ep1, + const struct dcerpc_binding *ep2) { - if (ep1->type != ep2->type) { + if (ep1->transport != ep2->transport) { return False; } - switch (ep1->type) { - case NCACN_NP: - if (strcasecmp(ep1->info.smb_pipe,ep2->info.smb_pipe)==0) { - return True; - } - break; - case NCACN_IP_TCP: - if (ep1->info.tcp_port == ep2->info.tcp_port) { - return True; - } - break; - default: - /* Not supported yet */ - return False; + if (!ep1->options || !ep2->options) { + return ep1->options == ep2->options; } - return False; + if (!ep1->options[0] || !ep2->options[0]) { + return ep1->options[0] == ep2->options[0]; + } + + if (strcasecmp(ep1->options[0], ep2->options[0]) != 0) + return False; + + return True; } /* find an endpoint in the dcesrv_context */ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, - const struct dcesrv_ep_description *ep_description) + const struct dcerpc_binding *ep_description) { struct dcesrv_endpoint *ep; for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) { @@ -153,7 +148,6 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, const struct dcesrv_interface *iface, const struct security_descriptor *sd) { - struct dcesrv_ep_description ep_description; struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; struct dcerpc_binding binding; @@ -167,46 +161,15 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, return status; } - ep_description.type = binding.transport; - switch (binding.transport) { - case NCACN_IP_TCP: - ep_description.info.tcp_port = 0; - - if (binding.options && binding.options[0]) { - ep_description.info.tcp_port = atoi(binding.options[0]); - } - break; - case NCACN_NP: - ep_description.info.smb_pipe = binding.options[0]; - break; - default: - DEBUG(0, ("Unsupported transport type '%d'\n", binding.transport)); - return NT_STATUS_NOT_SUPPORTED; - } - /* check if this endpoint exists */ - if ((ep=find_endpoint(dce_ctx, &ep_description))==NULL) { + if ((ep=find_endpoint(dce_ctx, &binding))==NULL) { ep = talloc_p(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(ep); - ep->ep_description.type = binding.transport; - switch (binding.transport) { - case NCACN_IP_TCP: - ep->ep_description.info.tcp_port = 0; - - if (binding.options && binding.options[0]) { - ep->ep_description.info.tcp_port = atoi(binding.options[0]); - } - break; - case NCACN_NP: - ep->ep_description.info.smb_pipe = binding.options[0]; - break; - default: - return NT_STATUS_NOT_SUPPORTED; - } + ep->ep_description = binding; add_ep = True; } @@ -352,7 +315,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, search and connect to a dcerpc endpoint */ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, - const struct dcesrv_ep_description *ep_description, + const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, struct dcesrv_connection **dce_conn_p) { @@ -1192,7 +1155,6 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) sizeof(struct dcesrv_context), sizeof(struct dcesrv_endpoint), sizeof(struct dcesrv_endpoint_server), - sizeof(struct dcesrv_ep_description), sizeof(struct dcesrv_interface), sizeof(struct dcesrv_if_list), sizeof(struct dcesrv_connection), -- cgit From 78e5bc76b602f9ccf49e2f139cbd1f20b458def4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 24 Oct 2004 15:48:19 +0000 Subject: r3163: Add server side support for ncalrpc: and ncacn_unix_stream: Examples of binding strings are : ncalrpc:[EPMAPPER] ncacn_unix_stream:[/tmp/epmapper] N.B. The unix socket support in lib/socket/ appears to close and remove the socket it is listening on after the first client disconnects so until that has been fixed, it is only possible to do one ncalrpc: or ncacn_unix_stream: request per instance of smbd :-) Support for looking up NCALRPC names via the endpoint mapper will be added later. (This used to be commit 426f3e63cae3d306dcdc13ee4b655eed30057ff8) --- source4/rpc_server/dcerpc_server.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a4e31712bd..cf078b9426 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1048,40 +1048,40 @@ static void dcesrv_init(struct server_service *service, const struct model_ops * } } - dcesrv_tcp_init(service, model_ops, dce_ctx); + dcesrv_sock_init(service, model_ops, dce_ctx); return; } static void dcesrv_accept(struct server_connection *srv_conn) { - dcesrv_tcp_accept(srv_conn); + dcesrv_sock_accept(srv_conn); } static void dcesrv_recv(struct server_connection *srv_conn, time_t t, uint16_t flags) { - dcesrv_tcp_recv(srv_conn, t, flags); + dcesrv_sock_recv(srv_conn, t, flags); } static void dcesrv_send(struct server_connection *srv_conn, time_t t, uint16_t flags) { - dcesrv_tcp_send(srv_conn, t, flags); + dcesrv_sock_send(srv_conn, t, flags); } static void dcesrv_idle(struct server_connection *srv_conn, time_t t) { - dcesrv_tcp_idle(srv_conn, t); + dcesrv_sock_idle(srv_conn, t); } static void dcesrv_close(struct server_connection *srv_conn, const char *reason) { - dcesrv_tcp_close(srv_conn, reason); + dcesrv_sock_close(srv_conn, reason); return; } static void dcesrv_exit(struct server_service *service, const char *reason) { - dcesrv_tcp_exit(service, reason); + dcesrv_sock_exit(service, reason); return; } -- cgit From 026bae22de58fde67514a3a940d8f627edf8791a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 24 Oct 2004 17:06:35 +0000 Subject: r3165: Support local connections in Gtk+ tools (This used to be commit 3de0cf22ddd6b7fb4a2214f3f99d37174c54840f) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cf078b9426..a174266518 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1178,7 +1178,7 @@ BOOL subsystem_dcerpc_init(void) return False; } - /* FIXME: Perhaps panic if a basic endpoint server, such as EPMAPER, fails to initialise? */ + /* FIXME: Perhaps panic if a basic endpoint server, such as EPMAPPER, fails to initialise? */ static_init_dcerpc; DEBUG(3,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); -- cgit From 06b3879c8fec97ef5de9b969301611e28fff00de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 24 Oct 2004 22:46:47 +0000 Subject: r3167: Add a member 'endpoint' to the dcerpc_binding struct to use instead of options[0]. (This used to be commit 18582083af800abd3d8de40eb73255c8ae6598dd) --- source4/rpc_server/dcerpc_server.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a174266518..9373b06643 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -33,15 +33,11 @@ static BOOL endpoints_match(const struct dcerpc_binding *ep1, return False; } - if (!ep1->options || !ep2->options) { - return ep1->options == ep2->options; + if (!ep1->endpoint || !ep2->endpoint) { + return ep1->endpoint == ep2->endpoint; } - if (!ep1->options[0] || !ep2->options[0]) { - return ep1->options[0] == ep2->options[0]; - } - - if (strcasecmp(ep1->options[0], ep2->options[0]) != 0) + if (strcasecmp(ep1->endpoint, ep2->endpoint) != 0) return False; return True; -- cgit From 8262efeb0b918785d45d1fd9e971b5ed44a3ccfb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 11:59:03 +0000 Subject: r3320: fixed bugs in the rpc_server code in handling partial packet receives and sends it now passes the non-blocking test suite (This used to be commit 6cdf485fb263c69d62ea2e98236d92ffbf6b7a3e) --- source4/rpc_server/dcerpc_server.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9373b06643..fd605fb955 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -907,7 +907,6 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, struct dcesrv_call_state *call; struct dcesrv_call_reply *rep; ssize_t nwritten; - NTSTATUS status = NT_STATUS_OK; call = dce_conn->call_list; if (!call || !call->replies) { @@ -928,8 +927,6 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (rep->data.length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); - } else { - status = STATUS_BUFFER_OVERFLOW; } if (call->replies == NULL) { @@ -938,7 +935,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, talloc_free(call); } - return status; + return NT_STATUS_OK; } -- cgit From a6ae640313a47ac2950c0948e4385fa934a5ef09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 13:19:39 +0000 Subject: r3323: more warning reductions (This used to be commit 5921587ec26e4892efc678421277e4969417d7f5) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fd605fb955..59ea8321ff 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -238,7 +238,7 @@ NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { /* this took quite a few CPU cycles to find ... */ - session_key->data = "SystemLibraryDTC"; + session_key->data = discard_const_p(char, "SystemLibraryDTC"); session_key->length = 16; return NT_STATUS_OK; } -- cgit From 90067934cd3195df80f8b1e614629d51fffcb38b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 10:30:34 +0000 Subject: r3428: switched to using minimal includes for the auto-generated RPC code. The thing that finally convinced me that minimal includes was worth pursuing for rpc was a compiler (tcc) that failed to build Samba due to reaching internal limits of the size of include files. Also the fact that includes.h.gch was 16MB, which really seems excessive. This patch brings it back to 12M, which is still too large, but better. Note that this patch speeds up compile times for both the pch and non-pch case. This change also includes the addition iof a "depends()" option in our IDL files, allowing you to specify that one IDL file depends on another. This capability was needed for the auto-includes generation. (This used to be commit b8f5fa8ac8e8725f3d321004f0aedf4246fc6b49) --- source4/rpc_server/dcerpc_server.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 59ea8321ff..652aa87f5a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -22,6 +22,9 @@ */ #include "includes.h" +#include "librpc/gen_ndr/ndr_epmapper.h" +#include "librpc/gen_ndr/ndr_dcom.h" +#include "librpc/gen_ndr/ndr_oxidresolver.h" /* see if two endpoints match -- cgit From edbfc0f6e70150e321822365bf0eead2821551bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:57:18 +0000 Subject: r3453: - split out the auth and popt includes - tidied up some of the system includes - moved a few more structures back from misc.idl to netlogon.idl and samr.idl now that pidl knows about inter-IDL dependencies (This used to be commit 7b7477ac42d96faac1b0ff361525d2c63cedfc64) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 652aa87f5a..32addde703 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -23,8 +23,8 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_epmapper.h" -#include "librpc/gen_ndr/ndr_dcom.h" #include "librpc/gen_ndr/ndr_oxidresolver.h" +#include "auth/auth.h" /* see if two endpoints match -- cgit From 3643fb11092e28a9538ef32cedce8ff21ad86a28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:42:15 +0000 Subject: r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h) (This used to be commit b97e395c814762024336c1cf4d7c25be8da5813a) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 32addde703..4bcbdc5b94 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -25,6 +25,7 @@ #include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_oxidresolver.h" #include "auth/auth.h" +#include "dlinklist.h" /* see if two endpoints match -- cgit From c051779a0a34a9c40a5425fb1eb821983b8dc852 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 07:42:47 +0000 Subject: r3468: split out dcerpc_server.h (This used to be commit 729e0026e4408f74f140375537d4fe48c1fc3242) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4bcbdc5b94..fe58ee53ee 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -26,6 +26,7 @@ #include "librpc/gen_ndr/ndr_oxidresolver.h" #include "auth/auth.h" #include "dlinklist.h" +#include "rpc_server/dcerpc_server.h" /* see if two endpoints match -- cgit From 02785df1b06647f1adaaac3c93f363ec5070a941 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 00:38:05 +0000 Subject: r3497: removed some include cruft, and split out librpc/gen_ndr/tables.h (This used to be commit 7dd3a5a6dadb0edc4fad56deba84f24b1e6dd2bc) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fe58ee53ee..f9e2d8d28e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -24,6 +24,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_oxidresolver.h" +#include "librpc/gen_ndr/tables.h" #include "auth/auth.h" #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" -- cgit From dde07058075d357cfdc63624c8dcaa67ebd40add Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 10:09:48 +0000 Subject: r3507: - added deferred replies on sharing violation in pvfs open. The deferred reply is short-circuited immediately when the file is closed by another user, allowing it to be opened by the waiting user. - added a sane set of timeval manipulation routines - converted all the events code and code that uses it to use struct timeval instead of time_t, which allows for microsecond resolution instead of 1 second resolution. This was needed for doing the pvfs deferred open code, and is why the patch is so big. (This used to be commit 0d51511d408d91eb5f68a35e980e0875299b1831) --- source4/rpc_server/dcerpc_server.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f9e2d8d28e..3aeb7033d1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1057,21 +1057,18 @@ static void dcesrv_accept(struct server_connection *srv_conn) dcesrv_sock_accept(srv_conn); } -static void dcesrv_recv(struct server_connection *srv_conn, time_t t, uint16_t flags) +static void dcesrv_recv(struct server_connection *srv_conn, + struct timeval t, uint16_t flags) { dcesrv_sock_recv(srv_conn, t, flags); } -static void dcesrv_send(struct server_connection *srv_conn, time_t t, uint16_t flags) +static void dcesrv_send(struct server_connection *srv_conn, + struct timeval t, uint16_t flags) { dcesrv_sock_send(srv_conn, t, flags); } -static void dcesrv_idle(struct server_connection *srv_conn, time_t t) -{ - dcesrv_sock_idle(srv_conn, t); -} - static void dcesrv_close(struct server_connection *srv_conn, const char *reason) { dcesrv_sock_close(srv_conn, reason); @@ -1190,7 +1187,7 @@ static const struct server_service_ops dcesrv_ops = { .accept_connection = dcesrv_accept, .recv_handler = dcesrv_recv, .send_handler = dcesrv_send, - .idle_handler = dcesrv_idle, + .idle_handler = NULL, .close_connection = dcesrv_close, .service_exit = dcesrv_exit, }; -- cgit From 71db46ea665606384f2be1be708c74c97c9adfb2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Nov 2004 23:23:15 +0000 Subject: r3586: Fix some of the issues with the module init functions. Both subsystems and modules can now have init functions, which can be specified in .mk files (INIT_FUNCTION = ...) The build system will define : - SUBSYSTEM_init_static_modules that calls the init functions of all statically compiled modules. Failing to load will generate an error which is not fatal - BINARY_init_subsystems that calls the init functions (if defined) for the subsystems the binary depends on This removes the hack with the "static bool Initialised = " and the "lazy_init" functions (This used to be commit 7a8244761bfdfdfb48f8264d76951ebdfbf7bd8a) --- source4/rpc_server/dcerpc_server.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3aeb7033d1..70b7d18f39 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1165,20 +1165,19 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) /* initialise the DCERPC subsystem */ -BOOL subsystem_dcerpc_init(void) +NTSTATUS dcerpc_server_init(void) { NTSTATUS status; status = register_subsystem("dcerpc", dcerpc_register_ep_server); if (!NT_STATUS_IS_OK(status)) { - return False; + return status; } - /* FIXME: Perhaps panic if a basic endpoint server, such as EPMAPPER, fails to initialise? */ - static_init_dcerpc; + dcerpc_init_static_modules; DEBUG(3,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); - return True; + return NT_STATUS_OK; } static const struct server_service_ops dcesrv_ops = { -- cgit From 0639758dd9b19926baac1fd5636d00e3a3d23404 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 9 Nov 2004 01:04:29 +0000 Subject: r3630: More work on DCOM server side (This used to be commit e995a1c0e5d2ee2dc50c31c01ce281a303dd5231) --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 70b7d18f39..83c0872ba7 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -595,6 +595,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_ORPC) { + pull->flags |= LIBNDR_FLAG_OBJECT_PRESENT; + } + r = talloc(call, call->conn->iface->ndr->calls[opnum].struct_size); if (!r) { return NT_STATUS_NO_MEMORY; -- cgit From 31ded4901b4529ad2e49871502cab5ecba71483a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 22:23:23 +0000 Subject: r3737: - Get rid of the register_subsystem() and register_backend() functions. - Re-disable tdbtool (it was building fine on my Debian box but other machines were having problems) (This used to be commit 0d7bb2c40b7a9ed59df3f8944133ea562697e814) --- source4/rpc_server/dcerpc_server.c | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 83c0872ba7..67baa6281c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1100,7 +1100,7 @@ static int num_ep_servers; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -static NTSTATUS dcerpc_register_ep_server(const void *_ep_server) +NTSTATUS dcerpc_register_ep_server(const void *_ep_server) { const struct dcesrv_endpoint_server *ep_server = _ep_server; @@ -1166,24 +1166,6 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) return &critical_sizes; } -/* - initialise the DCERPC subsystem -*/ -NTSTATUS dcerpc_server_init(void) -{ - NTSTATUS status; - - status = register_subsystem("dcerpc", dcerpc_register_ep_server); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - dcerpc_init_static_modules; - - DEBUG(3,("DCERPC subsystem version %d initialised\n", DCERPC_MODULE_VERSION)); - return NT_STATUS_OK; -} - static const struct server_service_ops dcesrv_ops = { .name = "rpc", .service_init = dcesrv_init, -- cgit From 46badf19089668e470e9bb5b2300017f8948b49e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 16 Nov 2004 21:07:08 +0000 Subject: r3790: use a registration function that is called from dcerpc_*_init functions rather then a large table in librpc/gen_ndr/tables.c. This will allow us to only link in only the required gen_ndr files (speeds up linking quite a bit, makes binaries smaller). Each gen_ndr_* file now has a init function that calls the init functions of the interfaces it contains. I did it this way to keep pidl's code simple, though it might hurt startup time a bit. I'd be happy to change it if people like one function better. (This used to be commit 3c436590ae95b58ad6d00e72d6fdd08a4d80f208) --- source4/rpc_server/dcerpc_server.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 67baa6281c..11e385153e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -24,7 +24,6 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_oxidresolver.h" -#include "librpc/gen_ndr/tables.h" #include "auth/auth.h" #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" -- cgit From 856ee665374071c89f5ecf540dcc3d68ccf2ff16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Nov 2004 14:35:29 +0000 Subject: r3810: create a LIB_SECURITY subsystem - move dom_sid, security_descriptor, security_* funtions to one place and rename some of them metze (This used to be commit b620bdd672cfdf0e009492e648b0709e6b6d8596) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 11e385153e..de8ac73304 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -198,7 +198,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, * we try to set it */ if (ep->sd == NULL) { - ep->sd = copy_security_descriptor(dce_ctx, sd); + ep->sd = security_descriptor_copy(dce_ctx, sd); } /* if now there's no security descriptor given on the endpoint -- cgit From c199c2af1fa686962bb313222a0a0a29625ec450 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 19:27:17 +0000 Subject: r3968: fix compiler warnings metze (This used to be commit 6440476f7f2fd5776ec4a21240e7482603000d19) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index de8ac73304..4a9465b9eb 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -243,7 +243,7 @@ NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { /* this took quite a few CPU cycles to find ... */ - session_key->data = discard_const_p(char, "SystemLibraryDTC"); + session_key->data = discard_const_p(void, "SystemLibraryDTC"); session_key->length = 16; return NT_STATUS_OK; } -- cgit From 15543f18acc9040fd3213e826147fe5604bb1ae1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 29 Nov 2004 12:01:46 +0000 Subject: r4000: DATA_BLOB.data is uint8_t * not void * :-) (thanks abartlet for telling me) metze (This used to be commit 2783bf393f6310f9d827538329d619dad5b02dd0) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4a9465b9eb..3d34a7e1c0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -243,7 +243,7 @@ NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { /* this took quite a few CPU cycles to find ... */ - session_key->data = discard_const_p(void, "SystemLibraryDTC"); + session_key->data = discard_const_p(uint8_t, "SystemLibraryDTC"); session_key->length = 16; return NT_STATUS_OK; } -- cgit From 58c326809a816703dc516c3022c9c4dbb9d09445 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:24:38 +0000 Subject: r4052: fixed a bunch of code to use the type safe _p allocation macros (This used to be commit 80d15fa3402a9d1183467463f6b21c0b674bc442) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3d34a7e1c0..d11d5dddd8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1086,7 +1086,7 @@ static void dcesrv_exit(struct server_service *service, const char *reason) /* the list of currently registered DCERPC endpoint servers. */ -static struct { +static struct ep_server { struct dcesrv_endpoint_server *ep_server; } *ep_servers = NULL; static int num_ep_servers; @@ -1110,7 +1110,7 @@ NTSTATUS dcerpc_register_ep_server(const void *_ep_server) return NT_STATUS_OBJECT_NAME_COLLISION; } - ep_servers = Realloc(ep_servers, sizeof(ep_servers[0]) * (num_ep_servers+1)); + ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1); if (!ep_servers) { smb_panic("out of memory in dcerpc_register"); } -- cgit From 10918b7b707eb922cb2641d4e9416fb334b1f7cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 6 Dec 2004 17:48:51 +0000 Subject: r4082: support alter_context requests metze (This used to be commit ab6ec6b5f4e04322eb151b7bf9c530a0dc16bf89) --- source4/rpc_server/dcerpc_server.c | 62 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d11d5dddd8..3afe5f1dc5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -564,6 +564,65 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return NT_STATUS_OK; } +/* + handle a bind request +*/ +static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) +{ + struct dcerpc_packet pkt; + struct dcesrv_call_reply *rep; + NTSTATUS status; + uint32_t result=0, reason=0; + + /* handle any authentication that is being requested */ + if (!dcesrv_auth_alter(call)) { + /* TODO: work out the right reject code */ + return dcesrv_bind_nak(call, 0); + } + + /* setup a alter_ack */ + dcesrv_init_hdr(&pkt); + pkt.auth_length = 0; + pkt.call_id = call->pkt.call_id; + pkt.ptype = DCERPC_PKT_ALTER_ACK; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.u.alter_ack.max_xmit_frag = 0x2000; + pkt.u.alter_ack.max_recv_frag = 0x2000; + pkt.u.alter_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; + pkt.u.alter_ack.secondary_address = NULL; + pkt.u.alter_ack.num_results = 1; + pkt.u.alter_ack.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); + if (!pkt.u.alter_ack.ctx_list) { + return NT_STATUS_NO_MEMORY; + } + pkt.u.alter_ack.ctx_list[0].result = result; + pkt.u.alter_ack.ctx_list[0].reason = reason; + GUID_from_string(NDR_GUID, &pkt.u.alter_ack.ctx_list[0].syntax.uuid); + pkt.u.alter_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; + pkt.u.alter_ack.auth_info = data_blob(NULL, 0); + + if (!dcesrv_auth_alter_ack(call, &pkt)) { + return dcesrv_bind_nak(call, 0); + } + + rep = talloc_p(call, struct dcesrv_call_reply); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } + + status = dcerpc_push_auth(&rep->data, call, &pkt, + call->conn->auth_state.auth_info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + dcerpc_set_frag_length(&rep->data, rep->data.length); + + DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + + return NT_STATUS_OK; +} /* handle a dcerpc request packet @@ -848,6 +907,9 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) case DCERPC_PKT_AUTH3: status = dcesrv_auth3(call); break; + case DCERPC_PKT_ALTER: + status = dcesrv_alter(call); + break; case DCERPC_PKT_REQUEST: status = dcesrv_request(call); break; -- cgit From 1960714669d03ce6c2f1fda34e9798cda555c962 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Dec 2004 08:35:11 +0000 Subject: r4161: two more fixes for NT4 clients. Bugs found by kukks. - nt4 doesn't setup the pfc flags correctly for rpc packet types other than normal requests, so don't check for fragmented packets unless they are of type request - ensure we give STATUS_BUFFER_OVERFLOW when we return a partial fragment in SMBtrans requests on ncacn_np (This used to be commit 83ebffec3215c58c5cebf1a7c9a58904854203c8) --- source4/rpc_server/dcerpc_server.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3afe5f1dc5..6e608fd30b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -849,7 +849,8 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) dce_partial_advance(dce_conn, blob.length); /* see if this is a continued packet */ - if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { + if (call->pkt.ptype == DCERPC_PKT_REQUEST && + !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { struct dcesrv_call_state *call2 = call; uint32_t alloc_size; @@ -895,7 +896,8 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) /* this may not be the last pdu in the chain - if its isn't then just put it on the call_list and wait for the rest */ - if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { + if (call->pkt.ptype == DCERPC_PKT_REQUEST && + !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { DLIST_ADD_END(dce_conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; } @@ -998,6 +1000,8 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (rep->data.length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); + } else { + return STATUS_BUFFER_OVERFLOW; } if (call->replies == NULL) { -- cgit From bb072199b14c0e877360475eefb89021e7ec0bcf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Dec 2004 14:37:54 +0000 Subject: r4288: don't use struct dcerpc_interface_table anymore in the main rpc server code. let the backends specify a ndr_push/ndr_pull function like we already do with the dispatch() function. this allows an interface implmentation to work as real proxy without needing to know the idl for an interface that means just the plain decrypted payload can be forwarded If someone want to write such a backend, patches are wellcome metze (This used to be commit a150bdf140d9165a05cbc7cac40b6e3c03a7bd3c) --- source4/rpc_server/dcerpc_server.c | 45 ++++++++++++-------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6e608fd30b..231778247f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -69,11 +69,11 @@ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, static BOOL interface_match(const struct dcesrv_interface *if1, const struct dcesrv_interface *if2) { - if (if1->ndr->if_version != if2->ndr->if_version) { + if (if1->if_version != if2->if_version) { return False; } - if (strcmp(if1->ndr->uuid, if2->ndr->uuid)==0) { + if (strcmp(if1->uuid, if2->uuid)==0) { return True; } @@ -101,11 +101,11 @@ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoin static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, const char *uuid, uint32_t if_version) { - if (iface->ndr->if_version != if_version) { + if (iface->if_version != if_version) { return False; } - if (strcmp(iface->ndr->uuid, uuid)==0) { + if (strcmp(iface->uuid, uuid)==0) { return True; } @@ -177,7 +177,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* see if the interface is already registered on te endpoint */ if (find_interface(ep, iface)!=NULL) { DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n", - iface->ndr->name, ep_name)); + iface->name, ep_name)); return NT_STATUS_OBJECT_NAME_COLLISION; } @@ -208,7 +208,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, if (ep->sd != NULL) { DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n" " on endpoint '%s'\n", - iface->ndr->name, ep_name)); + iface->name, ep_name)); if (add_ep) free(ep); free(ifl); return NT_STATUS_OBJECT_NAME_COLLISION; @@ -224,7 +224,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n", - iface->ndr->name, ep_name)); + iface->name, ep_name)); return NT_STATUS_OK; } @@ -497,10 +497,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; - if (call->conn->iface && call->conn->iface->ndr) { + if (call->conn->iface) { /* FIXME: Use pipe name as specified by endpoint instead of interface name */ pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", - call->conn->iface->ndr->name); + call->conn->iface->name); } else { pkt.u.bind_ack.secondary_address = ""; } @@ -631,23 +631,17 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { struct ndr_pull *pull; struct ndr_push *push; - uint16_t opnum; void *r; NTSTATUS status; DATA_BLOB stub; uint32_t total_length; + call->fault_code = 0; if (!call->conn->iface) { return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } - opnum = call->pkt.u.request.opnum; - - if (opnum >= call->conn->iface->ndr->num_calls) { - return dcesrv_fault(call, DCERPC_FAULT_OP_RNG_ERROR); - } - pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); if (!pull) { return NT_STATUS_NO_MEMORY; @@ -657,21 +651,14 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pull->flags |= LIBNDR_FLAG_OBJECT_PRESENT; } - r = talloc(call, call->conn->iface->ndr->calls[opnum].struct_size); - if (!r) { - return NT_STATUS_NO_MEMORY; - } - if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } /* unravel the NDR for the packet */ - status = call->conn->iface->ndr->calls[opnum].ndr_pull(pull, NDR_IN, r); + status = call->conn->iface->ndr_pull(call, call, pull, &r); if (!NT_STATUS_IS_OK(status)) { - dcerpc_log_packet(call->conn->iface->ndr, opnum, NDR_IN, - &call->pkt.u.request.stub_and_verifier); - return dcesrv_fault(call, DCERPC_FAULT_NDR); + return dcesrv_fault(call, call->fault_code); } if (pull->offset != pull->data_size) { @@ -680,13 +667,9 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) dump_data(10, pull->data+pull->offset, pull->data_size - pull->offset); } - call->fault_code = 0; - /* call the dispatch function */ status = call->conn->iface->dispatch(call, call, r); if (!NT_STATUS_IS_OK(status)) { - dcerpc_log_packet(call->conn->iface->ndr, opnum, NDR_IN, - &call->pkt.u.request.stub_and_verifier); return dcesrv_fault(call, call->fault_code); } @@ -705,9 +688,9 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) push->flags |= LIBNDR_FLAG_BIGENDIAN; } - status = call->conn->iface->ndr->calls[opnum].ndr_push(push, NDR_OUT, r); + status = call->conn->iface->ndr_push(call, call, push, r); if (!NT_STATUS_IS_OK(status)) { - return dcesrv_fault(call, DCERPC_FAULT_NDR); + return dcesrv_fault(call, call->fault_code); } stub = ndr_push_blob(push); -- cgit From 0f1444b77232d59aaa025fa44e5b88c4aabaf877 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 Dec 2004 23:02:39 +0000 Subject: r4358: At metze's request, the Christmas elves have removed gensec_end in favor of talloc_free(). Andrew Bartlett (This used to be commit 1933cd12fbaed56e13f2386b19de6ade99bf9478) --- source4/rpc_server/dcerpc_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 231778247f..cf4ea8bea8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -274,7 +274,8 @@ static int dcesrv_endpoint_destructor(void *ptr) } if (p->auth_state.gensec_security) { - gensec_end(&p->auth_state.gensec_security); + talloc_free(p->auth_state.gensec_security); + p->auth_state.gensec_security = NULL; } return 0; -- cgit From 4620625ea3c49c2795bcf706387c09b930079534 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 25 Dec 2004 14:01:19 +0000 Subject: r4359: using talloc_free() of a child struct in a talloc_destructor is useless metze (This used to be commit e51f2cf43f2cbcf3c3bbb00abc99f1bddb9f7f35) --- source4/rpc_server/dcerpc_server.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cf4ea8bea8..c53036b45b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -273,11 +273,6 @@ static int dcesrv_endpoint_destructor(void *ptr) dcesrv_handle_destroy(p, p->handles); } - if (p->auth_state.gensec_security) { - talloc_free(p->auth_state.gensec_security); - p->auth_state.gensec_security = NULL; - } - return 0; } -- cgit From 11ce2cfd70df264c5c91b4daaa9a01c5abc673b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 04:39:16 +0000 Subject: r4591: - converted the other _p talloc functions to not need _p - added #if TALLOC_DEPRECATED around the _p functions - fixes the code that broke from the above while doing this I fixed quite a number of places that were incorrectly using the non type-safe talloc functions to use the type safe ones. Some were even doing multiplies for array allocation, which is potentially unsafe. (This used to be commit 6e7754abd0c225527fb38363996a6e241b87b37e) --- source4/rpc_server/dcerpc_server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c53036b45b..f0791e5928 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -857,7 +857,9 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) } call->pkt.u.request.stub_and_verifier.data = - talloc_realloc(call, call->pkt.u.request.stub_and_verifier.data, alloc_size); + talloc_realloc(call, + call->pkt.u.request.stub_and_verifier.data, + uint8_t, alloc_size); if (!call->pkt.u.request.stub_and_verifier.data) { return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } @@ -920,6 +922,7 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) dce_conn->partial_input.data = talloc_realloc(dce_conn, dce_conn->partial_input.data, + uint8_t, dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { return NT_STATUS_NO_MEMORY; -- cgit From e74b3ed6f195e66cb5fa0f387cea0f59fb66711b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Jan 2005 11:32:12 +0000 Subject: r4618: - tidied up the alter_context client code a bit - there is no alter_nak or alter_ack packet, its all done in an alter_response - auto-allocated the contex_ids - tried to fix up the dcom code to work again with alter_context. Jelmer, please take a look :) (This used to be commit dd1c54add8884376601f2f8a56c01bfb8add030c) --- source4/rpc_server/dcerpc_server.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f0791e5928..c86ffb2cd0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -580,22 +580,22 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; - pkt.ptype = DCERPC_PKT_ALTER_ACK; + pkt.ptype = DCERPC_PKT_ALTER_RESP; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; - pkt.u.alter_ack.max_xmit_frag = 0x2000; - pkt.u.alter_ack.max_recv_frag = 0x2000; - pkt.u.alter_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; - pkt.u.alter_ack.secondary_address = NULL; - pkt.u.alter_ack.num_results = 1; - pkt.u.alter_ack.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); - if (!pkt.u.alter_ack.ctx_list) { + pkt.u.alter_resp.max_xmit_frag = 0x2000; + pkt.u.alter_resp.max_recv_frag = 0x2000; + pkt.u.alter_resp.assoc_group_id = call->pkt.u.bind.assoc_group_id; + pkt.u.alter_resp.secondary_address = NULL; + pkt.u.alter_resp.num_results = 1; + pkt.u.alter_resp.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); + if (!pkt.u.alter_resp.ctx_list) { return NT_STATUS_NO_MEMORY; } - pkt.u.alter_ack.ctx_list[0].result = result; - pkt.u.alter_ack.ctx_list[0].reason = reason; - GUID_from_string(NDR_GUID, &pkt.u.alter_ack.ctx_list[0].syntax.uuid); - pkt.u.alter_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; - pkt.u.alter_ack.auth_info = data_blob(NULL, 0); + pkt.u.alter_resp.ctx_list[0].result = result; + pkt.u.alter_resp.ctx_list[0].reason = reason; + GUID_from_string(NDR_GUID, &pkt.u.alter_resp.ctx_list[0].syntax.uuid); + pkt.u.alter_resp.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; + pkt.u.alter_resp.auth_info = data_blob(NULL, 0); if (!dcesrv_auth_alter_ack(call, &pkt)) { return dcesrv_bind_nak(call, 0); -- cgit From 46a32687da249174a666d9166fccbe705c8beba0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 9 Jan 2005 12:55:25 +0000 Subject: r4620: - add interface functions to the auth subsystem so that callers doesn't need to use function pointers anymore - make the module init much easier - a lot of cleanups don't try to read the diff in auth/ better read the new files it passes test_echo.sh and test_rpc.sh abartlet: please fix spelling fixes metze (This used to be commit 3c0d16b8236451f2cfd38fc3db8ae2906106d847) --- source4/rpc_server/dcerpc_server.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c86ffb2cd0..e4f5818826 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -330,8 +330,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return status; } - session_info->refcount++; - (*dce_conn_p)->auth_state.session_info = session_info; + (*dce_conn_p)->auth_state.session_info = talloc_reference((*dce_conn_p), session_info); (*dce_conn_p)->auth_state.session_key = dcesrv_inherited_session_key; /* TODO: check security descriptor of the endpoint here -- cgit From 577218b2aded7adb367f3f33bcc5560f3d4c0ec2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jan 2005 12:15:26 +0000 Subject: r4640: first stage in the server side support for multiple context_ids on one pipe this stage does the following: - simplifies the dcerpc_handle handling, and all the callers of it - split out the context_id depenent state into a linked list of established contexts - fixed some talloc handling in several rpc servers that i noticed while doing the above (This used to be commit fde042b3fc609c94e2c7eedcdd72ecdf489cf63b) --- source4/rpc_server/dcerpc_server.c | 95 ++++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 25 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e4f5818826..808cad94d9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -63,6 +63,19 @@ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, return NULL; } +/* + find a registered context_id from a bind or alter_context +*/ +static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn, + uint32_t context_id) +{ + struct dcesrv_connection_context *c; + for (c=conn->contexts;c;c=c->next) { + if (c->context_id == context_id) return c; + } + return NULL; +} + /* see if a uuid and if_version match to an interface */ @@ -84,7 +97,7 @@ static BOOL interface_match(const struct dcesrv_interface *if1, find the interface operations on an endpoint */ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint, - const struct dcesrv_interface *iface) + const struct dcesrv_interface *iface) { struct dcesrv_if_list *ifl; for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) { @@ -264,15 +277,19 @@ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, static int dcesrv_endpoint_destructor(void *ptr) { struct dcesrv_connection *p = ptr; - if (p->iface) { - p->iface->unbind(p, p->iface); - } - /* destroy any handles */ - while (p->handles) { - dcesrv_handle_destroy(p, p->handles); + while (p->contexts) { + struct dcesrv_connection_context *c = p->contexts; + + DLIST_REMOVE(p->contexts, c); + + if (c->iface) { + c->iface->unbind(c, c->iface); + } + talloc_free(c); } + return 0; } @@ -291,11 +308,9 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, (*p)->dce_ctx = dce_ctx; (*p)->endpoint = ep; - (*p)->iface = NULL; - (*p)->private = NULL; + (*p)->contexts = NULL; (*p)->call_list = NULL; (*p)->cli_max_recv_frag = 0; - (*p)->handles = NULL; (*p)->partial_input = data_blob(NULL, 0); (*p)->auth_state.auth_info = NULL; (*p)->auth_state.gensec_security = NULL; @@ -443,12 +458,21 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) struct dcesrv_call_reply *rep; NTSTATUS status; uint32_t result=0, reason=0; + uint32_t context_id; + const struct dcesrv_interface *iface; if (call->pkt.u.bind.num_contexts != 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { return dcesrv_bind_nak(call, 0); } + context_id = call->pkt.u.bind.ctx_list[0].context_id; + + /* you can't bind twice on one context */ + if (dcesrv_find_context(call->conn, context_id) != NULL) { + return dcesrv_bind_nak(call, 0); + } + if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; uuid = GUID_string(call, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); if (!uuid) { @@ -465,14 +489,30 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - call->conn->iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version); - if (!call->conn->iface) { + iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version); + if (iface == NULL) { DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); /* we don't know about that interface */ result = DCERPC_BIND_PROVIDER_REJECT; reason = DCERPC_BIND_REASON_ASYNTAX; } + if (iface) { + /* add this context to the list of available context_ids */ + struct dcesrv_connection_context *context = talloc(call->conn, + struct dcesrv_connection_context); + if (context == NULL) { + return dcesrv_bind_nak(call, 0); + } + context->conn = call->conn; + context->iface = iface; + context->context_id = context_id; + context->private = NULL; + context->handles = NULL; + DLIST_ADD(call->conn->contexts, context); + call->context = context; + } + if (call->conn->cli_max_recv_frag == 0) { call->conn->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag; } @@ -492,10 +532,9 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; - if (call->conn->iface) { + if (iface) { /* FIXME: Use pipe name as specified by endpoint instead of interface name */ - pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", - call->conn->iface->name); + pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name); } else { pkt.u.bind_ack.secondary_address = ""; } @@ -514,15 +553,16 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - if (call->conn->iface) { - status = call->conn->iface->bind(call, call->conn->iface); + if (iface) { + status = iface->bind(call, iface); if (!NT_STATUS_IS_OK(status)) { - DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n", uuid, if_version, nt_errstr(status))); + DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n", + uuid, if_version, nt_errstr(status))); return dcesrv_bind_nak(call, 0); } } - rep = talloc_p(call, struct dcesrv_call_reply); + rep = talloc(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -630,13 +670,17 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) NTSTATUS status; DATA_BLOB stub; uint32_t total_length; + struct dcesrv_connection_context *context; call->fault_code = 0; - if (!call->conn->iface) { + context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id); + if (context == NULL) { return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } + call->context = context; + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); if (!pull) { return NT_STATUS_NO_MEMORY; @@ -651,7 +695,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* unravel the NDR for the packet */ - status = call->conn->iface->ndr_pull(call, call, pull, &r); + status = context->iface->ndr_pull(call, call, pull, &r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, call->fault_code); } @@ -663,7 +707,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* call the dispatch function */ - status = call->conn->iface->dispatch(call, call, r); + status = context->iface->dispatch(call, call, r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, call->fault_code); } @@ -683,7 +727,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) push->flags |= LIBNDR_FLAG_BIGENDIAN; } - status = call->conn->iface->ndr_push(call, call, push, r); + status = context->iface->ndr_push(call, call, push, r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, call->fault_code); } @@ -697,7 +741,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct dcesrv_call_reply *rep; struct dcerpc_packet pkt; - rep = talloc_p(call, struct dcesrv_call_reply); + rep = talloc(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -787,13 +831,14 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) struct dcesrv_call_state *call; DATA_BLOB blob; - call = talloc_p(dce_conn, struct dcesrv_call_state); + call = talloc(dce_conn, struct dcesrv_call_state); if (!call) { talloc_free(dce_conn->partial_input.data); return NT_STATUS_NO_MEMORY; } call->conn = dce_conn; call->replies = NULL; + call->context = NULL; blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); -- cgit From 34f6485dda4a48e7a70f11e7975c589981d27ca1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jan 2005 12:39:42 +0000 Subject: r4642: added support for alter_context in the server for adding new interfaces to an existing pipe (This used to be commit b6af57c86829aadc261cd7b79091cef17c15b967) --- source4/rpc_server/dcerpc_server.c | 71 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 808cad94d9..925004b191 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -599,6 +599,56 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) return NT_STATUS_OK; } + +/* + handle a bind request +*/ +static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32 context_id) +{ + uint32_t if_version, transfer_syntax_version; + const char *uuid, *transfer_syntax; + struct dcesrv_connection_context *context; + const struct dcesrv_interface *iface; + + if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version; + uuid = GUID_string(call, &call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid); + if (!uuid) { + return NT_STATUS_NO_MEMORY; + } + + transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version; + transfer_syntax = GUID_string(call, + &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid); + if (!transfer_syntax || + strcasecmp(NDR_GUID, transfer_syntax) != 0 || + NDR_GUID_VERSION != transfer_syntax_version) { + /* we only do NDR encoded dcerpc */ + return NT_STATUS_NO_MEMORY; + } + + iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version); + if (iface == NULL) { + DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); + return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED; + } + + /* add this context to the list of available context_ids */ + context = talloc(call->conn, struct dcesrv_connection_context); + if (context == NULL) { + return NT_STATUS_NO_MEMORY; + } + context->conn = call->conn; + context->iface = iface; + context->context_id = context_id; + context->private = NULL; + context->handles = NULL; + DLIST_ADD(call->conn->contexts, context); + call->context = context; + + return NT_STATUS_OK; +} + + /* handle a bind request */ @@ -608,14 +658,28 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) struct dcesrv_call_reply *rep; NTSTATUS status; uint32_t result=0, reason=0; + uint32_t context_id; /* handle any authentication that is being requested */ if (!dcesrv_auth_alter(call)) { /* TODO: work out the right reject code */ - return dcesrv_bind_nak(call, 0); + result = DCERPC_BIND_PROVIDER_REJECT; + reason = DCERPC_BIND_REASON_ASYNTAX; + } + + context_id = call->pkt.u.alter.ctx_list[0].context_id; + + /* see if they are asking for a new interface */ + if (result == 0 && + dcesrv_find_context(call->conn, context_id) == NULL) { + status = dcesrv_alter_new_context(call, context_id); + if (!NT_STATUS_IS_OK(status)) { + result = DCERPC_BIND_PROVIDER_REJECT; + reason = DCERPC_BIND_REASON_ASYNTAX; + } } - /* setup a alter_ack */ + /* setup a alter_resp */ dcesrv_init_hdr(&pkt); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; @@ -623,7 +687,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.u.alter_resp.max_xmit_frag = 0x2000; pkt.u.alter_resp.max_recv_frag = 0x2000; - pkt.u.alter_resp.assoc_group_id = call->pkt.u.bind.assoc_group_id; + pkt.u.alter_resp.assoc_group_id = call->pkt.u.alter.assoc_group_id; pkt.u.alter_resp.secondary_address = NULL; pkt.u.alter_resp.num_results = 1; pkt.u.alter_resp.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); @@ -635,6 +699,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) GUID_from_string(NDR_GUID, &pkt.u.alter_resp.ctx_list[0].syntax.uuid); pkt.u.alter_resp.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; pkt.u.alter_resp.auth_info = data_blob(NULL, 0); + pkt.u.alter_resp.secondary_address = ""; if (!dcesrv_auth_alter_ack(call, &pkt)) { return dcesrv_bind_nak(call, 0); -- cgit From fae215266b6711b24f4893653b146751885e4e5f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Jan 2005 16:53:02 +0000 Subject: r4690: - add support for async rpc server replies the backend should check for (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_MAY_ASYNC) then it's allowed to reply async then the backend should mark that call as async with dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; later it has to manualy set r->out.result and then send the reply by calling status = dcesrv_reply(p->dce_call); NOTE: that ncacn_np doesn't support async replies yet - implement an async version of echo_TestSleep - reenable the echo_TestSleep torture test (this need to be more strict when we have support for async ncacn_np) metze (This used to be commit f0a0dbeb25b034b1333078ca085999359f5f6209) --- source4/rpc_server/dcerpc_server.c | 221 +++++++++++++++++++++---------------- 1 file changed, 125 insertions(+), 96 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 925004b191..f031bcb50b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -3,8 +3,8 @@ server side dcerpc core code - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Stefan (metze) Metzmacher 2004 + Copyright (C) Andrew Tridgell 2003-2005 + Copyright (C) Stefan (metze) Metzmacher 2004-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 @@ -27,6 +27,7 @@ #include "auth/auth.h" #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" +#include "events.h" /* see if two endpoints match @@ -286,10 +287,8 @@ static int dcesrv_endpoint_destructor(void *ptr) if (c->iface) { c->iface->unbind(c, c->iface); } - talloc_free(c); } - return 0; } @@ -298,28 +297,32 @@ static int dcesrv_endpoint_destructor(void *ptr) connect to a dcerpc endpoint */ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, + TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, - struct dcesrv_connection **p) + struct server_connection *srv_conn, + struct dcesrv_connection **_p) { - *p = talloc_p(dce_ctx, struct dcesrv_connection); - if (! *p) { - return NT_STATUS_NO_MEMORY; - } - - (*p)->dce_ctx = dce_ctx; - (*p)->endpoint = ep; - (*p)->contexts = NULL; - (*p)->call_list = NULL; - (*p)->cli_max_recv_frag = 0; - (*p)->partial_input = data_blob(NULL, 0); - (*p)->auth_state.auth_info = NULL; - (*p)->auth_state.gensec_security = NULL; - (*p)->auth_state.session_info = NULL; - (*p)->auth_state.session_key = dcesrv_generic_session_key; - (*p)->srv_conn = NULL; - - talloc_set_destructor(*p, dcesrv_endpoint_destructor); - + struct dcesrv_connection *p; + + p = talloc(mem_ctx, struct dcesrv_connection); + NT_STATUS_HAVE_NO_MEMORY(p); + + p->dce_ctx = dce_ctx; + p->endpoint = ep; + p->contexts = NULL; + p->call_list = NULL; + p->pending_call_list = NULL; + p->cli_max_recv_frag = 0; + p->partial_input = data_blob(NULL, 0); + p->auth_state.auth_info = NULL; + p->auth_state.gensec_security = NULL; + p->auth_state.session_info = NULL; + p->auth_state.session_key = dcesrv_generic_session_key; + p->srv_conn = srv_conn; + + talloc_set_destructor(p, dcesrv_endpoint_destructor); + + *_p = p; return NT_STATUS_OK; } @@ -327,8 +330,10 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, search and connect to a dcerpc endpoint */ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, + TALLOC_CTX *mem_ctx, const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, + struct server_connection *srv_conn, struct dcesrv_connection **dce_conn_p) { NTSTATUS status; @@ -340,7 +345,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = dcesrv_endpoint_connect(dce_ctx, ep, dce_conn_p); + status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, srv_conn, dce_conn_p); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -730,26 +735,24 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) { struct ndr_pull *pull; - struct ndr_push *push; - void *r; NTSTATUS status; - DATA_BLOB stub; - uint32_t total_length; struct dcesrv_connection_context *context; - call->fault_code = 0; + call->fault_code = 0; + call->state_flags = call->conn->dce_ctx->state_flags; + call->time = timeval_current(); context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id); if (context == NULL) { return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } - call->context = context; - pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); - if (!pull) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(pull); + + call->context = context; + call->event_ctx = context->conn->srv_conn->event.ctx; + call->ndr_pull = pull; if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_ORPC) { pull->flags |= LIBNDR_FLAG_OBJECT_PRESENT; @@ -760,7 +763,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* unravel the NDR for the packet */ - status = context->iface->ndr_pull(call, call, pull, &r); + status = context->iface->ndr_pull(call, call, pull, &call->r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, call->fault_code); } @@ -772,27 +775,49 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* call the dispatch function */ - status = context->iface->dispatch(call, call, r); + status = context->iface->dispatch(call, call, call->r); + if (!NT_STATUS_IS_OK(status)) { + return dcesrv_fault(call, call->fault_code); + } + + /* add the call to the pending list */ + DLIST_ADD_END(call->conn->pending_call_list, call, struct dcesrv_call_state *); + + if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) { + return NT_STATUS_OK; + } + + return dcesrv_reply(call); +} + +NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) +{ + struct ndr_push *push; + NTSTATUS status; + DATA_BLOB stub; + uint32_t total_length; + struct dcesrv_connection_context *context = call->context; + + /* call the reply function */ + status = context->iface->reply(call, call, call->r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, call->fault_code); } /* form the reply NDR */ push = ndr_push_init_ctx(call); - if (!push) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(push); /* carry over the pointer count to the reply in case we are using full pointer. See NDR specification for full pointers */ - push->ptr_count = pull->ptr_count; + push->ptr_count = call->ndr_pull->ptr_count; if (lp_rpc_big_endian()) { push->flags |= LIBNDR_FLAG_BIGENDIAN; } - status = context->iface->ndr_push(call, call, push, r); + status = context->iface->ndr_push(call, call, push, call->r); if (!NT_STATUS_IS_OK(status)) { return dcesrv_fault(call, call->fault_code); } @@ -807,9 +832,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct dcerpc_packet pkt; rep = talloc(call, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(rep); length = stub.length; if (length + DCERPC_RESPONSE_LENGTH > call->conn->cli_max_recv_frag) { @@ -848,8 +871,17 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) stub.length -= length; } while (stub.length != 0); + /* move the call from the pending to the finished calls list */ + DLIST_REMOVE(call->conn->pending_call_list, call); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + if (call->conn->call_list && call->conn->call_list->replies) { + if (call->conn->srv_conn && + call->conn->srv_conn->event.fde) { + call->conn->srv_conn->event.fde->flags |= EVENT_FD_WRITE; + } + } + return NT_STATUS_OK; } @@ -1074,6 +1106,13 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, call = dce_conn->call_list; if (!call || !call->replies) { + if (dce_conn->pending_call_list) { + /* TODO: we need to say act async here + * as we know we have pending requests + * which will be finished at a time + */ + return NT_STATUS_FOOBAR; + } return NT_STATUS_FOOBAR; } rep = call->replies; @@ -1128,83 +1167,73 @@ NTSTATUS dcesrv_output_blob(struct dcesrv_connection *dce_conn, return dcesrv_output(dce_conn, blob, dcesrv_output_blob_write_fn); } -/* - initialise the dcerpc server context -*/ -NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **dce_ctx) +static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, uint32_t state_flags, struct dcesrv_context **_dce_ctx) { + NTSTATUS status; + struct dcesrv_context *dce_ctx; int i; - const char **endpoint_servers = lp_dcerpc_endpoint_servers(); - (*dce_ctx) = talloc_p(mem_ctx, struct dcesrv_context); - if (! *dce_ctx) { - return NT_STATUS_NO_MEMORY; - } - - (*dce_ctx)->endpoint_list = NULL; + DEBUG(1,("dcesrv_init\n")); if (!endpoint_servers) { - DEBUG(3,("dcesrv_init_context: no endpoint servers configured\n")); - return NT_STATUS_OK; + DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n")); + return NT_STATUS_INTERNAL_ERROR; } + dce_ctx = talloc(mem_ctx, struct dcesrv_context); + NT_STATUS_HAVE_NO_MEMORY(dce_ctx); + dce_ctx->endpoint_list = NULL; + dce_ctx->state_flags = state_flags; + for (i=0;endpoint_servers[i];i++) { - NTSTATUS ret; const struct dcesrv_endpoint_server *ep_server; - + ep_server = dcesrv_ep_server_byname(endpoint_servers[i]); if (!ep_server) { DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i])); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_INTERNAL_ERROR; } - ret = ep_server->init_server(*dce_ctx, ep_server); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s'\n", endpoint_servers[i])); - return ret; + status = ep_server->init_server(dce_ctx, ep_server); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i], + nt_errstr(status))); + return status; } } + *_dce_ctx = dce_ctx; return NT_STATUS_OK; } -static void dcesrv_init(struct server_service *service, const struct model_ops *model_ops) +/* + initialise the dcerpc server context +*/ +NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) { + NTSTATUS status; struct dcesrv_context *dce_ctx; - int i; - const char **endpoint_servers = lp_dcerpc_endpoint_servers(); - DEBUG(1,("dcesrv_init\n")); + status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), 0, &dce_ctx); + NT_STATUS_NOT_OK_RETURN(status); - if (!endpoint_servers) { - DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n")); - return; - } - - dce_ctx = talloc_p(service, struct dcesrv_context); - if (!dce_ctx) { - DEBUG(0,("talloc_p(mem_ctx, struct dcesrv_context) failed\n")); - return; - } + *_dce_ctx = dce_ctx; + return NT_STATUS_OK; +} - ZERO_STRUCTP(dce_ctx); - dce_ctx->endpoint_list = NULL; +static void dcesrv_init(struct server_service *service, const struct model_ops *model_ops) +{ + NTSTATUS status; + struct dcesrv_context *dce_ctx; - for (i=0;endpoint_servers[i];i++) { - NTSTATUS ret; - const struct dcesrv_endpoint_server *ep_server; - - ep_server = dcesrv_ep_server_byname(endpoint_servers[i]); - if (!ep_server) { - DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i])); - return; - } + DEBUG(1,("dcesrv_init\n")); - ret = ep_server->init_server(dce_ctx, ep_server); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s'\n", endpoint_servers[i])); - return; - } + status = dcesrv_init_context(service, + lp_dcerpc_endpoint_servers(), + DCESRV_CALL_STATE_FLAG_MAY_ASYNC, + &dce_ctx); + if (!NT_STATUS_IS_OK(status)) { + return; } dcesrv_sock_init(service, model_ops, dce_ctx); @@ -1330,7 +1359,7 @@ static const struct server_service_ops dcesrv_ops = { .send_handler = dcesrv_send, .idle_handler = NULL, .close_connection = dcesrv_close, - .service_exit = dcesrv_exit, + .service_exit = dcesrv_exit, }; const struct server_service_ops *dcesrv_get_ops(void) -- cgit From a2e754c2947d5acd826f15364b7cbf06012e79e7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Jan 2005 11:46:43 +0000 Subject: r4712: slight tidy up in alter_context server (This used to be commit 20ab5bed34c852509b7f3e4c778ff23f4379b36e) --- source4/rpc_server/dcerpc_server.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f031bcb50b..282860b05a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -693,9 +693,8 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) pkt.u.alter_resp.max_xmit_frag = 0x2000; pkt.u.alter_resp.max_recv_frag = 0x2000; pkt.u.alter_resp.assoc_group_id = call->pkt.u.alter.assoc_group_id; - pkt.u.alter_resp.secondary_address = NULL; pkt.u.alter_resp.num_results = 1; - pkt.u.alter_resp.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); + pkt.u.alter_resp.ctx_list = talloc_array(call, struct dcerpc_ack_ctx, 1); if (!pkt.u.alter_resp.ctx_list) { return NT_STATUS_NO_MEMORY; } -- cgit From 9327ec51d11855ec0ceac3ce1f4e0a75c8b57081 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Jan 2005 01:32:56 +0000 Subject: r4728: split up server_services into: - stream_socket services the smb, ldap and rpc service which sets up a srtam socket end then waits for connections and - task services which this you can create a seperate task that do something (this is also going through the process_model subsystem so with -M standard a new process for this created with -M thread a new thread ... I'll add datagram services later when we whave support for datagram sockets in lib/socket/ see the next commit as an example for service_task's metze (This used to be commit d5fa02746c6569b09b6e05785642da2fad3ba3e0) --- source4/rpc_server/dcerpc_server.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 282860b05a..1fcd9a3261 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1220,7 +1220,7 @@ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_d return NT_STATUS_OK; } -static void dcesrv_init(struct server_service *service, const struct model_ops *model_ops) +static void dcesrv_init(struct server_service *service) { NTSTATUS status; struct dcesrv_context *dce_ctx; @@ -1235,7 +1235,9 @@ static void dcesrv_init(struct server_service *service, const struct model_ops * return; } - dcesrv_sock_init(service, model_ops, dce_ctx); + service->service.private_data = dce_ctx; + + dcesrv_sock_init(service); return; } @@ -1257,18 +1259,6 @@ static void dcesrv_send(struct server_connection *srv_conn, dcesrv_sock_send(srv_conn, t, flags); } -static void dcesrv_close(struct server_connection *srv_conn, const char *reason) -{ - dcesrv_sock_close(srv_conn, reason); - return; -} - -static void dcesrv_exit(struct server_service *service, const char *reason) -{ - dcesrv_sock_exit(service, reason); - return; -} - /* the list of currently registered DCERPC endpoint servers. */ static struct ep_server { @@ -1350,15 +1340,24 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) return &critical_sizes; } -static const struct server_service_ops dcesrv_ops = { +static const struct server_stream_ops dcesrv_stream_ops = { .name = "rpc", - .service_init = dcesrv_init, + .socket_init = NULL, .accept_connection = dcesrv_accept, .recv_handler = dcesrv_recv, .send_handler = dcesrv_send, .idle_handler = NULL, - .close_connection = dcesrv_close, - .service_exit = dcesrv_exit, + .close_connection = NULL +}; + +const struct server_stream_ops *dcesrv_get_stream_ops(void) +{ + return &dcesrv_stream_ops; +} + +static const struct server_service_ops dcesrv_ops = { + .name = "rpc", + .service_init = dcesrv_init, }; const struct server_service_ops *dcesrv_get_ops(void) -- cgit From 61a3d370b98ca4b75cd61e22f0d6b0f3fb7561b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 11:58:52 +0000 Subject: r4758: - added async support to the session request code - added async support to the negprot client code - removed two unused parameters from smbcli_full_connection() code - converted smbclient to use smbcli_full_connection() rather than reinventing everything itself (This used to be commit 71cbe2873473e039b4511511302cb63f1c50bce8) --- source4/rpc_server/dcerpc_server.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1fcd9a3261..40335e4246 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1172,8 +1172,6 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s struct dcesrv_context *dce_ctx; int i; - DEBUG(1,("dcesrv_init\n")); - if (!endpoint_servers) { DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n")); return NT_STATUS_INTERNAL_ERROR; -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/rpc_server/dcerpc_server.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 40335e4246..575c073e46 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -179,7 +179,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* check if this endpoint exists */ if ((ep=find_endpoint(dce_ctx, &binding))==NULL) { - ep = talloc_p(dce_ctx, struct dcesrv_endpoint); + ep = talloc(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } @@ -196,7 +196,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } /* talloc a new interface list element */ - ifl = talloc_p(dce_ctx, struct dcesrv_if_list); + ifl = talloc(dce_ctx, struct dcesrv_if_list); if (!ifl) { return NT_STATUS_NO_MEMORY; } @@ -396,7 +396,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - rep = talloc_p(call, struct dcesrv_call_reply); + rep = talloc(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -433,7 +433,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.reject_reason = reason; pkt.u.bind_nak.num_versions = 0; - rep = talloc_p(call, struct dcesrv_call_reply); + rep = talloc(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } @@ -544,7 +544,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.secondary_address = ""; } pkt.u.bind_ack.num_results = 1; - pkt.u.bind_ack.ctx_list = talloc_p(call, struct dcerpc_ack_ctx); + pkt.u.bind_ack.ctx_list = talloc(call, struct dcerpc_ack_ctx); if (!pkt.u.bind_ack.ctx_list) { return NT_STATUS_NO_MEMORY; } @@ -709,7 +709,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - rep = talloc_p(call, struct dcesrv_call_reply); + rep = talloc(call, struct dcesrv_call_reply); if (!rep) { return NT_STATUS_NO_MEMORY; } -- cgit From 55d4d36993293fee914a009f1d8f05810e347f2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 00:54:57 +0000 Subject: r5102: This is a major simplification of the logic for controlling top level servers in smbd. The old code still contained a fairly bit of legacy from the time when smbd was only handling SMB connection. The new code gets rid of all of the smb_server specific code in smbd/, and creates a much simpler infrastructures for new server code. Major changes include: - simplified the process model code a lot. - got rid of the top level server and service structures completely. The top level context is now the event_context. This got rid of service.h and server.h completely (they were the most confusing parts of the old code) - added service_stream.[ch] for the helper functions that are specific to stream type services (services that handle streams, and use a logically separate process per connection) - got rid of the builtin idle_handler code in the service logic, as none of the servers were using it, and it can easily be handled by a server in future by adding its own timed_event to the event context. - fixed some major memory leaks in the rpc server code. - added registration of servers, rather than hard coding our list of possible servers. This allows for servers as modules in the future. - temporarily disabled the winbind code until I add the helper functions for that type of server - added error checking on service startup. If a configured server fails to startup then smbd doesn't startup. - cleaned up the command line handling in smbd, removing unused options (This used to be commit cf6a46c3cbde7b1eb1b86bd3882b953a2de3a42e) --- source4/rpc_server/dcerpc_server.c | 81 +++++++++----------------------------- 1 file changed, 18 insertions(+), 63 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 575c073e46..c21ab3d883 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -28,6 +28,7 @@ #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" #include "events.h" +#include "smbd/service_stream.h" /* see if two endpoints match @@ -299,7 +300,7 @@ static int dcesrv_endpoint_destructor(void *ptr) NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, - struct server_connection *srv_conn, + struct stream_connection *srv_conn, struct dcesrv_connection **_p) { struct dcesrv_connection *p; @@ -333,7 +334,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, - struct server_connection *srv_conn, + struct stream_connection *srv_conn, struct dcesrv_connection **dce_conn_p) { NTSTATUS status; @@ -1204,7 +1205,7 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s } /* - initialise the dcerpc server context + initialise the dcerpc server context for ncacn_np based services */ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) { @@ -1218,45 +1219,6 @@ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_d return NT_STATUS_OK; } -static void dcesrv_init(struct server_service *service) -{ - NTSTATUS status; - struct dcesrv_context *dce_ctx; - - DEBUG(1,("dcesrv_init\n")); - - status = dcesrv_init_context(service, - lp_dcerpc_endpoint_servers(), - DCESRV_CALL_STATE_FLAG_MAY_ASYNC, - &dce_ctx); - if (!NT_STATUS_IS_OK(status)) { - return; - } - - service->service.private_data = dce_ctx; - - dcesrv_sock_init(service); - - return; -} - -static void dcesrv_accept(struct server_connection *srv_conn) -{ - dcesrv_sock_accept(srv_conn); -} - -static void dcesrv_recv(struct server_connection *srv_conn, - struct timeval t, uint16_t flags) -{ - dcesrv_sock_recv(srv_conn, t, flags); -} - -static void dcesrv_send(struct server_connection *srv_conn, - struct timeval t, uint16_t flags) -{ - dcesrv_sock_send(srv_conn, t, flags); -} - /* the list of currently registered DCERPC endpoint servers. */ static struct ep_server { @@ -1338,32 +1300,25 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) return &critical_sizes; } -static const struct server_stream_ops dcesrv_stream_ops = { - .name = "rpc", - .socket_init = NULL, - .accept_connection = dcesrv_accept, - .recv_handler = dcesrv_recv, - .send_handler = dcesrv_send, - .idle_handler = NULL, - .close_connection = NULL -}; - -const struct server_stream_ops *dcesrv_get_stream_ops(void) +/* + initialise the dcerpc server context for socket based services +*/ +static NTSTATUS dcesrv_init(struct event_context *event_context, const struct model_ops *model_ops) { - return &dcesrv_stream_ops; -} + NTSTATUS status; + struct dcesrv_context *dce_ctx; -static const struct server_service_ops dcesrv_ops = { - .name = "rpc", - .service_init = dcesrv_init, -}; + status = dcesrv_init_context(event_context, + lp_dcerpc_endpoint_servers(), + DCESRV_CALL_STATE_FLAG_MAY_ASYNC, + &dce_ctx); + NT_STATUS_NOT_OK_RETURN(status); -const struct server_service_ops *dcesrv_get_ops(void) -{ - return &dcesrv_ops; + return dcesrv_sock_init(dce_ctx, event_context, model_ops); } + NTSTATUS server_service_rpc_init(void) { - return NT_STATUS_OK; + return register_server_service("rpc", dcesrv_init); } -- cgit From 66170ef8b36b499aa5b44ef10c1bd362a50f2636 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 02:35:52 +0000 Subject: r5185: make all the events data structures private to events.c. This will make it possible to add optimisations to the events code such as keeping the next timed event in a sorted list, and using epoll for file descriptor events. I also removed the loop events code, as it wasn't being used anywhere, and changed timed events to always be one-shot (as adding a new timed event in the event handler is so easy to do if needed) (This used to be commit d7b4b6de51342a65bf46fce772d313f92f8d73d3) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c21ab3d883..51902ecb87 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -878,7 +878,7 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) if (call->conn->call_list && call->conn->call_list->replies) { if (call->conn->srv_conn && call->conn->srv_conn->event.fde) { - call->conn->srv_conn->event.fde->flags |= EVENT_FD_WRITE; + EVENT_FD_WRITEABLE(call->conn->srv_conn->event.fde); } } -- cgit From 131dc76d56df40b3511c47e54f15412a25b491f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 11:56:03 +0000 Subject: r5197: moved events code to lib/events/ (suggestion from metze) (This used to be commit 7f54c8a339f36aa43c9340be70ab7f0067593ef2) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 51902ecb87..63f8187f24 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -27,7 +27,7 @@ #include "auth/auth.h" #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" -#include "events.h" +#include "lib/events/events.h" #include "smbd/service_stream.h" /* -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 63f8187f24..c0cd221da6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -609,7 +609,7 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) /* handle a bind request */ -static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32 context_id) +static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_t context_id) { uint32_t if_version, transfer_syntax_version; const char *uuid, *transfer_syntax; -- cgit From df643022136a4b229aca817f5b57f7302a97f852 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Mar 2005 08:34:43 +0000 Subject: r5902: A rather large change... I wanted to add a simple 'workstation' argument to the DCERPC authenticated binding calls, but this patch kind of grew from there. With SCHANNEL, the 'workstation' name (the netbios name of the client) matters, as this is what ties the session between the NETLOGON ops and the SCHANNEL bind. This changes a lot of files, and these will again be changed when jelmer does the credentials work. I also correct some schannel IDL to distinguish between workstation names and account names. The distinction matters for domain trust accounts. Issues in handling this (issues with lifetime of talloc pointers) caused me to change the 'creds_CredentialsState' and 'struct dcerpc_binding' pointers to always be talloc()ed pointers. In the schannel DB, we now store both the domain and computername, and query on both. This should ensure we fault correctly when the domain is specified incorrectly in the SCHANNEL bind. In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out, where the comment claimed we re-used a connection, but in fact we made a new connection. This was achived by breaking apart some of the dcerpc_secondary_connection() logic. The addition of workstation handling was also propogated to NTLMSSP and GENSEC, for completeness. The RPC-SAMSYNC test has been cleaned up a little, using a loop over usernames/passwords rather than manually expanded tests. This will be expanded further (the code in #if 0 in this patch) to use a newly created user account for testing. In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO server, caused by the removal of [ref] and the assoicated pointer from the IDL. This has been re-added, until the underlying pidl issues are solved. (This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9) --- source4/rpc_server/dcerpc_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c0cd221da6..b050830883 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -58,7 +58,7 @@ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx, { struct dcesrv_endpoint *ep; for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) { - if (endpoints_match(&ep->ep_description, ep_description)) { + if (endpoints_match(ep->ep_description, ep_description)) { return ep; } } @@ -166,7 +166,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, { struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; - struct dcerpc_binding binding; + struct dcerpc_binding *binding; BOOL add_ep = False; NTSTATUS status; @@ -179,13 +179,13 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, /* check if this endpoint exists */ - if ((ep=find_endpoint(dce_ctx, &binding))==NULL) { + if ((ep=find_endpoint(dce_ctx, binding))==NULL) { ep = talloc(dce_ctx, struct dcesrv_endpoint); if (!ep) { return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(ep); - ep->ep_description = binding; + ep->ep_description = talloc_reference(ep, binding); add_ep = True; } -- cgit From 6b6bb89c91d412ef7d8c355fdd005de228af62c2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 30 Apr 2005 08:17:13 +0000 Subject: r6526: Rename this RPC fault. Everybody else calls this ACCESS_DENIED, and it certainly doesn't make sense as LOGON_FAILURE. Andrew Bartlett (This used to be commit 4bec3d3f378ed8b988e00441c9bb5718b8548ba6) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b050830883..cb1cdc9416 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -963,7 +963,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) if (call->pkt.ptype == DCERPC_PKT_REQUEST && !dcesrv_auth_request(call, &blob)) { dce_partial_advance(dce_conn, blob.length); - return dcesrv_fault(call, DCERPC_FAULT_LOGON_FAILURE); + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); } dce_partial_advance(dce_conn, blob.length); -- cgit From fa24196d0d5c7373317894865b7a88d972762101 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 10 May 2005 11:04:04 +0000 Subject: r6705: let the gensec module decide if messages can be signed and sealed in a different order than a strict request - reply sequence Note: we should also fix the client code... metze (This used to be commit 0a61d1f65150546f7a7582512ca010d156f963bf) --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cb1cdc9416..12e24859ec 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -742,6 +742,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) call->state_flags = call->conn->dce_ctx->state_flags; call->time = timeval_current(); + if (!gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { + call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC; + } + context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id); if (context == NULL) { return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); -- cgit From b5da6b2c853b2aca572435ef989148adbf2f3ff0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 10 May 2005 16:30:51 +0000 Subject: r6714: We can only ask GENSEC questions if we are authenticated. Andrew Bartlett (This used to be commit b429712f1e8234c64138aaa8ff67dce94988406c) --- source4/rpc_server/dcerpc_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 12e24859ec..52da43a35e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -742,7 +742,9 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) call->state_flags = call->conn->dce_ctx->state_flags; call->time = timeval_current(); - if (!gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { + /* if authenticated, and the mech we use can't do async replies, don't use them... */ + if (call->conn->auth_state.gensec_security && + !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC; } -- cgit From e427f58622e3d88c59953d6c1fb583acfb046213 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 25 May 2005 13:50:27 +0000 Subject: r6973: Merge new version of pidl into the main SAMBA_4_0 branch. The main difference in this new version is the extra data structure generated between the IDL data structure and the NDR parser: IDL -> NDR -> { ndr_parser, ndr_header, eparser, etc } This makes the ndr_parser.pm internals much more sane. Other changes include: - Remove unnecessary calls with NDR_BUFFERS (for example, GUID doesn't have any buffers, just scalars) as well as some (unnecessary) nested setting of flags. - Parse array loops in the C code rather then calling ndr_pull_array(). This allows us to have, for example, arrays of pointers or arrays of pointers to arrays, etc.. - Use if() {} rather then if () goto foo; everywhere - NDR_IN no longer implies LIBNDR_FLAG_REF_ALLOC - By default, top level pointers are now "ref" (as is the default in most other IDL compilers). This can be overridden using the default_pointer_top() property. - initial work on new ethereal parser generators by Alan DeKok and me - pidl now writes errors in the standard format used by compilers, which is parsable by most editors - ability to warn about the fact that pidl extension(s) have been used, useful for making sure IDL files work with other IDL compilers. oh, and there's probably some other things I can't think of right now.. (This used to be commit 13cf227615f6b9e0e5fa62e59197024410254f01) --- source4/rpc_server/dcerpc_server.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 52da43a35e..241986a4b1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -756,6 +756,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); NT_STATUS_HAVE_NO_MEMORY(pull); + pull->flags |= LIBNDR_FLAG_REF_ALLOC; + call->context = context; call->event_ctx = context->conn->srv_conn->event.ctx; call->ndr_pull = pull; -- cgit From 430dc36c1a456607826cedb9610d2a39cb923bd5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Jun 2005 23:05:37 +0000 Subject: r7312: Add IDL for ncadg packets. (This used to be commit 2009a430b03c685dd65bd573e70d3618f2e0dd0f) --- source4/rpc_server/dcerpc_server.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 241986a4b1..3882da08d8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -363,7 +363,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, } -static void dcesrv_init_hdr(struct dcerpc_packet *pkt) +static void dcesrv_init_hdr(struct ncacn_packet *pkt) { pkt->rpc_vers = 5; pkt->rpc_vers_minor = 0; @@ -382,7 +382,7 @@ static void dcesrv_init_hdr(struct dcerpc_packet *pkt) */ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) { - struct dcerpc_packet pkt; + struct ncacn_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; @@ -421,7 +421,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code */ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) { - struct dcerpc_packet pkt; + struct ncacn_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; @@ -460,7 +460,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) { const char *uuid, *transfer_syntax; uint32_t if_version, transfer_syntax_version; - struct dcerpc_packet pkt; + struct ncacn_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; uint32_t result=0, reason=0; @@ -660,7 +660,7 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ */ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { - struct dcerpc_packet pkt; + struct ncacn_packet pkt; struct dcesrv_call_reply *rep; NTSTATUS status; uint32_t result=0, reason=0; @@ -837,7 +837,7 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) do { uint32_t length; struct dcesrv_call_reply *rep; - struct dcerpc_packet pkt; + struct ncacn_packet pkt; rep = talloc(call, struct dcesrv_call_reply); NT_STATUS_HAVE_NO_MEMORY(rep); @@ -959,7 +959,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } - status = ndr_pull_dcerpc_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); + status = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); if (!NT_STATUS_IS_OK(status)) { talloc_free(dce_conn->partial_input.data); talloc_free(call); -- cgit From fcc74fc060ff6e721c78cde0ace517c3d91325f3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 5 Jun 2005 23:39:00 +0000 Subject: r7313: Prefix a few functions with ncacn_ rather then dcerpc_ because they are ncacn_ specific (This used to be commit 875cce126878172eedb43b4ecab3970ea9d82e4a) --- source4/rpc_server/dcerpc_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3882da08d8..f3495ab01c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -402,7 +402,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call, &pkt, NULL); + status = ncacn_push_auth(&rep->data, call, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -439,7 +439,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call, &pkt, NULL); + status = ncacn_push_auth(&rep->data, call, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -573,7 +573,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call, &pkt, + status = ncacn_push_auth(&rep->data, call, &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; @@ -715,7 +715,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - status = dcerpc_push_auth(&rep->data, call, &pkt, + status = ncacn_push_auth(&rep->data, call, &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; -- cgit From f021c2da15ac549c253ddc2c0cb4f15fba7bdc07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Jun 2005 12:49:51 +0000 Subject: r7755: fixed an uninitialised event_ctx found by abartlet (This used to be commit 1462da3b6d190eecfb82268e6f2f04a42d8d5298) --- source4/rpc_server/dcerpc_server.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f3495ab01c..700892b49c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -941,9 +941,10 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) talloc_free(dce_conn->partial_input.data); return NT_STATUS_NO_MEMORY; } - call->conn = dce_conn; - call->replies = NULL; - call->context = NULL; + call->conn = dce_conn; + call->replies = NULL; + call->context = NULL; + call->event_ctx = dce_conn->srv_conn->event.ctx; blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); -- cgit From f0420c029299fd503dd6980484e970a9a141d523 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Jun 2005 06:03:11 +0000 Subject: r7800: added the same request serialisation logic to our socket based rpc servers as I added to the smb server yesterday. This means rpc server code can assume it runs serially unless it explicitly sets the async flag on the request and returns (This used to be commit 8546adb56aa4dda608a176409c243b074aeca77d) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 700892b49c..f4059e4a46 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -320,6 +320,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->auth_state.session_info = NULL; p->auth_state.session_key = dcesrv_generic_session_key; p->srv_conn = srv_conn; + p->processing = False; talloc_set_destructor(p, dcesrv_endpoint_destructor); -- cgit From 382fc485b2285434f7613255da7b3e894222dcf3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Jun 2005 07:31:45 +0000 Subject: r7927: fixed an error on partial socket writes in the rpc server (This used to be commit 3c7b5de67294ef161289af7da6716b44ffc5d526) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f4059e4a46..709216db46 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1103,7 +1103,7 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) write_fn() should return the number of bytes successfully written. - this will return STATUS_BUFFER_OVERFLOW if there is more to be read + this will return STATUS_BUFFER_OVERFLOW if there is more to be written from the current fragment */ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, -- cgit From 939cb07232fc522ff53b32a6f201a8ff951aa4ae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Jun 2005 01:59:51 +0000 Subject: r8006: I have seen w2k3 send multiple encoding syntaxes in rpc bind requests. This is a simple change to accept that, as long as the first one is NDR. (This used to be commit 330293ddff39266abb688c6292e59472ff47aebe) --- source4/rpc_server/dcerpc_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 709216db46..87f8c9a421 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -468,7 +468,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; - if (call->pkt.u.bind.num_contexts != 1 || + if (call->pkt.u.bind.num_contexts < 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { return dcesrv_bind_nak(call, 0); } @@ -493,6 +493,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) strcasecmp(NDR_GUID, transfer_syntax) != 0 || NDR_GUID_VERSION != transfer_syntax_version) { /* we only do NDR encoded dcerpc */ + DEBUG(0,("Non NDR transfer syntax requested - %s\n", transfer_syntax)); return dcesrv_bind_nak(call, 0); } -- cgit From 8a300c9248cc956d2aaed59e89efc2535a9f60f5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Jun 2005 17:10:03 +0000 Subject: r8021: we only need to return STATUS_BUFFER_OVERFLOW for the ipc_trans replies and not for the ipc_read() replies as here the client explicit says how much data it wants the write_fn() in dcesrv_output() now returns NTSTATUS and the ipc specific implementations are moved to the ntvfs_ipc module metze (This used to be commit fe483dcd874b7243d61e9623840c672b4ea06b2c) --- source4/rpc_server/dcerpc_server.c | 49 +++++++------------------------------- 1 file changed, 9 insertions(+), 40 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 87f8c9a421..15da8c6964 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1100,20 +1100,19 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) The first argument to write_fn() will be 'private', the second will be a pointer to a buffer containing the data to be sent and the 3rd - will be the number of bytes to be sent. + will be a pointer to a size_t variable that will be set to the + number of bytes that are consumed from the output. - write_fn() should return the number of bytes successfully written. - - this will return STATUS_BUFFER_OVERFLOW if there is more to be written from the current fragment */ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, - void *private, - ssize_t (*write_fn)(void *, DATA_BLOB *)) + void *private_data, + NTSTATUS (*write_fn)(void *private_data, DATA_BLOB *output, size_t *nwritten)) { + NTSTATUS status; struct dcesrv_call_state *call; struct dcesrv_call_reply *rep; - ssize_t nwritten; + size_t nwritten; call = dce_conn->call_list; if (!call || !call->replies) { @@ -1128,12 +1127,8 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, } rep = call->replies; - nwritten = write_fn(private, &rep->data); - if (nwritten == -1) { - /* TODO: hmm, how do we cope with this? destroy the - connection perhaps? */ - return NT_STATUS_UNSUCCESSFUL; - } + status = write_fn(private_data, &rep->data, &nwritten); + NT_STATUS_IS_ERR_RETURN(status); rep->data.length -= nwritten; rep->data.data += nwritten; @@ -1141,8 +1136,6 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (rep->data.length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); - } else { - return STATUS_BUFFER_OVERFLOW; } if (call->replies == NULL) { @@ -1151,31 +1144,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, talloc_free(call); } - return NT_STATUS_OK; -} - - -/* - write_fn() for dcesrv_output_blob() -*/ -static ssize_t dcesrv_output_blob_write_fn(void *private, DATA_BLOB *out) -{ - DATA_BLOB *blob = private; - if (out->length < blob->length) { - blob->length = out->length; - } - memcpy(blob->data, out->data, blob->length); - return blob->length; -} - -/* - a simple wrapper for dcesrv_output() for when we want to output - into a data blob -*/ -NTSTATUS dcesrv_output_blob(struct dcesrv_connection *dce_conn, - DATA_BLOB *blob) -{ - return dcesrv_output(dce_conn, blob, dcesrv_output_blob_write_fn); + return status; } static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, uint32_t state_flags, struct dcesrv_context **_dce_ctx) -- cgit From 5afa0a2d62de1be027190190d97e4c46201c977b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Jun 2005 19:24:29 +0000 Subject: r8023: use a pointer to a DATA_BLOB for each reply, that will allow the write_fn callback of dcesrv_output() to reference the memory with a valid TALLOC pointer metze (This used to be commit d0574d407f426f5c001e943dee5c03d24f4fb21c) --- source4/rpc_server/dcerpc_server.c | 79 +++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 40 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 15da8c6964..3976173824 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -399,16 +399,15 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code pkt.u.fault.status = fault_code; rep = talloc(call, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(rep); - status = ncacn_push_auth(&rep->data, call, &pkt, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + rep->data = talloc(call, DATA_BLOB); + NT_STATUS_HAVE_NO_MEMORY(rep->data); + + status = ncacn_push_auth(rep->data, call, &pkt, NULL); + NT_STATUS_NOT_OK_RETURN(status); - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(rep->data, rep->data->length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -436,16 +435,15 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.num_versions = 0; rep = talloc(call, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(rep); - status = ncacn_push_auth(&rep->data, call, &pkt, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + rep->data = talloc(call, DATA_BLOB); + NT_STATUS_HAVE_NO_MEMORY(rep->data); + + status = ncacn_push_auth(rep->data, call, &pkt, NULL); + NT_STATUS_NOT_OK_RETURN(status); - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(rep->data, rep->data->length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -571,17 +569,16 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } rep = talloc(call, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(rep); - status = ncacn_push_auth(&rep->data, call, &pkt, - call->conn->auth_state.auth_info); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + rep->data = talloc(call, DATA_BLOB); + NT_STATUS_HAVE_NO_MEMORY(rep->data); + + status = ncacn_push_auth(rep->data, call, &pkt, + call->conn->auth_state.auth_info); + NT_STATUS_NOT_OK_RETURN(status); - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(rep->data, rep->data->length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -713,17 +710,16 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } rep = talloc(call, struct dcesrv_call_reply); - if (!rep) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(rep); - status = ncacn_push_auth(&rep->data, call, &pkt, - call->conn->auth_state.auth_info); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + rep->data = talloc(call, DATA_BLOB); + NT_STATUS_HAVE_NO_MEMORY(rep->data); + + status = ncacn_push_auth(rep->data, call, &pkt, + call->conn->auth_state.auth_info); + NT_STATUS_IS_OK_RETURN(status); - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(rep->data, rep->data->length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -844,6 +840,9 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) rep = talloc(call, struct dcesrv_call_reply); NT_STATUS_HAVE_NO_MEMORY(rep); + rep->data = talloc(call, DATA_BLOB); + NT_STATUS_HAVE_NO_MEMORY(rep->data); + length = stub.length; if (length + DCERPC_RESPONSE_LENGTH > call->conn->cli_max_recv_frag) { /* the 32 is to cope with signing data */ @@ -869,11 +868,11 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) pkt.u.response.stub_and_verifier.data = stub.data; pkt.u.response.stub_and_verifier.length = length; - if (!dcesrv_auth_response(call, &rep->data, &pkt)) { + if (!dcesrv_auth_response(call, rep->data, &pkt)) { return dcesrv_fault(call, DCERPC_FAULT_OTHER); } - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(rep->data, rep->data->length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -1127,13 +1126,13 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, } rep = call->replies; - status = write_fn(private_data, &rep->data, &nwritten); + status = write_fn(private_data, rep->data, &nwritten); NT_STATUS_IS_ERR_RETURN(status); - rep->data.length -= nwritten; - rep->data.data += nwritten; + rep->data->length -= nwritten; + rep->data->data += nwritten; - if (rep->data.length == 0) { + if (rep->data->length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); } -- cgit From 8ab3f59a10d00357cb129a2051fd0f694b5c8081 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Jul 2005 06:05:49 +0000 Subject: r8036: revert rev 8023/8024 as they have a bugs. metze (This used to be commit 66d6b1d5783cba98f2f8e1c8eed1bdc26a5bad4f) --- source4/rpc_server/dcerpc_server.c | 79 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 39 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3976173824..15da8c6964 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -399,15 +399,16 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code pkt.u.fault.status = fault_code; rep = talloc(call, struct dcesrv_call_reply); - NT_STATUS_HAVE_NO_MEMORY(rep); - - rep->data = talloc(call, DATA_BLOB); - NT_STATUS_HAVE_NO_MEMORY(rep->data); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } - status = ncacn_push_auth(rep->data, call, &pkt, NULL); - NT_STATUS_NOT_OK_RETURN(status); + status = ncacn_push_auth(&rep->data, call, &pkt, NULL); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - dcerpc_set_frag_length(rep->data, rep->data->length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -435,15 +436,16 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.num_versions = 0; rep = talloc(call, struct dcesrv_call_reply); - NT_STATUS_HAVE_NO_MEMORY(rep); - - rep->data = talloc(call, DATA_BLOB); - NT_STATUS_HAVE_NO_MEMORY(rep->data); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } - status = ncacn_push_auth(rep->data, call, &pkt, NULL); - NT_STATUS_NOT_OK_RETURN(status); + status = ncacn_push_auth(&rep->data, call, &pkt, NULL); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - dcerpc_set_frag_length(rep->data, rep->data->length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -569,16 +571,17 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } rep = talloc(call, struct dcesrv_call_reply); - NT_STATUS_HAVE_NO_MEMORY(rep); - - rep->data = talloc(call, DATA_BLOB); - NT_STATUS_HAVE_NO_MEMORY(rep->data); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } - status = ncacn_push_auth(rep->data, call, &pkt, - call->conn->auth_state.auth_info); - NT_STATUS_NOT_OK_RETURN(status); + status = ncacn_push_auth(&rep->data, call, &pkt, + call->conn->auth_state.auth_info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - dcerpc_set_frag_length(rep->data, rep->data->length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -710,16 +713,17 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } rep = talloc(call, struct dcesrv_call_reply); - NT_STATUS_HAVE_NO_MEMORY(rep); - - rep->data = talloc(call, DATA_BLOB); - NT_STATUS_HAVE_NO_MEMORY(rep->data); + if (!rep) { + return NT_STATUS_NO_MEMORY; + } - status = ncacn_push_auth(rep->data, call, &pkt, - call->conn->auth_state.auth_info); - NT_STATUS_IS_OK_RETURN(status); + status = ncacn_push_auth(&rep->data, call, &pkt, + call->conn->auth_state.auth_info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - dcerpc_set_frag_length(rep->data, rep->data->length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); @@ -840,9 +844,6 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) rep = talloc(call, struct dcesrv_call_reply); NT_STATUS_HAVE_NO_MEMORY(rep); - rep->data = talloc(call, DATA_BLOB); - NT_STATUS_HAVE_NO_MEMORY(rep->data); - length = stub.length; if (length + DCERPC_RESPONSE_LENGTH > call->conn->cli_max_recv_frag) { /* the 32 is to cope with signing data */ @@ -868,11 +869,11 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) pkt.u.response.stub_and_verifier.data = stub.data; pkt.u.response.stub_and_verifier.length = length; - if (!dcesrv_auth_response(call, rep->data, &pkt)) { + if (!dcesrv_auth_response(call, &rep->data, &pkt)) { return dcesrv_fault(call, DCERPC_FAULT_OTHER); } - dcerpc_set_frag_length(rep->data, rep->data->length); + dcerpc_set_frag_length(&rep->data, rep->data.length); DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); @@ -1126,13 +1127,13 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, } rep = call->replies; - status = write_fn(private_data, rep->data, &nwritten); + status = write_fn(private_data, &rep->data, &nwritten); NT_STATUS_IS_ERR_RETURN(status); - rep->data->length -= nwritten; - rep->data->data += nwritten; + rep->data.length -= nwritten; + rep->data.data += nwritten; - if (rep->data->length == 0) { + if (rep->data.length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); } -- cgit From 6553dd0c60e922f42de347a02c8f792f087c393c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 28 Jul 2005 00:27:28 +0000 Subject: r8811: Fix the build.. (This used to be commit fac77f5fa267da57a55e88cad8993897e80741a0) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 15da8c6964..29583ce4ed 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -23,6 +23,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_epmapper.h" +#include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/gen_ndr/ndr_oxidresolver.h" #include "auth/auth.h" #include "dlinklist.h" -- cgit From 227e0c6d67f04adfaa4ace6fa51556d69c7eed4f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Aug 2005 10:12:55 +0000 Subject: r9384: added a debug to show the dcerpc fault code for any calls we fault (This used to be commit 92ed69695b2a5459e79f3edb37790a17de5a66c6) --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 29583ce4ed..d1ee53b538 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -788,6 +788,10 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) /* call the dispatch function */ status = context->iface->dispatch(call, call, call->r); if (!NT_STATUS_IS_OK(status)) { + DEBUG(5,("dcerpc fault in call %s:%02x - %s\n", + context->iface->name, + call->pkt.u.request.opnum, + dcerpc_errstr(pull, call->fault_code))); return dcesrv_fault(call, call->fault_code); } -- cgit From a8ec371a61d5786f40ebb29f3e79b3ec45c3ffbe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Sep 2005 11:26:05 +0000 Subject: r10078: - add a 'struct data_blob_list_item' - use this for the send_queue's of the different stream_servers to not redefine the same struct so often, and it maybe will be used in other places too metze (This used to be commit b6694f067ab7aff0ee303dbfe8a6e7fad801e7e9) --- source4/rpc_server/dcerpc_server.c | 60 +++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d1ee53b538..a00d697520 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -385,7 +385,7 @@ static void dcesrv_init_hdr(struct ncacn_packet *pkt) static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) { struct ncacn_packet pkt; - struct dcesrv_call_reply *rep; + struct data_blob_list_item *rep; NTSTATUS status; /* setup a bind_ack */ @@ -399,19 +399,19 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; - rep = talloc(call, struct dcesrv_call_reply); + rep = talloc(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->data, call, &pkt, NULL); + status = ncacn_push_auth(&rep->blob, call, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(&rep->blob, rep->blob.length); - DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; @@ -424,7 +424,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) { struct ncacn_packet pkt; - struct dcesrv_call_reply *rep; + struct data_blob_list_item *rep; NTSTATUS status; /* setup a bind_nak */ @@ -436,19 +436,19 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.u.bind_nak.reject_reason = reason; pkt.u.bind_nak.num_versions = 0; - rep = talloc(call, struct dcesrv_call_reply); + rep = talloc(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->data, call, &pkt, NULL); + status = ncacn_push_auth(&rep->blob, call, &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(&rep->blob, rep->blob.length); - DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; @@ -463,7 +463,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) const char *uuid, *transfer_syntax; uint32_t if_version, transfer_syntax_version; struct ncacn_packet pkt; - struct dcesrv_call_reply *rep; + struct data_blob_list_item *rep; NTSTATUS status; uint32_t result=0, reason=0; uint32_t context_id; @@ -571,20 +571,20 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } } - rep = talloc(call, struct dcesrv_call_reply); + rep = talloc(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->data, call, &pkt, + status = ncacn_push_auth(&rep->blob, call, &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(&rep->blob, rep->blob.length); - DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; @@ -664,7 +664,7 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { struct ncacn_packet pkt; - struct dcesrv_call_reply *rep; + struct data_blob_list_item *rep; NTSTATUS status; uint32_t result=0, reason=0; uint32_t context_id; @@ -713,20 +713,20 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - rep = talloc(call, struct dcesrv_call_reply); + rep = talloc(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->data, call, &pkt, + status = ncacn_push_auth(&rep->blob, call, &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(&rep->blob, rep->blob.length); - DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; @@ -843,10 +843,10 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) do { uint32_t length; - struct dcesrv_call_reply *rep; + struct data_blob_list_item *rep; struct ncacn_packet pkt; - rep = talloc(call, struct dcesrv_call_reply); + rep = talloc(call, struct data_blob_list_item); NT_STATUS_HAVE_NO_MEMORY(rep); length = stub.length; @@ -874,13 +874,13 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) pkt.u.response.stub_and_verifier.data = stub.data; pkt.u.response.stub_and_verifier.length = length; - if (!dcesrv_auth_response(call, &rep->data, &pkt)) { + if (!dcesrv_auth_response(call, &rep->blob, &pkt)) { return dcesrv_fault(call, DCERPC_FAULT_OTHER); } - dcerpc_set_frag_length(&rep->data, rep->data.length); + dcerpc_set_frag_length(&rep->blob, rep->blob.length); - DLIST_ADD_END(call->replies, rep, struct dcesrv_call_reply *); + DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); stub.data += length; stub.length -= length; @@ -1116,7 +1116,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, { NTSTATUS status; struct dcesrv_call_state *call; - struct dcesrv_call_reply *rep; + struct data_blob_list_item *rep; size_t nwritten; call = dce_conn->call_list; @@ -1132,13 +1132,13 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, } rep = call->replies; - status = write_fn(private_data, &rep->data, &nwritten); + status = write_fn(private_data, &rep->blob, &nwritten); NT_STATUS_IS_ERR_RETURN(status); - rep->data.length -= nwritten; - rep->data.data += nwritten; + rep->blob.length -= nwritten; + rep->blob.data += nwritten; - if (rep->data.length == 0) { + if (rep->blob.length == 0) { /* we're done with this section of the call */ DLIST_REMOVE(call->replies, rep); } -- cgit From ca92ed140c7caef19225ec2024260e1c56244eab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Sep 2005 14:35:51 +0000 Subject: r10580: More generic approach for adding endpoints (This used to be commit 0ef7fe6f4c979dcc3a0ab268253e493d8e929dd7) --- source4/rpc_server/dcerpc_server.c | 39 +++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a00d697520..17a097a4cc 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -30,6 +30,7 @@ #include "rpc_server/dcerpc_server.h" #include "lib/events/events.h" #include "smbd/service_stream.h" +#include "system/filesys.h" /* see if two endpoints match @@ -1286,12 +1287,13 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) } /* - initialise the dcerpc server context for socket based services + initialise the dcerpc server context */ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct model_ops *model_ops) { NTSTATUS status; struct dcesrv_context *dce_ctx; + struct dcesrv_endpoint *e; status = dcesrv_init_context(event_context, lp_dcerpc_endpoint_servers(), @@ -1299,9 +1301,40 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo &dce_ctx); NT_STATUS_NOT_OK_RETURN(status); - return dcesrv_sock_init(dce_ctx, event_context, model_ops); -} + /* Make sure the directory for NCALRPC exists */ + if (!directory_exist(lp_ncalrpc_dir())) { + mkdir(lp_ncalrpc_dir(), 0755); + } + + for (e=dce_ctx->endpoint_list;e;e=e->next) { + switch (e->ep_description->transport) { + case NCACN_UNIX_STREAM: + status = dcesrv_add_ep_unix(dce_ctx, e, event_context, model_ops); + NT_STATUS_NOT_OK_RETURN(status); + break; + + case NCALRPC: + status = dcesrv_add_ep_ncalrpc(dce_ctx, e, event_context, model_ops); + NT_STATUS_NOT_OK_RETURN(status); + break; + + case NCACN_IP_TCP: + status = dcesrv_add_ep_tcp(dce_ctx, e, event_context, model_ops); + NT_STATUS_NOT_OK_RETURN(status); + break; + + case NCACN_NP: +/* FIXME: status = dcesrv_add_ep_np(dce_ctx, e, event_context, model_ops); + NT_STATUS_NOT_OK_RETURN(status); */ + break; + + default: + return NT_STATUS_NOT_SUPPORTED; + } + } + return NT_STATUS_OK; +} NTSTATUS server_service_rpc_init(void) { -- cgit From 448483199fb436309735f5203b3282fca2c517ec Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 16:46:55 +0000 Subject: r12494: Support loading modules from .so files for most subsystems. We now use a different system for initializing the modules for a subsystem. Most subsystems now have an init function that looks something like this: init_module_fn static_init[] = STATIC_AUTH_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "auth"); run_init_functions(static_init); run_init_functions(shared_init); talloc_free(shared_init); I hope to eliminate the other init functions later on (the init_programname_subsystems; defines). (This used to be commit b6d2ad4ce0a91c4be790dd258820c492ff1787ea) --- source4/rpc_server/dcerpc_server.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 17a097a4cc..276779ef19 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1338,5 +1338,13 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo NTSTATUS server_service_rpc_init(void) { + init_module_fn static_init[] = STATIC_DCERPC_MODULES; + init_module_fn *shared_init = load_samba_modules(NULL, "rpc_server"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + return register_server_service("rpc", dcesrv_init); } -- cgit From 6aafed9600a3fa05932668c70fc0e20f3724dab6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:48:23 +0000 Subject: r12499: Move smb_build.h out of includes.h (This used to be commit c92ace494f92084ddf178626cdf392d151043bc7) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 276779ef19..a8724b5bb8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -31,6 +31,7 @@ #include "lib/events/events.h" #include "smbd/service_stream.h" #include "system/filesys.h" +#include "smb_build.h" /* see if two endpoints match -- cgit From d658de65d32e6746ac51aeb4da7aa74b3da40c2b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 16:22:35 +0000 Subject: r12512: Use GUID structs in API functions everywhere rather then converting back and forth between GUID structs and strings in several places. (This used to be commit 3564e2f967ef72d6301b4f7e9a311cebcded4d75) --- source4/rpc_server/dcerpc_server.c | 58 +++++++++++++++----------------------- 1 file changed, 23 insertions(+), 35 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a8724b5bb8..facf6bc0af 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -87,15 +87,8 @@ static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_conne static BOOL interface_match(const struct dcesrv_interface *if1, const struct dcesrv_interface *if2) { - if (if1->if_version != if2->if_version) { - return False; - } - - if (strcmp(if1->uuid, if2->uuid)==0) { - return True; - } - - return False; + return (if1->if_version == if2->if_version && + GUID_equal(&if1->uuid, &if2->uuid)); } /* @@ -117,24 +110,16 @@ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoin see if a uuid and if_version match to an interface */ static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, - const char *uuid, uint32_t if_version) + const struct GUID *uuid, uint32_t if_version) { - if (iface->if_version != if_version) { - return False; - } - - if (strcmp(iface->uuid, uuid)==0) { - return True; - } - - return False; + return (iface->if_version == if_version && GUID_equal(&iface->uuid, uuid)); } /* find the interface operations on an endpoint by uuid */ static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint, - const char *uuid, uint32_t if_version) + const struct GUID *uuid, uint32_t if_version) { struct dcesrv_if_list *ifl; for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) { @@ -462,8 +447,9 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) */ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) { - const char *uuid, *transfer_syntax; + const char *transfer_syntax; uint32_t if_version, transfer_syntax_version; + struct GUID uuid; struct ncacn_packet pkt; struct data_blob_list_item *rep; NTSTATUS status; @@ -484,10 +470,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; - uuid = GUID_string(call, &call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid); - if (!uuid) { - return dcesrv_bind_nak(call, 0); - } + uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid; transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version; transfer_syntax = GUID_string(call, @@ -500,9 +483,12 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return dcesrv_bind_nak(call, 0); } - iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version); + iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version); if (iface == NULL) { - DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); + char *uuid_str = GUID_string(call, &uuid); + DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version)); + talloc_free(uuid_str); + /* we don't know about that interface */ result = DCERPC_BIND_PROVIDER_REJECT; reason = DCERPC_BIND_REASON_ASYNTAX; @@ -567,8 +553,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) if (iface) { status = iface->bind(call, iface); if (!NT_STATUS_IS_OK(status)) { + char *uuid_str = GUID_string(call, &uuid); DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n", - uuid, if_version, nt_errstr(status))); + uuid_str, if_version, nt_errstr(status))); + talloc_free(uuid_str); return dcesrv_bind_nak(call, 0); } } @@ -617,15 +605,13 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_t context_id) { uint32_t if_version, transfer_syntax_version; - const char *uuid, *transfer_syntax; + const char *transfer_syntax; struct dcesrv_connection_context *context; const struct dcesrv_interface *iface; + struct GUID uuid; if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version; - uuid = GUID_string(call, &call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid); - if (!uuid) { - return NT_STATUS_NO_MEMORY; - } + uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid; transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version; transfer_syntax = GUID_string(call, @@ -637,9 +623,11 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ return NT_STATUS_NO_MEMORY; } - iface = find_interface_by_uuid(call->conn->endpoint, uuid, if_version); + iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version); if (iface == NULL) { - DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid, if_version)); + char *uuid_str = GUID_string(call, &uuid); + DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version)); + talloc_free(uuid_str); return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED; } -- cgit From e748b53e4343fbac00a19e8fc76b42624eb5af02 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 16:47:09 +0000 Subject: r12513: Similar change as my previous commit, but now for transfer syntaxes. Avoids converting a static string to GUID every time we check whether a transfer syntax is equal to that of NDR. (This used to be commit 8dcfcaf75ab8cf4a54cf5e56f6be25acc68e3989) --- source4/rpc_server/dcerpc_server.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index facf6bc0af..927d88a4ec 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -447,9 +447,8 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) */ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) { - const char *transfer_syntax; uint32_t if_version, transfer_syntax_version; - struct GUID uuid; + struct GUID uuid, *transfer_syntax_uuid; struct ncacn_packet pkt; struct data_blob_list_item *rep; NTSTATUS status; @@ -473,13 +472,13 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid; transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version; - transfer_syntax = GUID_string(call, - &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid); - if (!transfer_syntax || - strcasecmp(NDR_GUID, transfer_syntax) != 0 || - NDR_GUID_VERSION != transfer_syntax_version) { + transfer_syntax_uuid = &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid; + if (!GUID_equal(&ndr_transfer_syntax.uuid, transfer_syntax_uuid) != 0 || + ndr_transfer_syntax.if_version != transfer_syntax_version) { + char *uuid_str = GUID_string(call, transfer_syntax_uuid); /* we only do NDR encoded dcerpc */ - DEBUG(0,("Non NDR transfer syntax requested - %s\n", transfer_syntax)); + DEBUG(0,("Non NDR transfer syntax requested - %s\n", uuid_str)); + talloc_free(uuid_str); return dcesrv_bind_nak(call, 0); } @@ -542,8 +541,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } pkt.u.bind_ack.ctx_list[0].result = result; pkt.u.bind_ack.ctx_list[0].reason = reason; - GUID_from_string(NDR_GUID, &pkt.u.bind_ack.ctx_list[0].syntax.uuid); - pkt.u.bind_ack.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; + pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax; pkt.u.bind_ack.auth_info = data_blob(NULL, 0); if (!dcesrv_auth_bind_ack(call, &pkt)) { @@ -605,22 +603,19 @@ static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_t context_id) { uint32_t if_version, transfer_syntax_version; - const char *transfer_syntax; struct dcesrv_connection_context *context; const struct dcesrv_interface *iface; - struct GUID uuid; + struct GUID uuid, *transfer_syntax_uuid; if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version; uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid; transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version; - transfer_syntax = GUID_string(call, - &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid); - if (!transfer_syntax || - strcasecmp(NDR_GUID, transfer_syntax) != 0 || - NDR_GUID_VERSION != transfer_syntax_version) { + transfer_syntax_uuid = &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid; + if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax.uuid) || + ndr_transfer_syntax.if_version != transfer_syntax_version) { /* we only do NDR encoded dcerpc */ - return NT_STATUS_NO_MEMORY; + return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED; } iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version); @@ -694,8 +689,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } pkt.u.alter_resp.ctx_list[0].result = result; pkt.u.alter_resp.ctx_list[0].reason = reason; - GUID_from_string(NDR_GUID, &pkt.u.alter_resp.ctx_list[0].syntax.uuid); - pkt.u.alter_resp.ctx_list[0].syntax.if_version = NDR_GUID_VERSION; + pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax; pkt.u.alter_resp.auth_info = data_blob(NULL, 0); pkt.u.alter_resp.secondary_address = ""; -- cgit From 302cab75c33c1fb3127161a930e63df18c05159c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Dec 2005 22:47:22 +0000 Subject: r12554: get rid of the pesky NTLMSSP warnings about being called after processing is finished (This used to be commit ca6ae1afa0a8a105ab09199425f308c9ae85902f) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 927d88a4ec..246f6a7274 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -644,7 +644,7 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ /* - handle a bind request + handle a alter context request */ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) { -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/rpc_server/dcerpc_server.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 246f6a7274..bd8c40e6fd 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -22,9 +22,7 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_epmapper.h" #include "librpc/gen_ndr/ndr_dcerpc.h" -#include "librpc/gen_ndr/ndr_oxidresolver.h" #include "auth/auth.h" #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" -- cgit From 25bb00fbcd409572e1c19c05fdc42c883936780b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 13:41:17 +0000 Subject: r12693: Move core data structures out of smb.h into core.h torture prototypes in seperate header (This used to be commit 73610639b23ca3743077193fa0b1de7c7f65944d) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index bd8c40e6fd..2aeb737f5e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1319,7 +1319,7 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo NTSTATUS server_service_rpc_init(void) { - init_module_fn static_init[] = STATIC_DCERPC_MODULES; + init_module_fn static_init[] = STATIC_DCERPC_SERVER_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "rpc_server"); run_init_functions(static_init); -- cgit From ad6303f82fa862111c239b32b39f299e563a0802 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Jan 2006 12:58:38 +0000 Subject: r13208: Clearly separate named pipes from the IPC$ NTVFS type. This allows the easy addition of additional named pipes and removes the circular dependencies between the CIFS, RPC and RAP servers. Simple tests for a custom named pipe included. (This used to be commit 898d15acbd18e3b302a856c847e08c22c5024792) --- source4/rpc_server/dcerpc_server.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 2aeb737f5e..0c50c4aaaa 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1171,21 +1171,6 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s return NT_STATUS_OK; } -/* - initialise the dcerpc server context for ncacn_np based services -*/ -NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) -{ - NTSTATUS status; - struct dcesrv_context *dce_ctx; - - status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), 0, &dce_ctx); - NT_STATUS_NOT_OK_RETURN(status); - - *_dce_ctx = dce_ctx; - return NT_STATUS_OK; -} - /* the list of currently registered DCERPC endpoint servers. */ static struct ep_server { @@ -1305,8 +1290,8 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo break; case NCACN_NP: -/* FIXME: status = dcesrv_add_ep_np(dce_ctx, e, event_context, model_ops); - NT_STATUS_NOT_OK_RETURN(status); */ + status = dcesrv_add_ep_np(dce_ctx, e, event_context, model_ops); + NT_STATUS_NOT_OK_RETURN(status); break; default: -- cgit From 713b296441ec8b1447a0bc451720a8b84fd7e1fc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Jan 2006 20:08:03 +0000 Subject: r13210: Revert my named pipes patch until it passes not just 'make quicktest' but also 'make test' (This used to be commit e3d0676aee84e96e5c87bed4cd0cde75a4191953) --- source4/rpc_server/dcerpc_server.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 0c50c4aaaa..2aeb737f5e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1171,6 +1171,21 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s return NT_STATUS_OK; } +/* + initialise the dcerpc server context for ncacn_np based services +*/ +NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) +{ + NTSTATUS status; + struct dcesrv_context *dce_ctx; + + status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), 0, &dce_ctx); + NT_STATUS_NOT_OK_RETURN(status); + + *_dce_ctx = dce_ctx; + return NT_STATUS_OK; +} + /* the list of currently registered DCERPC endpoint servers. */ static struct ep_server { @@ -1290,8 +1305,8 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo break; case NCACN_NP: - status = dcesrv_add_ep_np(dce_ctx, e, event_context, model_ops); - NT_STATUS_NOT_OK_RETURN(status); +/* FIXME: status = dcesrv_add_ep_np(dce_ctx, e, event_context, model_ops); + NT_STATUS_NOT_OK_RETURN(status); */ break; default: -- cgit From 80c8a522861068e7b0974986936f65052dd6f70f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 12:48:13 +0000 Subject: r13655: Use new name of build header (This used to be commit bca0e8054f6d9c7adc9d92e0c30d4323f994c9e9) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 2aeb737f5e..29648b9e33 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -29,7 +29,7 @@ #include "lib/events/events.h" #include "smbd/service_stream.h" #include "system/filesys.h" -#include "smb_build.h" +#include "build.h" /* see if two endpoints match -- cgit From 45c92c9cf08210e1d5792e2d8db93912727c3dba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 11:02:47 +0000 Subject: r13923: make the state_flags per dcesrv_connection this will may help with a generic named pipe solution metze (This used to be commit c6fa9bd15cdb096c3dfc7a4109d9298933981255) --- source4/rpc_server/dcerpc_server.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 29648b9e33..74f8dfe8d5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -287,6 +287,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, struct stream_connection *srv_conn, + uint32_t state_flags, struct dcesrv_connection **_p) { struct dcesrv_connection *p; @@ -307,6 +308,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->auth_state.session_key = dcesrv_generic_session_key; p->srv_conn = srv_conn; p->processing = False; + p->state_flags = state_flags; talloc_set_destructor(p, dcesrv_endpoint_destructor); @@ -322,6 +324,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, struct stream_connection *srv_conn, + uint32_t state_flags, struct dcesrv_connection **dce_conn_p) { NTSTATUS status; @@ -333,7 +336,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, srv_conn, dce_conn_p); + status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, srv_conn, state_flags, dce_conn_p); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -724,7 +727,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) struct dcesrv_connection_context *context; call->fault_code = 0; - call->state_flags = call->conn->dce_ctx->state_flags; + call->state_flags = call->conn->state_flags; call->time = timeval_current(); /* if authenticated, and the mech we use can't do async replies, don't use them... */ @@ -1134,7 +1137,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, return status; } -static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, uint32_t state_flags, struct dcesrv_context **_dce_ctx) +static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx) { NTSTATUS status; struct dcesrv_context *dce_ctx; @@ -1148,7 +1151,6 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s dce_ctx = talloc(mem_ctx, struct dcesrv_context); NT_STATUS_HAVE_NO_MEMORY(dce_ctx); dce_ctx->endpoint_list = NULL; - dce_ctx->state_flags = state_flags; for (i=0;endpoint_servers[i];i++) { const struct dcesrv_endpoint_server *ep_server; @@ -1179,7 +1181,7 @@ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_d NTSTATUS status; struct dcesrv_context *dce_ctx; - status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), 0, &dce_ctx); + status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx); NT_STATUS_NOT_OK_RETURN(status); *_dce_ctx = dce_ctx; @@ -1278,7 +1280,6 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo status = dcesrv_init_context(event_context, lp_dcerpc_endpoint_servers(), - DCESRV_CALL_STATE_FLAG_MAY_ASYNC, &dce_ctx); NT_STATUS_NOT_OK_RETURN(status); -- cgit From 4ac2be99588b48b0652a524bf12fb1aa9c3f5fbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 11:07:23 +0000 Subject: r13924: Split more prototypes out of include/proto.h + initial work on header file dependencies (This used to be commit 122835876748a3eaf5e8d31ad1abddab9acb8781) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 74f8dfe8d5..3e92ce0ef3 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -29,6 +29,7 @@ #include "lib/events/events.h" #include "smbd/service_stream.h" #include "system/filesys.h" +#include "libcli/security/proto.h" #include "build.h" /* -- cgit From 9bd7dd912124d8ffda6f9967d6ba358c16be2aa0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 12:08:58 +0000 Subject: r13926: More header splitups. (This used to be commit 930daa9f416ecba1d75b8ad46bb42e336545672f) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3e92ce0ef3..3b38353ba4 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -28,6 +28,7 @@ #include "rpc_server/dcerpc_server.h" #include "lib/events/events.h" #include "smbd/service_stream.h" +#include "smbd/proto.h" #include "system/filesys.h" #include "libcli/security/proto.h" #include "build.h" -- cgit From 0de1ad5ae621ad99d507b38d3eb2e2015b2fbd71 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 13:22:00 +0000 Subject: r13937: fix the build metze (This used to be commit 7aabff829836580be8816f38a6e0ef5b7c3bb565) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 3b38353ba4..1229d26323 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -28,7 +28,7 @@ #include "rpc_server/dcerpc_server.h" #include "lib/events/events.h" #include "smbd/service_stream.h" -#include "smbd/proto.h" +#include "smbd/service.h" #include "system/filesys.h" #include "libcli/security/proto.h" #include "build.h" -- cgit From 306b12ad4943737f6810df9237ab93b64c931fbd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 9 Mar 2006 19:55:04 +0000 Subject: r14094: Use saner module directory names, fix loading of server service modules. (This used to be commit b6ffad3860ba2cf9d8f3423d65be91dcfc962ca2) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1229d26323..ab40a642c4 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1322,7 +1322,7 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo NTSTATUS server_service_rpc_init(void) { - init_module_fn static_init[] = STATIC_DCERPC_SERVER_MODULES; + init_module_fn static_init[] = STATIC_dcerpc_server_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "rpc_server"); run_init_functions(static_init); -- cgit From bfcaa4000e11c84fb31abe11a1631ea3c4ca4c31 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 9 Mar 2006 20:36:01 +0000 Subject: r14096: setup a service task for smbsrv and dcesrv metze (This used to be commit 7ad522c7acfe276d08bf59e851697fe93fa622db) --- source4/rpc_server/dcerpc_server.c | 46 +++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ab40a642c4..da0bc8fd6f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -27,6 +27,7 @@ #include "dlinklist.h" #include "rpc_server/dcerpc_server.h" #include "lib/events/events.h" +#include "smbd/service_task.h" #include "smbd/service_stream.h" #include "smbd/service.h" #include "system/filesys.h" @@ -1272,18 +1273,20 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) } /* - initialise the dcerpc server context + open the dcerpc server sockets */ -static NTSTATUS dcesrv_init(struct event_context *event_context, const struct model_ops *model_ops) +static void dcesrv_task_init(struct task_server *task) { NTSTATUS status; struct dcesrv_context *dce_ctx; struct dcesrv_endpoint *e; - status = dcesrv_init_context(event_context, + task_server_set_title(task, "task[dcesrv]"); + + status = dcesrv_init_context(task->event_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx); - NT_STATUS_NOT_OK_RETURN(status); + if (!NT_STATUS_IS_OK(status)) goto failed; /* Make sure the directory for NCALRPC exists */ if (!directory_exist(lp_ncalrpc_dir())) { @@ -1293,31 +1296,44 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, const struct mo for (e=dce_ctx->endpoint_list;e;e=e->next) { switch (e->ep_description->transport) { case NCACN_UNIX_STREAM: - status = dcesrv_add_ep_unix(dce_ctx, e, event_context, model_ops); - NT_STATUS_NOT_OK_RETURN(status); + status = dcesrv_add_ep_unix(dce_ctx, e, task->event_ctx, task->model_ops); + if (!NT_STATUS_IS_OK(status)) goto failed; break; case NCALRPC: - status = dcesrv_add_ep_ncalrpc(dce_ctx, e, event_context, model_ops); - NT_STATUS_NOT_OK_RETURN(status); + status = dcesrv_add_ep_ncalrpc(dce_ctx, e, task->event_ctx, task->model_ops); + if (!NT_STATUS_IS_OK(status)) goto failed; break; case NCACN_IP_TCP: - status = dcesrv_add_ep_tcp(dce_ctx, e, event_context, model_ops); - NT_STATUS_NOT_OK_RETURN(status); + status = dcesrv_add_ep_tcp(dce_ctx, e, task->event_ctx, task->model_ops); + if (!NT_STATUS_IS_OK(status)) goto failed; break; case NCACN_NP: -/* FIXME: status = dcesrv_add_ep_np(dce_ctx, e, event_context, model_ops); - NT_STATUS_NOT_OK_RETURN(status); */ - break; +/* FIXME: status = dcesrv_add_ep_np(dce_ctx, e, task->event_ctx, task->model_ops); + if (!NT_STATUS_IS_OK(status)) goto failed; +*/ break; default: - return NT_STATUS_NOT_SUPPORTED; + status = NT_STATUS_NOT_SUPPORTED; + if (!NT_STATUS_IS_OK(status)) goto failed; } } - return NT_STATUS_OK; + return; +failed: + task_server_terminate(task, "Failed to startup dcerpc server task"); +} + +/* + called on startup of the smb server service It's job is to start + listening on all configured sockets +*/ +static NTSTATUS dcesrv_init(struct event_context *event_context, + const struct model_ops *model_ops) +{ + return task_server_startup(event_context, model_ops, dcesrv_task_init); } NTSTATUS server_service_rpc_init(void) -- cgit From a949db7c6d4bd35df59ba066111e6566172d4814 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Mar 2006 18:46:49 +0000 Subject: r14486: remove the need of a stream_connection on a dcesrv_connection, and let the transport set callbacks for getting the own and peer socket_address metze (This used to be commit 56fac3ddbbeecb834e5c7a439df344e11fe12a7b) --- source4/rpc_server/dcerpc_server.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index da0bc8fd6f..f4780eaf38 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -289,7 +289,7 @@ static int dcesrv_endpoint_destructor(void *ptr) NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, - struct stream_connection *srv_conn, + struct event_context *event_ctx, uint32_t state_flags, struct dcesrv_connection **_p) { @@ -309,9 +309,10 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->auth_state.gensec_security = NULL; p->auth_state.session_info = NULL; p->auth_state.session_key = dcesrv_generic_session_key; - p->srv_conn = srv_conn; + p->event_ctx = event_ctx; p->processing = False; p->state_flags = state_flags; + ZERO_STRUCT(p->transport); talloc_set_destructor(p, dcesrv_endpoint_destructor); @@ -326,7 +327,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, - struct stream_connection *srv_conn, + struct event_context *event_ctx, uint32_t state_flags, struct dcesrv_connection **dce_conn_p) { @@ -339,7 +340,7 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, srv_conn, state_flags, dce_conn_p); + status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, event_ctx, state_flags, dce_conn_p); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -750,7 +751,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pull->flags |= LIBNDR_FLAG_REF_ALLOC; call->context = context; - call->event_ctx = context->conn->srv_conn->event.ctx; + call->event_ctx = context->conn->event_ctx; call->ndr_pull = pull; if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_ORPC) { @@ -879,15 +880,31 @@ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); if (call->conn->call_list && call->conn->call_list->replies) { - if (call->conn->srv_conn && - call->conn->srv_conn->event.fde) { - EVENT_FD_WRITEABLE(call->conn->srv_conn->event.fde); + if (call->conn->transport.report_output_data) { + call->conn->transport.report_output_data(call->conn); } } return NT_STATUS_OK; } +struct socket_address *dcesrv_connection_get_my_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx) +{ + if (!conn->transport.get_my_addr) { + return NULL; + } + + return conn->transport.get_my_addr(conn, mem_ctx); +} + +struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx) +{ + if (!conn->transport.get_peer_addr) { + return NULL; + } + + return conn->transport.get_peer_addr(conn, mem_ctx); +} /* work out if we have a full packet yet @@ -939,7 +956,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) call->conn = dce_conn; call->replies = NULL; call->context = NULL; - call->event_ctx = dce_conn->srv_conn->event.ctx; + call->event_ctx = dce_conn->event_ctx; blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); -- cgit From 8f3a9d2b27b2519569382b13b03b0f9563418221 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Mar 2006 17:57:34 +0000 Subject: r14569: Make more functions public. (This used to be commit da0a4118189d1026e04e46cb73ba90a4a94d8819) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f4780eaf38..121474051e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1115,7 +1115,7 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) from the current fragment */ -NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, +_PUBLIC_ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, void *private_data, NTSTATUS (*write_fn)(void *private_data, DATA_BLOB *output, size_t *nwritten)) { -- cgit From c06acda7d5b78bfd5c098477b1ca9d949092e281 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Mar 2006 18:47:35 +0000 Subject: r14571: More improvements on shared library support in Samba. Only ldb is left now... (This used to be commit e71cca7f0cec62357eba6ba02d13f1c3f04edaa7) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 121474051e..f9eb9e92d7 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1356,7 +1356,7 @@ static NTSTATUS dcesrv_init(struct event_context *event_context, NTSTATUS server_service_rpc_init(void) { init_module_fn static_init[] = STATIC_dcerpc_server_MODULES; - init_module_fn *shared_init = load_samba_modules(NULL, "rpc_server"); + init_module_fn *shared_init = load_samba_modules(NULL, "dcerpc_server"); run_init_functions(static_init); run_init_functions(shared_init); -- cgit From 0ff7e52340aa0e8319a9d0127ae8d6822e1ff301 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Mar 2006 16:23:19 +0000 Subject: r14653: make sure we always have a valid session_info metze (This used to be commit 42b3f83d1c5a4dced146cbc3861bcc838fda26c0) --- source4/rpc_server/dcerpc_server.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f9eb9e92d7..37026f901f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -289,15 +289,25 @@ static int dcesrv_endpoint_destructor(void *ptr) NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, + struct auth_session_info *session_info, struct event_context *event_ctx, uint32_t state_flags, struct dcesrv_connection **_p) { struct dcesrv_connection *p; + if (!session_info) { + return NT_STATUS_ACCESS_DENIED; + } + p = talloc(mem_ctx, struct dcesrv_connection); NT_STATUS_HAVE_NO_MEMORY(p); + if (!talloc_reference(p, session_info)) { + talloc_free(p); + return NT_STATUS_NO_MEMORY; + } + p->dce_ctx = dce_ctx; p->endpoint = ep; p->contexts = NULL; @@ -307,7 +317,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->partial_input = data_blob(NULL, 0); p->auth_state.auth_info = NULL; p->auth_state.gensec_security = NULL; - p->auth_state.session_info = NULL; + p->auth_state.session_info = session_info; p->auth_state.session_key = dcesrv_generic_session_key; p->event_ctx = event_ctx; p->processing = False; @@ -340,12 +350,9 @@ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, event_ctx, state_flags, dce_conn_p); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, session_info, event_ctx, state_flags, dce_conn_p); + NT_STATUS_NOT_OK_RETURN(status); - (*dce_conn_p)->auth_state.session_info = talloc_reference((*dce_conn_p), session_info); (*dce_conn_p)->auth_state.session_key = dcesrv_inherited_session_key; /* TODO: check security descriptor of the endpoint here -- cgit From ff573597613e8253ff1b9d6c6a69cd127a9e4fb5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 Mar 2006 11:40:16 +0000 Subject: r14715: Correct the definition of the DCE/RPC bind_nak, per the OpenGroup spec. This allows us to correctly parse the bind_nak from NT4, when we use an invalid auth type (the unsupported SPNEGO).. Andrew Bartlett (This used to be commit ce0c7f86fd5eeeacad885d732b66c65ac9103ace) --- source4/rpc_server/dcerpc_server.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 37026f901f..4c39333e86 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -433,7 +433,9 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) pkt.ptype = DCERPC_PKT_BIND_NAK; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.u.bind_nak.reject_reason = reason; - pkt.u.bind_nak.num_versions = 0; + if (pkt.u.bind_nak.reject_reason == DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED) { + pkt.u.bind_nak.versions.v.num_versions = 0; + } rep = talloc(call, struct data_blob_list_item); if (!rep) { @@ -527,8 +529,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) /* handle any authentication that is being requested */ if (!dcesrv_auth_bind(call)) { - /* TODO: work out the right reject code */ - return dcesrv_bind_nak(call, 0); + return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE); } /* setup a bind_ack */ -- cgit From 42da534d66c14c60844568246a2862da7b49f1d5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 26 Mar 2006 00:59:17 +0000 Subject: r14735: Use dcerpc_syntax_id rather then seperate GUID + if_version everywhere (This used to be commit a316b33057f3ec8532677980e093cd327d33f257) --- source4/rpc_server/dcerpc_server.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4c39333e86..f161075fa6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -88,8 +88,8 @@ static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_conne static BOOL interface_match(const struct dcesrv_interface *if1, const struct dcesrv_interface *if2) { - return (if1->if_version == if2->if_version && - GUID_equal(&if1->uuid, &if2->uuid)); + return (if1->syntax_id.if_version == if2->syntax_id.if_version && + GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid)); } /* @@ -113,7 +113,8 @@ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoin static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version) { - return (iface->if_version == if_version && GUID_equal(&iface->uuid, uuid)); + return (iface->syntax_id.if_version == if_version && + GUID_equal(&iface->syntax_id.uuid, uuid)); } /* -- cgit From 1af925f394b1084779f5b1b5a10c2ec512d7e5be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 2 Apr 2006 12:02:01 +0000 Subject: r14860: create libcli/security/security.h metze (This used to be commit 9ec706238c173992dc938d537bdf1103bf519dbf) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f161075fa6..d5012c0609 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -31,7 +31,7 @@ #include "smbd/service_stream.h" #include "smbd/service.h" #include "system/filesys.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "build.h" /* -- cgit From 5c3a1d76ffc7b9e41846f7eaf6039f58184737a0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 18:11:15 +0000 Subject: r15379: Fix shared library build's unresolved dependencies (This used to be commit 0fafa2e59566f8f892d7dfd7dd33d0100b96a780) --- source4/rpc_server/dcerpc_server.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d5012c0609..b56e397cf0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -149,7 +149,7 @@ static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_ /* register an interface on an endpoint */ -NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, +_PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, const char *ep_name, const struct dcesrv_interface *iface, const struct security_descriptor *sd) @@ -256,7 +256,7 @@ NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, /* fetch the user session key - may be default (above) or the SMB session key */ -NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, +_PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { return p->auth_state.session_key(p, session_key); @@ -334,7 +334,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, /* search and connect to a dcerpc endpoint */ -NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, +_PUBLIC_ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, @@ -803,7 +803,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_reply(call); } -NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) +_PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) { struct ndr_push *push; NTSTATUS status; @@ -1087,7 +1087,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) provide some input to a dcerpc endpoint server. This passes data from a dcerpc client into the server */ -NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) +_PUBLIC_ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; @@ -1205,7 +1205,7 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s /* initialise the dcerpc server context for ncacn_np based services */ -NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) +_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) { NTSTATUS status; struct dcesrv_context *dce_ctx; @@ -1232,7 +1232,7 @@ static int num_ep_servers; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -NTSTATUS dcerpc_register_ep_server(const void *_ep_server) +_PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server) { const struct dcesrv_endpoint_server *ep_server = _ep_server; -- cgit From e941cc3003f84de4d7846c4f19ce5d006e9f8e98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 11:39:50 +0000 Subject: r15772: pass the messaging context and server_id to the dcerpc server subsystem metze (This used to be commit fb1debf219089188d1a8233ab3ff4ff314f7df0b) --- source4/rpc_server/dcerpc_server.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b56e397cf0..394bd45cea 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -292,6 +292,8 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, struct event_context *event_ctx, + struct messaging_context *msg_ctx, + uint32_t server_id, uint32_t state_flags, struct dcesrv_connection **_p) { @@ -321,6 +323,8 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->auth_state.session_info = session_info; p->auth_state.session_key = dcesrv_generic_session_key; p->event_ctx = event_ctx; + p->msg_ctx = msg_ctx; + p->server_id = server_id; p->processing = False; p->state_flags = state_flags; ZERO_STRUCT(p->transport); @@ -339,6 +343,8 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, const struct dcerpc_binding *ep_description, struct auth_session_info *session_info, struct event_context *event_ctx, + struct messaging_context *msg_ctx, + uint32_t server_id, uint32_t state_flags, struct dcesrv_connection **dce_conn_p) { @@ -351,7 +357,9 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, session_info, event_ctx, state_flags, dce_conn_p); + status = dcesrv_endpoint_connect(dce_ctx, mem_ctx, ep, session_info, + event_ctx, msg_ctx, server_id, + state_flags, dce_conn_p); NT_STATUS_NOT_OK_RETURN(status); (*dce_conn_p)->auth_state.session_key = dcesrv_inherited_session_key; -- cgit From 151713d694508ce5af39aebbb00ace214361732b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 21 May 2006 14:59:02 +0000 Subject: r15777: Fix unresolved symbols in shared library build. (This used to be commit 3fb9f07a7576c465853b03916cb7c0e87e68a276) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 394bd45cea..a0a0148959 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -905,7 +905,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) return NT_STATUS_OK; } -struct socket_address *dcesrv_connection_get_my_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx) +_PUBLIC_ struct socket_address *dcesrv_connection_get_my_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx) { if (!conn->transport.get_my_addr) { return NULL; @@ -914,7 +914,7 @@ struct socket_address *dcesrv_connection_get_my_addr(struct dcesrv_connection *c return conn->transport.get_my_addr(conn, mem_ctx); } -struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx) +_PUBLIC_ struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_connection *conn, TALLOC_CTX *mem_ctx) { if (!conn->transport.get_peer_addr) { return NULL; -- cgit From 92acfc07998da1546182579ad12a063f025c9286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:35:06 +0000 Subject: r15855: more talloc_set_destructor() typesafe fixes. nearly done ... (This used to be commit 396d82a231b6e3a91178db08b706626d4d4b420c) --- source4/rpc_server/dcerpc_server.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a0a0148959..fcc1989cec 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -266,10 +266,8 @@ _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, /* destroy a link to an endpoint */ -static int dcesrv_endpoint_destructor(void *ptr) +static int dcesrv_endpoint_destructor(struct dcesrv_connection *p) { - struct dcesrv_connection *p = ptr; - while (p->contexts) { struct dcesrv_connection_context *c = p->contexts; -- cgit From 63aaa6b782bf6b8b2badabd41579fff2a235d526 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jul 2006 13:40:49 +0000 Subject: r17340: initialize elements od dcesrc_call_state in one central place and pass the messaging context to the call metze (This used to be commit 0d7f16d7befa1e8824173d7b9da580e6a92ae4e5) --- source4/rpc_server/dcerpc_server.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fcc1989cec..e7a77d0875 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -745,10 +745,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) NTSTATUS status; struct dcesrv_connection_context *context; - call->fault_code = 0; - call->state_flags = call->conn->state_flags; - call->time = timeval_current(); - /* if authenticated, and the mech we use can't do async replies, don't use them... */ if (call->conn->auth_state.gensec_security && !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) { @@ -766,7 +762,6 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) pull->flags |= LIBNDR_FLAG_REF_ALLOC; call->context = context; - call->event_ctx = context->conn->event_ctx; call->ndr_pull = pull; if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_ORPC) { @@ -963,15 +958,16 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) struct dcesrv_call_state *call; DATA_BLOB blob; - call = talloc(dce_conn, struct dcesrv_call_state); + call = talloc_zero(dce_conn, struct dcesrv_call_state); if (!call) { talloc_free(dce_conn->partial_input.data); return NT_STATUS_NO_MEMORY; } - call->conn = dce_conn; - call->replies = NULL; - call->context = NULL; - call->event_ctx = dce_conn->event_ctx; + call->conn = dce_conn; + call->event_ctx = dce_conn->event_ctx; + call->msg_ctx = dce_conn->msg_ctx; + call->state_flags = call->conn->state_flags; + call->time = timeval_current(); blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e7a77d0875..c467728747 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -24,7 +24,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "auth/auth.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "rpc_server/dcerpc_server.h" #include "lib/events/events.h" #include "smbd/service_task.h" -- cgit From 72c5be634c1f656039c32406213e69bb5c120952 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 11 Sep 2006 06:17:12 +0000 Subject: r18363: Found a rather nasty bug in our fragment handling. We were adding packet fragments onto the *reply* queue, not the recieve queue. This worked, as long as we got a whole packet before we did any reply work, but failed once the backend called a remote LDAP server (and I presume something invoked the event loop). Andrew Bartlett (This used to be commit a0162e0ace48104d94f7b7dd3d2f62a7f42e10c6) --- source4/rpc_server/dcerpc_server.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c467728747..980fd5490b 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -133,12 +133,12 @@ static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv } /* - find a call that is pending in our call list + find the earlier parts of a fragmented call awaiting reassembily */ -static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_conn, uint16_t call_id) +static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id) { struct dcesrv_call_state *c; - for (c=dce_conn->call_list;c;c=c->next) { + for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) { if (c->pkt.call_id == call_id) { return c; } @@ -1013,7 +1013,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) /* this is a continuation of an existing call - find the call then tack it on the end */ - call = dcesrv_find_call(dce_conn, call2->pkt.call_id); + call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); if (!call) { return dcesrv_fault(call2, DCERPC_FAULT_OTHER); } @@ -1049,10 +1049,11 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) } /* this may not be the last pdu in the chain - if its isn't then - just put it on the call_list and wait for the rest */ + just put it on the incoming_fragmented_call_list and wait for the rest */ if (call->pkt.ptype == DCERPC_PKT_REQUEST && !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { - DLIST_ADD_END(dce_conn->call_list, call, struct dcesrv_call_state *); + DLIST_ADD_END(dce_conn->incoming_fragmented_call_list, call, + struct dcesrv_call_state *); return NT_STATUS_OK; } -- cgit From 87c998b1e7c37748d6af6074e2c8ec605403e3a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 11 Sep 2006 06:49:24 +0000 Subject: r18365: When adding a new structure member, always remember to fragment it. Andrew Bartlett (This used to be commit 27259f3632a3fe21cfc5d1375aa630ec0f9f4734) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 980fd5490b..f74e522564 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -313,6 +313,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->endpoint = ep; p->contexts = NULL; p->call_list = NULL; + p->incoming_fragmented_call_list = NULL; p->pending_call_list = NULL; p->cli_max_recv_frag = 0; p->partial_input = data_blob(NULL, 0); -- cgit From 67231dcbb1c31dc128bcc773de67a86c0b795398 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Sep 2006 06:34:21 +0000 Subject: r18779: Not simo's fault, this is actually a bug I introduced a week ago, when I fixed the previous bug in this code. We need to remove fragments from the incoming fragment list, or else we leak (actually, we walk free()'ed data as we add/remove elements). Andrew Bartlett (This used to be commit 77473d2ef9a7673cebb56b398acf390fd51a08c8) --- source4/rpc_server/dcerpc_server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f74e522564..a78c424eaa 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1056,7 +1056,10 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) DLIST_ADD_END(dce_conn->incoming_fragmented_call_list, call, struct dcesrv_call_state *); return NT_STATUS_OK; - } + } + + /* This removes any fragments we may have had stashed away */ + DLIST_REMOVE(dce_conn->incoming_fragmented_call_list, call); switch (call->pkt.ptype) { case DCERPC_PKT_BIND: -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a78c424eaa..08b68b2318 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -24,6 +24,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "auth/auth.h" +#include "auth/gensec/gensec.h" #include "lib/util/dlinklist.h" #include "rpc_server/dcerpc_server.h" #include "lib/events/events.h" -- cgit From 1cd4339b9a2786aa26691ca4f02fa93ab0958b88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 10:52:09 +0000 Subject: r20646: first preparations for cluster enablement. This changes " uint32_t server_id to struct server_id server_id; which allows a server ID to have an node number. The node number will be zero in non-clustered case. This is the most basic hook needed for clustering, and ctdb. (This used to be commit 2365abaa991d57d68c6ebe9be608e01c907102eb) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 08b68b2318..6233a2e088 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -292,7 +292,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, struct auth_session_info *session_info, struct event_context *event_ctx, struct messaging_context *msg_ctx, - uint32_t server_id, + struct server_id server_id, uint32_t state_flags, struct dcesrv_connection **_p) { @@ -344,7 +344,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, struct auth_session_info *session_info, struct event_context *event_ctx, struct messaging_context *msg_ctx, - uint32_t server_id, + struct server_id server_id, uint32_t state_flags, struct dcesrv_connection **dce_conn_p) { -- cgit From 615895332a73ad372bcb5918190cbfff6ba83e05 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 16 Jan 2007 14:44:23 +0000 Subject: r20830: merge mgmt work (This used to be commit 3cc299dbbe278936281f8e7071e6de8ec1bb219c) --- source4/rpc_server/dcerpc_server.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6233a2e088..6af4be9cc1 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -35,6 +35,8 @@ #include "libcli/security/security.h" #include "build.h" +extern const struct dcesrv_interface dcesrv_mgmt_interface; + /* see if two endpoints match */ @@ -178,6 +180,17 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, ZERO_STRUCTP(ep); ep->ep_description = talloc_reference(ep, binding); add_ep = True; + + /* add mgmt interface */ + ifl = talloc(dce_ctx, struct dcesrv_if_list); + if (!ifl) { + return NT_STATUS_NO_MEMORY; + } + + memcpy(&(ifl->iface), &dcesrv_mgmt_interface, + sizeof(struct dcesrv_interface)); + + DLIST_ADD(ep->interface_list, ifl); } /* see if the interface is already registered on te endpoint */ -- cgit From 1b17d9a587bf3600d449c2481fe1191793479e32 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 Feb 2007 11:00:20 +0000 Subject: r21515: add some more PFC_FLAGS from the DCERPC spec, and fix some names also make it possible to pass and get the assoc_group_id for a pipe. also make it possible to pass the DCERPC_PFC_FLAG_CONC_MPX flag in bind requests. From the spec it triggers support for concurrent multiplexing on a single connection. w2k3 uses the assoc_group_id feature when it becomes a domain controller of an existing domain. Know the ugly part, with this it's possible to use a policy handle from one connection on a different one... typically the DsBind() call is on the 1st connection while DsGetNCChanges() call using the first connections bind handle are on the 2nd connection. The second connection also has the DCERPC_PFC_FLAG_CONC_MPX flag attached, but that doesn't seem to be related to the cross connection handle usage Can anyone think of a nice way to implement the assoc_group_id stuff in our server? metze (This used to be commit 2d8c85397d9027485ed6dbdcca87cc1ec84c7b76) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6af4be9cc1..5d718369e4 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -779,7 +779,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) call->context = context; call->ndr_pull = pull; - if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_ORPC) { + if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) { pull->flags |= LIBNDR_FLAG_OBJECT_PRESENT; } -- cgit From ca14957d50d2fcd0b973814d7b16218e4e52f08a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Feb 2007 17:02:28 +0000 Subject: r21589: give an error when the assoc_group_id isn't 0 TODO: we need to correctly implement assoc groups! metze (This used to be commit df7c6c6e0b961eda8daf182df8faed6b29639149) --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 5d718369e4..364ff1a07e 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -492,6 +492,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; + if (call->pkt.u.bind.assoc_group_id != 0) { + return dcesrv_bind_nak(call, 0); + } + if (call->pkt.u.bind.num_contexts < 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { return dcesrv_bind_nak(call, 0); -- cgit From dfb04271eb94d0a64cd776b597b08a732dc6dbbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Mar 2007 22:58:23 +0000 Subject: r21835: fixed a rpc server bug where we failed to remove a call from one linked list when moving it to another. This could cause a valgrind error under the RPC-SCANNER test. (This used to be commit 9ba8c008513e362fbb860af899006505cadb4a2f) --- source4/rpc_server/dcerpc_server.c | 69 ++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 11 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 364ff1a07e..9c7f6dfa28 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -400,6 +400,43 @@ static void dcesrv_init_hdr(struct ncacn_packet *pkt) pkt->drep[3] = 0; } +/* + move a call from an existing linked list to the specified list. This + prevents bugs where we forget to remove the call from a previous + list when moving it. + */ +static void dcesrv_call_set_list(struct dcesrv_call_state *call, + enum dcesrv_call_list list) +{ + switch (call->list) { + case DCESRV_LIST_NONE: + break; + case DCESRV_LIST_CALL_LIST: + DLIST_REMOVE(call->conn->call_list, call); + break; + case DCESRV_LIST_FRAGMENTED_CALL_LIST: + DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call); + break; + case DCESRV_LIST_PENDING_CALL_LIST: + DLIST_REMOVE(call->conn->pending_call_list, call); + break; + } + call->list = list; + switch (list) { + case DCESRV_LIST_NONE: + break; + case DCESRV_LIST_CALL_LIST: + DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + break; + case DCESRV_LIST_FRAGMENTED_CALL_LIST: + DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call, struct dcesrv_call_state *); + break; + case DCESRV_LIST_PENDING_CALL_LIST: + DLIST_ADD_END(call->conn->pending_call_list, call, struct dcesrv_call_state *); + break; + } +} + /* return a dcerpc fault */ @@ -433,7 +470,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code dcerpc_set_frag_length(&rep->blob, rep->blob.length); DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); - DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); return NT_STATUS_OK; } @@ -472,7 +509,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) dcerpc_set_frag_length(&rep->blob, rep->blob.length); DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); - DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); return NT_STATUS_OK; } @@ -612,7 +649,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) dcerpc_set_frag_length(&rep->blob, rep->blob.length); DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); - DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); return NT_STATUS_OK; } @@ -750,7 +787,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) dcerpc_set_frag_length(&rep->blob, rep->blob.length); DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *); - DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); return NT_STATUS_OK; } @@ -814,7 +851,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } /* add the call to the pending list */ - DLIST_ADD_END(call->conn->pending_call_list, call, struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST); if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) { return NT_STATUS_OK; @@ -905,8 +942,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) } while (stub.length != 0); /* move the call from the pending to the finished calls list */ - DLIST_REMOVE(call->conn->pending_call_list, call); - DLIST_ADD_END(call->conn->call_list, call, struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); if (call->conn->call_list && call->conn->call_list->replies) { if (call->conn->transport.report_output_data) { @@ -967,6 +1003,15 @@ static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32_t off data_blob_free(&blob); } +/* + remove the call from the right list when freed + */ +static int dcesrv_call_dequeue(struct dcesrv_call_state *call) +{ + dcesrv_call_set_list(call, DCESRV_LIST_NONE); + return 0; +} + /* process some input to a dcerpc endpoint server. */ @@ -987,6 +1032,9 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) call->msg_ctx = dce_conn->msg_ctx; call->state_flags = call->conn->state_flags; call->time = timeval_current(); + call->list = DCESRV_LIST_NONE; + + talloc_set_destructor(call, dcesrv_call_dequeue); blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); @@ -1071,13 +1119,12 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) just put it on the incoming_fragmented_call_list and wait for the rest */ if (call->pkt.ptype == DCERPC_PKT_REQUEST && !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { - DLIST_ADD_END(dce_conn->incoming_fragmented_call_list, call, - struct dcesrv_call_state *); + dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST); return NT_STATUS_OK; } /* This removes any fragments we may have had stashed away */ - DLIST_REMOVE(dce_conn->incoming_fragmented_call_list, call); + dcesrv_call_set_list(call, DCESRV_LIST_NONE); switch (call->pkt.ptype) { case DCERPC_PKT_BIND: @@ -1184,7 +1231,7 @@ _PUBLIC_ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, if (call->replies == NULL) { /* we're done with the whole call */ - DLIST_REMOVE(dce_conn->call_list, call); + dcesrv_call_set_list(call, DCESRV_LIST_NONE); talloc_free(call); } -- cgit From ab652246b9b456db30dfb9517a6f96edee5d0dc0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Mar 2007 17:05:39 +0000 Subject: r21911: Some more work on making the ncacn_np handling in smbd be less special. (This used to be commit 52f32b7330ee1a2dd5850fd0e412279777edc00d) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 9c7f6dfa28..fddbc6076a 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1409,9 +1409,9 @@ static void dcesrv_task_init(struct task_server *task) break; case NCACN_NP: -/* FIXME: status = dcesrv_add_ep_np(dce_ctx, e, task->event_ctx, task->model_ops); + status = dcesrv_add_ep_np(dce_ctx, e, task->event_ctx, task->model_ops); if (!NT_STATUS_IS_OK(status)) goto failed; -*/ break; + break; default: status = NT_STATUS_NOT_SUPPORTED; -- cgit From 518f41fec0075aff78bba85f435f0a7876b114d3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 13 May 2007 12:59:42 +0000 Subject: r22825: let longhorn beta3 work with samba4 if we return a zero assoc_group_id longhorn beta3 stops after getting the bind_ack. metze (This used to be commit 09aea65960073cc8b50a4b39531490876f6d89ef) --- source4/rpc_server/dcerpc_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fddbc6076a..95f537c9c2 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -603,7 +603,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; - pkt.u.bind_ack.assoc_group_id = call->pkt.u.bind.assoc_group_id; + /* we need to send a non zero assoc_group_id here to make longhorn happy, it also matches samba3 */ + pkt.u.bind_ack.assoc_group_id = 0x12345678; if (iface) { /* FIXME: Use pipe name as specified by endpoint instead of interface name */ pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name); -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/rpc_server/dcerpc_server.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 95f537c9c2..f9d1606df8 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -8,7 +8,7 @@ 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 - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 85555742b109387f32ecc0e17c6b47681bdf8936 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Aug 2007 05:28:39 +0000 Subject: r24504: Try to return more useful error information on why a bind failed. Note that the correct return for a failed alter_context is a fault, not a bind_nak. Andrew Bartlett (This used to be commit 52cce94532edf1dd7f26e39bf3377f0077ea6792) --- source4/rpc_server/dcerpc_server.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f9d1606df8..35b37b3af6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -620,7 +620,8 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax; pkt.u.bind_ack.auth_info = data_blob(NULL, 0); - if (!dcesrv_auth_bind_ack(call, &pkt)) { + status = dcesrv_auth_bind_ack(call, &pkt); + if (!NT_STATUS_IS_OK(status)) { return dcesrv_bind_nak(call, 0); } @@ -769,8 +770,15 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) pkt.u.alter_resp.auth_info = data_blob(NULL, 0); pkt.u.alter_resp.secondary_address = ""; - if (!dcesrv_auth_alter_ack(call, &pkt)) { - return dcesrv_bind_nak(call, 0); + status = dcesrv_auth_alter_ack(call, &pkt); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) + || NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE) + || NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) + || NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { + return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); + } + return dcesrv_fault(call, 0); } rep = talloc(call, struct data_blob_list_item); -- cgit From d7f84b51f96c2e1b48a38de823329f2e4ea86e55 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Aug 2007 04:28:15 +0000 Subject: r24611: Following up on the re-opening of bug 4817 is it pretty clear that machine accounts are not subject to password policy in Win2k3 R2 (at least in terms of password quality). In testing this, I found that Win2k3 R2 has changed the way the old ChangePassword RPC call is handled - the 'cross-checks' between new LM and NT passwords are not required. Andrew Bartlett (This used to be commit 417ea885b41cc097a0bb3a10ffbffb31f234f25d) --- source4/rpc_server/dcerpc_server.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 35b37b3af6..7d257fac06 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -528,10 +528,6 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; - if (call->pkt.u.bind.assoc_group_id != 0) { - return dcesrv_bind_nak(call, 0); - } - if (call->pkt.u.bind.num_contexts < 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { return dcesrv_bind_nak(call, 0); -- cgit From 7aa29fd85432d4212d963665ceb02e9614f7aec0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 22 Aug 2007 04:43:17 +0000 Subject: r24612: Revert this part of -r 24611. This isn't related to my SAMR password work, but to an odd bind failure I noticed in a trace. I need to commit this with changes to the torture suite. Andrew Bartlett (This used to be commit 3ab90ad312b85b5a887090418e9cb7594f519b2f) --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 7d257fac06..35b37b3af6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -528,6 +528,10 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; + if (call->pkt.u.bind.assoc_group_id != 0) { + return dcesrv_bind_nak(call, 0); + } + if (call->pkt.u.bind.num_contexts < 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { return dcesrv_bind_nak(call, 0); -- cgit From 8e2d624a588552f5d06f21fe37281615f3ec6296 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Sep 2007 13:13:25 +0000 Subject: r24937: Merge tests spoolss RPC callbacks. (This used to be commit 9b256a0ca232ea6e89771bf73a1adf877273a752) --- source4/rpc_server/dcerpc_server.c | 97 +++++--------------------------------- 1 file changed, 11 insertions(+), 86 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 35b37b3af6..466d35c373 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -39,11 +39,11 @@ extern const struct dcesrv_interface dcesrv_mgmt_interface; /* see if two endpoints match */ -static BOOL endpoints_match(const struct dcerpc_binding *ep1, +static bool endpoints_match(const struct dcerpc_binding *ep1, const struct dcerpc_binding *ep2) { if (ep1->transport != ep2->transport) { - return False; + return false; } if (!ep1->endpoint || !ep2->endpoint) { @@ -51,9 +51,9 @@ static BOOL endpoints_match(const struct dcerpc_binding *ep1, } if (strcasecmp(ep1->endpoint, ep2->endpoint) != 0) - return False; + return false; - return True; + return true; } /* @@ -1246,7 +1246,7 @@ _PUBLIC_ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, return status; } -static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx) +_PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx) { NTSTATUS status; struct dcesrv_context *dce_ctx; @@ -1282,21 +1282,6 @@ static NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_s return NT_STATUS_OK; } -/* - initialise the dcerpc server context for ncacn_np based services -*/ -_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) -{ - NTSTATUS status; - struct dcesrv_context *dce_ctx; - - status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx); - NT_STATUS_NOT_OK_RETURN(status); - - *_dce_ctx = dce_ctx; - return NT_STATUS_OK; -} - /* the list of currently registered DCERPC endpoint servers. */ static struct ep_server { @@ -1379,78 +1364,18 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) } /* - open the dcerpc server sockets + initialise the dcerpc server context for ncacn_np based services */ -static void dcesrv_task_init(struct task_server *task) +_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) { NTSTATUS status; struct dcesrv_context *dce_ctx; - struct dcesrv_endpoint *e; - task_server_set_title(task, "task[dcesrv]"); - - status = dcesrv_init_context(task->event_ctx, - lp_dcerpc_endpoint_servers(), - &dce_ctx); - if (!NT_STATUS_IS_OK(status)) goto failed; - - /* Make sure the directory for NCALRPC exists */ - if (!directory_exist(lp_ncalrpc_dir())) { - mkdir(lp_ncalrpc_dir(), 0755); - } - - for (e=dce_ctx->endpoint_list;e;e=e->next) { - switch (e->ep_description->transport) { - case NCACN_UNIX_STREAM: - status = dcesrv_add_ep_unix(dce_ctx, e, task->event_ctx, task->model_ops); - if (!NT_STATUS_IS_OK(status)) goto failed; - break; - - case NCALRPC: - status = dcesrv_add_ep_ncalrpc(dce_ctx, e, task->event_ctx, task->model_ops); - if (!NT_STATUS_IS_OK(status)) goto failed; - break; - - case NCACN_IP_TCP: - status = dcesrv_add_ep_tcp(dce_ctx, e, task->event_ctx, task->model_ops); - if (!NT_STATUS_IS_OK(status)) goto failed; - break; - - case NCACN_NP: - status = dcesrv_add_ep_np(dce_ctx, e, task->event_ctx, task->model_ops); - if (!NT_STATUS_IS_OK(status)) goto failed; - break; - - default: - status = NT_STATUS_NOT_SUPPORTED; - if (!NT_STATUS_IS_OK(status)) goto failed; - } - } - - return; -failed: - task_server_terminate(task, "Failed to startup dcerpc server task"); -} + status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx); + NT_STATUS_NOT_OK_RETURN(status); -/* - called on startup of the smb server service It's job is to start - listening on all configured sockets -*/ -static NTSTATUS dcesrv_init(struct event_context *event_context, - const struct model_ops *model_ops) -{ - return task_server_startup(event_context, model_ops, dcesrv_task_init); + *_dce_ctx = dce_ctx; + return NT_STATUS_OK; } -NTSTATUS server_service_rpc_init(void) -{ - init_module_fn static_init[] = STATIC_dcerpc_server_MODULES; - init_module_fn *shared_init = load_samba_modules(NULL, "dcerpc_server"); - - run_init_functions(static_init); - run_init_functions(shared_init); - talloc_free(shared_init); - - return register_server_service("rpc", dcesrv_init); -} -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/rpc_server/dcerpc_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 466d35c373..c3de00d8d0 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -33,6 +33,7 @@ #include "system/filesys.h" #include "libcli/security/security.h" #include "build.h" +#include "param/param.h" extern const struct dcesrv_interface dcesrv_mgmt_interface; -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/rpc_server/dcerpc_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index c3de00d8d0..02f38a15fd 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -390,7 +390,7 @@ static void dcesrv_init_hdr(struct ncacn_packet *pkt) { pkt->rpc_vers = 5; pkt->rpc_vers_minor = 0; - if (lp_rpc_big_endian()) { + if (lp_rpc_big_endian(global_loadparm)) { pkt->drep[0] = 0; } else { pkt->drep[0] = DCERPC_DREP_LE; @@ -892,7 +892,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) pointers */ push->ptr_count = call->ndr_pull->ptr_count; - if (lp_rpc_big_endian()) { + if (lp_rpc_big_endian(global_loadparm)) { push->flags |= LIBNDR_FLAG_BIGENDIAN; } @@ -1372,7 +1372,7 @@ _PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_con NTSTATUS status; struct dcesrv_context *dce_ctx; - status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(), &dce_ctx); + status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(global_loadparm), &dce_ctx); NT_STATUS_NOT_OK_RETURN(status); *_dce_ctx = dce_ctx; -- cgit From 05e7c481465e3065effaf21b43636d6605d7c313 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:25:41 +0000 Subject: r25553: Convert to standard bool type. (This used to be commit b7371f1a191fb86834c0d586d094f39f0b04544b) --- source4/rpc_server/dcerpc_server.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 02f38a15fd..4388c86f22 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -88,7 +88,7 @@ static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_conne /* see if a uuid and if_version match to an interface */ -static BOOL interface_match(const struct dcesrv_interface *if1, +static bool interface_match(const struct dcesrv_interface *if1, const struct dcesrv_interface *if2) { return (if1->syntax_id.if_version == if2->syntax_id.if_version && @@ -113,7 +113,7 @@ static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoin /* see if a uuid and if_version match to an interface */ -static BOOL interface_match_by_uuid(const struct dcesrv_interface *iface, +static bool interface_match_by_uuid(const struct dcesrv_interface *iface, const struct GUID *uuid, uint32_t if_version) { return (iface->syntax_id.if_version == if_version && @@ -160,7 +160,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *ep; struct dcesrv_if_list *ifl; struct dcerpc_binding *binding; - BOOL add_ep = False; + bool add_ep = false; NTSTATUS status; status = dcerpc_parse_binding(dce_ctx, ep_name, &binding); @@ -179,7 +179,7 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx, } ZERO_STRUCTP(ep); ep->ep_description = talloc_reference(ep, binding); - add_ep = True; + add_ep = true; /* add mgmt interface */ ifl = talloc(dce_ctx, struct dcesrv_if_list); @@ -338,7 +338,7 @@ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->event_ctx = event_ctx; p->msg_ctx = msg_ctx; p->server_id = server_id; - p->processing = False; + p->processing = false; p->state_flags = state_flags; ZERO_STRUCT(p->transport); @@ -983,15 +983,15 @@ _PUBLIC_ struct socket_address *dcesrv_connection_get_peer_addr(struct dcesrv_co /* work out if we have a full packet yet */ -static BOOL dce_full_packet(const DATA_BLOB *data) +static bool dce_full_packet(const DATA_BLOB *data) { if (data->length < DCERPC_FRAG_LEN_OFFSET+2) { - return False; + return false; } if (dcerpc_get_frag_length(data) > data->length) { - return False; + return false; } - return True; + return true; } /* -- cgit From 529763a9aa192a6785ba878aceeb1683c2510913 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:24:51 +0100 Subject: r25920: ndr: change NTSTAUS into enum ndr_err_code (samba4 callers) lib/messaging/ lib/registry/ lib/ldb-samba/ librpc/rpc/ auth/auth_winbind.c auth/gensec/ auth/kerberos/ dsdb/repl/ dsdb/samdb/ dsdb/schema/ torture/ cluster/ctdb/ kdc/ ntvfs/ipc/ torture/rap/ ntvfs/ utils/getntacl.c ntptr/ smb_server/ libcli/wrepl/ wrepl_server/ libcli/cldap/ libcli/dgram/ libcli/ldap/ libcli/raw/ libcli/nbt/ libnet/ winbind/ rpc_server/ metze (This used to be commit 6223c7fddc972687eb577e04fc1c8e0604c35435) --- source4/rpc_server/dcerpc_server.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 4388c86f22..e146509b67 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -1027,6 +1027,7 @@ static int dcesrv_call_dequeue(struct dcesrv_call_state *call) NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) { struct ndr_pull *ndr; + enum ndr_err_code ndr_err; NTSTATUS status; struct dcesrv_call_state *call; DATA_BLOB blob; @@ -1059,11 +1060,11 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } - status = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, &call->pkt); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(dce_conn->partial_input.data); talloc_free(call); - return status; + return ndr_map_error2ntstatus(ndr_err); } /* we have to check the signing here, before combining the -- cgit From 57f20ccd242e45ff91850341594aa040d113c19e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Dec 2007 20:05:00 +0100 Subject: r26296: Store loadparm context in DCE/RPC server context. (This used to be commit fc1f4d2d65d4c983cba5421e7ffb64dd75482860) --- source4/rpc_server/dcerpc_server.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e146509b67..f5576c5a6c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -386,11 +386,11 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_search_connect(struct dcesrv_context *dce_ctx, } -static void dcesrv_init_hdr(struct ncacn_packet *pkt) +static void dcesrv_init_hdr(struct ncacn_packet *pkt, bool bigendian) { pkt->rpc_vers = 5; pkt->rpc_vers_minor = 0; - if (lp_rpc_big_endian(global_loadparm)) { + if (bigendian) { pkt->drep[0] = 0; } else { pkt->drep[0] = DCERPC_DREP_LE; @@ -447,7 +447,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code NTSTATUS status; /* setup a bind_ack */ - dcesrv_init_hdr(&pkt); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_FAULT; @@ -486,7 +486,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) NTSTATUS status; /* setup a bind_nak */ - dcesrv_init_hdr(&pkt); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(global_loadparm)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_NAK; @@ -596,7 +596,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } /* setup a bind_ack */ - dcesrv_init_hdr(&pkt); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(global_loadparm)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_ACK; @@ -752,7 +752,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } /* setup a alter_resp */ - dcesrv_init_hdr(&pkt); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(global_loadparm)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_ALTER_RESP; @@ -892,7 +892,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) pointers */ push->ptr_count = call->ndr_pull->ptr_count; - if (lp_rpc_big_endian(global_loadparm)) { + if (lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)) { push->flags |= LIBNDR_FLAG_BIGENDIAN; } @@ -921,7 +921,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) } /* form the dcerpc response packet */ - dcesrv_init_hdr(&pkt); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_RESPONSE; @@ -1248,7 +1248,9 @@ _PUBLIC_ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, return status; } -_PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint_servers, struct dcesrv_context **_dce_ctx) +_PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + const char **endpoint_servers, struct dcesrv_context **_dce_ctx) { NTSTATUS status; struct dcesrv_context *dce_ctx; @@ -1262,6 +1264,7 @@ _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx, const char **endpoint dce_ctx = talloc(mem_ctx, struct dcesrv_context); NT_STATUS_HAVE_NO_MEMORY(dce_ctx); dce_ctx->endpoint_list = NULL; + dce_ctx->lp_ctx = lp_ctx; for (i=0;endpoint_servers[i];i++) { const struct dcesrv_endpoint_server *ep_server; @@ -1368,12 +1371,13 @@ const struct dcesrv_critical_sizes *dcerpc_module_version(void) /* initialise the dcerpc server context for ncacn_np based services */ -_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct dcesrv_context **_dce_ctx) +_PUBLIC_ NTSTATUS dcesrv_init_ipc_context(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct dcesrv_context **_dce_ctx) { NTSTATUS status; struct dcesrv_context *dce_ctx; - status = dcesrv_init_context(mem_ctx, lp_dcerpc_endpoint_servers(global_loadparm), &dce_ctx); + status = dcesrv_init_context(mem_ctx, lp_ctx, lp_dcerpc_endpoint_servers(lp_ctx), &dce_ctx); NT_STATUS_NOT_OK_RETURN(status); *_dce_ctx = dce_ctx; -- cgit From d378cf4c15e09b980f874bb103b28e89d9dd3a26 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 16:36:54 +0100 Subject: r26310: Remove more uses of global_loadparm. (This used to be commit 9d806da113b5f0688b6193dfdee9b8765e18b38f) --- source4/rpc_server/dcerpc_server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f5576c5a6c..256f20ed54 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -486,7 +486,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) NTSTATUS status; /* setup a bind_nak */ - dcesrv_init_hdr(&pkt, lp_rpc_big_endian(global_loadparm)); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_NAK; @@ -596,7 +596,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) } /* setup a bind_ack */ - dcesrv_init_hdr(&pkt, lp_rpc_big_endian(global_loadparm)); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_ACK; @@ -752,7 +752,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) } /* setup a alter_resp */ - dcesrv_init_hdr(&pkt, lp_rpc_big_endian(global_loadparm)); + dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_ALTER_RESP; -- cgit From 61873ce94c172c801a4831de5550a8e0fe54c5f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:23 +0100 Subject: r26431: Require ndr_push creators to specify a iconv_convenience context. (This used to be commit 7352206f4450fdf881b95bda064cedd9d2477e4c) --- source4/rpc_server/dcerpc_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 256f20ed54..db4136a853 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -884,7 +884,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) } /* form the reply NDR */ - push = ndr_push_init_ctx(call); + push = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(push); /* carry over the pointer count to the reply in case we are -- cgit From d1e716cf4331bf09cfe15a6634bc5887aff81d20 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:27 +0100 Subject: r26432: Require ndr_pull users to specify iconv_convenience. (This used to be commit 28b1d36551b75241c1cf9fca5d74f45a6dc884ab) --- source4/rpc_server/dcerpc_server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index db4136a853..cf89143b34 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -821,7 +821,8 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) return dcesrv_fault(call, DCERPC_FAULT_UNK_IF); } - pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); + pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call, + lp_iconv_convenience(global_loadparm)); NT_STATUS_HAVE_NO_MEMORY(pull); pull->flags |= LIBNDR_FLAG_REF_ALLOC; @@ -1049,7 +1050,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn) blob = dce_conn->partial_input; blob.length = dcerpc_get_frag_length(&blob); - ndr = ndr_pull_init_blob(&blob, call); + ndr = ndr_pull_init_blob(&blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx)); if (!ndr) { talloc_free(dce_conn->partial_input.data); talloc_free(call); -- cgit From e31abef15f7696cf39e9e81307f153da93568e02 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:55 +0100 Subject: r26440: Remove more uses of global_loadparm. (This used to be commit 8858cf39722f192865e531164c72039fd18d7a8d) --- source4/rpc_server/dcerpc_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cf89143b34..b043424faa 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -822,7 +822,7 @@ static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) } pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call, - lp_iconv_convenience(global_loadparm)); + lp_iconv_convenience(call->conn->dce_ctx->lp_ctx)); NT_STATUS_HAVE_NO_MEMORY(pull); pull->flags |= LIBNDR_FLAG_REF_ALLOC; @@ -885,7 +885,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) } /* form the reply NDR */ - push = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); + push = ndr_push_init_ctx(call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx)); NT_STATUS_HAVE_NO_MEMORY(push); /* carry over the pointer count to the reply in case we are -- cgit From 10169a203019445e6d325a5c1559de3c73782237 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:54:24 +0100 Subject: Remove more global_loadparm instance.s (This used to be commit a1280252ce924df69d911e597b7f65d8038abef9) --- source4/rpc_server/dcerpc_server.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index b043424faa..6e53c7c8ae 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -462,7 +462,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->blob, call, &pkt, NULL); + status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx), &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -501,7 +501,7 @@ static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason) return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->blob, call, &pkt, NULL); + status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx), &pkt, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -642,8 +642,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->blob, call, &pkt, - call->conn->auth_state.auth_info); + status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx), &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -787,8 +786,7 @@ static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) return NT_STATUS_NO_MEMORY; } - status = ncacn_push_auth(&rep->blob, call, &pkt, - call->conn->auth_state.auth_info); + status = ncacn_push_auth(&rep->blob, call, lp_iconv_convenience(call->conn->dce_ctx->lp_ctx), &pkt, call->conn->auth_state.auth_info); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 2bf39edc9d0abf3306bd25b9c40d88aceb029be7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 15:28:12 +0100 Subject: Push SOVERSION and VERSION out of perl code. (This used to be commit 0ba8ac6a14c62ff9edfe9f0bf43b8a7406b85291) --- source4/rpc_server/dcerpc_server.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6e53c7c8ae..cc9819e40c 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -32,7 +32,6 @@ #include "smbd/service.h" #include "system/filesys.h" #include "libcli/security/security.h" -#include "build.h" #include "param/param.h" extern const struct dcesrv_interface dcesrv_mgmt_interface; -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/rpc_server/dcerpc_server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 6e53c7c8ae..beb795ea22 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -26,6 +26,8 @@ #include "auth/gensec/gensec.h" #include "lib/util/dlinklist.h" #include "rpc_server/dcerpc_server.h" +#include "rpc_server/dcerpc_server_proto.h" +#include "librpc/rpc/dcerpc_proto.h" #include "lib/events/events.h" #include "smbd/service_task.h" #include "smbd/service_stream.h" @@ -299,7 +301,7 @@ static int dcesrv_endpoint_destructor(struct dcesrv_connection *p) /* connect to a dcerpc endpoint */ -NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, +_PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, TALLOC_CTX *mem_ctx, const struct dcesrv_endpoint *ep, struct auth_session_info *session_info, -- cgit From 25a82b8fc93ca01b7f142a680ad9a327e8cb8fa9 Mon Sep 17 00:00:00 2001 From: Julien Kerihuel Date: Thu, 15 May 2008 13:54:07 +0200 Subject: This patch adds remaining padding bytes to the dcerpc_fault IDL structure and adds a const 4 bytes blob to pkt.u.fault. Signed-off-by: Stefan Metzmacher (This used to be commit 652b8c5f156b357e231057a5a0fbded88f4f9c5f) --- source4/rpc_server/dcerpc_server.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1962a97d5b..eb467709c9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -445,6 +445,7 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code { struct ncacn_packet pkt; struct data_blob_list_item *rep; + uint8_t zeros[4]; NTSTATUS status; /* setup a bind_ack */ @@ -458,6 +459,9 @@ static NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code pkt.u.fault.cancel_count = 0; pkt.u.fault.status = fault_code; + ZERO_STRUCT(zeros); + pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); + rep = talloc(call, struct data_blob_list_item); if (!rep) { return NT_STATUS_NO_MEMORY; -- cgit From 8651def04c140da23f564be46b86c5e1f33349c4 Mon Sep 17 00:00:00 2001 From: Julien Kerihuel Date: Thu, 15 May 2008 13:55:23 +0200 Subject: The following patch calls the op_bind operation for an interface which context is altered by dcerpc alter_context requests. It prevents dcerpc_server from returning errors (nca_s_fault_access_denied, then nca_s_fault_context_mismatch in further client requests) and keeps the connection alive. Signed-off-by: Stefan Metzmacher (This used to be commit 718f9ce6889346c92894e868f0678fbe404a43ab) --- source4/rpc_server/dcerpc_server.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index eb467709c9..e0351bb259 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -688,6 +688,7 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ struct dcesrv_connection_context *context; const struct dcesrv_interface *iface; struct GUID uuid, *transfer_syntax_uuid; + NTSTATUS status; if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version; uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid; @@ -721,6 +722,13 @@ static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_ DLIST_ADD(call->conn->contexts, context); call->context = context; + if (iface) { + status = iface->bind(call, iface); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + return NT_STATUS_OK; } -- cgit From 8bd7dabb072942ed0955c8b2e26ee41c3edae0bf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 3 Jul 2008 13:39:55 +0200 Subject: rpc_server: use the same chunk_size logic as we we use in the client metze (This used to be commit 9ff0ce42b32bf0f1463d2cb9c2a6595f51b13d04) --- source4/rpc_server/dcerpc_server.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index e0351bb259..d8dafd61f6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -886,7 +886,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) struct ndr_push *push; NTSTATUS status; DATA_BLOB stub; - uint32_t total_length; + uint32_t total_length, chunk_size; struct dcesrv_connection_context *context = call->context; /* call the reply function */ @@ -917,20 +917,20 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) total_length = stub.length; + /* we can write a full max_recv_frag size, minus the dcerpc + request header size */ + chunk_size = call->conn->cli_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH); + do { uint32_t length; struct data_blob_list_item *rep; struct ncacn_packet pkt; + const uint32_t overhead = (DCERPC_MAX_SIGN_SIZE+DCERPC_RESPONSE_LENGTH); rep = talloc(call, struct data_blob_list_item); NT_STATUS_HAVE_NO_MEMORY(rep); - length = stub.length; - if (length + DCERPC_RESPONSE_LENGTH > call->conn->cli_max_recv_frag) { - /* the 32 is to cope with signing data */ - length = call->conn->cli_max_recv_frag - - (DCERPC_MAX_SIGN_SIZE+DCERPC_RESPONSE_LENGTH); - } + length = MIN(chunk_size, stub.length); /* form the dcerpc response packet */ dcesrv_init_hdr(&pkt, lp_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); -- cgit From d6fdd13dec854c681ad047d104ccfc2bf0ca5de5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Jul 2008 16:14:20 +1000 Subject: Remove the 'accoc_group_id' check in the RPC server. This check breaks more than it fixes, and while technically not correct, is the best solution we have at this time. Otherwise, SCHANNEL binds from WinXP fail. Andrew Bartlett (This used to be commit f8628fa330abcd50923d995d5bda1f4811582ea9) --- source4/rpc_server/dcerpc_server.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d8dafd61f6..91ae5fcd94 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -534,9 +534,20 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; +#if 0 + /* It is not safe to enable this check - windows clients + * (WinXP in particular) will use it for NETLOGON calls, for + * the subsequent SCHANNEL bind. It turns out that NETLOGON + * calls include no policy handles, so it is safe there. Let + * the failure occour on the attempt to reuse a poilcy handle, + * rather than here */ + + /* Association groups allow policy handles to be shared across + * multiple client connections. We don't implement this yet. */ if (call->pkt.u.bind.assoc_group_id != 0) { return dcesrv_bind_nak(call, 0); } +#endif if (call->pkt.u.bind.num_contexts < 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { -- cgit From 768515f4ad13785729fcd4df7cecaede39b7409a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Jul 2008 16:19:54 +1000 Subject: The SMB session key must not be more than 16 bytes in SAMR (and presumably LSA). Tests show that Vista requires the sesion key to be truncated for a domain join. Andrew Bartlett (This used to be commit af629a3738298d27eb2dbecf466ceb503cec9638) --- source4/rpc_server/dcerpc_server.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d8dafd61f6..fb487dfdcf 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -270,11 +270,20 @@ NTSTATUS dcesrv_generic_session_key(struct dcesrv_connection *p, /* fetch the user session key - may be default (above) or the SMB session key + + The key is always truncated to 16 bytes */ _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p, DATA_BLOB *session_key) { - return p->auth_state.session_key(p, session_key); + NTSTATUS status = p->auth_state.session_key(p, session_key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + session_key->length = MIN(session_key->length, 16); + + return NT_STATUS_OK; } -- cgit From 5bb679aa0fe87b5dd7f7c82d09157bc93b8b54cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Jul 2008 14:41:16 +0200 Subject: rpc_server: be more strict with the incoming assoc_group_id Allow 0 and 0x12345678 only. This fixes the RPC-HANDLES test. metze (This used to be commit c123e597cc84685abf2b0d3564e1a26d80bbef2f) --- source4/rpc_server/dcerpc_server.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a2ca897981..ac36825acd 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -543,20 +543,20 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t context_id; const struct dcesrv_interface *iface; -#if 0 - /* It is not safe to enable this check - windows clients - * (WinXP in particular) will use it for NETLOGON calls, for - * the subsequent SCHANNEL bind. It turns out that NETLOGON - * calls include no policy handles, so it is safe there. Let - * the failure occour on the attempt to reuse a poilcy handle, - * rather than here */ - - /* Association groups allow policy handles to be shared across - * multiple client connections. We don't implement this yet. */ - if (call->pkt.u.bind.assoc_group_id != 0) { + /* + * Association groups allow policy handles to be shared across + * multiple client connections. We don't implement this yet. + * + * So we just allow 0 if the client wants to create a new + * association group. + * + * And we allow the 0x12345678 value, we give away as + * assoc_group_id back to the clients + */ + if (call->pkt.u.bind.assoc_group_id != 0 && + call->pkt.u.bind.assoc_group_id != 0x12345678) { return dcesrv_bind_nak(call, 0); } -#endif if (call->pkt.u.bind.num_contexts < 1 || call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) { -- cgit From 552fd06dedbef0fbf3ba5c78698cd286973c61aa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jul 2008 14:11:18 +1000 Subject: Make a new define to ensure the accoc_group_id we use is always in common. (This used to be commit b62490e3e21b606b66e0737a403b0d170b64cddd) --- source4/rpc_server/dcerpc_server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index ac36825acd..cb07f6e8ce 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -36,6 +36,8 @@ #include "libcli/security/security.h" #include "param/param.h" +#define SAMBA_ACCOC_GROUP 0x12345678 + extern const struct dcesrv_interface dcesrv_mgmt_interface; /* @@ -554,7 +556,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) * assoc_group_id back to the clients */ if (call->pkt.u.bind.assoc_group_id != 0 && - call->pkt.u.bind.assoc_group_id != 0x12345678) { + call->pkt.u.bind.assoc_group_id != SAMBA_ACCOC_GROUP) { return dcesrv_bind_nak(call, 0); } @@ -629,7 +631,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; /* we need to send a non zero assoc_group_id here to make longhorn happy, it also matches samba3 */ - pkt.u.bind_ack.assoc_group_id = 0x12345678; + pkt.u.bind_ack.assoc_group_id = SAMBA_ACCOC_GROUP; if (iface) { /* FIXME: Use pipe name as specified by endpoint instead of interface name */ pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name); -- cgit From 14900695da4e32e64ddb6262b1764983254fcc1d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jul 2008 16:40:21 +0200 Subject: rpc_server: remove unused variable metze (This used to be commit c2186d5d60aa2b57ecafaa57f9fd41f2a6717046) --- source4/rpc_server/dcerpc_server.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index cb07f6e8ce..95589498e2 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -947,7 +947,6 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) uint32_t length; struct data_blob_list_item *rep; struct ncacn_packet pkt; - const uint32_t overhead = (DCERPC_MAX_SIGN_SIZE+DCERPC_RESPONSE_LENGTH); rep = talloc(call, struct data_blob_list_item); NT_STATUS_HAVE_NO_MEMORY(rep); -- cgit From 746d3c8ff9ce9b1ff55fa7953d29802714866c72 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 Aug 2008 22:28:04 +0200 Subject: rpc_server: add support for DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN you need "dcesrv:header signing=yes" to enable it. metze (This used to be commit bde2496e6b7034c99243b22434a97aebeb8f75b9) --- source4/rpc_server/dcerpc_server.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 95589498e2..a336ddb339 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -544,6 +544,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) uint32_t result=0, reason=0; uint32_t context_id; const struct dcesrv_interface *iface; + uint32_t extra_flags = 0; /* * Association groups allow policy handles to be shared across @@ -617,6 +618,12 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) call->conn->cli_max_recv_frag = call->pkt.u.bind.max_recv_frag; } + if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) && + lp_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","header signing", false)) { + call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_HEADER_SIGNING; + extra_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; + } + /* handle any authentication that is being requested */ if (!dcesrv_auth_bind(call)) { return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE); @@ -627,7 +634,7 @@ static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call) pkt.auth_length = 0; pkt.call_id = call->pkt.call_id; pkt.ptype = DCERPC_PKT_BIND_ACK; - pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; + pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; pkt.u.bind_ack.max_xmit_frag = 0x2000; pkt.u.bind_ack.max_recv_frag = 0x2000; /* we need to send a non zero assoc_group_id here to make longhorn happy, it also matches samba3 */ -- cgit From 97f59cb1902eec0fba610da6c13d7089ea7d7576 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Aug 2008 18:12:54 +0200 Subject: rpc_server: correct the chunk_size depending on the signature size metze (This used to be commit 20fc0d7bfdaa60d6a8ac939dc64733a91652587e) --- source4/rpc_server/dcerpc_server.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index a336ddb339..fa7b8d26f5 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -917,6 +917,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) DATA_BLOB stub; uint32_t total_length, chunk_size; struct dcesrv_connection_context *context = call->context; + size_t sig_size = 0; /* call the reply function */ status = context->iface->reply(call, call, call->r); @@ -948,7 +949,15 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) /* we can write a full max_recv_frag size, minus the dcerpc request header size */ - chunk_size = call->conn->cli_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH); + chunk_size = call->conn->cli_max_recv_frag; + chunk_size -= DCERPC_REQUEST_LENGTH; + if (call->conn->auth_state.gensec_security) { + chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; + sig_size = gensec_sig_size(call->conn->auth_state.gensec_security, + call->conn->cli_max_recv_frag); + chunk_size -= sig_size; + chunk_size -= (chunk_size % 16); + } do { uint32_t length; @@ -978,7 +987,7 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) pkt.u.response.stub_and_verifier.data = stub.data; pkt.u.response.stub_and_verifier.length = length; - if (!dcesrv_auth_response(call, &rep->blob, &pkt)) { + if (!dcesrv_auth_response(call, &rep->blob, sig_size, &pkt)) { return dcesrv_fault(call, DCERPC_FAULT_OTHER); } -- cgit From 9a222474bb891e0b1839ecad009e5d0420d4b308 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 12 Sep 2008 15:47:02 +0200 Subject: rpc_server: don't send auth trailers in level connect Also ignore auth trailers in level connect on receive. This fixes [krb5,connect] against windows. TODO: maybe the gensec mech need to decide if signatures are needed in level connect. metze (This used to be commit 2e3629719790e7631d9de383b565dc8a0997bcfb) --- source4/rpc_server/dcerpc_server.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/rpc_server/dcerpc_server.c') diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index fa7b8d26f5..e5f59d0cf9 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -951,13 +951,16 @@ _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) request header size */ chunk_size = call->conn->cli_max_recv_frag; chunk_size -= DCERPC_REQUEST_LENGTH; - if (call->conn->auth_state.gensec_security) { - chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; + if (call->conn->auth_state.auth_info && + call->conn->auth_state.gensec_security) { sig_size = gensec_sig_size(call->conn->auth_state.gensec_security, call->conn->cli_max_recv_frag); - chunk_size -= sig_size; - chunk_size -= (chunk_size % 16); + if (sig_size) { + chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; + chunk_size -= sig_size; + } } + chunk_size -= (chunk_size % 16); do { uint32_t length; -- cgit