X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source4%2Frpc_server%2Fdcerpc_server.c;h=17a097a4cc63a0203fae48ce7f22542402185c52;hb=1e7bc73e009e1c0adcd06129ae75ddc134956b40;hp=f4059e4a4646ee080bb972b96a46ec14310f8fa2;hpb=f0420c029299fd503dd6980484e970a9a141d523;p=bbaumbach%2Fsamba-autobuild%2F.git diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index f4059e4a464..17a097a4cc6 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -23,12 +23,14 @@ #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" #include "lib/events/events.h" #include "smbd/service_stream.h" +#include "system/filesys.h" /* see if two endpoints match @@ -384,7 +386,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 */ @@ -398,19 +400,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; @@ -423,7 +425,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 */ @@ -435,19 +437,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; @@ -462,13 +464,13 @@ 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; 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 +495,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); } @@ -569,20 +572,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; @@ -662,7 +665,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; @@ -711,20 +714,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; @@ -786,6 +789,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); } @@ -837,10 +844,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; @@ -868,13 +875,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; @@ -1099,20 +1106,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 read 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; + struct data_blob_list_item *rep; + size_t nwritten; call = dce_conn->call_list; if (!call || !call->replies) { @@ -1127,21 +1133,15 @@ 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->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); - } else { - return STATUS_BUFFER_OVERFLOW; } if (call->replies == NULL) { @@ -1150,31 +1150,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) @@ -1311,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(), @@ -1324,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) {