2 Unix SMB/CIFS implementation.
4 server side dcerpc core code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
45 extern const struct dcesrv_interface dcesrv_mgmt_interface;
47 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
48 const struct dcerpc_bind *b,
49 const struct dcerpc_ctx_list *ctx,
50 struct dcerpc_ack_ctx *ack,
51 const struct ndr_syntax_id *supported_transfer);
54 find an association group given a assoc_group_id
56 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
61 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
65 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
69 take a reference to an existing association group
71 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
72 struct dcesrv_context *dce_ctx,
75 struct dcesrv_assoc_group *assoc_group;
77 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
78 if (assoc_group == NULL) {
79 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
82 return talloc_reference(mem_ctx, assoc_group);
85 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
88 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
90 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
97 allocate a new association group
99 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
100 struct dcesrv_context *dce_ctx)
102 struct dcesrv_assoc_group *assoc_group;
105 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
106 if (assoc_group == NULL) {
110 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
112 talloc_free(assoc_group);
113 DEBUG(0,(__location__ ": Out of association groups!\n"));
117 assoc_group->id = id;
118 assoc_group->dce_ctx = dce_ctx;
120 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
127 see if two endpoints match
129 static bool endpoints_match(const struct dcerpc_binding *ep1,
130 const struct dcerpc_binding *ep2)
132 enum dcerpc_transport_t t1;
133 enum dcerpc_transport_t t2;
137 t1 = dcerpc_binding_get_transport(ep1);
138 t2 = dcerpc_binding_get_transport(ep2);
140 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
141 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
151 if (strcasecmp(e1, e2) != 0) {
159 find an endpoint in the dcesrv_context
161 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
162 const struct dcerpc_binding *ep_description)
164 struct dcesrv_endpoint *ep;
165 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
166 if (endpoints_match(ep->ep_description, ep_description)) {
174 find a registered context_id from a bind or alter_context
176 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
179 struct dcesrv_connection_context *c;
180 for (c=conn->contexts;c;c=c->next) {
181 if (c->context_id == context_id) return c;
187 see if a uuid and if_version match to an interface
189 static bool interface_match(const struct dcesrv_interface *if1,
190 const struct dcesrv_interface *if2)
192 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
193 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
197 find the interface operations on an endpoint
199 static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint,
200 const struct dcesrv_interface *iface)
202 struct dcesrv_if_list *ifl;
203 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
204 if (interface_match(&(ifl->iface), iface)) {
205 return &(ifl->iface);
212 see if a uuid and if_version match to an interface
214 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
215 const struct GUID *uuid, uint32_t if_version)
217 return (iface->syntax_id.if_version == if_version &&
218 GUID_equal(&iface->syntax_id.uuid, uuid));
222 find the interface operations on an endpoint by uuid
224 static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
225 const struct GUID *uuid, uint32_t if_version)
227 struct dcesrv_if_list *ifl;
228 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
229 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
230 return &(ifl->iface);
237 find the earlier parts of a fragmented call awaiting reassembily
239 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
241 struct dcesrv_call_state *c;
242 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
243 if (c->pkt.call_id == call_id) {
251 register an interface on an endpoint
253 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
255 const struct dcesrv_interface *iface,
256 const struct security_descriptor *sd)
258 struct dcesrv_endpoint *ep;
259 struct dcesrv_if_list *ifl;
260 struct dcerpc_binding *binding;
264 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
266 if (NT_STATUS_IS_ERR(status)) {
267 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
271 /* check if this endpoint exists
273 if ((ep=find_endpoint(dce_ctx, binding))==NULL) {
274 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
276 return NT_STATUS_NO_MEMORY;
279 ep->ep_description = talloc_move(ep, &binding);
282 /* add mgmt interface */
283 ifl = talloc_zero(ep, struct dcesrv_if_list);
285 return NT_STATUS_NO_MEMORY;
288 memcpy(&(ifl->iface), &dcesrv_mgmt_interface,
289 sizeof(struct dcesrv_interface));
291 DLIST_ADD(ep->interface_list, ifl);
294 /* see if the interface is already registered on te endpoint */
295 if (find_interface(ep, iface)!=NULL) {
296 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
297 iface->name, ep_name));
298 return NT_STATUS_OBJECT_NAME_COLLISION;
301 /* talloc a new interface list element */
302 ifl = talloc_zero(ep, struct dcesrv_if_list);
304 return NT_STATUS_NO_MEMORY;
307 /* copy the given interface struct to the one on the endpoints interface list */
308 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
310 /* if we have a security descriptor given,
311 * we should see if we can set it up on the endpoint
314 /* if there's currently no security descriptor given on the endpoint
317 if (ep->sd == NULL) {
318 ep->sd = security_descriptor_copy(ep, sd);
321 /* if now there's no security descriptor given on the endpoint
322 * something goes wrong, either we failed to copy the security descriptor
323 * or there was already one on the endpoint
325 if (ep->sd != NULL) {
326 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
327 " on endpoint '%s'\n",
328 iface->name, ep_name));
329 if (add_ep) free(ep);
331 return NT_STATUS_OBJECT_NAME_COLLISION;
335 /* finally add the interface on the endpoint */
336 DLIST_ADD(ep->interface_list, ifl);
338 /* if it's a new endpoint add it to the dcesrv_context */
340 DLIST_ADD(dce_ctx->endpoint_list, ep);
343 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
344 iface->name, ep_name));
349 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
350 DATA_BLOB *session_key)
352 if (p->auth_state.session_info->session_key.length) {
353 *session_key = p->auth_state.session_info->session_key;
356 return NT_STATUS_NO_USER_SESSION_KEY;
360 fetch the user session key - may be default (above) or the SMB session key
362 The key is always truncated to 16 bytes
364 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
365 DATA_BLOB *session_key)
367 NTSTATUS status = p->auth_state.session_key(p, session_key);
368 if (!NT_STATUS_IS_OK(status)) {
372 session_key->length = MIN(session_key->length, 16);
378 connect to a dcerpc endpoint
380 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
382 const struct dcesrv_endpoint *ep,
383 struct auth_session_info *session_info,
384 struct tevent_context *event_ctx,
385 struct imessaging_context *msg_ctx,
386 struct server_id server_id,
387 uint32_t state_flags,
388 struct dcesrv_connection **_p)
390 struct dcesrv_connection *p;
393 return NT_STATUS_ACCESS_DENIED;
396 p = talloc_zero(mem_ctx, struct dcesrv_connection);
397 NT_STATUS_HAVE_NO_MEMORY(p);
399 if (!talloc_reference(p, session_info)) {
401 return NT_STATUS_NO_MEMORY;
404 p->dce_ctx = dce_ctx;
406 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
407 p->auth_state.session_info = session_info;
408 p->auth_state.session_key = dcesrv_generic_session_key;
409 p->event_ctx = event_ctx;
410 p->msg_ctx = msg_ctx;
411 p->server_id = server_id;
412 p->state_flags = state_flags;
413 p->allow_bind = true;
414 p->max_recv_frag = 5840;
415 p->max_xmit_frag = 5840;
416 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
423 move a call from an existing linked list to the specified list. This
424 prevents bugs where we forget to remove the call from a previous
427 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
428 enum dcesrv_call_list list)
430 switch (call->list) {
431 case DCESRV_LIST_NONE:
433 case DCESRV_LIST_CALL_LIST:
434 DLIST_REMOVE(call->conn->call_list, call);
436 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
437 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
439 case DCESRV_LIST_PENDING_CALL_LIST:
440 DLIST_REMOVE(call->conn->pending_call_list, call);
445 case DCESRV_LIST_NONE:
447 case DCESRV_LIST_CALL_LIST:
448 DLIST_ADD_END(call->conn->call_list, call);
450 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
451 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
453 case DCESRV_LIST_PENDING_CALL_LIST:
454 DLIST_ADD_END(call->conn->pending_call_list, call);
459 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
462 if (call->conn->terminate != NULL) {
466 call->conn->allow_bind = false;
467 call->conn->allow_alter = false;
468 call->conn->allow_auth3 = false;
469 call->conn->allow_request = false;
471 call->terminate_reason = talloc_strdup(call, reason);
472 if (call->terminate_reason == NULL) {
473 call->terminate_reason = __location__;
478 return a dcerpc bind_nak
480 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
482 struct ncacn_packet pkt;
483 struct dcerpc_bind_nak_version version;
484 struct data_blob_list_item *rep;
486 static const uint8_t _pad[3] = { 0, };
489 * We add the call to the pending_call_list
490 * in order to defer the termination.
492 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
494 /* setup a bind_nak */
495 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
497 pkt.call_id = call->pkt.call_id;
498 pkt.ptype = DCERPC_PKT_BIND_NAK;
499 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
500 pkt.u.bind_nak.reject_reason = reason;
501 version.rpc_vers = 5;
502 version.rpc_vers_minor = 0;
503 pkt.u.bind_nak.num_versions = 1;
504 pkt.u.bind_nak.versions = &version;
505 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
507 rep = talloc_zero(call, struct data_blob_list_item);
509 return NT_STATUS_NO_MEMORY;
512 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
513 if (!NT_STATUS_IS_OK(status)) {
517 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
519 DLIST_ADD_END(call->replies, rep);
520 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
522 if (call->conn->call_list && call->conn->call_list->replies) {
523 if (call->conn->transport.report_output_data) {
524 call->conn->transport.report_output_data(call->conn);
531 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
535 * We add the call to the pending_call_list
536 * in order to defer the termination.
538 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
540 return dcesrv_fault_with_flags(call, fault_code,
541 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
544 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
546 DLIST_REMOVE(c->conn->contexts, c);
548 if (c->iface && c->iface->unbind) {
549 c->iface->unbind(c, c->iface);
556 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
558 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
559 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
560 enum dcerpc_transport_t transport =
561 dcerpc_binding_get_transport(endpoint->ep_description);
562 struct dcesrv_connection_context *context = dce_call->context;
563 const struct dcesrv_interface *iface = context->iface;
565 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
567 if (transport == NCALRPC) {
568 context->allow_connect = true;
573 * allow overwrite per interface
574 * allow dcerpc auth level connect:<interface>
576 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
577 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
578 "allow dcerpc auth level connect",
580 context->allow_connect);
583 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
584 const struct dcesrv_interface *iface)
586 if (dce_call->context == NULL) {
587 return NT_STATUS_INTERNAL_ERROR;
591 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
592 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
594 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
598 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
599 const struct dcesrv_interface *iface)
601 if (dce_call->context == NULL) {
602 return NT_STATUS_INTERNAL_ERROR;
605 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
609 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
610 const struct dcesrv_interface *iface)
612 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
613 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
614 enum dcerpc_transport_t transport =
615 dcerpc_binding_get_transport(endpoint->ep_description);
616 struct dcesrv_connection_context *context = dce_call->context;
618 if (context == NULL) {
619 return NT_STATUS_INTERNAL_ERROR;
622 if (transport == NCALRPC) {
623 context->allow_connect = true;
628 * allow overwrite per interface
629 * allow dcerpc auth level connect:<interface>
631 context->allow_connect = false;
632 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
633 "allow dcerpc auth level connect",
635 context->allow_connect);
639 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
640 const struct dcesrv_interface *iface)
642 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
643 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
644 enum dcerpc_transport_t transport =
645 dcerpc_binding_get_transport(endpoint->ep_description);
646 struct dcesrv_connection_context *context = dce_call->context;
648 if (context == NULL) {
649 return NT_STATUS_INTERNAL_ERROR;
652 if (transport == NCALRPC) {
653 context->allow_connect = true;
658 * allow overwrite per interface
659 * allow dcerpc auth level connect:<interface>
661 context->allow_connect = true;
662 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
663 "allow dcerpc auth level connect",
665 context->allow_connect);
670 handle a bind request
672 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
674 struct ncacn_packet pkt;
675 struct data_blob_list_item *rep;
677 uint32_t extra_flags = 0;
678 uint16_t max_req = 0;
679 uint16_t max_rep = 0;
680 const char *ep_prefix = "";
681 const char *endpoint = NULL;
682 const struct dcerpc_ctx_list *ctx = NULL;
683 struct dcerpc_ack_ctx *ack = NULL;
685 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
687 call->pkt.u.bind.auth_info.length,
688 0, /* required flags */
689 DCERPC_PFC_FLAG_FIRST |
690 DCERPC_PFC_FLAG_LAST |
691 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
692 0x08 | /* this is not defined, but should be ignored */
693 DCERPC_PFC_FLAG_CONC_MPX |
694 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
695 DCERPC_PFC_FLAG_MAYBE |
696 DCERPC_PFC_FLAG_OBJECT_UUID);
697 if (!NT_STATUS_IS_OK(status)) {
698 return dcesrv_bind_nak(call,
699 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
702 /* max_recv_frag and max_xmit_frag result always in the same value! */
703 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
704 call->pkt.u.bind.max_recv_frag);
706 * The values are between 2048 and 5840 tested against Windows 2012R2
707 * via ncacn_ip_tcp on port 135.
709 max_req = MAX(2048, max_req);
710 max_rep = MIN(max_req, call->conn->max_recv_frag);
711 /* They are truncated to an 8 byte boundary. */
714 /* max_recv_frag and max_xmit_frag result always in the same value! */
715 call->conn->max_recv_frag = max_rep;
716 call->conn->max_xmit_frag = max_rep;
719 if provided, check the assoc_group is valid
721 if (call->pkt.u.bind.assoc_group_id != 0) {
722 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
724 call->pkt.u.bind.assoc_group_id);
726 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
727 call->conn->dce_ctx);
729 if (call->conn->assoc_group == NULL) {
730 return dcesrv_bind_nak(call, 0);
733 if (call->pkt.u.bind.num_contexts < 1 ||
734 call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) {
735 return dcesrv_bind_nak(call, 0);
738 ctx = &call->pkt.u.bind.ctx_list[0];
740 ack = talloc_zero(call, struct dcerpc_ack_ctx);
742 return NT_STATUS_NO_MEMORY;
745 * Set some sane defaults, required by dcesrv_check_or_create_context()
747 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
748 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
750 status = dcesrv_check_or_create_context(call, &call->pkt.u.bind,
752 &ndr_transfer_syntax_ndr);
753 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
754 return dcesrv_bind_nak(call, 0);
756 if (!NT_STATUS_IS_OK(status)) {
760 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
761 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
762 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
763 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
766 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
767 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
770 /* handle any authentication that is being requested */
771 if (!dcesrv_auth_bind(call)) {
772 struct dcesrv_auth *auth = &call->conn->auth_state;
774 TALLOC_FREE(call->context);
776 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
778 * With DCERPC_AUTH_LEVEL_NONE, we get the
779 * reject_reason in auth->auth_context_id.
781 return dcesrv_bind_nak(call, auth->auth_context_id);
785 * This must a be a temporary failure e.g. talloc or invalid
786 * configuration, e.g. no machine account.
788 return dcesrv_bind_nak(call,
789 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
792 /* setup a bind_ack */
793 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
795 pkt.call_id = call->pkt.call_id;
796 pkt.ptype = DCERPC_PKT_BIND_ACK;
797 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
798 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
799 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
800 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
802 endpoint = dcerpc_binding_get_string_option(
803 call->conn->endpoint->ep_description,
805 if (endpoint == NULL) {
809 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
811 * TODO: check if this is really needed
813 * Or if we should fix this in our idl files.
815 ep_prefix = "\\PIPE\\";
819 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
822 if (pkt.u.bind_ack.secondary_address == NULL) {
823 TALLOC_FREE(call->context);
824 return NT_STATUS_NO_MEMORY;
826 pkt.u.bind_ack.num_results = 1;
827 pkt.u.bind_ack.ctx_list = ack;
828 pkt.u.bind_ack.auth_info = data_blob_null;
830 status = dcesrv_auth_bind_ack(call, &pkt);
831 if (!NT_STATUS_IS_OK(status)) {
832 TALLOC_FREE(call->context);
833 return dcesrv_bind_nak(call, 0);
836 rep = talloc_zero(call, struct data_blob_list_item);
838 TALLOC_FREE(call->context);
839 return NT_STATUS_NO_MEMORY;
842 status = ncacn_push_auth(&rep->blob, call, &pkt,
843 call->out_auth_info);
844 if (!NT_STATUS_IS_OK(status)) {
845 TALLOC_FREE(call->context);
849 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
851 DLIST_ADD_END(call->replies, rep);
852 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
854 if (call->conn->call_list && call->conn->call_list->replies) {
855 if (call->conn->transport.report_output_data) {
856 call->conn->transport.report_output_data(call->conn);
865 handle a auth3 request
867 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
871 if (!call->conn->allow_auth3) {
872 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
875 if (call->conn->auth_state.auth_finished) {
876 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
879 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
881 call->pkt.u.auth3.auth_info.length,
882 0, /* required flags */
883 DCERPC_PFC_FLAG_FIRST |
884 DCERPC_PFC_FLAG_LAST |
885 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
886 0x08 | /* this is not defined, but should be ignored */
887 DCERPC_PFC_FLAG_CONC_MPX |
888 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
889 DCERPC_PFC_FLAG_MAYBE |
890 DCERPC_PFC_FLAG_OBJECT_UUID);
891 if (!NT_STATUS_IS_OK(status)) {
892 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
895 /* handle the auth3 in the auth code */
896 if (!dcesrv_auth_auth3(call)) {
897 call->conn->auth_state.auth_invalid = true;
898 if (call->fault_code != 0) {
899 return dcesrv_fault_disconnect(call, call->fault_code);
905 /* we don't send a reply to a auth3 request, except by a
911 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
912 const struct dcerpc_bind *b,
913 const struct dcerpc_ctx_list *ctx,
914 struct dcerpc_ack_ctx *ack,
915 const struct ndr_syntax_id *supported_transfer)
918 struct dcesrv_connection_context *context;
919 const struct dcesrv_interface *iface;
922 const struct ndr_syntax_id *selected_transfer = NULL;
927 return NT_STATUS_INTERNAL_ERROR;
930 return NT_STATUS_INTERNAL_ERROR;
932 if (ctx->num_transfer_syntaxes < 1) {
933 return NT_STATUS_INTERNAL_ERROR;
936 return NT_STATUS_INTERNAL_ERROR;
938 if (supported_transfer == NULL) {
939 return NT_STATUS_INTERNAL_ERROR;
942 switch (ack->result) {
943 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
945 * We is already completed.
952 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
953 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
955 if_version = ctx->abstract_syntax.if_version;
956 uuid = ctx->abstract_syntax.uuid;
958 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
960 char *uuid_str = GUID_string(call, &uuid);
961 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
962 talloc_free(uuid_str);
964 * We report this only via ack->result
969 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
970 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
972 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
974 * we only do NDR encoded dcerpc for now.
976 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
979 selected_transfer = supported_transfer;
984 context = dcesrv_find_context(call->conn, ctx->context_id);
985 if (context != NULL) {
986 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
987 &ctx->abstract_syntax);
989 return NT_STATUS_RPC_PROTOCOL_ERROR;
992 if (ctx->num_transfer_syntaxes != 1) {
993 return NT_STATUS_RPC_PROTOCOL_ERROR;
996 if (selected_transfer != NULL) {
997 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1000 return NT_STATUS_RPC_PROTOCOL_ERROR;
1003 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1004 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1005 ack->syntax = context->transfer_syntax;
1007 return NT_STATUS_RPC_PROTOCOL_ERROR;
1011 * We report this only via ack->result
1013 return NT_STATUS_OK;
1016 if (selected_transfer == NULL) {
1018 * We report this only via ack->result
1020 return NT_STATUS_OK;
1023 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1024 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1026 /* add this context to the list of available context_ids */
1027 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1028 if (context == NULL) {
1029 return NT_STATUS_NO_MEMORY;
1031 context->conn = call->conn;
1032 context->context_id = ctx->context_id;
1033 context->iface = iface;
1034 context->transfer_syntax = *selected_transfer;
1035 context->private_data = NULL;
1036 DLIST_ADD(call->conn->contexts, context);
1037 call->context = context;
1038 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1040 dcesrv_prepare_context_auth(call);
1042 status = iface->bind(call, iface, if_version);
1043 call->context = NULL;
1044 if (!NT_STATUS_IS_OK(status)) {
1045 /* we don't want to trigger the iface->unbind() hook */
1046 context->iface = NULL;
1047 talloc_free(context);
1049 * We report this only via ack->result
1051 return NT_STATUS_OK;
1054 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1055 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1056 ack->syntax = context->transfer_syntax;
1057 return NT_STATUS_OK;
1061 handle a alter context request
1063 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1066 bool auth_ok = false;
1067 struct ncacn_packet pkt;
1068 uint32_t extra_flags = 0;
1069 struct data_blob_list_item *rep = NULL;
1070 const struct dcerpc_ctx_list *ctx = NULL;
1071 struct dcerpc_ack_ctx *ack = NULL;
1073 if (!call->conn->allow_alter) {
1074 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1077 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1079 call->pkt.u.alter.auth_info.length,
1080 0, /* required flags */
1081 DCERPC_PFC_FLAG_FIRST |
1082 DCERPC_PFC_FLAG_LAST |
1083 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1084 0x08 | /* this is not defined, but should be ignored */
1085 DCERPC_PFC_FLAG_CONC_MPX |
1086 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1087 DCERPC_PFC_FLAG_MAYBE |
1088 DCERPC_PFC_FLAG_OBJECT_UUID);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1093 auth_ok = dcesrv_auth_alter(call);
1095 if (call->fault_code != 0) {
1096 return dcesrv_fault_disconnect(call, call->fault_code);
1100 if (call->pkt.u.alter.num_contexts < 1) {
1101 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1103 ctx = &call->pkt.u.alter.ctx_list[0];
1104 if (ctx->num_transfer_syntaxes < 1) {
1105 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1108 ack = talloc_zero(call, struct dcerpc_ack_ctx);
1110 return NT_STATUS_NO_MEMORY;
1113 * Set some sane defaults, required by dcesrv_check_or_create_context()
1115 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1116 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1118 status = dcesrv_check_or_create_context(call, &call->pkt.u.alter,
1120 &ndr_transfer_syntax_ndr);
1121 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1122 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1124 if (!NT_STATUS_IS_OK(status)) {
1128 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1129 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1130 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1131 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1134 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1135 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1138 /* handle any authentication that is being requested */
1140 if (call->in_auth_info.auth_type !=
1141 call->conn->auth_state.auth_type)
1143 return dcesrv_fault_disconnect(call,
1144 DCERPC_FAULT_SEC_PKG_ERROR);
1146 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1149 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1150 pkt.auth_length = 0;
1151 pkt.call_id = call->pkt.call_id;
1152 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1153 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1154 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1155 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1156 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1157 pkt.u.alter_resp.secondary_address = "";
1158 pkt.u.alter_resp.num_results = 1;
1159 pkt.u.alter_resp.ctx_list = ack;
1160 pkt.u.alter_resp.auth_info = data_blob_null;
1162 status = dcesrv_auth_alter_ack(call, &pkt);
1163 if (!NT_STATUS_IS_OK(status)) {
1164 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1167 rep = talloc_zero(call, struct data_blob_list_item);
1169 return NT_STATUS_NO_MEMORY;
1172 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1173 if (!NT_STATUS_IS_OK(status)) {
1177 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1179 DLIST_ADD_END(call->replies, rep);
1180 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1182 if (call->conn->call_list && call->conn->call_list->replies) {
1183 if (call->conn->transport.report_output_data) {
1184 call->conn->transport.report_output_data(call->conn);
1188 return NT_STATUS_OK;
1192 possibly save the call for inspection with ndrdump
1194 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1198 const char *dump_dir;
1199 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1203 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1205 call->context->iface->name,
1206 call->pkt.u.request.opnum,
1208 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1209 DEBUG(0,("RPC SAVED %s\n", fname));
1215 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1217 TALLOC_CTX *frame = talloc_stackframe();
1218 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1219 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1220 const struct dcerpc_sec_vt_pcontext pcontext = {
1221 .abstract_syntax = call->context->iface->syntax_id,
1222 .transfer_syntax = call->context->transfer_syntax,
1224 const struct dcerpc_sec_vt_header2 header2 =
1225 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1226 enum ndr_err_code ndr_err;
1227 struct dcerpc_sec_verification_trailer *vt = NULL;
1228 NTSTATUS status = NT_STATUS_OK;
1231 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1233 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1235 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1236 status = ndr_map_error2ntstatus(ndr_err);
1240 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1241 &pcontext, &header2);
1243 status = NT_STATUS_ACCESS_DENIED;
1252 handle a dcerpc request packet
1254 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1256 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1257 enum dcerpc_transport_t transport =
1258 dcerpc_binding_get_transport(endpoint->ep_description);
1259 struct ndr_pull *pull;
1261 struct dcesrv_connection_context *context;
1263 if (!call->conn->allow_request) {
1264 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1267 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1268 if (call->conn->auth_state.gensec_security &&
1269 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1270 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1273 context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1274 if (context == NULL) {
1275 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1276 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1279 switch (call->conn->auth_state.auth_level) {
1280 case DCERPC_AUTH_LEVEL_NONE:
1281 case DCERPC_AUTH_LEVEL_PACKET:
1282 case DCERPC_AUTH_LEVEL_INTEGRITY:
1283 case DCERPC_AUTH_LEVEL_PRIVACY:
1286 if (!context->allow_connect) {
1289 addr = tsocket_address_string(call->conn->remote_address,
1292 DEBUG(2, ("%s: restrict auth_level_connect access "
1293 "to [%s] with auth[type=0x%x,level=0x%x] "
1294 "on [%s] from [%s]\n",
1295 __func__, context->iface->name,
1296 call->conn->auth_state.auth_type,
1297 call->conn->auth_state.auth_level,
1298 derpc_transport_string_by_transport(transport),
1300 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1305 if (call->conn->auth_state.auth_level < context->min_auth_level) {
1308 addr = tsocket_address_string(call->conn->remote_address, call);
1310 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1311 "to [%s] with auth[type=0x%x,level=0x%x] "
1312 "on [%s] from [%s]\n",
1314 context->min_auth_level,
1315 context->iface->name,
1316 call->conn->auth_state.auth_type,
1317 call->conn->auth_state.auth_level,
1318 derpc_transport_string_by_transport(transport),
1320 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1323 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1324 NT_STATUS_HAVE_NO_MEMORY(pull);
1326 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1328 call->context = context;
1329 call->ndr_pull = pull;
1331 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1332 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1335 status = dcesrv_check_verification_trailer(call);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 uint32_t faultcode = DCERPC_FAULT_OTHER;
1338 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1339 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1341 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1342 nt_errstr(status)));
1343 return dcesrv_fault(call, faultcode);
1346 /* unravel the NDR for the packet */
1347 status = context->iface->ndr_pull(call, call, pull, &call->r);
1348 if (!NT_STATUS_IS_OK(status)) {
1349 uint8_t extra_flags = 0;
1350 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1351 /* we got an unknown call */
1352 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1353 call->pkt.u.request.opnum, context->iface->name));
1354 dcesrv_save_call(call, "unknown");
1355 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1357 dcesrv_save_call(call, "pullfail");
1359 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1362 if (pull->offset != pull->data_size) {
1363 dcesrv_save_call(call, "extrabytes");
1364 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1365 pull->data_size - pull->offset));
1368 /* call the dispatch function */
1369 status = context->iface->dispatch(call, call, call->r);
1370 if (!NT_STATUS_IS_OK(status)) {
1371 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1372 context->iface->name,
1373 call->pkt.u.request.opnum,
1374 dcerpc_errstr(pull, call->fault_code)));
1375 return dcesrv_fault(call, call->fault_code);
1378 /* add the call to the pending list */
1379 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1381 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1382 return NT_STATUS_OK;
1385 return dcesrv_reply(call);
1390 remove the call from the right list when freed
1392 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1394 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1398 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1400 return conn->local_address;
1403 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1405 return conn->remote_address;
1409 process some input to a dcerpc endpoint server.
1411 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1412 struct ncacn_packet *pkt,
1416 struct dcesrv_call_state *call;
1417 struct dcesrv_call_state *existing = NULL;
1419 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1421 data_blob_free(&blob);
1423 return NT_STATUS_NO_MEMORY;
1425 call->conn = dce_conn;
1426 call->event_ctx = dce_conn->event_ctx;
1427 call->msg_ctx = dce_conn->msg_ctx;
1428 call->state_flags = call->conn->state_flags;
1429 call->time = timeval_current();
1430 call->list = DCESRV_LIST_NONE;
1432 talloc_steal(call, pkt);
1433 talloc_steal(call, blob.data);
1436 talloc_set_destructor(call, dcesrv_call_dequeue);
1438 if (call->conn->allow_bind) {
1440 * Only one bind is possible per connection
1442 call->conn->allow_bind = false;
1443 return dcesrv_bind(call);
1446 /* we have to check the signing here, before combining the
1448 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1449 if (!call->conn->allow_request) {
1450 return dcesrv_fault_disconnect(call,
1451 DCERPC_NCA_S_PROTO_ERROR);
1454 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1456 call->pkt.u.request.stub_and_verifier.length,
1457 0, /* required_flags */
1458 DCERPC_PFC_FLAG_FIRST |
1459 DCERPC_PFC_FLAG_LAST |
1460 DCERPC_PFC_FLAG_PENDING_CANCEL |
1461 0x08 | /* this is not defined, but should be ignored */
1462 DCERPC_PFC_FLAG_CONC_MPX |
1463 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1464 DCERPC_PFC_FLAG_MAYBE |
1465 DCERPC_PFC_FLAG_OBJECT_UUID);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 return dcesrv_fault_disconnect(call,
1468 DCERPC_NCA_S_PROTO_ERROR);
1471 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1473 * We don't use dcesrv_fault_disconnect()
1474 * here, because we don't want to set
1475 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1477 * Note that we don't check against the negotiated
1478 * max_recv_frag, but a hard coded value.
1480 dcesrv_call_disconnect_after(call,
1481 "dcesrv_auth_request - frag_length too large");
1482 return dcesrv_fault(call,
1483 DCERPC_NCA_S_PROTO_ERROR);
1486 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1487 /* only one request is possible in the fragmented list */
1488 if (dce_conn->incoming_fragmented_call_list != NULL) {
1490 call = dce_conn->incoming_fragmented_call_list;
1491 dcesrv_call_disconnect_after(call,
1492 "dcesrv_auth_request - "
1493 "existing fragmented call");
1494 return dcesrv_fault(call,
1495 DCERPC_NCA_S_PROTO_ERROR);
1497 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1498 return dcesrv_fault_disconnect(call,
1499 DCERPC_FAULT_NO_CALL_ACTIVE);
1502 const struct dcerpc_request *nr = &call->pkt.u.request;
1503 const struct dcerpc_request *er = NULL;
1506 existing = dcesrv_find_fragmented_call(dce_conn,
1508 if (existing == NULL) {
1509 dcesrv_call_disconnect_after(call,
1510 "dcesrv_auth_request - "
1511 "no existing fragmented call");
1512 return dcesrv_fault(call,
1513 DCERPC_NCA_S_PROTO_ERROR);
1515 er = &existing->pkt.u.request;
1517 if (call->pkt.ptype != existing->pkt.ptype) {
1518 /* trying to play silly buggers are we? */
1519 return dcesrv_fault_disconnect(existing,
1520 DCERPC_NCA_S_PROTO_ERROR);
1522 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1525 return dcesrv_fault_disconnect(existing,
1526 DCERPC_NCA_S_PROTO_ERROR);
1528 if (nr->context_id != er->context_id) {
1529 return dcesrv_fault_disconnect(existing,
1530 DCERPC_NCA_S_PROTO_ERROR);
1532 if (nr->opnum != er->opnum) {
1533 return dcesrv_fault_disconnect(existing,
1534 DCERPC_NCA_S_PROTO_ERROR);
1538 if (!dcesrv_auth_request(call, &blob)) {
1540 * We don't use dcesrv_fault_disconnect()
1541 * here, because we don't want to set
1542 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1544 dcesrv_call_disconnect_after(call,
1545 "dcesrv_auth_request - failed");
1546 if (call->fault_code == 0) {
1547 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1549 return dcesrv_fault(call, call->fault_code);
1553 /* see if this is a continued packet */
1554 if (existing != NULL) {
1555 struct dcerpc_request *er = &existing->pkt.u.request;
1556 const struct dcerpc_request *nr = &call->pkt.u.request;
1562 * Up to 4 MByte are allowed by all fragments
1564 available = dce_conn->max_total_request_size;
1565 if (er->stub_and_verifier.length > available) {
1566 dcesrv_call_disconnect_after(existing,
1567 "dcesrv_auth_request - existing payload too large");
1568 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1570 available -= er->stub_and_verifier.length;
1571 if (nr->alloc_hint > available) {
1572 dcesrv_call_disconnect_after(existing,
1573 "dcesrv_auth_request - alloc hint too large");
1574 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1576 if (nr->stub_and_verifier.length > available) {
1577 dcesrv_call_disconnect_after(existing,
1578 "dcesrv_auth_request - new payload too large");
1579 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1581 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1582 /* allocate at least 1 byte */
1583 alloc_hint = MAX(alloc_hint, 1);
1584 alloc_size = er->stub_and_verifier.length +
1585 nr->stub_and_verifier.length;
1586 alloc_size = MAX(alloc_size, alloc_hint);
1588 er->stub_and_verifier.data =
1589 talloc_realloc(existing,
1590 er->stub_and_verifier.data,
1591 uint8_t, alloc_size);
1592 if (er->stub_and_verifier.data == NULL) {
1594 return dcesrv_fault_with_flags(existing,
1595 DCERPC_FAULT_OUT_OF_RESOURCES,
1596 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1598 memcpy(er->stub_and_verifier.data +
1599 er->stub_and_verifier.length,
1600 nr->stub_and_verifier.data,
1601 nr->stub_and_verifier.length);
1602 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1604 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1610 /* this may not be the last pdu in the chain - if its isn't then
1611 just put it on the incoming_fragmented_call_list and wait for the rest */
1612 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1613 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1615 * Up to 4 MByte are allowed by all fragments
1617 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1618 dcesrv_call_disconnect_after(call,
1619 "dcesrv_auth_request - initial alloc hint too large");
1620 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1622 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1623 return NT_STATUS_OK;
1626 /* This removes any fragments we may have had stashed away */
1627 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1629 switch (call->pkt.ptype) {
1630 case DCERPC_PKT_BIND:
1631 status = dcesrv_bind_nak(call,
1632 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1634 case DCERPC_PKT_AUTH3:
1635 status = dcesrv_auth3(call);
1637 case DCERPC_PKT_ALTER:
1638 status = dcesrv_alter(call);
1640 case DCERPC_PKT_REQUEST:
1641 status = dcesrv_request(call);
1644 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1648 /* if we are going to be sending a reply then add
1649 it to the list of pending calls. We add it to the end to keep the call
1650 list in the order we will answer */
1651 if (!NT_STATUS_IS_OK(status)) {
1658 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1659 struct loadparm_context *lp_ctx,
1660 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1663 struct dcesrv_context *dce_ctx;
1666 if (!endpoint_servers) {
1667 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1668 return NT_STATUS_INTERNAL_ERROR;
1671 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1672 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1674 if (uid_wrapper_enabled()) {
1675 setenv("UID_WRAPPER_MYUID", "1", 1);
1677 dce_ctx->initial_euid = geteuid();
1678 if (uid_wrapper_enabled()) {
1679 unsetenv("UID_WRAPPER_MYUID");
1682 dce_ctx->endpoint_list = NULL;
1683 dce_ctx->lp_ctx = lp_ctx;
1684 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1685 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1686 dce_ctx->broken_connections = NULL;
1688 for (i=0;endpoint_servers[i];i++) {
1689 const struct dcesrv_endpoint_server *ep_server;
1691 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1693 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1694 return NT_STATUS_INTERNAL_ERROR;
1697 status = ep_server->init_server(dce_ctx, ep_server);
1698 if (!NT_STATUS_IS_OK(status)) {
1699 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1700 nt_errstr(status)));
1705 *_dce_ctx = dce_ctx;
1706 return NT_STATUS_OK;
1709 /* the list of currently registered DCERPC endpoint servers.
1711 static struct ep_server {
1712 struct dcesrv_endpoint_server *ep_server;
1713 } *ep_servers = NULL;
1714 static int num_ep_servers;
1717 register a DCERPC endpoint server.
1719 The 'name' can be later used by other backends to find the operations
1720 structure for this backend.
1722 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1724 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1726 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1728 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1729 /* its already registered! */
1730 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1732 return NT_STATUS_OBJECT_NAME_COLLISION;
1735 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1737 smb_panic("out of memory in dcerpc_register");
1740 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1741 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1745 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1748 return NT_STATUS_OK;
1752 return the operations structure for a named backend of the specified type
1754 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1758 for (i=0;i<num_ep_servers;i++) {
1759 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1760 return ep_servers[i].ep_server;
1767 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1769 static bool initialized;
1770 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1771 STATIC_dcerpc_server_MODULES_PROTO;
1772 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1773 init_module_fn *shared_init;
1780 shared_init = load_samba_modules(NULL, "dcerpc_server");
1782 run_init_functions(static_init);
1783 run_init_functions(shared_init);
1785 talloc_free(shared_init);
1789 return the DCERPC module version, and the size of some critical types
1790 This can be used by endpoint server modules to either detect compilation errors, or provide
1791 multiple implementations for different smbd compilation options in one module
1793 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1795 static const struct dcesrv_critical_sizes critical_sizes = {
1796 DCERPC_MODULE_VERSION,
1797 sizeof(struct dcesrv_context),
1798 sizeof(struct dcesrv_endpoint),
1799 sizeof(struct dcesrv_endpoint_server),
1800 sizeof(struct dcesrv_interface),
1801 sizeof(struct dcesrv_if_list),
1802 sizeof(struct dcesrv_connection),
1803 sizeof(struct dcesrv_call_state),
1804 sizeof(struct dcesrv_auth),
1805 sizeof(struct dcesrv_handle)
1808 return &critical_sizes;
1811 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1813 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1814 struct stream_connection *srv_conn;
1815 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1816 struct stream_connection);
1818 dce_conn->allow_bind = false;
1819 dce_conn->allow_auth3 = false;
1820 dce_conn->allow_alter = false;
1821 dce_conn->allow_request = false;
1823 if (dce_conn->pending_call_list == NULL) {
1824 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1826 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1827 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1831 if (dce_conn->terminate != NULL) {
1835 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
1837 dce_conn->terminate = talloc_strdup(dce_conn, reason);
1838 if (dce_conn->terminate == NULL) {
1839 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
1841 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
1844 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
1846 struct dcesrv_connection *cur, *next;
1848 next = dce_ctx->broken_connections;
1849 while (next != NULL) {
1853 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1854 struct dcesrv_connection_context *context_cur, *context_next;
1856 context_next = cur->contexts;
1857 while (context_next != NULL) {
1858 context_cur = context_next;
1859 context_next = context_cur->next;
1861 dcesrv_connection_context_destructor(context_cur);
1865 dcesrv_terminate_connection(cur, cur->terminate);
1869 /* We need this include to be able to compile on some plateforms
1870 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
1872 * It has to be that deep because otherwise we have a conflict on
1873 * const struct dcesrv_interface declaration.
1874 * This is mostly due to socket_wrapper defining #define bind swrap_bind
1875 * which conflict with the bind used before.
1877 #include "system/network.h"
1879 struct dcesrv_sock_reply_state {
1880 struct dcesrv_connection *dce_conn;
1881 struct dcesrv_call_state *call;
1885 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
1886 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
1888 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
1890 struct dcesrv_call_state *call;
1892 call = dce_conn->call_list;
1893 if (!call || !call->replies) {
1897 while (call->replies) {
1898 struct data_blob_list_item *rep = call->replies;
1899 struct dcesrv_sock_reply_state *substate;
1900 struct tevent_req *subreq;
1902 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
1904 dcesrv_terminate_connection(dce_conn, "no memory");
1908 substate->dce_conn = dce_conn;
1909 substate->call = NULL;
1911 DLIST_REMOVE(call->replies, rep);
1913 if (call->replies == NULL && call->terminate_reason == NULL) {
1914 substate->call = call;
1917 substate->iov.iov_base = (void *) rep->blob.data;
1918 substate->iov.iov_len = rep->blob.length;
1920 subreq = tstream_writev_queue_send(substate,
1921 dce_conn->event_ctx,
1923 dce_conn->send_queue,
1926 dcesrv_terminate_connection(dce_conn, "no memory");
1929 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
1933 if (call->terminate_reason != NULL) {
1934 struct tevent_req *subreq;
1936 subreq = tevent_queue_wait_send(call,
1937 dce_conn->event_ctx,
1938 dce_conn->send_queue);
1940 dcesrv_terminate_connection(dce_conn, __location__);
1943 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
1947 DLIST_REMOVE(call->conn->call_list, call);
1948 call->list = DCESRV_LIST_NONE;
1951 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
1953 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
1954 struct dcesrv_sock_reply_state);
1958 struct dcesrv_call_state *call = substate->call;
1960 ret = tstream_writev_queue_recv(subreq, &sys_errno);
1961 TALLOC_FREE(subreq);
1963 status = map_nt_error_from_unix_common(sys_errno);
1964 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
1968 talloc_free(substate);
1974 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
1976 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
1978 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1979 struct dcesrv_call_state);
1983 /* make sure we stop send queue before removing subreq */
1984 tevent_queue_stop(call->conn->send_queue);
1986 ok = tevent_queue_wait_recv(subreq);
1987 TALLOC_FREE(subreq);
1989 dcesrv_terminate_connection(call->conn, __location__);
1993 /* disconnect after 200 usecs */
1994 tv = timeval_current_ofs_usec(200);
1995 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
1996 if (subreq == NULL) {
1997 dcesrv_terminate_connection(call->conn, __location__);
2000 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2004 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2006 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2007 struct dcesrv_call_state);
2010 ok = tevent_wakeup_recv(subreq);
2011 TALLOC_FREE(subreq);
2013 dcesrv_terminate_connection(call->conn, __location__);
2017 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2020 struct dcesrv_socket_context {
2021 const struct dcesrv_endpoint *endpoint;
2022 struct dcesrv_context *dcesrv_ctx;
2026 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2028 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2031 struct dcesrv_socket_context *dcesrv_sock =
2032 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2033 enum dcerpc_transport_t transport =
2034 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2035 struct dcesrv_connection *dcesrv_conn = NULL;
2037 struct tevent_req *subreq;
2038 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2040 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2042 if (!srv_conn->session_info) {
2043 status = auth_anonymous_session_info(srv_conn,
2045 &srv_conn->session_info);
2046 if (!NT_STATUS_IS_OK(status)) {
2047 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2048 nt_errstr(status)));
2049 stream_terminate_connection(srv_conn, nt_errstr(status));
2054 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2056 dcesrv_sock->endpoint,
2057 srv_conn->session_info,
2058 srv_conn->event.ctx,
2060 srv_conn->server_id,
2061 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2063 if (!NT_STATUS_IS_OK(status)) {
2064 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2065 nt_errstr(status)));
2066 stream_terminate_connection(srv_conn, nt_errstr(status));
2070 dcesrv_conn->transport.private_data = srv_conn;
2071 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2073 TALLOC_FREE(srv_conn->event.fde);
2075 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2076 if (!dcesrv_conn->send_queue) {
2077 status = NT_STATUS_NO_MEMORY;
2078 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2079 nt_errstr(status)));
2080 stream_terminate_connection(srv_conn, nt_errstr(status));
2084 if (transport == NCACN_NP) {
2085 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2086 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2087 &srv_conn->tstream);
2089 ret = tstream_bsd_existing_socket(dcesrv_conn,
2090 socket_get_fd(srv_conn->socket),
2091 &dcesrv_conn->stream);
2093 status = map_nt_error_from_unix_common(errno);
2094 DEBUG(0, ("dcesrv_sock_accept: "
2095 "failed to setup tstream: %s\n",
2096 nt_errstr(status)));
2097 stream_terminate_connection(srv_conn, nt_errstr(status));
2100 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2103 dcesrv_conn->local_address = srv_conn->local_address;
2104 dcesrv_conn->remote_address = srv_conn->remote_address;
2106 if (transport == NCALRPC) {
2111 sock_fd = socket_get_fd(srv_conn->socket);
2112 if (sock_fd == -1) {
2113 stream_terminate_connection(
2114 srv_conn, "socket_get_fd failed\n");
2118 ret = getpeereid(sock_fd, &uid, &gid);
2120 status = map_nt_error_from_unix_common(errno);
2121 DEBUG(0, ("dcesrv_sock_accept: "
2122 "getpeereid() failed for NCALRPC: %s\n",
2123 nt_errstr(status)));
2124 stream_terminate_connection(srv_conn, nt_errstr(status));
2127 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2128 struct tsocket_address *r = NULL;
2130 ret = tsocket_address_unix_from_path(dcesrv_conn,
2131 "/root/ncalrpc_as_system",
2134 status = map_nt_error_from_unix_common(errno);
2135 DEBUG(0, ("dcesrv_sock_accept: "
2136 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2137 nt_errstr(status)));
2138 stream_terminate_connection(srv_conn, nt_errstr(status));
2141 dcesrv_conn->remote_address = r;
2145 srv_conn->private_data = dcesrv_conn;
2147 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2149 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2150 dcesrv_conn->event_ctx,
2151 dcesrv_conn->stream);
2153 status = NT_STATUS_NO_MEMORY;
2154 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2155 nt_errstr(status)));
2156 stream_terminate_connection(srv_conn, nt_errstr(status));
2159 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2164 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2166 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2167 struct dcesrv_connection);
2168 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2169 struct ncacn_packet *pkt;
2173 if (dce_conn->terminate) {
2175 * if the current connection is broken
2176 * we need to clean it up before any other connection
2178 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2179 dcesrv_cleanup_broken_connections(dce_ctx);
2183 dcesrv_cleanup_broken_connections(dce_ctx);
2185 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2187 TALLOC_FREE(subreq);
2188 if (!NT_STATUS_IS_OK(status)) {
2189 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2193 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2194 if (!NT_STATUS_IS_OK(status)) {
2195 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2199 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2200 dce_conn->event_ctx,
2203 status = NT_STATUS_NO_MEMORY;
2204 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2207 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2210 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2212 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2213 struct dcesrv_connection);
2214 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2217 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2219 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2220 struct dcesrv_connection);
2221 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2225 static const struct stream_server_ops dcesrv_stream_ops = {
2227 .accept_connection = dcesrv_sock_accept,
2228 .recv_handler = dcesrv_sock_recv,
2229 .send_handler = dcesrv_sock_send,
2232 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2233 struct loadparm_context *lp_ctx,
2234 struct dcesrv_endpoint *e,
2235 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2237 struct dcesrv_socket_context *dcesrv_sock;
2240 const char *endpoint;
2242 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2243 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2245 /* remember the endpoint of this socket */
2246 dcesrv_sock->endpoint = e;
2247 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2249 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2251 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2252 model_ops, &dcesrv_stream_ops,
2253 "unix", endpoint, &port,
2254 lpcfg_socket_options(lp_ctx),
2256 if (!NT_STATUS_IS_OK(status)) {
2257 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2258 endpoint, nt_errstr(status)));
2264 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2265 struct loadparm_context *lp_ctx,
2266 struct dcesrv_endpoint *e,
2267 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2269 struct dcesrv_socket_context *dcesrv_sock;
2273 const char *endpoint;
2275 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2277 if (endpoint == NULL) {
2279 * No identifier specified: use DEFAULT.
2281 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2282 * no endpoint and let the epmapper worry about it.
2284 endpoint = "DEFAULT";
2285 status = dcerpc_binding_set_string_option(e->ep_description,
2288 if (!NT_STATUS_IS_OK(status)) {
2289 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2290 nt_errstr(status)));
2295 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2298 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2299 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2301 /* remember the endpoint of this socket */
2302 dcesrv_sock->endpoint = e;
2303 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2305 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2306 model_ops, &dcesrv_stream_ops,
2307 "unix", full_path, &port,
2308 lpcfg_socket_options(lp_ctx),
2310 if (!NT_STATUS_IS_OK(status)) {
2311 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2312 endpoint, full_path, nt_errstr(status)));
2317 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2318 struct loadparm_context *lp_ctx,
2319 struct dcesrv_endpoint *e,
2320 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2322 struct dcesrv_socket_context *dcesrv_sock;
2324 const char *endpoint;
2326 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2327 if (endpoint == NULL) {
2328 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2329 return NT_STATUS_INVALID_PARAMETER;
2332 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2333 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2335 /* remember the endpoint of this socket */
2336 dcesrv_sock->endpoint = e;
2337 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2339 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2340 model_ops, &dcesrv_stream_ops,
2343 if (!NT_STATUS_IS_OK(status)) {
2344 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2345 endpoint, nt_errstr(status)));
2349 return NT_STATUS_OK;
2353 add a socket address to the list of events, one event per dcerpc endpoint
2355 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2356 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2357 const char *address)
2359 struct dcesrv_socket_context *dcesrv_sock;
2362 const char *endpoint;
2365 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2366 if (endpoint != NULL) {
2367 port = atoi(endpoint);
2370 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2371 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2373 /* remember the endpoint of this socket */
2374 dcesrv_sock->endpoint = e;
2375 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2377 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2378 model_ops, &dcesrv_stream_ops,
2379 "ip", address, &port,
2380 lpcfg_socket_options(dce_ctx->lp_ctx),
2382 if (!NT_STATUS_IS_OK(status)) {
2383 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2384 address, port, nt_errstr(status)));
2388 snprintf(port_str, sizeof(port_str), "%u", port);
2390 status = dcerpc_binding_set_string_option(e->ep_description,
2391 "endpoint", port_str);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2394 port_str, nt_errstr(status)));
2398 return NT_STATUS_OK;
2401 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2403 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2404 struct loadparm_context *lp_ctx,
2405 struct dcesrv_endpoint *e,
2406 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2410 /* Add TCP/IP sockets */
2411 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2414 struct interface *ifaces;
2416 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2418 num_interfaces = iface_list_count(ifaces);
2419 for(i = 0; i < num_interfaces; i++) {
2420 const char *address = iface_list_n_ip(ifaces, i);
2421 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2422 NT_STATUS_NOT_OK_RETURN(status);
2428 wcard = iface_list_wildcard(dce_ctx);
2429 NT_STATUS_HAVE_NO_MEMORY(wcard);
2430 for (i=0; wcard[i]; i++) {
2431 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2432 if (NT_STATUS_IS_OK(status)) {
2437 if (num_binds == 0) {
2438 return NT_STATUS_INVALID_PARAMETER_MIX;
2442 return NT_STATUS_OK;
2445 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2446 struct loadparm_context *lp_ctx,
2447 struct dcesrv_endpoint *e,
2448 struct tevent_context *event_ctx,
2449 const struct model_ops *model_ops)
2451 enum dcerpc_transport_t transport =
2452 dcerpc_binding_get_transport(e->ep_description);
2454 switch (transport) {
2455 case NCACN_UNIX_STREAM:
2456 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2459 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2462 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2465 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2468 return NT_STATUS_NOT_SUPPORTED;
2474 * retrieve credentials from a dce_call
2476 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2478 return dce_call->conn->auth_state.session_info->credentials;
2482 * returns true if this is an authenticated call
2484 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2486 enum security_user_level level;
2487 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2488 return level >= SECURITY_USER;
2492 * retrieve account_name for a dce_call
2494 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2496 return dce_call->context->conn->auth_state.session_info->info->account_name;