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;
49 find an association group given a assoc_group_id
51 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
56 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
60 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
64 take a reference to an existing association group
66 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
67 struct dcesrv_context *dce_ctx,
70 struct dcesrv_assoc_group *assoc_group;
72 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
73 if (assoc_group == NULL) {
74 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
77 return talloc_reference(mem_ctx, assoc_group);
80 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
83 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
85 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
92 allocate a new association group
94 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
95 struct dcesrv_context *dce_ctx)
97 struct dcesrv_assoc_group *assoc_group;
100 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
101 if (assoc_group == NULL) {
105 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
107 talloc_free(assoc_group);
108 DEBUG(0,(__location__ ": Out of association groups!\n"));
112 assoc_group->id = id;
113 assoc_group->dce_ctx = dce_ctx;
115 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
122 see if two endpoints match
124 static bool endpoints_match(const struct dcerpc_binding *ep1,
125 const struct dcerpc_binding *ep2)
127 enum dcerpc_transport_t t1;
128 enum dcerpc_transport_t t2;
132 t1 = dcerpc_binding_get_transport(ep1);
133 t2 = dcerpc_binding_get_transport(ep2);
135 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
136 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
146 if (strcasecmp(e1, e2) != 0) {
154 find an endpoint in the dcesrv_context
156 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
157 const struct dcerpc_binding *ep_description)
159 struct dcesrv_endpoint *ep;
160 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
161 if (endpoints_match(ep->ep_description, ep_description)) {
169 find a registered context_id from a bind or alter_context
171 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
174 struct dcesrv_connection_context *c;
175 for (c=conn->contexts;c;c=c->next) {
176 if (c->context_id == context_id) return c;
182 see if a uuid and if_version match to an interface
184 static bool interface_match(const struct dcesrv_interface *if1,
185 const struct dcesrv_interface *if2)
187 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
188 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
192 find the interface operations on an endpoint
194 static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint,
195 const struct dcesrv_interface *iface)
197 struct dcesrv_if_list *ifl;
198 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
199 if (interface_match(&(ifl->iface), iface)) {
200 return &(ifl->iface);
207 see if a uuid and if_version match to an interface
209 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
210 const struct GUID *uuid, uint32_t if_version)
212 return (iface->syntax_id.if_version == if_version &&
213 GUID_equal(&iface->syntax_id.uuid, uuid));
217 find the interface operations on an endpoint by uuid
219 static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
220 const struct GUID *uuid, uint32_t if_version)
222 struct dcesrv_if_list *ifl;
223 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
224 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
225 return &(ifl->iface);
232 find the earlier parts of a fragmented call awaiting reassembily
234 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
236 struct dcesrv_call_state *c;
237 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
238 if (c->pkt.call_id == call_id) {
246 register an interface on an endpoint
248 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
250 const struct dcesrv_interface *iface,
251 const struct security_descriptor *sd)
253 struct dcesrv_endpoint *ep;
254 struct dcesrv_if_list *ifl;
255 struct dcerpc_binding *binding;
259 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
261 if (NT_STATUS_IS_ERR(status)) {
262 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
266 /* check if this endpoint exists
268 if ((ep=find_endpoint(dce_ctx, binding))==NULL) {
269 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
271 return NT_STATUS_NO_MEMORY;
274 ep->ep_description = talloc_move(ep, &binding);
277 /* add mgmt interface */
278 ifl = talloc_zero(ep, struct dcesrv_if_list);
280 return NT_STATUS_NO_MEMORY;
283 memcpy(&(ifl->iface), &dcesrv_mgmt_interface,
284 sizeof(struct dcesrv_interface));
286 DLIST_ADD(ep->interface_list, ifl);
289 /* see if the interface is already registered on te endpoint */
290 if (find_interface(ep, iface)!=NULL) {
291 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
292 iface->name, ep_name));
293 return NT_STATUS_OBJECT_NAME_COLLISION;
296 /* talloc a new interface list element */
297 ifl = talloc_zero(ep, struct dcesrv_if_list);
299 return NT_STATUS_NO_MEMORY;
302 /* copy the given interface struct to the one on the endpoints interface list */
303 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
305 /* if we have a security descriptor given,
306 * we should see if we can set it up on the endpoint
309 /* if there's currently no security descriptor given on the endpoint
312 if (ep->sd == NULL) {
313 ep->sd = security_descriptor_copy(ep, sd);
316 /* if now there's no security descriptor given on the endpoint
317 * something goes wrong, either we failed to copy the security descriptor
318 * or there was already one on the endpoint
320 if (ep->sd != NULL) {
321 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
322 " on endpoint '%s'\n",
323 iface->name, ep_name));
324 if (add_ep) free(ep);
326 return NT_STATUS_OBJECT_NAME_COLLISION;
330 /* finally add the interface on the endpoint */
331 DLIST_ADD(ep->interface_list, ifl);
333 /* if it's a new endpoint add it to the dcesrv_context */
335 DLIST_ADD(dce_ctx->endpoint_list, ep);
338 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
339 iface->name, ep_name));
344 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
345 DATA_BLOB *session_key)
347 if (p->auth_state.session_info->session_key.length) {
348 *session_key = p->auth_state.session_info->session_key;
351 return NT_STATUS_NO_USER_SESSION_KEY;
355 fetch the user session key - may be default (above) or the SMB session key
357 The key is always truncated to 16 bytes
359 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
360 DATA_BLOB *session_key)
362 NTSTATUS status = p->auth_state.session_key(p, session_key);
363 if (!NT_STATUS_IS_OK(status)) {
367 session_key->length = MIN(session_key->length, 16);
373 connect to a dcerpc endpoint
375 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
377 const struct dcesrv_endpoint *ep,
378 struct auth_session_info *session_info,
379 struct tevent_context *event_ctx,
380 struct imessaging_context *msg_ctx,
381 struct server_id server_id,
382 uint32_t state_flags,
383 struct dcesrv_connection **_p)
385 struct dcesrv_connection *p;
388 return NT_STATUS_ACCESS_DENIED;
391 p = talloc_zero(mem_ctx, struct dcesrv_connection);
392 NT_STATUS_HAVE_NO_MEMORY(p);
394 if (!talloc_reference(p, session_info)) {
396 return NT_STATUS_NO_MEMORY;
399 p->dce_ctx = dce_ctx;
401 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
402 p->auth_state.session_info = session_info;
403 p->auth_state.session_key = dcesrv_generic_session_key;
404 p->event_ctx = event_ctx;
405 p->msg_ctx = msg_ctx;
406 p->server_id = server_id;
407 p->state_flags = state_flags;
408 p->allow_bind = true;
409 p->max_recv_frag = 5840;
410 p->max_xmit_frag = 5840;
411 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
418 move a call from an existing linked list to the specified list. This
419 prevents bugs where we forget to remove the call from a previous
422 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
423 enum dcesrv_call_list list)
425 switch (call->list) {
426 case DCESRV_LIST_NONE:
428 case DCESRV_LIST_CALL_LIST:
429 DLIST_REMOVE(call->conn->call_list, call);
431 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
432 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
434 case DCESRV_LIST_PENDING_CALL_LIST:
435 DLIST_REMOVE(call->conn->pending_call_list, call);
440 case DCESRV_LIST_NONE:
442 case DCESRV_LIST_CALL_LIST:
443 DLIST_ADD_END(call->conn->call_list, call);
445 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
446 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
448 case DCESRV_LIST_PENDING_CALL_LIST:
449 DLIST_ADD_END(call->conn->pending_call_list, call);
454 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
457 if (call->conn->terminate != NULL) {
461 call->conn->allow_bind = false;
462 call->conn->allow_alter = false;
463 call->conn->allow_auth3 = false;
464 call->conn->allow_request = false;
466 call->terminate_reason = talloc_strdup(call, reason);
467 if (call->terminate_reason == NULL) {
468 call->terminate_reason = __location__;
473 return a dcerpc bind_nak
475 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
477 struct ncacn_packet pkt;
478 struct dcerpc_bind_nak_version version;
479 struct data_blob_list_item *rep;
481 static const uint8_t _pad[3] = { 0, };
484 * We add the call to the pending_call_list
485 * in order to defer the termination.
487 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
489 /* setup a bind_nak */
490 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
492 pkt.call_id = call->pkt.call_id;
493 pkt.ptype = DCERPC_PKT_BIND_NAK;
494 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
495 pkt.u.bind_nak.reject_reason = reason;
496 version.rpc_vers = 5;
497 version.rpc_vers_minor = 0;
498 pkt.u.bind_nak.num_versions = 1;
499 pkt.u.bind_nak.versions = &version;
500 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
502 rep = talloc_zero(call, struct data_blob_list_item);
504 return NT_STATUS_NO_MEMORY;
507 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
508 if (!NT_STATUS_IS_OK(status)) {
512 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
514 DLIST_ADD_END(call->replies, rep);
515 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
517 if (call->conn->call_list && call->conn->call_list->replies) {
518 if (call->conn->transport.report_output_data) {
519 call->conn->transport.report_output_data(call->conn);
526 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
530 * We add the call to the pending_call_list
531 * in order to defer the termination.
533 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
535 return dcesrv_fault_with_flags(call, fault_code,
536 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
539 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
541 DLIST_REMOVE(c->conn->contexts, c);
543 if (c->iface && c->iface->unbind) {
544 c->iface->unbind(c, c->iface);
551 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
553 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
554 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
555 enum dcerpc_transport_t transport =
556 dcerpc_binding_get_transport(endpoint->ep_description);
557 struct dcesrv_connection_context *context = dce_call->context;
558 const struct dcesrv_interface *iface = context->iface;
560 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
562 if (transport == NCALRPC) {
563 context->allow_connect = true;
568 * allow overwrite per interface
569 * allow dcerpc auth level connect:<interface>
571 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
572 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
573 "allow dcerpc auth level connect",
575 context->allow_connect);
578 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
579 const struct dcesrv_interface *iface)
581 if (dce_call->context == NULL) {
582 return NT_STATUS_INTERNAL_ERROR;
585 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
589 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
590 const struct dcesrv_interface *iface)
592 if (dce_call->context == NULL) {
593 return NT_STATUS_INTERNAL_ERROR;
596 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
600 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
601 const struct dcesrv_interface *iface)
603 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
604 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
605 enum dcerpc_transport_t transport =
606 dcerpc_binding_get_transport(endpoint->ep_description);
607 struct dcesrv_connection_context *context = dce_call->context;
609 if (context == NULL) {
610 return NT_STATUS_INTERNAL_ERROR;
613 if (transport == NCALRPC) {
614 context->allow_connect = true;
619 * allow overwrite per interface
620 * allow dcerpc auth level connect:<interface>
622 context->allow_connect = false;
623 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
624 "allow dcerpc auth level connect",
626 context->allow_connect);
630 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
631 const struct dcesrv_interface *iface)
633 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
634 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
635 enum dcerpc_transport_t transport =
636 dcerpc_binding_get_transport(endpoint->ep_description);
637 struct dcesrv_connection_context *context = dce_call->context;
639 if (context == NULL) {
640 return NT_STATUS_INTERNAL_ERROR;
643 if (transport == NCALRPC) {
644 context->allow_connect = true;
649 * allow overwrite per interface
650 * allow dcerpc auth level connect:<interface>
652 context->allow_connect = true;
653 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
654 "allow dcerpc auth level connect",
656 context->allow_connect);
661 handle a bind request
663 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
665 uint32_t if_version, transfer_syntax_version;
666 struct GUID uuid, *transfer_syntax_uuid;
667 struct ncacn_packet pkt;
668 struct data_blob_list_item *rep;
670 uint32_t result=0, reason=0;
672 const struct dcesrv_interface *iface;
673 uint32_t extra_flags = 0;
674 uint16_t max_req = 0;
675 uint16_t max_rep = 0;
676 const char *ep_prefix = "";
677 const char *endpoint = NULL;
679 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
681 call->pkt.u.bind.auth_info.length,
682 0, /* required flags */
683 DCERPC_PFC_FLAG_FIRST |
684 DCERPC_PFC_FLAG_LAST |
685 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
686 0x08 | /* this is not defined, but should be ignored */
687 DCERPC_PFC_FLAG_CONC_MPX |
688 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
689 DCERPC_PFC_FLAG_MAYBE |
690 DCERPC_PFC_FLAG_OBJECT_UUID);
691 if (!NT_STATUS_IS_OK(status)) {
692 return dcesrv_bind_nak(call,
693 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
696 /* max_recv_frag and max_xmit_frag result always in the same value! */
697 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
698 call->pkt.u.bind.max_recv_frag);
700 * The values are between 2048 and 5840 tested against Windows 2012R2
701 * via ncacn_ip_tcp on port 135.
703 max_req = MAX(2048, max_req);
704 max_rep = MIN(max_req, call->conn->max_recv_frag);
705 /* They are truncated to an 8 byte boundary. */
708 /* max_recv_frag and max_xmit_frag result always in the same value! */
709 call->conn->max_recv_frag = max_rep;
710 call->conn->max_xmit_frag = max_rep;
713 if provided, check the assoc_group is valid
715 if (call->pkt.u.bind.assoc_group_id != 0) {
716 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
718 call->pkt.u.bind.assoc_group_id);
720 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
721 call->conn->dce_ctx);
723 if (call->conn->assoc_group == NULL) {
724 return dcesrv_bind_nak(call, 0);
727 if (call->pkt.u.bind.num_contexts < 1 ||
728 call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) {
729 return dcesrv_bind_nak(call, 0);
732 context_id = call->pkt.u.bind.ctx_list[0].context_id;
733 if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
734 uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid;
736 transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version;
737 transfer_syntax_uuid = &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid;
738 if (!GUID_equal(&ndr_transfer_syntax_ndr.uuid, transfer_syntax_uuid) != 0 ||
739 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
740 char *uuid_str = GUID_string(call, transfer_syntax_uuid);
741 /* we only do NDR encoded dcerpc */
742 DEBUG(0,("Non NDR transfer syntax requested - %s\n", uuid_str));
743 talloc_free(uuid_str);
744 return dcesrv_bind_nak(call, 0);
747 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
749 char *uuid_str = GUID_string(call, &uuid);
750 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
751 talloc_free(uuid_str);
753 /* we don't know about that interface */
754 result = DCERPC_BIND_PROVIDER_REJECT;
755 reason = DCERPC_BIND_REASON_ASYNTAX;
759 /* add this context to the list of available context_ids */
760 struct dcesrv_connection_context *context = talloc_zero(call->conn,
761 struct dcesrv_connection_context);
762 if (context == NULL) {
763 return dcesrv_bind_nak(call, 0);
765 context->conn = call->conn;
766 context->iface = iface;
767 context->context_id = context_id;
768 /* legacy for openchange dcesrv_mapiproxy.c */
769 context->assoc_group = call->conn->assoc_group;
770 context->private_data = NULL;
771 DLIST_ADD(call->conn->contexts, context);
772 call->context = context;
773 talloc_set_destructor(context, dcesrv_connection_context_destructor);
775 dcesrv_prepare_context_auth(call);
777 status = iface->bind(call, iface, if_version);
778 if (!NT_STATUS_IS_OK(status)) {
779 char *uuid_str = GUID_string(call, &uuid);
780 DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n",
781 uuid_str, if_version, nt_errstr(status)));
782 talloc_free(uuid_str);
783 /* we don't want to trigger the iface->unbind() hook */
784 context->iface = NULL;
785 talloc_free(call->context);
786 call->context = NULL;
787 return dcesrv_bind_nak(call, 0);
791 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
792 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
793 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
794 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
797 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
798 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
801 /* handle any authentication that is being requested */
802 if (!dcesrv_auth_bind(call)) {
803 struct dcesrv_auth *auth = &call->conn->auth_state;
805 TALLOC_FREE(call->context);
807 if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) {
809 * We only give INVALID_AUTH_TYPE if the auth_level was
812 return dcesrv_bind_nak(call,
813 DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE);
815 return dcesrv_bind_nak(call,
816 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
819 /* setup a bind_ack */
820 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
822 pkt.call_id = call->pkt.call_id;
823 pkt.ptype = DCERPC_PKT_BIND_ACK;
824 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
825 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
826 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
827 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
830 endpoint = dcerpc_binding_get_string_option(
831 call->conn->endpoint->ep_description,
835 if (endpoint == NULL) {
839 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
841 * TODO: check if this is really needed
843 * Or if we should fix this in our idl files.
845 ep_prefix = "\\PIPE\\";
849 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
852 if (pkt.u.bind_ack.secondary_address == NULL) {
853 TALLOC_FREE(call->context);
854 return NT_STATUS_NO_MEMORY;
856 pkt.u.bind_ack.num_results = 1;
857 pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
858 if (!pkt.u.bind_ack.ctx_list) {
859 talloc_free(call->context);
860 call->context = NULL;
861 return NT_STATUS_NO_MEMORY;
863 pkt.u.bind_ack.ctx_list[0].result = result;
864 pkt.u.bind_ack.ctx_list[0].reason.value = reason;
865 pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
866 pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
868 status = dcesrv_auth_bind_ack(call, &pkt);
869 if (!NT_STATUS_IS_OK(status)) {
870 talloc_free(call->context);
871 call->context = NULL;
872 return dcesrv_bind_nak(call, 0);
875 rep = talloc_zero(call, struct data_blob_list_item);
877 talloc_free(call->context);
878 call->context = NULL;
879 return NT_STATUS_NO_MEMORY;
882 status = ncacn_push_auth(&rep->blob, call, &pkt,
883 call->out_auth_info);
884 if (!NT_STATUS_IS_OK(status)) {
885 talloc_free(call->context);
886 call->context = NULL;
890 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
892 DLIST_ADD_END(call->replies, rep);
893 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
895 if (call->conn->call_list && call->conn->call_list->replies) {
896 if (call->conn->transport.report_output_data) {
897 call->conn->transport.report_output_data(call->conn);
906 handle a auth3 request
908 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
912 if (!call->conn->allow_auth3) {
913 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
916 if (call->conn->auth_state.auth_finished) {
917 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
920 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
922 call->pkt.u.auth3.auth_info.length,
923 0, /* required flags */
924 DCERPC_PFC_FLAG_FIRST |
925 DCERPC_PFC_FLAG_LAST |
926 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
927 0x08 | /* this is not defined, but should be ignored */
928 DCERPC_PFC_FLAG_CONC_MPX |
929 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
930 DCERPC_PFC_FLAG_MAYBE |
931 DCERPC_PFC_FLAG_OBJECT_UUID);
932 if (!NT_STATUS_IS_OK(status)) {
933 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
936 /* handle the auth3 in the auth code */
937 if (!dcesrv_auth_auth3(call)) {
938 call->conn->auth_state.auth_invalid = true;
943 /* we don't send a reply to a auth3 request, except by a
950 handle a bind request
952 static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_t context_id)
954 uint32_t if_version, transfer_syntax_version;
955 struct dcesrv_connection_context *context;
956 const struct dcesrv_interface *iface;
957 struct GUID uuid, *transfer_syntax_uuid;
960 if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version;
961 uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid;
963 transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version;
964 transfer_syntax_uuid = &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid;
965 if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax_ndr.uuid) ||
966 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
967 /* we only do NDR encoded dcerpc */
968 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
971 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
973 char *uuid_str = GUID_string(call, &uuid);
974 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
975 talloc_free(uuid_str);
976 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
979 /* add this context to the list of available context_ids */
980 context = talloc_zero(call->conn, struct dcesrv_connection_context);
981 if (context == NULL) {
982 return NT_STATUS_NO_MEMORY;
984 context->conn = call->conn;
985 context->iface = iface;
986 context->context_id = context_id;
987 /* legacy for openchange dcesrv_mapiproxy.c */
988 context->assoc_group = call->conn->assoc_group;
989 context->private_data = NULL;
990 DLIST_ADD(call->conn->contexts, context);
991 call->context = context;
992 talloc_set_destructor(context, dcesrv_connection_context_destructor);
994 dcesrv_prepare_context_auth(call);
996 status = iface->bind(call, iface, if_version);
997 if (!NT_STATUS_IS_OK(status)) {
998 /* we don't want to trigger the iface->unbind() hook */
999 context->iface = NULL;
1000 talloc_free(context);
1001 call->context = NULL;
1005 return NT_STATUS_OK;
1008 /* setup and send an alter_resp */
1009 static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call,
1013 struct ncacn_packet pkt;
1014 uint32_t extra_flags = 0;
1015 struct data_blob_list_item *rep = NULL;
1018 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1019 pkt.auth_length = 0;
1020 pkt.call_id = call->pkt.call_id;
1021 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1023 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1024 call->context->conn->state_flags &
1025 DCESRV_CALL_STATE_FLAG_MULTIPLEXED) {
1026 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1028 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1029 call->context->conn->state_flags |=
1030 DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1033 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1034 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1035 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1036 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1037 pkt.u.alter_resp.num_results = 1;
1038 pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
1039 if (!pkt.u.alter_resp.ctx_list) {
1040 return NT_STATUS_NO_MEMORY;
1042 pkt.u.alter_resp.ctx_list[0].result = result;
1043 pkt.u.alter_resp.ctx_list[0].reason.value = reason;
1044 pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
1045 pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
1046 pkt.u.alter_resp.secondary_address = "";
1048 status = dcesrv_auth_alter_ack(call, &pkt);
1049 if (!NT_STATUS_IS_OK(status)) {
1050 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1053 rep = talloc_zero(call, struct data_blob_list_item);
1055 return NT_STATUS_NO_MEMORY;
1058 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1059 if (!NT_STATUS_IS_OK(status)) {
1063 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1065 DLIST_ADD_END(call->replies, rep);
1066 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1068 if (call->conn->call_list && call->conn->call_list->replies) {
1069 if (call->conn->transport.report_output_data) {
1070 call->conn->transport.report_output_data(call->conn);
1074 return NT_STATUS_OK;
1078 handle a alter context request
1080 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1083 const struct dcerpc_ctx_list *ctx = NULL;
1084 bool auth_ok = false;
1086 if (!call->conn->allow_alter) {
1087 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1090 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1092 call->pkt.u.alter.auth_info.length,
1093 0, /* required flags */
1094 DCERPC_PFC_FLAG_FIRST |
1095 DCERPC_PFC_FLAG_LAST |
1096 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1097 0x08 | /* this is not defined, but should be ignored */
1098 DCERPC_PFC_FLAG_CONC_MPX |
1099 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1100 DCERPC_PFC_FLAG_MAYBE |
1101 DCERPC_PFC_FLAG_OBJECT_UUID);
1102 if (!NT_STATUS_IS_OK(status)) {
1103 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1106 auth_ok = dcesrv_auth_alter(call);
1108 if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) {
1109 return dcesrv_fault_disconnect(call,
1110 DCERPC_FAULT_ACCESS_DENIED);
1114 if (call->pkt.u.alter.num_contexts < 1) {
1115 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1117 ctx = &call->pkt.u.alter.ctx_list[0];
1118 if (ctx->num_transfer_syntaxes < 1) {
1119 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1122 /* see if they are asking for a new interface */
1123 call->context = dcesrv_find_context(call->conn, ctx->context_id);
1124 if (!call->context) {
1125 status = dcesrv_alter_new_context(call, ctx->context_id);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 return dcesrv_alter_resp(call,
1128 DCERPC_BIND_PROVIDER_REJECT,
1129 DCERPC_BIND_REASON_ASYNTAX);
1134 ok = ndr_syntax_id_equal(&ctx->abstract_syntax,
1135 &call->context->iface->syntax_id);
1137 return dcesrv_fault_disconnect(call,
1138 DCERPC_NCA_S_PROTO_ERROR);
1141 if (ctx->num_transfer_syntaxes != 1) {
1142 return dcesrv_fault_disconnect(call,
1143 DCERPC_NCA_S_PROTO_ERROR);
1146 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[0],
1147 &ndr_transfer_syntax_ndr);
1149 return dcesrv_fault_disconnect(call,
1150 DCERPC_NCA_S_PROTO_ERROR);
1154 /* handle any authentication that is being requested */
1156 if (call->in_auth_info.auth_type !=
1157 call->conn->auth_state.auth_type)
1159 return dcesrv_fault_disconnect(call,
1160 DCERPC_FAULT_SEC_PKG_ERROR);
1162 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1165 return dcesrv_alter_resp(call,
1166 DCERPC_BIND_ACK_RESULT_ACCEPTANCE,
1167 DCERPC_BIND_ACK_REASON_NOT_SPECIFIED);
1171 possibly save the call for inspection with ndrdump
1173 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1177 const char *dump_dir;
1178 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1182 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1184 call->context->iface->name,
1185 call->pkt.u.request.opnum,
1187 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1188 DEBUG(0,("RPC SAVED %s\n", fname));
1194 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1196 TALLOC_CTX *frame = talloc_stackframe();
1197 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1198 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1199 const struct dcerpc_sec_vt_pcontext pcontext = {
1200 .abstract_syntax = call->context->iface->syntax_id,
1201 .transfer_syntax = ndr_transfer_syntax_ndr,
1203 const struct dcerpc_sec_vt_header2 header2 =
1204 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1205 enum ndr_err_code ndr_err;
1206 struct dcerpc_sec_verification_trailer *vt = NULL;
1207 NTSTATUS status = NT_STATUS_OK;
1210 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1212 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1214 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1215 status = ndr_map_error2ntstatus(ndr_err);
1219 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1220 &pcontext, &header2);
1222 status = NT_STATUS_ACCESS_DENIED;
1231 handle a dcerpc request packet
1233 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1235 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1236 enum dcerpc_transport_t transport =
1237 dcerpc_binding_get_transport(endpoint->ep_description);
1238 struct ndr_pull *pull;
1240 struct dcesrv_connection_context *context;
1242 if (!call->conn->allow_request) {
1243 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1246 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1247 if (call->conn->auth_state.gensec_security &&
1248 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1249 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1252 context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1253 if (context == NULL) {
1254 return dcesrv_fault(call, DCERPC_FAULT_UNK_IF);
1257 switch (call->conn->auth_state.auth_level) {
1258 case DCERPC_AUTH_LEVEL_NONE:
1259 case DCERPC_AUTH_LEVEL_INTEGRITY:
1260 case DCERPC_AUTH_LEVEL_PRIVACY:
1263 if (!context->allow_connect) {
1266 addr = tsocket_address_string(call->conn->remote_address,
1269 DEBUG(2, ("%s: restrict auth_level_connect access "
1270 "to [%s] with auth[type=0x%x,level=0x%x] "
1271 "on [%s] from [%s]\n",
1272 __func__, context->iface->name,
1273 call->conn->auth_state.auth_type,
1274 call->conn->auth_state.auth_level,
1275 derpc_transport_string_by_transport(transport),
1277 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1282 if (call->conn->auth_state.auth_level < context->min_auth_level) {
1285 addr = tsocket_address_string(call->conn->remote_address, call);
1287 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1288 "to [%s] with auth[type=0x%x,level=0x%x] "
1289 "on [%s] from [%s]\n",
1291 context->min_auth_level,
1292 context->iface->name,
1293 call->conn->auth_state.auth_type,
1294 call->conn->auth_state.auth_level,
1295 derpc_transport_string_by_transport(transport),
1297 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1300 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1301 NT_STATUS_HAVE_NO_MEMORY(pull);
1303 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1305 call->context = context;
1306 call->ndr_pull = pull;
1308 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1309 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1312 status = dcesrv_check_verification_trailer(call);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 uint32_t faultcode = DCERPC_FAULT_OTHER;
1315 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1316 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1318 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1319 nt_errstr(status)));
1320 return dcesrv_fault(call, faultcode);
1323 /* unravel the NDR for the packet */
1324 status = context->iface->ndr_pull(call, call, pull, &call->r);
1325 if (!NT_STATUS_IS_OK(status)) {
1326 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1327 /* we got an unknown call */
1328 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1329 call->pkt.u.request.opnum, context->iface->name));
1330 dcesrv_save_call(call, "unknown");
1332 dcesrv_save_call(call, "pullfail");
1334 return dcesrv_fault(call, call->fault_code);
1337 if (pull->offset != pull->data_size) {
1338 dcesrv_save_call(call, "extrabytes");
1339 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1340 pull->data_size - pull->offset));
1343 /* call the dispatch function */
1344 status = context->iface->dispatch(call, call, call->r);
1345 if (!NT_STATUS_IS_OK(status)) {
1346 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1347 context->iface->name,
1348 call->pkt.u.request.opnum,
1349 dcerpc_errstr(pull, call->fault_code)));
1350 return dcesrv_fault(call, call->fault_code);
1353 /* add the call to the pending list */
1354 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1356 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1357 return NT_STATUS_OK;
1360 return dcesrv_reply(call);
1365 remove the call from the right list when freed
1367 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1369 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1373 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1375 return conn->local_address;
1378 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1380 return conn->remote_address;
1384 process some input to a dcerpc endpoint server.
1386 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1387 struct ncacn_packet *pkt,
1391 struct dcesrv_call_state *call;
1392 struct dcesrv_call_state *existing = NULL;
1394 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1396 data_blob_free(&blob);
1398 return NT_STATUS_NO_MEMORY;
1400 call->conn = dce_conn;
1401 call->event_ctx = dce_conn->event_ctx;
1402 call->msg_ctx = dce_conn->msg_ctx;
1403 call->state_flags = call->conn->state_flags;
1404 call->time = timeval_current();
1405 call->list = DCESRV_LIST_NONE;
1407 talloc_steal(call, pkt);
1408 talloc_steal(call, blob.data);
1411 talloc_set_destructor(call, dcesrv_call_dequeue);
1413 if (call->conn->allow_bind) {
1415 * Only one bind is possible per connection
1417 call->conn->allow_bind = false;
1418 return dcesrv_bind(call);
1421 /* we have to check the signing here, before combining the
1423 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1424 if (!call->conn->allow_request) {
1425 return dcesrv_fault_disconnect(call,
1426 DCERPC_NCA_S_PROTO_ERROR);
1429 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1431 call->pkt.u.request.stub_and_verifier.length,
1432 0, /* required_flags */
1433 DCERPC_PFC_FLAG_FIRST |
1434 DCERPC_PFC_FLAG_LAST |
1435 DCERPC_PFC_FLAG_PENDING_CANCEL |
1436 0x08 | /* this is not defined, but should be ignored */
1437 DCERPC_PFC_FLAG_CONC_MPX |
1438 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1439 DCERPC_PFC_FLAG_MAYBE |
1440 DCERPC_PFC_FLAG_OBJECT_UUID);
1441 if (!NT_STATUS_IS_OK(status)) {
1442 return dcesrv_fault_disconnect(call,
1443 DCERPC_NCA_S_PROTO_ERROR);
1446 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1448 * We don't use dcesrv_fault_disconnect()
1449 * here, because we don't want to set
1450 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1452 * Note that we don't check against the negotiated
1453 * max_recv_frag, but a hard coded value.
1455 dcesrv_call_disconnect_after(call,
1456 "dcesrv_auth_request - frag_length too large");
1457 return dcesrv_fault(call,
1458 DCERPC_NCA_S_PROTO_ERROR);
1461 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1462 /* only one request is possible in the fragmented list */
1463 if (dce_conn->incoming_fragmented_call_list != NULL) {
1465 call = dce_conn->incoming_fragmented_call_list;
1466 dcesrv_call_disconnect_after(call,
1467 "dcesrv_auth_request - "
1468 "existing fragmented call");
1469 return dcesrv_fault(call,
1470 DCERPC_NCA_S_PROTO_ERROR);
1472 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1473 return dcesrv_fault_disconnect(call,
1474 DCERPC_FAULT_NO_CALL_ACTIVE);
1477 const struct dcerpc_request *nr = &call->pkt.u.request;
1478 const struct dcerpc_request *er = NULL;
1481 existing = dcesrv_find_fragmented_call(dce_conn,
1483 if (existing == NULL) {
1484 dcesrv_call_disconnect_after(call,
1485 "dcesrv_auth_request - "
1486 "no existing fragmented call");
1487 return dcesrv_fault(call,
1488 DCERPC_NCA_S_PROTO_ERROR);
1490 er = &existing->pkt.u.request;
1492 if (call->pkt.ptype != existing->pkt.ptype) {
1493 /* trying to play silly buggers are we? */
1494 return dcesrv_fault_disconnect(existing,
1495 DCERPC_NCA_S_PROTO_ERROR);
1497 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1500 return dcesrv_fault_disconnect(existing,
1501 DCERPC_NCA_S_PROTO_ERROR);
1503 if (nr->context_id != er->context_id) {
1504 return dcesrv_fault_disconnect(existing,
1505 DCERPC_NCA_S_PROTO_ERROR);
1507 if (nr->opnum != er->opnum) {
1508 return dcesrv_fault_disconnect(existing,
1509 DCERPC_NCA_S_PROTO_ERROR);
1513 if (!dcesrv_auth_request(call, &blob)) {
1515 * We don't use dcesrv_fault_disconnect()
1516 * here, because we don't want to set
1517 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1519 dcesrv_call_disconnect_after(call,
1520 "dcesrv_auth_request - failed");
1521 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1525 /* see if this is a continued packet */
1526 if (existing != NULL) {
1527 struct dcerpc_request *er = &existing->pkt.u.request;
1528 const struct dcerpc_request *nr = &call->pkt.u.request;
1534 * Up to 4 MByte are allowed by all fragments
1536 available = dce_conn->max_total_request_size;
1537 if (er->stub_and_verifier.length > available) {
1538 dcesrv_call_disconnect_after(existing,
1539 "dcesrv_auth_request - existing payload too large");
1540 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1542 available -= er->stub_and_verifier.length;
1543 if (nr->alloc_hint > available) {
1544 dcesrv_call_disconnect_after(existing,
1545 "dcesrv_auth_request - alloc hint too large");
1546 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1548 if (nr->stub_and_verifier.length > available) {
1549 dcesrv_call_disconnect_after(existing,
1550 "dcesrv_auth_request - new payload too large");
1551 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1553 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1554 /* allocate at least 1 byte */
1555 alloc_hint = MAX(alloc_hint, 1);
1556 alloc_size = er->stub_and_verifier.length +
1557 nr->stub_and_verifier.length;
1558 alloc_size = MAX(alloc_size, alloc_hint);
1560 er->stub_and_verifier.data =
1561 talloc_realloc(existing,
1562 er->stub_and_verifier.data,
1563 uint8_t, alloc_size);
1564 if (er->stub_and_verifier.data == NULL) {
1566 return dcesrv_fault_with_flags(existing,
1567 DCERPC_FAULT_OUT_OF_RESOURCES,
1568 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1570 memcpy(er->stub_and_verifier.data +
1571 er->stub_and_verifier.length,
1572 nr->stub_and_verifier.data,
1573 nr->stub_and_verifier.length);
1574 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1576 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1582 /* this may not be the last pdu in the chain - if its isn't then
1583 just put it on the incoming_fragmented_call_list and wait for the rest */
1584 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1585 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1587 * Up to 4 MByte are allowed by all fragments
1589 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1590 dcesrv_call_disconnect_after(call,
1591 "dcesrv_auth_request - initial alloc hint too large");
1592 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1594 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1595 return NT_STATUS_OK;
1598 /* This removes any fragments we may have had stashed away */
1599 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1601 switch (call->pkt.ptype) {
1602 case DCERPC_PKT_BIND:
1603 status = dcesrv_bind_nak(call,
1604 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1606 case DCERPC_PKT_AUTH3:
1607 status = dcesrv_auth3(call);
1609 case DCERPC_PKT_ALTER:
1610 status = dcesrv_alter(call);
1612 case DCERPC_PKT_REQUEST:
1613 status = dcesrv_request(call);
1616 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1620 /* if we are going to be sending a reply then add
1621 it to the list of pending calls. We add it to the end to keep the call
1622 list in the order we will answer */
1623 if (!NT_STATUS_IS_OK(status)) {
1630 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1631 struct loadparm_context *lp_ctx,
1632 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1635 struct dcesrv_context *dce_ctx;
1638 if (!endpoint_servers) {
1639 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1640 return NT_STATUS_INTERNAL_ERROR;
1643 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1644 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1646 if (uid_wrapper_enabled()) {
1647 setenv("UID_WRAPPER_MYUID", "1", 1);
1649 dce_ctx->initial_euid = geteuid();
1650 if (uid_wrapper_enabled()) {
1651 unsetenv("UID_WRAPPER_MYUID");
1654 dce_ctx->endpoint_list = NULL;
1655 dce_ctx->lp_ctx = lp_ctx;
1656 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1657 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1658 dce_ctx->broken_connections = NULL;
1660 for (i=0;endpoint_servers[i];i++) {
1661 const struct dcesrv_endpoint_server *ep_server;
1663 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1665 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1666 return NT_STATUS_INTERNAL_ERROR;
1669 status = ep_server->init_server(dce_ctx, ep_server);
1670 if (!NT_STATUS_IS_OK(status)) {
1671 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1672 nt_errstr(status)));
1677 *_dce_ctx = dce_ctx;
1678 return NT_STATUS_OK;
1681 /* the list of currently registered DCERPC endpoint servers.
1683 static struct ep_server {
1684 struct dcesrv_endpoint_server *ep_server;
1685 } *ep_servers = NULL;
1686 static int num_ep_servers;
1689 register a DCERPC endpoint server.
1691 The 'name' can be later used by other backends to find the operations
1692 structure for this backend.
1694 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1696 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1698 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1700 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1701 /* its already registered! */
1702 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1704 return NT_STATUS_OBJECT_NAME_COLLISION;
1707 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1709 smb_panic("out of memory in dcerpc_register");
1712 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1713 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1717 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1720 return NT_STATUS_OK;
1724 return the operations structure for a named backend of the specified type
1726 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1730 for (i=0;i<num_ep_servers;i++) {
1731 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1732 return ep_servers[i].ep_server;
1739 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1741 static bool initialized;
1742 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1743 STATIC_dcerpc_server_MODULES_PROTO;
1744 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1745 init_module_fn *shared_init;
1752 shared_init = load_samba_modules(NULL, "dcerpc_server");
1754 run_init_functions(static_init);
1755 run_init_functions(shared_init);
1757 talloc_free(shared_init);
1761 return the DCERPC module version, and the size of some critical types
1762 This can be used by endpoint server modules to either detect compilation errors, or provide
1763 multiple implementations for different smbd compilation options in one module
1765 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1767 static const struct dcesrv_critical_sizes critical_sizes = {
1768 DCERPC_MODULE_VERSION,
1769 sizeof(struct dcesrv_context),
1770 sizeof(struct dcesrv_endpoint),
1771 sizeof(struct dcesrv_endpoint_server),
1772 sizeof(struct dcesrv_interface),
1773 sizeof(struct dcesrv_if_list),
1774 sizeof(struct dcesrv_connection),
1775 sizeof(struct dcesrv_call_state),
1776 sizeof(struct dcesrv_auth),
1777 sizeof(struct dcesrv_handle)
1780 return &critical_sizes;
1783 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1785 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1786 struct stream_connection *srv_conn;
1787 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1788 struct stream_connection);
1790 dce_conn->allow_bind = false;
1791 dce_conn->allow_auth3 = false;
1792 dce_conn->allow_alter = false;
1793 dce_conn->allow_request = false;
1795 if (dce_conn->pending_call_list == NULL) {
1796 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1798 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1799 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1803 if (dce_conn->terminate != NULL) {
1807 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
1809 dce_conn->terminate = talloc_strdup(dce_conn, reason);
1810 if (dce_conn->terminate == NULL) {
1811 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
1813 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
1816 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
1818 struct dcesrv_connection *cur, *next;
1820 next = dce_ctx->broken_connections;
1821 while (next != NULL) {
1825 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1826 struct dcesrv_connection_context *context_cur, *context_next;
1828 context_next = cur->contexts;
1829 while (context_next != NULL) {
1830 context_cur = context_next;
1831 context_next = context_cur->next;
1833 dcesrv_connection_context_destructor(context_cur);
1837 dcesrv_terminate_connection(cur, cur->terminate);
1841 /* We need this include to be able to compile on some plateforms
1842 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
1844 * It has to be that deep because otherwise we have a conflict on
1845 * const struct dcesrv_interface declaration.
1846 * This is mostly due to socket_wrapper defining #define bind swrap_bind
1847 * which conflict with the bind used before.
1849 #include "system/network.h"
1851 struct dcesrv_sock_reply_state {
1852 struct dcesrv_connection *dce_conn;
1853 struct dcesrv_call_state *call;
1857 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
1858 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
1860 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
1862 struct dcesrv_call_state *call;
1864 call = dce_conn->call_list;
1865 if (!call || !call->replies) {
1869 while (call->replies) {
1870 struct data_blob_list_item *rep = call->replies;
1871 struct dcesrv_sock_reply_state *substate;
1872 struct tevent_req *subreq;
1874 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
1876 dcesrv_terminate_connection(dce_conn, "no memory");
1880 substate->dce_conn = dce_conn;
1881 substate->call = NULL;
1883 DLIST_REMOVE(call->replies, rep);
1885 if (call->replies == NULL && call->terminate_reason == NULL) {
1886 substate->call = call;
1889 substate->iov.iov_base = (void *) rep->blob.data;
1890 substate->iov.iov_len = rep->blob.length;
1892 subreq = tstream_writev_queue_send(substate,
1893 dce_conn->event_ctx,
1895 dce_conn->send_queue,
1898 dcesrv_terminate_connection(dce_conn, "no memory");
1901 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
1905 if (call->terminate_reason != NULL) {
1906 struct tevent_req *subreq;
1908 subreq = tevent_queue_wait_send(call,
1909 dce_conn->event_ctx,
1910 dce_conn->send_queue);
1912 dcesrv_terminate_connection(dce_conn, __location__);
1915 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
1919 DLIST_REMOVE(call->conn->call_list, call);
1920 call->list = DCESRV_LIST_NONE;
1923 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
1925 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
1926 struct dcesrv_sock_reply_state);
1930 struct dcesrv_call_state *call = substate->call;
1932 ret = tstream_writev_queue_recv(subreq, &sys_errno);
1933 TALLOC_FREE(subreq);
1935 status = map_nt_error_from_unix_common(sys_errno);
1936 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
1940 talloc_free(substate);
1946 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
1948 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
1950 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1951 struct dcesrv_call_state);
1955 /* make sure we stop send queue before removing subreq */
1956 tevent_queue_stop(call->conn->send_queue);
1958 ok = tevent_queue_wait_recv(subreq);
1959 TALLOC_FREE(subreq);
1961 dcesrv_terminate_connection(call->conn, __location__);
1965 /* disconnect after 200 usecs */
1966 tv = timeval_current_ofs_usec(200);
1967 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
1968 if (subreq == NULL) {
1969 dcesrv_terminate_connection(call->conn, __location__);
1972 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
1976 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
1978 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1979 struct dcesrv_call_state);
1982 ok = tevent_wakeup_recv(subreq);
1983 TALLOC_FREE(subreq);
1985 dcesrv_terminate_connection(call->conn, __location__);
1989 dcesrv_terminate_connection(call->conn, call->terminate_reason);
1992 struct dcesrv_socket_context {
1993 const struct dcesrv_endpoint *endpoint;
1994 struct dcesrv_context *dcesrv_ctx;
1998 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2000 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2003 struct dcesrv_socket_context *dcesrv_sock =
2004 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2005 enum dcerpc_transport_t transport =
2006 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2007 struct dcesrv_connection *dcesrv_conn = NULL;
2009 struct tevent_req *subreq;
2010 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2012 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2014 if (!srv_conn->session_info) {
2015 status = auth_anonymous_session_info(srv_conn,
2017 &srv_conn->session_info);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2020 nt_errstr(status)));
2021 stream_terminate_connection(srv_conn, nt_errstr(status));
2026 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2028 dcesrv_sock->endpoint,
2029 srv_conn->session_info,
2030 srv_conn->event.ctx,
2032 srv_conn->server_id,
2033 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2035 if (!NT_STATUS_IS_OK(status)) {
2036 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2037 nt_errstr(status)));
2038 stream_terminate_connection(srv_conn, nt_errstr(status));
2042 dcesrv_conn->transport.private_data = srv_conn;
2043 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2045 TALLOC_FREE(srv_conn->event.fde);
2047 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2048 if (!dcesrv_conn->send_queue) {
2049 status = NT_STATUS_NO_MEMORY;
2050 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2051 nt_errstr(status)));
2052 stream_terminate_connection(srv_conn, nt_errstr(status));
2056 if (transport == NCACN_NP) {
2057 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2058 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2059 &srv_conn->tstream);
2061 ret = tstream_bsd_existing_socket(dcesrv_conn,
2062 socket_get_fd(srv_conn->socket),
2063 &dcesrv_conn->stream);
2065 status = map_nt_error_from_unix_common(errno);
2066 DEBUG(0, ("dcesrv_sock_accept: "
2067 "failed to setup tstream: %s\n",
2068 nt_errstr(status)));
2069 stream_terminate_connection(srv_conn, nt_errstr(status));
2072 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2075 dcesrv_conn->local_address = srv_conn->local_address;
2076 dcesrv_conn->remote_address = srv_conn->remote_address;
2078 if (transport == NCALRPC) {
2083 sock_fd = socket_get_fd(srv_conn->socket);
2084 if (sock_fd == -1) {
2085 stream_terminate_connection(
2086 srv_conn, "socket_get_fd failed\n");
2090 ret = getpeereid(sock_fd, &uid, &gid);
2092 status = map_nt_error_from_unix_common(errno);
2093 DEBUG(0, ("dcesrv_sock_accept: "
2094 "getpeereid() failed for NCALRPC: %s\n",
2095 nt_errstr(status)));
2096 stream_terminate_connection(srv_conn, nt_errstr(status));
2099 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2100 struct tsocket_address *r = NULL;
2102 ret = tsocket_address_unix_from_path(dcesrv_conn,
2103 "/root/ncalrpc_as_system",
2106 status = map_nt_error_from_unix_common(errno);
2107 DEBUG(0, ("dcesrv_sock_accept: "
2108 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2109 nt_errstr(status)));
2110 stream_terminate_connection(srv_conn, nt_errstr(status));
2113 dcesrv_conn->remote_address = r;
2117 srv_conn->private_data = dcesrv_conn;
2119 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2121 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2122 dcesrv_conn->event_ctx,
2123 dcesrv_conn->stream);
2125 status = NT_STATUS_NO_MEMORY;
2126 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2127 nt_errstr(status)));
2128 stream_terminate_connection(srv_conn, nt_errstr(status));
2131 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2136 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2138 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2139 struct dcesrv_connection);
2140 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2141 struct ncacn_packet *pkt;
2145 if (dce_conn->terminate) {
2147 * if the current connection is broken
2148 * we need to clean it up before any other connection
2150 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2151 dcesrv_cleanup_broken_connections(dce_ctx);
2155 dcesrv_cleanup_broken_connections(dce_ctx);
2157 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2159 TALLOC_FREE(subreq);
2160 if (!NT_STATUS_IS_OK(status)) {
2161 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2165 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2166 if (!NT_STATUS_IS_OK(status)) {
2167 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2171 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2172 dce_conn->event_ctx,
2175 status = NT_STATUS_NO_MEMORY;
2176 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2179 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2182 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2184 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2185 struct dcesrv_connection);
2186 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2189 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2191 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2192 struct dcesrv_connection);
2193 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2197 static const struct stream_server_ops dcesrv_stream_ops = {
2199 .accept_connection = dcesrv_sock_accept,
2200 .recv_handler = dcesrv_sock_recv,
2201 .send_handler = dcesrv_sock_send,
2204 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2205 struct loadparm_context *lp_ctx,
2206 struct dcesrv_endpoint *e,
2207 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2209 struct dcesrv_socket_context *dcesrv_sock;
2212 const char *endpoint;
2214 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2215 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2217 /* remember the endpoint of this socket */
2218 dcesrv_sock->endpoint = e;
2219 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2221 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2223 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2224 model_ops, &dcesrv_stream_ops,
2225 "unix", endpoint, &port,
2226 lpcfg_socket_options(lp_ctx),
2228 if (!NT_STATUS_IS_OK(status)) {
2229 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2230 endpoint, nt_errstr(status)));
2236 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2237 struct loadparm_context *lp_ctx,
2238 struct dcesrv_endpoint *e,
2239 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2241 struct dcesrv_socket_context *dcesrv_sock;
2245 const char *endpoint;
2247 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2249 if (endpoint == NULL) {
2251 * No identifier specified: use DEFAULT.
2253 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2254 * no endpoint and let the epmapper worry about it.
2256 endpoint = "DEFAULT";
2257 status = dcerpc_binding_set_string_option(e->ep_description,
2260 if (!NT_STATUS_IS_OK(status)) {
2261 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2262 nt_errstr(status)));
2267 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2270 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2271 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2273 /* remember the endpoint of this socket */
2274 dcesrv_sock->endpoint = e;
2275 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2277 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2278 model_ops, &dcesrv_stream_ops,
2279 "unix", full_path, &port,
2280 lpcfg_socket_options(lp_ctx),
2282 if (!NT_STATUS_IS_OK(status)) {
2283 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2284 endpoint, full_path, nt_errstr(status)));
2289 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2290 struct loadparm_context *lp_ctx,
2291 struct dcesrv_endpoint *e,
2292 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2294 struct dcesrv_socket_context *dcesrv_sock;
2296 const char *endpoint;
2298 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2299 if (endpoint == NULL) {
2300 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2301 return NT_STATUS_INVALID_PARAMETER;
2304 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2305 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2307 /* remember the endpoint of this socket */
2308 dcesrv_sock->endpoint = e;
2309 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2311 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2312 model_ops, &dcesrv_stream_ops,
2315 if (!NT_STATUS_IS_OK(status)) {
2316 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2317 endpoint, nt_errstr(status)));
2321 return NT_STATUS_OK;
2325 add a socket address to the list of events, one event per dcerpc endpoint
2327 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2328 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2329 const char *address)
2331 struct dcesrv_socket_context *dcesrv_sock;
2334 const char *endpoint;
2337 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2338 if (endpoint != NULL) {
2339 port = atoi(endpoint);
2342 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2343 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2345 /* remember the endpoint of this socket */
2346 dcesrv_sock->endpoint = e;
2347 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2349 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2350 model_ops, &dcesrv_stream_ops,
2351 "ip", address, &port,
2352 lpcfg_socket_options(dce_ctx->lp_ctx),
2354 if (!NT_STATUS_IS_OK(status)) {
2355 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2356 address, port, nt_errstr(status)));
2360 snprintf(port_str, sizeof(port_str), "%u", port);
2362 status = dcerpc_binding_set_string_option(e->ep_description,
2363 "endpoint", port_str);
2364 if (!NT_STATUS_IS_OK(status)) {
2365 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2366 port_str, nt_errstr(status)));
2370 return NT_STATUS_OK;
2373 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2375 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2376 struct loadparm_context *lp_ctx,
2377 struct dcesrv_endpoint *e,
2378 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2382 /* Add TCP/IP sockets */
2383 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2386 struct interface *ifaces;
2388 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2390 num_interfaces = iface_list_count(ifaces);
2391 for(i = 0; i < num_interfaces; i++) {
2392 const char *address = iface_list_n_ip(ifaces, i);
2393 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2394 NT_STATUS_NOT_OK_RETURN(status);
2400 wcard = iface_list_wildcard(dce_ctx);
2401 NT_STATUS_HAVE_NO_MEMORY(wcard);
2402 for (i=0; wcard[i]; i++) {
2403 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2404 if (NT_STATUS_IS_OK(status)) {
2409 if (num_binds == 0) {
2410 return NT_STATUS_INVALID_PARAMETER_MIX;
2414 return NT_STATUS_OK;
2417 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2418 struct loadparm_context *lp_ctx,
2419 struct dcesrv_endpoint *e,
2420 struct tevent_context *event_ctx,
2421 const struct model_ops *model_ops)
2423 enum dcerpc_transport_t transport =
2424 dcerpc_binding_get_transport(e->ep_description);
2426 switch (transport) {
2427 case NCACN_UNIX_STREAM:
2428 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2431 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2434 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2437 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2440 return NT_STATUS_NOT_SUPPORTED;
2446 * retrieve credentials from a dce_call
2448 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2450 return dce_call->conn->auth_state.session_info->credentials;
2454 * returns true if this is an authenticated call
2456 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2458 enum security_user_level level;
2459 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2460 return level >= SECURITY_USER;
2464 * retrieve account_name for a dce_call
2466 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2468 return dce_call->context->conn->auth_state.session_info->info->account_name;