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 context->private_data = NULL;
769 DLIST_ADD(call->conn->contexts, context);
770 call->context = context;
771 talloc_set_destructor(context, dcesrv_connection_context_destructor);
773 dcesrv_prepare_context_auth(call);
775 status = iface->bind(call, iface, if_version);
776 if (!NT_STATUS_IS_OK(status)) {
777 char *uuid_str = GUID_string(call, &uuid);
778 DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n",
779 uuid_str, if_version, nt_errstr(status)));
780 talloc_free(uuid_str);
781 /* we don't want to trigger the iface->unbind() hook */
782 context->iface = NULL;
783 talloc_free(call->context);
784 call->context = NULL;
785 return dcesrv_bind_nak(call, 0);
789 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
790 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
791 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
792 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
795 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
796 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
799 /* handle any authentication that is being requested */
800 if (!dcesrv_auth_bind(call)) {
801 struct dcesrv_auth *auth = &call->conn->auth_state;
803 TALLOC_FREE(call->context);
805 if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) {
807 * We only give INVALID_AUTH_TYPE if the auth_level was
810 return dcesrv_bind_nak(call,
811 DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE);
813 return dcesrv_bind_nak(call,
814 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
817 /* setup a bind_ack */
818 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
820 pkt.call_id = call->pkt.call_id;
821 pkt.ptype = DCERPC_PKT_BIND_ACK;
822 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
823 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
824 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
825 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
828 endpoint = dcerpc_binding_get_string_option(
829 call->conn->endpoint->ep_description,
833 if (endpoint == NULL) {
837 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
839 * TODO: check if this is really needed
841 * Or if we should fix this in our idl files.
843 ep_prefix = "\\PIPE\\";
847 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
850 if (pkt.u.bind_ack.secondary_address == NULL) {
851 TALLOC_FREE(call->context);
852 return NT_STATUS_NO_MEMORY;
854 pkt.u.bind_ack.num_results = 1;
855 pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
856 if (!pkt.u.bind_ack.ctx_list) {
857 talloc_free(call->context);
858 call->context = NULL;
859 return NT_STATUS_NO_MEMORY;
861 pkt.u.bind_ack.ctx_list[0].result = result;
862 pkt.u.bind_ack.ctx_list[0].reason.value = reason;
863 pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
864 pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
866 status = dcesrv_auth_bind_ack(call, &pkt);
867 if (!NT_STATUS_IS_OK(status)) {
868 talloc_free(call->context);
869 call->context = NULL;
870 return dcesrv_bind_nak(call, 0);
873 rep = talloc_zero(call, struct data_blob_list_item);
875 talloc_free(call->context);
876 call->context = NULL;
877 return NT_STATUS_NO_MEMORY;
880 status = ncacn_push_auth(&rep->blob, call, &pkt,
881 call->out_auth_info);
882 if (!NT_STATUS_IS_OK(status)) {
883 talloc_free(call->context);
884 call->context = NULL;
888 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
890 DLIST_ADD_END(call->replies, rep);
891 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
893 if (call->conn->call_list && call->conn->call_list->replies) {
894 if (call->conn->transport.report_output_data) {
895 call->conn->transport.report_output_data(call->conn);
904 handle a auth3 request
906 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
910 if (!call->conn->allow_auth3) {
911 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
914 if (call->conn->auth_state.auth_finished) {
915 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
918 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
920 call->pkt.u.auth3.auth_info.length,
921 0, /* required flags */
922 DCERPC_PFC_FLAG_FIRST |
923 DCERPC_PFC_FLAG_LAST |
924 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
925 0x08 | /* this is not defined, but should be ignored */
926 DCERPC_PFC_FLAG_CONC_MPX |
927 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
928 DCERPC_PFC_FLAG_MAYBE |
929 DCERPC_PFC_FLAG_OBJECT_UUID);
930 if (!NT_STATUS_IS_OK(status)) {
931 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
934 /* handle the auth3 in the auth code */
935 if (!dcesrv_auth_auth3(call)) {
936 call->conn->auth_state.auth_invalid = true;
941 /* we don't send a reply to a auth3 request, except by a
948 handle a bind request
950 static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint16_t context_id)
952 uint32_t if_version, transfer_syntax_version;
953 struct dcesrv_connection_context *context;
954 const struct dcesrv_interface *iface;
955 struct GUID uuid, *transfer_syntax_uuid;
958 if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version;
959 uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid;
961 transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version;
962 transfer_syntax_uuid = &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid;
963 if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax_ndr.uuid) ||
964 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
965 /* we only do NDR encoded dcerpc */
966 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
969 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
971 char *uuid_str = GUID_string(call, &uuid);
972 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
973 talloc_free(uuid_str);
974 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
977 /* add this context to the list of available context_ids */
978 context = talloc_zero(call->conn, struct dcesrv_connection_context);
979 if (context == NULL) {
980 return NT_STATUS_NO_MEMORY;
982 context->conn = call->conn;
983 context->iface = iface;
984 context->context_id = context_id;
985 context->private_data = NULL;
986 DLIST_ADD(call->conn->contexts, context);
987 call->context = context;
988 talloc_set_destructor(context, dcesrv_connection_context_destructor);
990 dcesrv_prepare_context_auth(call);
992 status = iface->bind(call, iface, if_version);
993 if (!NT_STATUS_IS_OK(status)) {
994 /* we don't want to trigger the iface->unbind() hook */
995 context->iface = NULL;
996 talloc_free(context);
997 call->context = NULL;
1001 return NT_STATUS_OK;
1004 /* setup and send an alter_resp */
1005 static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call,
1009 struct ncacn_packet pkt;
1010 uint32_t extra_flags = 0;
1011 struct data_blob_list_item *rep = NULL;
1014 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1015 pkt.auth_length = 0;
1016 pkt.call_id = call->pkt.call_id;
1017 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1019 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1020 call->context->conn->state_flags &
1021 DCESRV_CALL_STATE_FLAG_MULTIPLEXED) {
1022 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1024 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1025 call->context->conn->state_flags |=
1026 DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1029 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1030 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1031 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1032 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1033 pkt.u.alter_resp.num_results = 1;
1034 pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
1035 if (!pkt.u.alter_resp.ctx_list) {
1036 return NT_STATUS_NO_MEMORY;
1038 pkt.u.alter_resp.ctx_list[0].result = result;
1039 pkt.u.alter_resp.ctx_list[0].reason.value = reason;
1040 pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
1041 pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
1042 pkt.u.alter_resp.secondary_address = "";
1044 status = dcesrv_auth_alter_ack(call, &pkt);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1049 rep = talloc_zero(call, struct data_blob_list_item);
1051 return NT_STATUS_NO_MEMORY;
1054 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1055 if (!NT_STATUS_IS_OK(status)) {
1059 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1061 DLIST_ADD_END(call->replies, rep);
1062 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1064 if (call->conn->call_list && call->conn->call_list->replies) {
1065 if (call->conn->transport.report_output_data) {
1066 call->conn->transport.report_output_data(call->conn);
1070 return NT_STATUS_OK;
1074 handle a alter context request
1076 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1079 const struct dcerpc_ctx_list *ctx = NULL;
1080 bool auth_ok = false;
1082 if (!call->conn->allow_alter) {
1083 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1086 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1088 call->pkt.u.alter.auth_info.length,
1089 0, /* required flags */
1090 DCERPC_PFC_FLAG_FIRST |
1091 DCERPC_PFC_FLAG_LAST |
1092 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1093 0x08 | /* this is not defined, but should be ignored */
1094 DCERPC_PFC_FLAG_CONC_MPX |
1095 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1096 DCERPC_PFC_FLAG_MAYBE |
1097 DCERPC_PFC_FLAG_OBJECT_UUID);
1098 if (!NT_STATUS_IS_OK(status)) {
1099 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1102 auth_ok = dcesrv_auth_alter(call);
1104 if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) {
1105 return dcesrv_fault_disconnect(call,
1106 DCERPC_FAULT_ACCESS_DENIED);
1110 if (call->pkt.u.alter.num_contexts < 1) {
1111 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1113 ctx = &call->pkt.u.alter.ctx_list[0];
1114 if (ctx->num_transfer_syntaxes < 1) {
1115 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1118 /* see if they are asking for a new interface */
1119 call->context = dcesrv_find_context(call->conn, ctx->context_id);
1120 if (!call->context) {
1121 status = dcesrv_alter_new_context(call, ctx->context_id);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 return dcesrv_alter_resp(call,
1124 DCERPC_BIND_PROVIDER_REJECT,
1125 DCERPC_BIND_REASON_ASYNTAX);
1130 ok = ndr_syntax_id_equal(&ctx->abstract_syntax,
1131 &call->context->iface->syntax_id);
1133 return dcesrv_fault_disconnect(call,
1134 DCERPC_NCA_S_PROTO_ERROR);
1137 if (ctx->num_transfer_syntaxes != 1) {
1138 return dcesrv_fault_disconnect(call,
1139 DCERPC_NCA_S_PROTO_ERROR);
1142 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[0],
1143 &ndr_transfer_syntax_ndr);
1145 return dcesrv_fault_disconnect(call,
1146 DCERPC_NCA_S_PROTO_ERROR);
1150 /* handle any authentication that is being requested */
1152 if (call->in_auth_info.auth_type !=
1153 call->conn->auth_state.auth_type)
1155 return dcesrv_fault_disconnect(call,
1156 DCERPC_FAULT_SEC_PKG_ERROR);
1158 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1161 return dcesrv_alter_resp(call,
1162 DCERPC_BIND_ACK_RESULT_ACCEPTANCE,
1163 DCERPC_BIND_ACK_REASON_NOT_SPECIFIED);
1167 possibly save the call for inspection with ndrdump
1169 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1173 const char *dump_dir;
1174 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1178 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1180 call->context->iface->name,
1181 call->pkt.u.request.opnum,
1183 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1184 DEBUG(0,("RPC SAVED %s\n", fname));
1190 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1192 TALLOC_CTX *frame = talloc_stackframe();
1193 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1194 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1195 const struct dcerpc_sec_vt_pcontext pcontext = {
1196 .abstract_syntax = call->context->iface->syntax_id,
1197 .transfer_syntax = ndr_transfer_syntax_ndr,
1199 const struct dcerpc_sec_vt_header2 header2 =
1200 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1201 enum ndr_err_code ndr_err;
1202 struct dcerpc_sec_verification_trailer *vt = NULL;
1203 NTSTATUS status = NT_STATUS_OK;
1206 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1208 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1210 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1211 status = ndr_map_error2ntstatus(ndr_err);
1215 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1216 &pcontext, &header2);
1218 status = NT_STATUS_ACCESS_DENIED;
1227 handle a dcerpc request packet
1229 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1231 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1232 enum dcerpc_transport_t transport =
1233 dcerpc_binding_get_transport(endpoint->ep_description);
1234 struct ndr_pull *pull;
1236 struct dcesrv_connection_context *context;
1238 if (!call->conn->allow_request) {
1239 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1242 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1243 if (call->conn->auth_state.gensec_security &&
1244 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1245 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1248 context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1249 if (context == NULL) {
1250 return dcesrv_fault(call, DCERPC_FAULT_UNK_IF);
1253 switch (call->conn->auth_state.auth_level) {
1254 case DCERPC_AUTH_LEVEL_NONE:
1255 case DCERPC_AUTH_LEVEL_INTEGRITY:
1256 case DCERPC_AUTH_LEVEL_PRIVACY:
1259 if (!context->allow_connect) {
1262 addr = tsocket_address_string(call->conn->remote_address,
1265 DEBUG(2, ("%s: restrict auth_level_connect access "
1266 "to [%s] with auth[type=0x%x,level=0x%x] "
1267 "on [%s] from [%s]\n",
1268 __func__, context->iface->name,
1269 call->conn->auth_state.auth_type,
1270 call->conn->auth_state.auth_level,
1271 derpc_transport_string_by_transport(transport),
1273 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1278 if (call->conn->auth_state.auth_level < context->min_auth_level) {
1281 addr = tsocket_address_string(call->conn->remote_address, call);
1283 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1284 "to [%s] with auth[type=0x%x,level=0x%x] "
1285 "on [%s] from [%s]\n",
1287 context->min_auth_level,
1288 context->iface->name,
1289 call->conn->auth_state.auth_type,
1290 call->conn->auth_state.auth_level,
1291 derpc_transport_string_by_transport(transport),
1293 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1296 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1297 NT_STATUS_HAVE_NO_MEMORY(pull);
1299 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1301 call->context = context;
1302 call->ndr_pull = pull;
1304 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1305 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1308 status = dcesrv_check_verification_trailer(call);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 uint32_t faultcode = DCERPC_FAULT_OTHER;
1311 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1312 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1314 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1315 nt_errstr(status)));
1316 return dcesrv_fault(call, faultcode);
1319 /* unravel the NDR for the packet */
1320 status = context->iface->ndr_pull(call, call, pull, &call->r);
1321 if (!NT_STATUS_IS_OK(status)) {
1322 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1323 /* we got an unknown call */
1324 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1325 call->pkt.u.request.opnum, context->iface->name));
1326 dcesrv_save_call(call, "unknown");
1328 dcesrv_save_call(call, "pullfail");
1330 return dcesrv_fault(call, call->fault_code);
1333 if (pull->offset != pull->data_size) {
1334 dcesrv_save_call(call, "extrabytes");
1335 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1336 pull->data_size - pull->offset));
1339 /* call the dispatch function */
1340 status = context->iface->dispatch(call, call, call->r);
1341 if (!NT_STATUS_IS_OK(status)) {
1342 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1343 context->iface->name,
1344 call->pkt.u.request.opnum,
1345 dcerpc_errstr(pull, call->fault_code)));
1346 return dcesrv_fault(call, call->fault_code);
1349 /* add the call to the pending list */
1350 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1352 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1353 return NT_STATUS_OK;
1356 return dcesrv_reply(call);
1361 remove the call from the right list when freed
1363 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1365 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1369 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1371 return conn->local_address;
1374 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1376 return conn->remote_address;
1380 process some input to a dcerpc endpoint server.
1382 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1383 struct ncacn_packet *pkt,
1387 struct dcesrv_call_state *call;
1388 struct dcesrv_call_state *existing = NULL;
1390 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1392 data_blob_free(&blob);
1394 return NT_STATUS_NO_MEMORY;
1396 call->conn = dce_conn;
1397 call->event_ctx = dce_conn->event_ctx;
1398 call->msg_ctx = dce_conn->msg_ctx;
1399 call->state_flags = call->conn->state_flags;
1400 call->time = timeval_current();
1401 call->list = DCESRV_LIST_NONE;
1403 talloc_steal(call, pkt);
1404 talloc_steal(call, blob.data);
1407 talloc_set_destructor(call, dcesrv_call_dequeue);
1409 if (call->conn->allow_bind) {
1411 * Only one bind is possible per connection
1413 call->conn->allow_bind = false;
1414 return dcesrv_bind(call);
1417 /* we have to check the signing here, before combining the
1419 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1420 if (!call->conn->allow_request) {
1421 return dcesrv_fault_disconnect(call,
1422 DCERPC_NCA_S_PROTO_ERROR);
1425 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1427 call->pkt.u.request.stub_and_verifier.length,
1428 0, /* required_flags */
1429 DCERPC_PFC_FLAG_FIRST |
1430 DCERPC_PFC_FLAG_LAST |
1431 DCERPC_PFC_FLAG_PENDING_CANCEL |
1432 0x08 | /* this is not defined, but should be ignored */
1433 DCERPC_PFC_FLAG_CONC_MPX |
1434 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1435 DCERPC_PFC_FLAG_MAYBE |
1436 DCERPC_PFC_FLAG_OBJECT_UUID);
1437 if (!NT_STATUS_IS_OK(status)) {
1438 return dcesrv_fault_disconnect(call,
1439 DCERPC_NCA_S_PROTO_ERROR);
1442 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1444 * We don't use dcesrv_fault_disconnect()
1445 * here, because we don't want to set
1446 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1448 * Note that we don't check against the negotiated
1449 * max_recv_frag, but a hard coded value.
1451 dcesrv_call_disconnect_after(call,
1452 "dcesrv_auth_request - frag_length too large");
1453 return dcesrv_fault(call,
1454 DCERPC_NCA_S_PROTO_ERROR);
1457 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1458 /* only one request is possible in the fragmented list */
1459 if (dce_conn->incoming_fragmented_call_list != NULL) {
1461 call = dce_conn->incoming_fragmented_call_list;
1462 dcesrv_call_disconnect_after(call,
1463 "dcesrv_auth_request - "
1464 "existing fragmented call");
1465 return dcesrv_fault(call,
1466 DCERPC_NCA_S_PROTO_ERROR);
1468 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1469 return dcesrv_fault_disconnect(call,
1470 DCERPC_FAULT_NO_CALL_ACTIVE);
1473 const struct dcerpc_request *nr = &call->pkt.u.request;
1474 const struct dcerpc_request *er = NULL;
1477 existing = dcesrv_find_fragmented_call(dce_conn,
1479 if (existing == NULL) {
1480 dcesrv_call_disconnect_after(call,
1481 "dcesrv_auth_request - "
1482 "no existing fragmented call");
1483 return dcesrv_fault(call,
1484 DCERPC_NCA_S_PROTO_ERROR);
1486 er = &existing->pkt.u.request;
1488 if (call->pkt.ptype != existing->pkt.ptype) {
1489 /* trying to play silly buggers are we? */
1490 return dcesrv_fault_disconnect(existing,
1491 DCERPC_NCA_S_PROTO_ERROR);
1493 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1496 return dcesrv_fault_disconnect(existing,
1497 DCERPC_NCA_S_PROTO_ERROR);
1499 if (nr->context_id != er->context_id) {
1500 return dcesrv_fault_disconnect(existing,
1501 DCERPC_NCA_S_PROTO_ERROR);
1503 if (nr->opnum != er->opnum) {
1504 return dcesrv_fault_disconnect(existing,
1505 DCERPC_NCA_S_PROTO_ERROR);
1509 if (!dcesrv_auth_request(call, &blob)) {
1511 * We don't use dcesrv_fault_disconnect()
1512 * here, because we don't want to set
1513 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1515 dcesrv_call_disconnect_after(call,
1516 "dcesrv_auth_request - failed");
1517 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1521 /* see if this is a continued packet */
1522 if (existing != NULL) {
1523 struct dcerpc_request *er = &existing->pkt.u.request;
1524 const struct dcerpc_request *nr = &call->pkt.u.request;
1530 * Up to 4 MByte are allowed by all fragments
1532 available = dce_conn->max_total_request_size;
1533 if (er->stub_and_verifier.length > available) {
1534 dcesrv_call_disconnect_after(existing,
1535 "dcesrv_auth_request - existing payload too large");
1536 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1538 available -= er->stub_and_verifier.length;
1539 if (nr->alloc_hint > available) {
1540 dcesrv_call_disconnect_after(existing,
1541 "dcesrv_auth_request - alloc hint too large");
1542 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1544 if (nr->stub_and_verifier.length > available) {
1545 dcesrv_call_disconnect_after(existing,
1546 "dcesrv_auth_request - new payload too large");
1547 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1549 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1550 /* allocate at least 1 byte */
1551 alloc_hint = MAX(alloc_hint, 1);
1552 alloc_size = er->stub_and_verifier.length +
1553 nr->stub_and_verifier.length;
1554 alloc_size = MAX(alloc_size, alloc_hint);
1556 er->stub_and_verifier.data =
1557 talloc_realloc(existing,
1558 er->stub_and_verifier.data,
1559 uint8_t, alloc_size);
1560 if (er->stub_and_verifier.data == NULL) {
1562 return dcesrv_fault_with_flags(existing,
1563 DCERPC_FAULT_OUT_OF_RESOURCES,
1564 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1566 memcpy(er->stub_and_verifier.data +
1567 er->stub_and_verifier.length,
1568 nr->stub_and_verifier.data,
1569 nr->stub_and_verifier.length);
1570 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1572 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1578 /* this may not be the last pdu in the chain - if its isn't then
1579 just put it on the incoming_fragmented_call_list and wait for the rest */
1580 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1581 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1583 * Up to 4 MByte are allowed by all fragments
1585 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1586 dcesrv_call_disconnect_after(call,
1587 "dcesrv_auth_request - initial alloc hint too large");
1588 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1590 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1591 return NT_STATUS_OK;
1594 /* This removes any fragments we may have had stashed away */
1595 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1597 switch (call->pkt.ptype) {
1598 case DCERPC_PKT_BIND:
1599 status = dcesrv_bind_nak(call,
1600 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1602 case DCERPC_PKT_AUTH3:
1603 status = dcesrv_auth3(call);
1605 case DCERPC_PKT_ALTER:
1606 status = dcesrv_alter(call);
1608 case DCERPC_PKT_REQUEST:
1609 status = dcesrv_request(call);
1612 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1616 /* if we are going to be sending a reply then add
1617 it to the list of pending calls. We add it to the end to keep the call
1618 list in the order we will answer */
1619 if (!NT_STATUS_IS_OK(status)) {
1626 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1627 struct loadparm_context *lp_ctx,
1628 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1631 struct dcesrv_context *dce_ctx;
1634 if (!endpoint_servers) {
1635 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1636 return NT_STATUS_INTERNAL_ERROR;
1639 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1640 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1642 if (uid_wrapper_enabled()) {
1643 setenv("UID_WRAPPER_MYUID", "1", 1);
1645 dce_ctx->initial_euid = geteuid();
1646 if (uid_wrapper_enabled()) {
1647 unsetenv("UID_WRAPPER_MYUID");
1650 dce_ctx->endpoint_list = NULL;
1651 dce_ctx->lp_ctx = lp_ctx;
1652 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1653 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1654 dce_ctx->broken_connections = NULL;
1656 for (i=0;endpoint_servers[i];i++) {
1657 const struct dcesrv_endpoint_server *ep_server;
1659 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1661 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1662 return NT_STATUS_INTERNAL_ERROR;
1665 status = ep_server->init_server(dce_ctx, ep_server);
1666 if (!NT_STATUS_IS_OK(status)) {
1667 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1668 nt_errstr(status)));
1673 *_dce_ctx = dce_ctx;
1674 return NT_STATUS_OK;
1677 /* the list of currently registered DCERPC endpoint servers.
1679 static struct ep_server {
1680 struct dcesrv_endpoint_server *ep_server;
1681 } *ep_servers = NULL;
1682 static int num_ep_servers;
1685 register a DCERPC endpoint server.
1687 The 'name' can be later used by other backends to find the operations
1688 structure for this backend.
1690 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1692 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1694 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1696 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1697 /* its already registered! */
1698 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1700 return NT_STATUS_OBJECT_NAME_COLLISION;
1703 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1705 smb_panic("out of memory in dcerpc_register");
1708 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1709 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1713 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1716 return NT_STATUS_OK;
1720 return the operations structure for a named backend of the specified type
1722 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1726 for (i=0;i<num_ep_servers;i++) {
1727 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1728 return ep_servers[i].ep_server;
1735 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1737 static bool initialized;
1738 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1739 STATIC_dcerpc_server_MODULES_PROTO;
1740 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1741 init_module_fn *shared_init;
1748 shared_init = load_samba_modules(NULL, "dcerpc_server");
1750 run_init_functions(static_init);
1751 run_init_functions(shared_init);
1753 talloc_free(shared_init);
1757 return the DCERPC module version, and the size of some critical types
1758 This can be used by endpoint server modules to either detect compilation errors, or provide
1759 multiple implementations for different smbd compilation options in one module
1761 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1763 static const struct dcesrv_critical_sizes critical_sizes = {
1764 DCERPC_MODULE_VERSION,
1765 sizeof(struct dcesrv_context),
1766 sizeof(struct dcesrv_endpoint),
1767 sizeof(struct dcesrv_endpoint_server),
1768 sizeof(struct dcesrv_interface),
1769 sizeof(struct dcesrv_if_list),
1770 sizeof(struct dcesrv_connection),
1771 sizeof(struct dcesrv_call_state),
1772 sizeof(struct dcesrv_auth),
1773 sizeof(struct dcesrv_handle)
1776 return &critical_sizes;
1779 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1781 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1782 struct stream_connection *srv_conn;
1783 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1784 struct stream_connection);
1786 dce_conn->allow_bind = false;
1787 dce_conn->allow_auth3 = false;
1788 dce_conn->allow_alter = false;
1789 dce_conn->allow_request = false;
1791 if (dce_conn->pending_call_list == NULL) {
1792 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1794 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1795 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1799 if (dce_conn->terminate != NULL) {
1803 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
1805 dce_conn->terminate = talloc_strdup(dce_conn, reason);
1806 if (dce_conn->terminate == NULL) {
1807 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
1809 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
1812 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
1814 struct dcesrv_connection *cur, *next;
1816 next = dce_ctx->broken_connections;
1817 while (next != NULL) {
1821 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1822 struct dcesrv_connection_context *context_cur, *context_next;
1824 context_next = cur->contexts;
1825 while (context_next != NULL) {
1826 context_cur = context_next;
1827 context_next = context_cur->next;
1829 dcesrv_connection_context_destructor(context_cur);
1833 dcesrv_terminate_connection(cur, cur->terminate);
1837 /* We need this include to be able to compile on some plateforms
1838 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
1840 * It has to be that deep because otherwise we have a conflict on
1841 * const struct dcesrv_interface declaration.
1842 * This is mostly due to socket_wrapper defining #define bind swrap_bind
1843 * which conflict with the bind used before.
1845 #include "system/network.h"
1847 struct dcesrv_sock_reply_state {
1848 struct dcesrv_connection *dce_conn;
1849 struct dcesrv_call_state *call;
1853 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
1854 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
1856 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
1858 struct dcesrv_call_state *call;
1860 call = dce_conn->call_list;
1861 if (!call || !call->replies) {
1865 while (call->replies) {
1866 struct data_blob_list_item *rep = call->replies;
1867 struct dcesrv_sock_reply_state *substate;
1868 struct tevent_req *subreq;
1870 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
1872 dcesrv_terminate_connection(dce_conn, "no memory");
1876 substate->dce_conn = dce_conn;
1877 substate->call = NULL;
1879 DLIST_REMOVE(call->replies, rep);
1881 if (call->replies == NULL && call->terminate_reason == NULL) {
1882 substate->call = call;
1885 substate->iov.iov_base = (void *) rep->blob.data;
1886 substate->iov.iov_len = rep->blob.length;
1888 subreq = tstream_writev_queue_send(substate,
1889 dce_conn->event_ctx,
1891 dce_conn->send_queue,
1894 dcesrv_terminate_connection(dce_conn, "no memory");
1897 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
1901 if (call->terminate_reason != NULL) {
1902 struct tevent_req *subreq;
1904 subreq = tevent_queue_wait_send(call,
1905 dce_conn->event_ctx,
1906 dce_conn->send_queue);
1908 dcesrv_terminate_connection(dce_conn, __location__);
1911 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
1915 DLIST_REMOVE(call->conn->call_list, call);
1916 call->list = DCESRV_LIST_NONE;
1919 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
1921 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
1922 struct dcesrv_sock_reply_state);
1926 struct dcesrv_call_state *call = substate->call;
1928 ret = tstream_writev_queue_recv(subreq, &sys_errno);
1929 TALLOC_FREE(subreq);
1931 status = map_nt_error_from_unix_common(sys_errno);
1932 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
1936 talloc_free(substate);
1942 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
1944 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
1946 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1947 struct dcesrv_call_state);
1951 /* make sure we stop send queue before removing subreq */
1952 tevent_queue_stop(call->conn->send_queue);
1954 ok = tevent_queue_wait_recv(subreq);
1955 TALLOC_FREE(subreq);
1957 dcesrv_terminate_connection(call->conn, __location__);
1961 /* disconnect after 200 usecs */
1962 tv = timeval_current_ofs_usec(200);
1963 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
1964 if (subreq == NULL) {
1965 dcesrv_terminate_connection(call->conn, __location__);
1968 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
1972 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
1974 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1975 struct dcesrv_call_state);
1978 ok = tevent_wakeup_recv(subreq);
1979 TALLOC_FREE(subreq);
1981 dcesrv_terminate_connection(call->conn, __location__);
1985 dcesrv_terminate_connection(call->conn, call->terminate_reason);
1988 struct dcesrv_socket_context {
1989 const struct dcesrv_endpoint *endpoint;
1990 struct dcesrv_context *dcesrv_ctx;
1994 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
1996 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
1999 struct dcesrv_socket_context *dcesrv_sock =
2000 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2001 enum dcerpc_transport_t transport =
2002 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2003 struct dcesrv_connection *dcesrv_conn = NULL;
2005 struct tevent_req *subreq;
2006 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2008 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2010 if (!srv_conn->session_info) {
2011 status = auth_anonymous_session_info(srv_conn,
2013 &srv_conn->session_info);
2014 if (!NT_STATUS_IS_OK(status)) {
2015 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2016 nt_errstr(status)));
2017 stream_terminate_connection(srv_conn, nt_errstr(status));
2022 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2024 dcesrv_sock->endpoint,
2025 srv_conn->session_info,
2026 srv_conn->event.ctx,
2028 srv_conn->server_id,
2029 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2031 if (!NT_STATUS_IS_OK(status)) {
2032 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2033 nt_errstr(status)));
2034 stream_terminate_connection(srv_conn, nt_errstr(status));
2038 dcesrv_conn->transport.private_data = srv_conn;
2039 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2041 TALLOC_FREE(srv_conn->event.fde);
2043 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2044 if (!dcesrv_conn->send_queue) {
2045 status = NT_STATUS_NO_MEMORY;
2046 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2047 nt_errstr(status)));
2048 stream_terminate_connection(srv_conn, nt_errstr(status));
2052 if (transport == NCACN_NP) {
2053 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2054 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2055 &srv_conn->tstream);
2057 ret = tstream_bsd_existing_socket(dcesrv_conn,
2058 socket_get_fd(srv_conn->socket),
2059 &dcesrv_conn->stream);
2061 status = map_nt_error_from_unix_common(errno);
2062 DEBUG(0, ("dcesrv_sock_accept: "
2063 "failed to setup tstream: %s\n",
2064 nt_errstr(status)));
2065 stream_terminate_connection(srv_conn, nt_errstr(status));
2068 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2071 dcesrv_conn->local_address = srv_conn->local_address;
2072 dcesrv_conn->remote_address = srv_conn->remote_address;
2074 if (transport == NCALRPC) {
2079 sock_fd = socket_get_fd(srv_conn->socket);
2080 if (sock_fd == -1) {
2081 stream_terminate_connection(
2082 srv_conn, "socket_get_fd failed\n");
2086 ret = getpeereid(sock_fd, &uid, &gid);
2088 status = map_nt_error_from_unix_common(errno);
2089 DEBUG(0, ("dcesrv_sock_accept: "
2090 "getpeereid() failed for NCALRPC: %s\n",
2091 nt_errstr(status)));
2092 stream_terminate_connection(srv_conn, nt_errstr(status));
2095 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2096 struct tsocket_address *r = NULL;
2098 ret = tsocket_address_unix_from_path(dcesrv_conn,
2099 "/root/ncalrpc_as_system",
2102 status = map_nt_error_from_unix_common(errno);
2103 DEBUG(0, ("dcesrv_sock_accept: "
2104 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2105 nt_errstr(status)));
2106 stream_terminate_connection(srv_conn, nt_errstr(status));
2109 dcesrv_conn->remote_address = r;
2113 srv_conn->private_data = dcesrv_conn;
2115 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2117 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2118 dcesrv_conn->event_ctx,
2119 dcesrv_conn->stream);
2121 status = NT_STATUS_NO_MEMORY;
2122 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2123 nt_errstr(status)));
2124 stream_terminate_connection(srv_conn, nt_errstr(status));
2127 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2132 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2134 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2135 struct dcesrv_connection);
2136 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2137 struct ncacn_packet *pkt;
2141 if (dce_conn->terminate) {
2143 * if the current connection is broken
2144 * we need to clean it up before any other connection
2146 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2147 dcesrv_cleanup_broken_connections(dce_ctx);
2151 dcesrv_cleanup_broken_connections(dce_ctx);
2153 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2155 TALLOC_FREE(subreq);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2161 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2162 if (!NT_STATUS_IS_OK(status)) {
2163 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2167 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2168 dce_conn->event_ctx,
2171 status = NT_STATUS_NO_MEMORY;
2172 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2175 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2178 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2180 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2181 struct dcesrv_connection);
2182 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2185 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2187 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2188 struct dcesrv_connection);
2189 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2193 static const struct stream_server_ops dcesrv_stream_ops = {
2195 .accept_connection = dcesrv_sock_accept,
2196 .recv_handler = dcesrv_sock_recv,
2197 .send_handler = dcesrv_sock_send,
2200 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2201 struct loadparm_context *lp_ctx,
2202 struct dcesrv_endpoint *e,
2203 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2205 struct dcesrv_socket_context *dcesrv_sock;
2208 const char *endpoint;
2210 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2211 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2213 /* remember the endpoint of this socket */
2214 dcesrv_sock->endpoint = e;
2215 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2217 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2219 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2220 model_ops, &dcesrv_stream_ops,
2221 "unix", endpoint, &port,
2222 lpcfg_socket_options(lp_ctx),
2224 if (!NT_STATUS_IS_OK(status)) {
2225 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2226 endpoint, nt_errstr(status)));
2232 static NTSTATUS dcesrv_add_ep_ncalrpc(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;
2241 const char *endpoint;
2243 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2245 if (endpoint == NULL) {
2247 * No identifier specified: use DEFAULT.
2249 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2250 * no endpoint and let the epmapper worry about it.
2252 endpoint = "DEFAULT";
2253 status = dcerpc_binding_set_string_option(e->ep_description,
2256 if (!NT_STATUS_IS_OK(status)) {
2257 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2258 nt_errstr(status)));
2263 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2266 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2267 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2269 /* remember the endpoint of this socket */
2270 dcesrv_sock->endpoint = e;
2271 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2273 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2274 model_ops, &dcesrv_stream_ops,
2275 "unix", full_path, &port,
2276 lpcfg_socket_options(lp_ctx),
2278 if (!NT_STATUS_IS_OK(status)) {
2279 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2280 endpoint, full_path, nt_errstr(status)));
2285 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2286 struct loadparm_context *lp_ctx,
2287 struct dcesrv_endpoint *e,
2288 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2290 struct dcesrv_socket_context *dcesrv_sock;
2292 const char *endpoint;
2294 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2295 if (endpoint == NULL) {
2296 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2297 return NT_STATUS_INVALID_PARAMETER;
2300 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2301 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2303 /* remember the endpoint of this socket */
2304 dcesrv_sock->endpoint = e;
2305 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2307 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2308 model_ops, &dcesrv_stream_ops,
2311 if (!NT_STATUS_IS_OK(status)) {
2312 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2313 endpoint, nt_errstr(status)));
2317 return NT_STATUS_OK;
2321 add a socket address to the list of events, one event per dcerpc endpoint
2323 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2324 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2325 const char *address)
2327 struct dcesrv_socket_context *dcesrv_sock;
2330 const char *endpoint;
2333 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2334 if (endpoint != NULL) {
2335 port = atoi(endpoint);
2338 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2339 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2341 /* remember the endpoint of this socket */
2342 dcesrv_sock->endpoint = e;
2343 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2345 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2346 model_ops, &dcesrv_stream_ops,
2347 "ip", address, &port,
2348 lpcfg_socket_options(dce_ctx->lp_ctx),
2350 if (!NT_STATUS_IS_OK(status)) {
2351 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2352 address, port, nt_errstr(status)));
2356 snprintf(port_str, sizeof(port_str), "%u", port);
2358 status = dcerpc_binding_set_string_option(e->ep_description,
2359 "endpoint", port_str);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2362 port_str, nt_errstr(status)));
2366 return NT_STATUS_OK;
2369 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2371 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2372 struct loadparm_context *lp_ctx,
2373 struct dcesrv_endpoint *e,
2374 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2378 /* Add TCP/IP sockets */
2379 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2382 struct interface *ifaces;
2384 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2386 num_interfaces = iface_list_count(ifaces);
2387 for(i = 0; i < num_interfaces; i++) {
2388 const char *address = iface_list_n_ip(ifaces, i);
2389 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2390 NT_STATUS_NOT_OK_RETURN(status);
2396 wcard = iface_list_wildcard(dce_ctx);
2397 NT_STATUS_HAVE_NO_MEMORY(wcard);
2398 for (i=0; wcard[i]; i++) {
2399 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2400 if (NT_STATUS_IS_OK(status)) {
2405 if (num_binds == 0) {
2406 return NT_STATUS_INVALID_PARAMETER_MIX;
2410 return NT_STATUS_OK;
2413 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2414 struct loadparm_context *lp_ctx,
2415 struct dcesrv_endpoint *e,
2416 struct tevent_context *event_ctx,
2417 const struct model_ops *model_ops)
2419 enum dcerpc_transport_t transport =
2420 dcerpc_binding_get_transport(e->ep_description);
2422 switch (transport) {
2423 case NCACN_UNIX_STREAM:
2424 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2427 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2430 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2433 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2436 return NT_STATUS_NOT_SUPPORTED;
2442 * retrieve credentials from a dce_call
2444 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2446 return dce_call->conn->auth_state.session_info->credentials;
2450 * returns true if this is an authenticated call
2452 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2454 enum security_user_level level;
2455 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2456 return level >= SECURITY_USER;
2460 * retrieve account_name for a dce_call
2462 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2464 return dce_call->context->conn->auth_state.session_info->info->account_name;