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;
417 move a call from an existing linked list to the specified list. This
418 prevents bugs where we forget to remove the call from a previous
421 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
422 enum dcesrv_call_list list)
424 switch (call->list) {
425 case DCESRV_LIST_NONE:
427 case DCESRV_LIST_CALL_LIST:
428 DLIST_REMOVE(call->conn->call_list, call);
430 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
431 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
433 case DCESRV_LIST_PENDING_CALL_LIST:
434 DLIST_REMOVE(call->conn->pending_call_list, call);
439 case DCESRV_LIST_NONE:
441 case DCESRV_LIST_CALL_LIST:
442 DLIST_ADD_END(call->conn->call_list, call);
444 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
445 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
447 case DCESRV_LIST_PENDING_CALL_LIST:
448 DLIST_ADD_END(call->conn->pending_call_list, call);
453 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
456 if (call->conn->terminate != NULL) {
460 call->conn->allow_bind = false;
461 call->conn->allow_alter = false;
462 call->conn->allow_auth3 = false;
463 call->conn->allow_request = false;
465 call->terminate_reason = talloc_strdup(call, reason);
466 if (call->terminate_reason == NULL) {
467 call->terminate_reason = __location__;
472 return a dcerpc bind_nak
474 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
476 struct ncacn_packet pkt;
477 struct dcerpc_bind_nak_version version;
478 struct data_blob_list_item *rep;
480 static const uint8_t _pad[3] = { 0, };
483 * We add the call to the pending_call_list
484 * in order to defer the termination.
486 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
488 /* setup a bind_nak */
489 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
491 pkt.call_id = call->pkt.call_id;
492 pkt.ptype = DCERPC_PKT_BIND_NAK;
493 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
494 pkt.u.bind_nak.reject_reason = reason;
495 version.rpc_vers = 5;
496 version.rpc_vers_minor = 0;
497 pkt.u.bind_nak.num_versions = 1;
498 pkt.u.bind_nak.versions = &version;
499 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
501 rep = talloc_zero(call, struct data_blob_list_item);
503 return NT_STATUS_NO_MEMORY;
506 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
507 if (!NT_STATUS_IS_OK(status)) {
511 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
513 DLIST_ADD_END(call->replies, rep);
514 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
516 if (call->conn->call_list && call->conn->call_list->replies) {
517 if (call->conn->transport.report_output_data) {
518 call->conn->transport.report_output_data(call->conn);
525 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
529 * We add the call to the pending_call_list
530 * in order to defer the termination.
532 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
534 return dcesrv_fault_with_flags(call, fault_code,
535 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
538 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
540 DLIST_REMOVE(c->conn->contexts, c);
542 if (c->iface && c->iface->unbind) {
543 c->iface->unbind(c, c->iface);
550 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
552 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
553 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
554 enum dcerpc_transport_t transport =
555 dcerpc_binding_get_transport(endpoint->ep_description);
556 struct dcesrv_connection_context *context = dce_call->context;
557 const struct dcesrv_interface *iface = context->iface;
559 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
561 if (transport == NCALRPC) {
562 context->allow_connect = true;
567 * allow overwrite per interface
568 * allow dcerpc auth level connect:<interface>
570 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
571 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
572 "allow dcerpc auth level connect",
574 context->allow_connect);
577 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
578 const struct dcesrv_interface *iface)
580 if (dce_call->context == NULL) {
581 return NT_STATUS_INTERNAL_ERROR;
584 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
588 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
589 const struct dcesrv_interface *iface)
591 if (dce_call->context == NULL) {
592 return NT_STATUS_INTERNAL_ERROR;
595 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
599 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
600 const struct dcesrv_interface *iface)
602 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
603 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
604 enum dcerpc_transport_t transport =
605 dcerpc_binding_get_transport(endpoint->ep_description);
606 struct dcesrv_connection_context *context = dce_call->context;
608 if (context == NULL) {
609 return NT_STATUS_INTERNAL_ERROR;
612 if (transport == NCALRPC) {
613 context->allow_connect = true;
618 * allow overwrite per interface
619 * allow dcerpc auth level connect:<interface>
621 context->allow_connect = false;
622 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
623 "allow dcerpc auth level connect",
625 context->allow_connect);
629 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
630 const struct dcesrv_interface *iface)
632 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
633 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
634 enum dcerpc_transport_t transport =
635 dcerpc_binding_get_transport(endpoint->ep_description);
636 struct dcesrv_connection_context *context = dce_call->context;
638 if (context == NULL) {
639 return NT_STATUS_INTERNAL_ERROR;
642 if (transport == NCALRPC) {
643 context->allow_connect = true;
648 * allow overwrite per interface
649 * allow dcerpc auth level connect:<interface>
651 context->allow_connect = true;
652 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
653 "allow dcerpc auth level connect",
655 context->allow_connect);
660 handle a bind request
662 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
664 uint32_t if_version, transfer_syntax_version;
665 struct GUID uuid, *transfer_syntax_uuid;
666 struct ncacn_packet pkt;
667 struct data_blob_list_item *rep;
669 uint32_t result=0, reason=0;
671 const struct dcesrv_interface *iface;
672 uint32_t extra_flags = 0;
673 uint16_t max_req = 0;
674 uint16_t max_rep = 0;
675 const char *ep_prefix = "";
676 const char *endpoint = NULL;
678 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
680 call->pkt.u.bind.auth_info.length,
681 0, /* required flags */
682 DCERPC_PFC_FLAG_FIRST |
683 DCERPC_PFC_FLAG_LAST |
684 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
685 0x08 | /* this is not defined, but should be ignored */
686 DCERPC_PFC_FLAG_CONC_MPX |
687 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
688 DCERPC_PFC_FLAG_MAYBE |
689 DCERPC_PFC_FLAG_OBJECT_UUID);
690 if (!NT_STATUS_IS_OK(status)) {
691 return dcesrv_bind_nak(call,
692 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
695 /* max_recv_frag and max_xmit_frag result always in the same value! */
696 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
697 call->pkt.u.bind.max_recv_frag);
699 * The values are between 2048 and 5840 tested against Windows 2012R2
700 * via ncacn_ip_tcp on port 135.
702 max_req = MAX(2048, max_req);
703 max_rep = MIN(max_req, call->conn->max_recv_frag);
704 /* They are truncated to an 8 byte boundary. */
707 /* max_recv_frag and max_xmit_frag result always in the same value! */
708 call->conn->max_recv_frag = max_rep;
709 call->conn->max_xmit_frag = max_rep;
712 if provided, check the assoc_group is valid
714 if (call->pkt.u.bind.assoc_group_id != 0) {
715 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
717 call->pkt.u.bind.assoc_group_id);
719 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
720 call->conn->dce_ctx);
722 if (call->conn->assoc_group == NULL) {
723 return dcesrv_bind_nak(call, 0);
726 if (call->pkt.u.bind.num_contexts < 1 ||
727 call->pkt.u.bind.ctx_list[0].num_transfer_syntaxes < 1) {
728 return dcesrv_bind_nak(call, 0);
731 context_id = call->pkt.u.bind.ctx_list[0].context_id;
732 if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
733 uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid;
735 transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version;
736 transfer_syntax_uuid = &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid;
737 if (!GUID_equal(&ndr_transfer_syntax_ndr.uuid, transfer_syntax_uuid) != 0 ||
738 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
739 char *uuid_str = GUID_string(call, transfer_syntax_uuid);
740 /* we only do NDR encoded dcerpc */
741 DEBUG(0,("Non NDR transfer syntax requested - %s\n", uuid_str));
742 talloc_free(uuid_str);
743 return dcesrv_bind_nak(call, 0);
746 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
748 char *uuid_str = GUID_string(call, &uuid);
749 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
750 talloc_free(uuid_str);
752 /* we don't know about that interface */
753 result = DCERPC_BIND_PROVIDER_REJECT;
754 reason = DCERPC_BIND_REASON_ASYNTAX;
758 /* add this context to the list of available context_ids */
759 struct dcesrv_connection_context *context = talloc_zero(call->conn,
760 struct dcesrv_connection_context);
761 if (context == NULL) {
762 return dcesrv_bind_nak(call, 0);
764 context->conn = call->conn;
765 context->iface = iface;
766 context->context_id = context_id;
767 /* legacy for openchange dcesrv_mapiproxy.c */
768 context->assoc_group = call->conn->assoc_group;
769 context->private_data = NULL;
770 DLIST_ADD(call->conn->contexts, context);
771 call->context = context;
772 talloc_set_destructor(context, dcesrv_connection_context_destructor);
774 dcesrv_prepare_context_auth(call);
776 status = iface->bind(call, iface, if_version);
777 if (!NT_STATUS_IS_OK(status)) {
778 char *uuid_str = GUID_string(call, &uuid);
779 DEBUG(2,("Request for dcerpc interface %s/%d rejected: %s\n",
780 uuid_str, if_version, nt_errstr(status)));
781 talloc_free(uuid_str);
782 /* we don't want to trigger the iface->unbind() hook */
783 context->iface = NULL;
784 talloc_free(call->context);
785 call->context = NULL;
786 return dcesrv_bind_nak(call, 0);
790 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
791 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
792 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
793 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
796 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
797 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
800 /* handle any authentication that is being requested */
801 if (!dcesrv_auth_bind(call)) {
802 struct dcesrv_auth *auth = &call->conn->auth_state;
804 TALLOC_FREE(call->context);
806 if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) {
808 * We only give INVALID_AUTH_TYPE if the auth_level was
811 return dcesrv_bind_nak(call,
812 DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE);
814 return dcesrv_bind_nak(call,
815 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
818 /* setup a bind_ack */
819 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
821 pkt.call_id = call->pkt.call_id;
822 pkt.ptype = DCERPC_PKT_BIND_ACK;
823 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
824 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
825 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
826 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
829 endpoint = dcerpc_binding_get_string_option(
830 call->conn->endpoint->ep_description,
834 if (endpoint == NULL) {
838 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
840 * TODO: check if this is really needed
842 * Or if we should fix this in our idl files.
844 ep_prefix = "\\PIPE\\";
848 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
851 if (pkt.u.bind_ack.secondary_address == NULL) {
852 TALLOC_FREE(call->context);
853 return NT_STATUS_NO_MEMORY;
855 pkt.u.bind_ack.num_results = 1;
856 pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
857 if (!pkt.u.bind_ack.ctx_list) {
858 talloc_free(call->context);
859 call->context = NULL;
860 return NT_STATUS_NO_MEMORY;
862 pkt.u.bind_ack.ctx_list[0].result = result;
863 pkt.u.bind_ack.ctx_list[0].reason.value = reason;
864 pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
865 pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
867 status = dcesrv_auth_bind_ack(call, &pkt);
868 if (!NT_STATUS_IS_OK(status)) {
869 talloc_free(call->context);
870 call->context = NULL;
871 return dcesrv_bind_nak(call, 0);
874 rep = talloc_zero(call, struct data_blob_list_item);
876 talloc_free(call->context);
877 call->context = NULL;
878 return NT_STATUS_NO_MEMORY;
881 status = ncacn_push_auth(&rep->blob, call, &pkt,
882 call->out_auth_info);
883 if (!NT_STATUS_IS_OK(status)) {
884 talloc_free(call->context);
885 call->context = NULL;
889 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
891 DLIST_ADD_END(call->replies, rep);
892 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
894 if (call->conn->call_list && call->conn->call_list->replies) {
895 if (call->conn->transport.report_output_data) {
896 call->conn->transport.report_output_data(call->conn);
905 handle a auth3 request
907 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
911 if (!call->conn->allow_auth3) {
912 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
915 if (call->conn->auth_state.auth_finished) {
916 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
919 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
921 call->pkt.u.auth3.auth_info.length,
922 0, /* required flags */
923 DCERPC_PFC_FLAG_FIRST |
924 DCERPC_PFC_FLAG_LAST |
925 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
926 0x08 | /* this is not defined, but should be ignored */
927 DCERPC_PFC_FLAG_CONC_MPX |
928 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
929 DCERPC_PFC_FLAG_MAYBE |
930 DCERPC_PFC_FLAG_OBJECT_UUID);
931 if (!NT_STATUS_IS_OK(status)) {
932 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
935 /* handle the auth3 in the auth code */
936 if (!dcesrv_auth_auth3(call)) {
937 call->conn->auth_state.auth_invalid = true;
942 /* we don't send a reply to a auth3 request, except by a
949 handle a bind request
951 static NTSTATUS dcesrv_alter_new_context(struct dcesrv_call_state *call, uint32_t context_id)
953 uint32_t if_version, transfer_syntax_version;
954 struct dcesrv_connection_context *context;
955 const struct dcesrv_interface *iface;
956 struct GUID uuid, *transfer_syntax_uuid;
959 if_version = call->pkt.u.alter.ctx_list[0].abstract_syntax.if_version;
960 uuid = call->pkt.u.alter.ctx_list[0].abstract_syntax.uuid;
962 transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version;
963 transfer_syntax_uuid = &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid;
964 if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax_ndr.uuid) ||
965 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) {
966 /* we only do NDR encoded dcerpc */
967 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
970 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
972 char *uuid_str = GUID_string(call, &uuid);
973 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
974 talloc_free(uuid_str);
975 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
978 /* add this context to the list of available context_ids */
979 context = talloc_zero(call->conn, struct dcesrv_connection_context);
980 if (context == NULL) {
981 return NT_STATUS_NO_MEMORY;
983 context->conn = call->conn;
984 context->iface = iface;
985 context->context_id = context_id;
986 /* legacy for openchange dcesrv_mapiproxy.c */
987 context->assoc_group = call->conn->assoc_group;
988 context->private_data = NULL;
989 DLIST_ADD(call->conn->contexts, context);
990 call->context = context;
991 talloc_set_destructor(context, dcesrv_connection_context_destructor);
993 dcesrv_prepare_context_auth(call);
995 status = iface->bind(call, iface, if_version);
996 if (!NT_STATUS_IS_OK(status)) {
997 /* we don't want to trigger the iface->unbind() hook */
998 context->iface = NULL;
999 talloc_free(context);
1000 call->context = NULL;
1004 return NT_STATUS_OK;
1007 /* setup and send an alter_resp */
1008 static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call,
1012 struct ncacn_packet pkt;
1013 uint32_t extra_flags = 0;
1014 struct data_blob_list_item *rep = NULL;
1017 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1018 pkt.auth_length = 0;
1019 pkt.call_id = call->pkt.call_id;
1020 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1022 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1023 call->context->conn->state_flags &
1024 DCESRV_CALL_STATE_FLAG_MULTIPLEXED) {
1025 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1027 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1028 call->context->conn->state_flags |=
1029 DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1032 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1033 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1034 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1035 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1036 pkt.u.alter_resp.num_results = 1;
1037 pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx);
1038 if (!pkt.u.alter_resp.ctx_list) {
1039 return NT_STATUS_NO_MEMORY;
1041 pkt.u.alter_resp.ctx_list[0].result = result;
1042 pkt.u.alter_resp.ctx_list[0].reason.value = reason;
1043 pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax_ndr;
1044 pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
1045 pkt.u.alter_resp.secondary_address = "";
1047 status = dcesrv_auth_alter_ack(call, &pkt);
1048 if (!NT_STATUS_IS_OK(status)) {
1049 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1052 rep = talloc_zero(call, struct data_blob_list_item);
1054 return NT_STATUS_NO_MEMORY;
1057 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1058 if (!NT_STATUS_IS_OK(status)) {
1062 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1064 DLIST_ADD_END(call->replies, rep);
1065 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1067 if (call->conn->call_list && call->conn->call_list->replies) {
1068 if (call->conn->transport.report_output_data) {
1069 call->conn->transport.report_output_data(call->conn);
1073 return NT_STATUS_OK;
1077 handle a alter context request
1079 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1082 const struct dcerpc_ctx_list *ctx = NULL;
1083 bool auth_ok = false;
1085 if (!call->conn->allow_alter) {
1086 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1089 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1091 call->pkt.u.alter.auth_info.length,
1092 0, /* required flags */
1093 DCERPC_PFC_FLAG_FIRST |
1094 DCERPC_PFC_FLAG_LAST |
1095 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1096 0x08 | /* this is not defined, but should be ignored */
1097 DCERPC_PFC_FLAG_CONC_MPX |
1098 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1099 DCERPC_PFC_FLAG_MAYBE |
1100 DCERPC_PFC_FLAG_OBJECT_UUID);
1101 if (!NT_STATUS_IS_OK(status)) {
1102 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1105 auth_ok = dcesrv_auth_alter(call);
1107 if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) {
1108 return dcesrv_fault_disconnect(call,
1109 DCERPC_FAULT_ACCESS_DENIED);
1113 if (call->pkt.u.alter.num_contexts < 1) {
1114 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1116 ctx = &call->pkt.u.alter.ctx_list[0];
1117 if (ctx->num_transfer_syntaxes < 1) {
1118 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1121 /* see if they are asking for a new interface */
1122 call->context = dcesrv_find_context(call->conn, ctx->context_id);
1123 if (!call->context) {
1124 status = dcesrv_alter_new_context(call, ctx->context_id);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 return dcesrv_alter_resp(call,
1127 DCERPC_BIND_PROVIDER_REJECT,
1128 DCERPC_BIND_REASON_ASYNTAX);
1133 ok = ndr_syntax_id_equal(&ctx->abstract_syntax,
1134 &call->context->iface->syntax_id);
1136 return dcesrv_fault_disconnect(call,
1137 DCERPC_NCA_S_PROTO_ERROR);
1140 if (ctx->num_transfer_syntaxes != 1) {
1141 return dcesrv_fault_disconnect(call,
1142 DCERPC_NCA_S_PROTO_ERROR);
1145 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[0],
1146 &ndr_transfer_syntax_ndr);
1148 return dcesrv_fault_disconnect(call,
1149 DCERPC_NCA_S_PROTO_ERROR);
1153 /* handle any authentication that is being requested */
1155 if (call->in_auth_info.auth_type !=
1156 call->conn->auth_state.auth_type)
1158 return dcesrv_fault_disconnect(call,
1159 DCERPC_FAULT_SEC_PKG_ERROR);
1161 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1164 return dcesrv_alter_resp(call,
1165 DCERPC_BIND_ACK_RESULT_ACCEPTANCE,
1166 DCERPC_BIND_ACK_REASON_NOT_SPECIFIED);
1170 possibly save the call for inspection with ndrdump
1172 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1176 const char *dump_dir;
1177 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1181 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1183 call->context->iface->name,
1184 call->pkt.u.request.opnum,
1186 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1187 DEBUG(0,("RPC SAVED %s\n", fname));
1193 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1195 TALLOC_CTX *frame = talloc_stackframe();
1196 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1197 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1198 const struct dcerpc_sec_vt_pcontext pcontext = {
1199 .abstract_syntax = call->context->iface->syntax_id,
1200 .transfer_syntax = ndr_transfer_syntax_ndr,
1202 const struct dcerpc_sec_vt_header2 header2 =
1203 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1204 enum ndr_err_code ndr_err;
1205 struct dcerpc_sec_verification_trailer *vt = NULL;
1206 NTSTATUS status = NT_STATUS_OK;
1209 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1211 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1213 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1214 status = ndr_map_error2ntstatus(ndr_err);
1218 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1219 &pcontext, &header2);
1221 status = NT_STATUS_ACCESS_DENIED;
1230 handle a dcerpc request packet
1232 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1234 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1235 enum dcerpc_transport_t transport =
1236 dcerpc_binding_get_transport(endpoint->ep_description);
1237 struct ndr_pull *pull;
1239 struct dcesrv_connection_context *context;
1241 if (!call->conn->allow_request) {
1242 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1245 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1246 if (call->conn->auth_state.gensec_security &&
1247 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1248 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1251 context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1252 if (context == NULL) {
1253 return dcesrv_fault(call, DCERPC_FAULT_UNK_IF);
1256 switch (call->conn->auth_state.auth_level) {
1257 case DCERPC_AUTH_LEVEL_NONE:
1258 case DCERPC_AUTH_LEVEL_INTEGRITY:
1259 case DCERPC_AUTH_LEVEL_PRIVACY:
1262 if (!context->allow_connect) {
1265 addr = tsocket_address_string(call->conn->remote_address,
1268 DEBUG(2, ("%s: restrict auth_level_connect access "
1269 "to [%s] with auth[type=0x%x,level=0x%x] "
1270 "on [%s] from [%s]\n",
1271 __func__, context->iface->name,
1272 call->conn->auth_state.auth_type,
1273 call->conn->auth_state.auth_level,
1274 derpc_transport_string_by_transport(transport),
1276 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1281 if (call->conn->auth_state.auth_level < context->min_auth_level) {
1284 addr = tsocket_address_string(call->conn->remote_address, call);
1286 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1287 "to [%s] with auth[type=0x%x,level=0x%x] "
1288 "on [%s] from [%s]\n",
1290 context->min_auth_level,
1291 context->iface->name,
1292 call->conn->auth_state.auth_type,
1293 call->conn->auth_state.auth_level,
1294 derpc_transport_string_by_transport(transport),
1296 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1299 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1300 NT_STATUS_HAVE_NO_MEMORY(pull);
1302 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1304 call->context = context;
1305 call->ndr_pull = pull;
1307 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1308 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1311 status = dcesrv_check_verification_trailer(call);
1312 if (!NT_STATUS_IS_OK(status)) {
1313 uint32_t faultcode = DCERPC_FAULT_OTHER;
1314 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1315 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1317 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1318 nt_errstr(status)));
1319 return dcesrv_fault(call, faultcode);
1322 /* unravel the NDR for the packet */
1323 status = context->iface->ndr_pull(call, call, pull, &call->r);
1324 if (!NT_STATUS_IS_OK(status)) {
1325 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1326 /* we got an unknown call */
1327 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1328 call->pkt.u.request.opnum, context->iface->name));
1329 dcesrv_save_call(call, "unknown");
1331 dcesrv_save_call(call, "pullfail");
1333 return dcesrv_fault(call, call->fault_code);
1336 if (pull->offset != pull->data_size) {
1337 dcesrv_save_call(call, "extrabytes");
1338 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1339 pull->data_size - pull->offset));
1342 /* call the dispatch function */
1343 status = context->iface->dispatch(call, call, call->r);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1346 context->iface->name,
1347 call->pkt.u.request.opnum,
1348 dcerpc_errstr(pull, call->fault_code)));
1349 return dcesrv_fault(call, call->fault_code);
1352 /* add the call to the pending list */
1353 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1355 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1356 return NT_STATUS_OK;
1359 return dcesrv_reply(call);
1364 remove the call from the right list when freed
1366 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1368 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1372 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1374 return conn->local_address;
1377 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1379 return conn->remote_address;
1383 process some input to a dcerpc endpoint server.
1385 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1386 struct ncacn_packet *pkt,
1390 struct dcesrv_call_state *call;
1391 struct dcesrv_call_state *existing = NULL;
1393 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1395 data_blob_free(&blob);
1397 return NT_STATUS_NO_MEMORY;
1399 call->conn = dce_conn;
1400 call->event_ctx = dce_conn->event_ctx;
1401 call->msg_ctx = dce_conn->msg_ctx;
1402 call->state_flags = call->conn->state_flags;
1403 call->time = timeval_current();
1404 call->list = DCESRV_LIST_NONE;
1406 talloc_steal(call, pkt);
1407 talloc_steal(call, blob.data);
1410 talloc_set_destructor(call, dcesrv_call_dequeue);
1412 if (call->conn->allow_bind) {
1414 * Only one bind is possible per connection
1416 call->conn->allow_bind = false;
1417 return dcesrv_bind(call);
1420 /* we have to check the signing here, before combining the
1422 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1423 if (!call->conn->allow_request) {
1424 return dcesrv_fault_disconnect(call,
1425 DCERPC_NCA_S_PROTO_ERROR);
1428 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1430 call->pkt.u.request.stub_and_verifier.length,
1431 0, /* required_flags */
1432 DCERPC_PFC_FLAG_FIRST |
1433 DCERPC_PFC_FLAG_LAST |
1434 DCERPC_PFC_FLAG_PENDING_CANCEL |
1435 0x08 | /* this is not defined, but should be ignored */
1436 DCERPC_PFC_FLAG_CONC_MPX |
1437 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1438 DCERPC_PFC_FLAG_MAYBE |
1439 DCERPC_PFC_FLAG_OBJECT_UUID);
1440 if (!NT_STATUS_IS_OK(status)) {
1441 return dcesrv_fault_disconnect(call,
1442 DCERPC_NCA_S_PROTO_ERROR);
1445 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1447 * We don't use dcesrv_fault_disconnect()
1448 * here, because we don't want to set
1449 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1451 * Note that we don't check against the negotiated
1452 * max_recv_frag, but a hard coded value.
1454 dcesrv_call_disconnect_after(call,
1455 "dcesrv_auth_request - frag_length too large");
1456 return dcesrv_fault(call,
1457 DCERPC_NCA_S_PROTO_ERROR);
1460 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1461 /* only one request is possible in the fragmented list */
1462 if (dce_conn->incoming_fragmented_call_list != NULL) {
1464 call = dce_conn->incoming_fragmented_call_list;
1465 dcesrv_call_disconnect_after(call,
1466 "dcesrv_auth_request - "
1467 "existing fragmented call");
1468 return dcesrv_fault(call,
1469 DCERPC_NCA_S_PROTO_ERROR);
1471 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1472 return dcesrv_fault_disconnect(call,
1473 DCERPC_FAULT_NO_CALL_ACTIVE);
1476 const struct dcerpc_request *nr = &call->pkt.u.request;
1477 const struct dcerpc_request *er = NULL;
1480 existing = dcesrv_find_fragmented_call(dce_conn,
1482 if (existing == NULL) {
1483 dcesrv_call_disconnect_after(call,
1484 "dcesrv_auth_request - "
1485 "no existing fragmented call");
1486 return dcesrv_fault(call,
1487 DCERPC_NCA_S_PROTO_ERROR);
1489 er = &existing->pkt.u.request;
1491 if (call->pkt.ptype != existing->pkt.ptype) {
1492 /* trying to play silly buggers are we? */
1493 return dcesrv_fault_disconnect(existing,
1494 DCERPC_NCA_S_PROTO_ERROR);
1496 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1499 return dcesrv_fault_disconnect(existing,
1500 DCERPC_NCA_S_PROTO_ERROR);
1502 if (nr->context_id != er->context_id) {
1503 return dcesrv_fault_disconnect(existing,
1504 DCERPC_NCA_S_PROTO_ERROR);
1506 if (nr->opnum != er->opnum) {
1507 return dcesrv_fault_disconnect(existing,
1508 DCERPC_NCA_S_PROTO_ERROR);
1512 if (!dcesrv_auth_request(call, &blob)) {
1514 * We don't use dcesrv_fault_disconnect()
1515 * here, because we don't want to set
1516 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1518 dcesrv_call_disconnect_after(call,
1519 "dcesrv_auth_request - failed");
1520 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1524 /* see if this is a continued packet */
1525 if (existing != NULL) {
1526 struct dcerpc_request *er = &existing->pkt.u.request;
1527 const struct dcerpc_request *nr = &call->pkt.u.request;
1533 * Up to 4 MByte are allowed by all fragments
1535 available = DCERPC_NCACN_PAYLOAD_MAX_SIZE;
1536 if (er->stub_and_verifier.length > available) {
1537 dcesrv_call_disconnect_after(existing,
1538 "dcesrv_auth_request - existing payload too large");
1539 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1541 available -= er->stub_and_verifier.length;
1542 if (nr->alloc_hint > available) {
1543 dcesrv_call_disconnect_after(existing,
1544 "dcesrv_auth_request - alloc hint too large");
1545 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1547 if (nr->stub_and_verifier.length > available) {
1548 dcesrv_call_disconnect_after(existing,
1549 "dcesrv_auth_request - new payload too large");
1550 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1552 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1553 /* allocate at least 1 byte */
1554 alloc_hint = MAX(alloc_hint, 1);
1555 alloc_size = er->stub_and_verifier.length +
1556 nr->stub_and_verifier.length;
1557 alloc_size = MAX(alloc_size, alloc_hint);
1559 er->stub_and_verifier.data =
1560 talloc_realloc(existing,
1561 er->stub_and_verifier.data,
1562 uint8_t, alloc_size);
1563 if (er->stub_and_verifier.data == NULL) {
1565 return dcesrv_fault_with_flags(existing,
1566 DCERPC_FAULT_OUT_OF_RESOURCES,
1567 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1569 memcpy(er->stub_and_verifier.data +
1570 er->stub_and_verifier.length,
1571 nr->stub_and_verifier.data,
1572 nr->stub_and_verifier.length);
1573 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1575 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1581 /* this may not be the last pdu in the chain - if its isn't then
1582 just put it on the incoming_fragmented_call_list and wait for the rest */
1583 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1584 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1586 * Up to 4 MByte are allowed by all fragments
1588 if (call->pkt.u.request.alloc_hint > DCERPC_NCACN_PAYLOAD_MAX_SIZE) {
1589 dcesrv_call_disconnect_after(call,
1590 "dcesrv_auth_request - initial alloc hint too large");
1591 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1593 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1594 return NT_STATUS_OK;
1597 /* This removes any fragments we may have had stashed away */
1598 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1600 switch (call->pkt.ptype) {
1601 case DCERPC_PKT_BIND:
1602 status = dcesrv_bind_nak(call,
1603 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1605 case DCERPC_PKT_AUTH3:
1606 status = dcesrv_auth3(call);
1608 case DCERPC_PKT_ALTER:
1609 status = dcesrv_alter(call);
1611 case DCERPC_PKT_REQUEST:
1612 status = dcesrv_request(call);
1615 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1619 /* if we are going to be sending a reply then add
1620 it to the list of pending calls. We add it to the end to keep the call
1621 list in the order we will answer */
1622 if (!NT_STATUS_IS_OK(status)) {
1629 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1630 struct loadparm_context *lp_ctx,
1631 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1634 struct dcesrv_context *dce_ctx;
1637 if (!endpoint_servers) {
1638 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1639 return NT_STATUS_INTERNAL_ERROR;
1642 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1643 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1645 if (uid_wrapper_enabled()) {
1646 setenv("UID_WRAPPER_MYUID", "1", 1);
1648 dce_ctx->initial_euid = geteuid();
1649 if (uid_wrapper_enabled()) {
1650 unsetenv("UID_WRAPPER_MYUID");
1653 dce_ctx->endpoint_list = NULL;
1654 dce_ctx->lp_ctx = lp_ctx;
1655 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1656 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1657 dce_ctx->broken_connections = NULL;
1659 for (i=0;endpoint_servers[i];i++) {
1660 const struct dcesrv_endpoint_server *ep_server;
1662 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1664 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1665 return NT_STATUS_INTERNAL_ERROR;
1668 status = ep_server->init_server(dce_ctx, ep_server);
1669 if (!NT_STATUS_IS_OK(status)) {
1670 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1671 nt_errstr(status)));
1676 *_dce_ctx = dce_ctx;
1677 return NT_STATUS_OK;
1680 /* the list of currently registered DCERPC endpoint servers.
1682 static struct ep_server {
1683 struct dcesrv_endpoint_server *ep_server;
1684 } *ep_servers = NULL;
1685 static int num_ep_servers;
1688 register a DCERPC endpoint server.
1690 The 'name' can be later used by other backends to find the operations
1691 structure for this backend.
1693 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1695 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1697 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1699 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1700 /* its already registered! */
1701 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1703 return NT_STATUS_OBJECT_NAME_COLLISION;
1706 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1708 smb_panic("out of memory in dcerpc_register");
1711 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1712 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1716 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1719 return NT_STATUS_OK;
1723 return the operations structure for a named backend of the specified type
1725 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1729 for (i=0;i<num_ep_servers;i++) {
1730 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1731 return ep_servers[i].ep_server;
1738 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1740 static bool initialized;
1741 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1742 STATIC_dcerpc_server_MODULES_PROTO;
1743 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1744 init_module_fn *shared_init;
1751 shared_init = load_samba_modules(NULL, "dcerpc_server");
1753 run_init_functions(static_init);
1754 run_init_functions(shared_init);
1756 talloc_free(shared_init);
1760 return the DCERPC module version, and the size of some critical types
1761 This can be used by endpoint server modules to either detect compilation errors, or provide
1762 multiple implementations for different smbd compilation options in one module
1764 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1766 static const struct dcesrv_critical_sizes critical_sizes = {
1767 DCERPC_MODULE_VERSION,
1768 sizeof(struct dcesrv_context),
1769 sizeof(struct dcesrv_endpoint),
1770 sizeof(struct dcesrv_endpoint_server),
1771 sizeof(struct dcesrv_interface),
1772 sizeof(struct dcesrv_if_list),
1773 sizeof(struct dcesrv_connection),
1774 sizeof(struct dcesrv_call_state),
1775 sizeof(struct dcesrv_auth),
1776 sizeof(struct dcesrv_handle)
1779 return &critical_sizes;
1782 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1784 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1785 struct stream_connection *srv_conn;
1786 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1787 struct stream_connection);
1789 dce_conn->allow_bind = false;
1790 dce_conn->allow_auth3 = false;
1791 dce_conn->allow_alter = false;
1792 dce_conn->allow_request = false;
1794 if (dce_conn->pending_call_list == NULL) {
1795 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1797 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1798 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1802 if (dce_conn->terminate != NULL) {
1806 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
1808 dce_conn->terminate = talloc_strdup(dce_conn, reason);
1809 if (dce_conn->terminate == NULL) {
1810 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
1812 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
1815 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
1817 struct dcesrv_connection *cur, *next;
1819 next = dce_ctx->broken_connections;
1820 while (next != NULL) {
1824 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1825 struct dcesrv_connection_context *context_cur, *context_next;
1827 context_next = cur->contexts;
1828 while (context_next != NULL) {
1829 context_cur = context_next;
1830 context_next = context_cur->next;
1832 dcesrv_connection_context_destructor(context_cur);
1836 dcesrv_terminate_connection(cur, cur->terminate);
1840 /* We need this include to be able to compile on some plateforms
1841 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
1843 * It has to be that deep because otherwise we have a conflict on
1844 * const struct dcesrv_interface declaration.
1845 * This is mostly due to socket_wrapper defining #define bind swrap_bind
1846 * which conflict with the bind used before.
1848 #include "system/network.h"
1850 struct dcesrv_sock_reply_state {
1851 struct dcesrv_connection *dce_conn;
1852 struct dcesrv_call_state *call;
1856 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
1857 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
1859 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
1861 struct dcesrv_call_state *call;
1863 call = dce_conn->call_list;
1864 if (!call || !call->replies) {
1868 while (call->replies) {
1869 struct data_blob_list_item *rep = call->replies;
1870 struct dcesrv_sock_reply_state *substate;
1871 struct tevent_req *subreq;
1873 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
1875 dcesrv_terminate_connection(dce_conn, "no memory");
1879 substate->dce_conn = dce_conn;
1880 substate->call = NULL;
1882 DLIST_REMOVE(call->replies, rep);
1884 if (call->replies == NULL && call->terminate_reason == NULL) {
1885 substate->call = call;
1888 substate->iov.iov_base = (void *) rep->blob.data;
1889 substate->iov.iov_len = rep->blob.length;
1891 subreq = tstream_writev_queue_send(substate,
1892 dce_conn->event_ctx,
1894 dce_conn->send_queue,
1897 dcesrv_terminate_connection(dce_conn, "no memory");
1900 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
1904 if (call->terminate_reason != NULL) {
1905 struct tevent_req *subreq;
1907 subreq = tevent_queue_wait_send(call,
1908 dce_conn->event_ctx,
1909 dce_conn->send_queue);
1911 dcesrv_terminate_connection(dce_conn, __location__);
1914 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
1918 DLIST_REMOVE(call->conn->call_list, call);
1919 call->list = DCESRV_LIST_NONE;
1922 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
1924 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
1925 struct dcesrv_sock_reply_state);
1929 struct dcesrv_call_state *call = substate->call;
1931 ret = tstream_writev_queue_recv(subreq, &sys_errno);
1932 TALLOC_FREE(subreq);
1934 status = map_nt_error_from_unix_common(sys_errno);
1935 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
1939 talloc_free(substate);
1945 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
1947 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
1949 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1950 struct dcesrv_call_state);
1954 /* make sure we stop send queue before removing subreq */
1955 tevent_queue_stop(call->conn->send_queue);
1957 ok = tevent_queue_wait_recv(subreq);
1958 TALLOC_FREE(subreq);
1960 dcesrv_terminate_connection(call->conn, __location__);
1964 /* disconnect after 200 usecs */
1965 tv = timeval_current_ofs_usec(200);
1966 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
1967 if (subreq == NULL) {
1968 dcesrv_terminate_connection(call->conn, __location__);
1971 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
1975 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
1977 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
1978 struct dcesrv_call_state);
1981 ok = tevent_wakeup_recv(subreq);
1982 TALLOC_FREE(subreq);
1984 dcesrv_terminate_connection(call->conn, __location__);
1988 dcesrv_terminate_connection(call->conn, call->terminate_reason);
1991 struct dcesrv_socket_context {
1992 const struct dcesrv_endpoint *endpoint;
1993 struct dcesrv_context *dcesrv_ctx;
1997 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
1999 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2002 struct dcesrv_socket_context *dcesrv_sock =
2003 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2004 enum dcerpc_transport_t transport =
2005 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2006 struct dcesrv_connection *dcesrv_conn = NULL;
2008 struct tevent_req *subreq;
2009 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2011 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2013 if (!srv_conn->session_info) {
2014 status = auth_anonymous_session_info(srv_conn,
2016 &srv_conn->session_info);
2017 if (!NT_STATUS_IS_OK(status)) {
2018 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2019 nt_errstr(status)));
2020 stream_terminate_connection(srv_conn, nt_errstr(status));
2025 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2027 dcesrv_sock->endpoint,
2028 srv_conn->session_info,
2029 srv_conn->event.ctx,
2031 srv_conn->server_id,
2032 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2034 if (!NT_STATUS_IS_OK(status)) {
2035 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2036 nt_errstr(status)));
2037 stream_terminate_connection(srv_conn, nt_errstr(status));
2041 dcesrv_conn->transport.private_data = srv_conn;
2042 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2044 TALLOC_FREE(srv_conn->event.fde);
2046 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2047 if (!dcesrv_conn->send_queue) {
2048 status = NT_STATUS_NO_MEMORY;
2049 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2050 nt_errstr(status)));
2051 stream_terminate_connection(srv_conn, nt_errstr(status));
2055 if (transport == NCACN_NP) {
2056 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2057 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2058 &srv_conn->tstream);
2060 ret = tstream_bsd_existing_socket(dcesrv_conn,
2061 socket_get_fd(srv_conn->socket),
2062 &dcesrv_conn->stream);
2064 status = map_nt_error_from_unix_common(errno);
2065 DEBUG(0, ("dcesrv_sock_accept: "
2066 "failed to setup tstream: %s\n",
2067 nt_errstr(status)));
2068 stream_terminate_connection(srv_conn, nt_errstr(status));
2071 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2074 dcesrv_conn->local_address = srv_conn->local_address;
2075 dcesrv_conn->remote_address = srv_conn->remote_address;
2077 if (transport == NCALRPC) {
2081 ret = getpeereid(socket_get_fd(srv_conn->socket), &uid, &gid);
2083 status = map_nt_error_from_unix_common(errno);
2084 DEBUG(0, ("dcesrv_sock_accept: "
2085 "getpeereid() failed for NCALRPC: %s\n",
2086 nt_errstr(status)));
2087 stream_terminate_connection(srv_conn, nt_errstr(status));
2090 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2091 struct tsocket_address *r = NULL;
2093 ret = tsocket_address_unix_from_path(dcesrv_conn,
2094 "/root/ncalrpc_as_system",
2097 status = map_nt_error_from_unix_common(errno);
2098 DEBUG(0, ("dcesrv_sock_accept: "
2099 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2100 nt_errstr(status)));
2101 stream_terminate_connection(srv_conn, nt_errstr(status));
2104 dcesrv_conn->remote_address = r;
2108 srv_conn->private_data = dcesrv_conn;
2110 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2112 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2113 dcesrv_conn->event_ctx,
2114 dcesrv_conn->stream);
2116 status = NT_STATUS_NO_MEMORY;
2117 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2118 nt_errstr(status)));
2119 stream_terminate_connection(srv_conn, nt_errstr(status));
2122 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2127 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2129 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2130 struct dcesrv_connection);
2131 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2132 struct ncacn_packet *pkt;
2136 if (dce_conn->terminate) {
2138 * if the current connection is broken
2139 * we need to clean it up before any other connection
2141 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2142 dcesrv_cleanup_broken_connections(dce_ctx);
2146 dcesrv_cleanup_broken_connections(dce_ctx);
2148 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2150 TALLOC_FREE(subreq);
2151 if (!NT_STATUS_IS_OK(status)) {
2152 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2156 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2157 if (!NT_STATUS_IS_OK(status)) {
2158 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2162 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2163 dce_conn->event_ctx,
2166 status = NT_STATUS_NO_MEMORY;
2167 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2170 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2173 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2175 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2176 struct dcesrv_connection);
2177 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2180 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2182 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2183 struct dcesrv_connection);
2184 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2188 static const struct stream_server_ops dcesrv_stream_ops = {
2190 .accept_connection = dcesrv_sock_accept,
2191 .recv_handler = dcesrv_sock_recv,
2192 .send_handler = dcesrv_sock_send,
2195 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2196 struct loadparm_context *lp_ctx,
2197 struct dcesrv_endpoint *e,
2198 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2200 struct dcesrv_socket_context *dcesrv_sock;
2203 const char *endpoint;
2205 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2206 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2208 /* remember the endpoint of this socket */
2209 dcesrv_sock->endpoint = e;
2210 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2212 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2214 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2215 model_ops, &dcesrv_stream_ops,
2216 "unix", endpoint, &port,
2217 lpcfg_socket_options(lp_ctx),
2219 if (!NT_STATUS_IS_OK(status)) {
2220 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2221 endpoint, nt_errstr(status)));
2227 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2228 struct loadparm_context *lp_ctx,
2229 struct dcesrv_endpoint *e,
2230 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2232 struct dcesrv_socket_context *dcesrv_sock;
2236 const char *endpoint;
2238 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2240 if (endpoint == NULL) {
2242 * No identifier specified: use DEFAULT.
2244 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2245 * no endpoint and let the epmapper worry about it.
2247 endpoint = "DEFAULT";
2248 status = dcerpc_binding_set_string_option(e->ep_description,
2251 if (!NT_STATUS_IS_OK(status)) {
2252 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2253 nt_errstr(status)));
2258 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2261 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2262 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2264 /* remember the endpoint of this socket */
2265 dcesrv_sock->endpoint = e;
2266 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2268 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2269 model_ops, &dcesrv_stream_ops,
2270 "unix", full_path, &port,
2271 lpcfg_socket_options(lp_ctx),
2273 if (!NT_STATUS_IS_OK(status)) {
2274 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2275 endpoint, full_path, nt_errstr(status)));
2280 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2281 struct loadparm_context *lp_ctx,
2282 struct dcesrv_endpoint *e,
2283 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2285 struct dcesrv_socket_context *dcesrv_sock;
2287 const char *endpoint;
2289 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2290 if (endpoint == NULL) {
2291 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2292 return NT_STATUS_INVALID_PARAMETER;
2295 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2296 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2298 /* remember the endpoint of this socket */
2299 dcesrv_sock->endpoint = e;
2300 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2302 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2303 model_ops, &dcesrv_stream_ops,
2306 if (!NT_STATUS_IS_OK(status)) {
2307 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2308 endpoint, nt_errstr(status)));
2312 return NT_STATUS_OK;
2316 add a socket address to the list of events, one event per dcerpc endpoint
2318 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2319 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2320 const char *address)
2322 struct dcesrv_socket_context *dcesrv_sock;
2325 const char *endpoint;
2328 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2329 if (endpoint != NULL) {
2330 port = atoi(endpoint);
2333 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2334 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2336 /* remember the endpoint of this socket */
2337 dcesrv_sock->endpoint = e;
2338 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2340 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2341 model_ops, &dcesrv_stream_ops,
2342 "ip", address, &port,
2343 lpcfg_socket_options(dce_ctx->lp_ctx),
2345 if (!NT_STATUS_IS_OK(status)) {
2346 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2347 address, port, nt_errstr(status)));
2351 snprintf(port_str, sizeof(port_str), "%u", port);
2353 status = dcerpc_binding_set_string_option(e->ep_description,
2354 "endpoint", port_str);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2357 port_str, nt_errstr(status)));
2361 return NT_STATUS_OK;
2364 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2366 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2367 struct loadparm_context *lp_ctx,
2368 struct dcesrv_endpoint *e,
2369 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2373 /* Add TCP/IP sockets */
2374 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2377 struct interface *ifaces;
2379 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2381 num_interfaces = iface_list_count(ifaces);
2382 for(i = 0; i < num_interfaces; i++) {
2383 const char *address = iface_list_n_ip(ifaces, i);
2384 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2385 NT_STATUS_NOT_OK_RETURN(status);
2391 wcard = iface_list_wildcard(dce_ctx);
2392 NT_STATUS_HAVE_NO_MEMORY(wcard);
2393 for (i=0; wcard[i]; i++) {
2394 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2395 if (NT_STATUS_IS_OK(status)) {
2400 if (num_binds == 0) {
2401 return NT_STATUS_INVALID_PARAMETER_MIX;
2405 return NT_STATUS_OK;
2408 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2409 struct loadparm_context *lp_ctx,
2410 struct dcesrv_endpoint *e,
2411 struct tevent_context *event_ctx,
2412 const struct model_ops *model_ops)
2414 enum dcerpc_transport_t transport =
2415 dcerpc_binding_get_transport(e->ep_description);
2417 switch (transport) {
2418 case NCACN_UNIX_STREAM:
2419 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2422 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2425 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2428 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2431 return NT_STATUS_NOT_SUPPORTED;
2437 * retrieve credentials from a dce_call
2439 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2441 return dce_call->conn->auth_state.session_info->credentials;
2445 * returns true if this is an authenticated call
2447 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2449 enum security_user_level level;
2450 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2451 return level >= SECURITY_USER;
2455 * retrieve account_name for a dce_call
2457 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2459 return dce_call->context->conn->auth_state.session_info->info->account_name;