2 Unix SMB/CIFS implementation.
4 server side dcerpc core code
6 Copyright (C) Andrew Tridgell 2003-2005
7 Copyright (C) Stefan (metze) Metzmacher 2004-2005
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
45 extern const struct dcesrv_interface dcesrv_mgmt_interface;
47 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
48 const struct dcerpc_bind *b,
49 struct dcerpc_ack_ctx *ack_ctx_list);
52 find an association group given a assoc_group_id
54 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
59 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
63 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
67 take a reference to an existing association group
69 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
70 struct dcesrv_context *dce_ctx,
73 struct dcesrv_assoc_group *assoc_group;
75 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
76 if (assoc_group == NULL) {
77 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
80 return talloc_reference(mem_ctx, assoc_group);
83 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
86 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
88 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
95 allocate a new association group
97 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
98 struct dcesrv_context *dce_ctx)
100 struct dcesrv_assoc_group *assoc_group;
103 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
104 if (assoc_group == NULL) {
108 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
110 talloc_free(assoc_group);
111 DEBUG(0,(__location__ ": Out of association groups!\n"));
115 assoc_group->id = id;
116 assoc_group->dce_ctx = dce_ctx;
118 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
125 see if two endpoints match
127 static bool endpoints_match(const struct dcerpc_binding *ep1,
128 const struct dcerpc_binding *ep2)
130 enum dcerpc_transport_t t1;
131 enum dcerpc_transport_t t2;
135 t1 = dcerpc_binding_get_transport(ep1);
136 t2 = dcerpc_binding_get_transport(ep2);
138 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
139 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
149 if (strcasecmp(e1, e2) != 0) {
157 find an endpoint in the dcesrv_context
159 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
160 const struct dcerpc_binding *ep_description)
162 struct dcesrv_endpoint *ep;
163 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
164 if (endpoints_match(ep->ep_description, ep_description)) {
172 find a registered context_id from a bind or alter_context
174 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
177 struct dcesrv_connection_context *c;
178 for (c=conn->contexts;c;c=c->next) {
179 if (c->context_id == context_id) return c;
185 see if a uuid and if_version match to an interface
187 static bool interface_match(const struct dcesrv_interface *if1,
188 const struct dcesrv_interface *if2)
190 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
191 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
195 find the interface operations on an endpoint
197 static const struct dcesrv_interface *find_interface(const struct dcesrv_endpoint *endpoint,
198 const struct dcesrv_interface *iface)
200 struct dcesrv_if_list *ifl;
201 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
202 if (interface_match(&(ifl->iface), iface)) {
203 return &(ifl->iface);
210 see if a uuid and if_version match to an interface
212 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
213 const struct GUID *uuid, uint32_t if_version)
215 return (iface->syntax_id.if_version == if_version &&
216 GUID_equal(&iface->syntax_id.uuid, uuid));
220 find the interface operations on an endpoint by uuid
222 static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
223 const struct GUID *uuid, uint32_t if_version)
225 struct dcesrv_if_list *ifl;
226 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
227 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
228 return &(ifl->iface);
235 find the earlier parts of a fragmented call awaiting reassembily
237 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
239 struct dcesrv_call_state *c;
240 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
241 if (c->pkt.call_id == call_id) {
249 register an interface on an endpoint
251 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
253 const struct dcesrv_interface *iface,
254 const struct security_descriptor *sd)
256 struct dcesrv_endpoint *ep;
257 struct dcesrv_if_list *ifl;
258 struct dcerpc_binding *binding;
262 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
264 if (NT_STATUS_IS_ERR(status)) {
265 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
269 /* check if this endpoint exists
271 if ((ep=find_endpoint(dce_ctx, binding))==NULL) {
272 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
274 return NT_STATUS_NO_MEMORY;
277 ep->ep_description = talloc_move(ep, &binding);
280 /* add mgmt interface */
281 ifl = talloc_zero(ep, struct dcesrv_if_list);
283 return NT_STATUS_NO_MEMORY;
286 memcpy(&(ifl->iface), &dcesrv_mgmt_interface,
287 sizeof(struct dcesrv_interface));
289 DLIST_ADD(ep->interface_list, ifl);
292 /* see if the interface is already registered on te endpoint */
293 if (find_interface(ep, iface)!=NULL) {
294 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
295 iface->name, ep_name));
296 return NT_STATUS_OBJECT_NAME_COLLISION;
299 /* talloc a new interface list element */
300 ifl = talloc_zero(ep, struct dcesrv_if_list);
302 return NT_STATUS_NO_MEMORY;
305 /* copy the given interface struct to the one on the endpoints interface list */
306 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
308 /* if we have a security descriptor given,
309 * we should see if we can set it up on the endpoint
312 /* if there's currently no security descriptor given on the endpoint
315 if (ep->sd == NULL) {
316 ep->sd = security_descriptor_copy(ep, sd);
319 /* if now there's no security descriptor given on the endpoint
320 * something goes wrong, either we failed to copy the security descriptor
321 * or there was already one on the endpoint
323 if (ep->sd != NULL) {
324 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
325 " on endpoint '%s'\n",
326 iface->name, ep_name));
327 if (add_ep) free(ep);
329 return NT_STATUS_OBJECT_NAME_COLLISION;
333 /* finally add the interface on the endpoint */
334 DLIST_ADD(ep->interface_list, ifl);
336 /* if it's a new endpoint add it to the dcesrv_context */
338 DLIST_ADD(dce_ctx->endpoint_list, ep);
341 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
342 iface->name, ep_name));
347 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
348 DATA_BLOB *session_key)
350 if (p->auth_state.session_info->session_key.length) {
351 *session_key = p->auth_state.session_info->session_key;
354 return NT_STATUS_NO_USER_SESSION_KEY;
358 fetch the user session key - may be default (above) or the SMB session key
360 The key is always truncated to 16 bytes
362 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
363 DATA_BLOB *session_key)
365 NTSTATUS status = p->auth_state.session_key(p, session_key);
366 if (!NT_STATUS_IS_OK(status)) {
370 session_key->length = MIN(session_key->length, 16);
376 connect to a dcerpc endpoint
378 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
380 const struct dcesrv_endpoint *ep,
381 struct auth_session_info *session_info,
382 struct tevent_context *event_ctx,
383 struct imessaging_context *msg_ctx,
384 struct server_id server_id,
385 uint32_t state_flags,
386 struct dcesrv_connection **_p)
388 struct dcesrv_connection *p;
391 return NT_STATUS_ACCESS_DENIED;
394 p = talloc_zero(mem_ctx, struct dcesrv_connection);
395 NT_STATUS_HAVE_NO_MEMORY(p);
397 if (!talloc_reference(p, session_info)) {
399 return NT_STATUS_NO_MEMORY;
402 p->dce_ctx = dce_ctx;
404 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
405 p->auth_state.session_info = session_info;
406 p->auth_state.session_key = dcesrv_generic_session_key;
407 p->event_ctx = event_ctx;
408 p->msg_ctx = msg_ctx;
409 p->server_id = server_id;
410 p->state_flags = state_flags;
411 p->allow_bind = true;
412 p->max_recv_frag = 5840;
413 p->max_xmit_frag = 5840;
414 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
417 * For now we only support NDR32.
419 p->preferred_transfer = &ndr_transfer_syntax_ndr;
426 move a call from an existing linked list to the specified list. This
427 prevents bugs where we forget to remove the call from a previous
430 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
431 enum dcesrv_call_list list)
433 switch (call->list) {
434 case DCESRV_LIST_NONE:
436 case DCESRV_LIST_CALL_LIST:
437 DLIST_REMOVE(call->conn->call_list, call);
439 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
440 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
442 case DCESRV_LIST_PENDING_CALL_LIST:
443 DLIST_REMOVE(call->conn->pending_call_list, call);
448 case DCESRV_LIST_NONE:
450 case DCESRV_LIST_CALL_LIST:
451 DLIST_ADD_END(call->conn->call_list, call);
453 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
454 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
456 case DCESRV_LIST_PENDING_CALL_LIST:
457 DLIST_ADD_END(call->conn->pending_call_list, call);
462 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
465 if (call->conn->terminate != NULL) {
469 call->conn->allow_bind = false;
470 call->conn->allow_alter = false;
471 call->conn->allow_auth3 = false;
472 call->conn->allow_request = false;
474 call->terminate_reason = talloc_strdup(call, reason);
475 if (call->terminate_reason == NULL) {
476 call->terminate_reason = __location__;
481 return a dcerpc bind_nak
483 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
485 struct ncacn_packet pkt;
486 struct dcerpc_bind_nak_version version;
487 struct data_blob_list_item *rep;
489 static const uint8_t _pad[3] = { 0, };
492 * We add the call to the pending_call_list
493 * in order to defer the termination.
495 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
497 /* setup a bind_nak */
498 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
500 pkt.call_id = call->pkt.call_id;
501 pkt.ptype = DCERPC_PKT_BIND_NAK;
502 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
503 pkt.u.bind_nak.reject_reason = reason;
504 version.rpc_vers = 5;
505 version.rpc_vers_minor = 0;
506 pkt.u.bind_nak.num_versions = 1;
507 pkt.u.bind_nak.versions = &version;
508 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
510 rep = talloc_zero(call, struct data_blob_list_item);
512 return NT_STATUS_NO_MEMORY;
515 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
516 if (!NT_STATUS_IS_OK(status)) {
520 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
522 DLIST_ADD_END(call->replies, rep);
523 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
525 if (call->conn->call_list && call->conn->call_list->replies) {
526 if (call->conn->transport.report_output_data) {
527 call->conn->transport.report_output_data(call->conn);
534 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
538 * We add the call to the pending_call_list
539 * in order to defer the termination.
541 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
543 return dcesrv_fault_with_flags(call, fault_code,
544 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
547 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
549 DLIST_REMOVE(c->conn->contexts, c);
551 if (c->iface && c->iface->unbind) {
552 c->iface->unbind(c, c->iface);
559 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
561 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
562 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
563 enum dcerpc_transport_t transport =
564 dcerpc_binding_get_transport(endpoint->ep_description);
565 struct dcesrv_connection_context *context = dce_call->context;
566 const struct dcesrv_interface *iface = context->iface;
568 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
570 if (transport == NCALRPC) {
571 context->allow_connect = true;
576 * allow overwrite per interface
577 * allow dcerpc auth level connect:<interface>
579 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
580 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
581 "allow dcerpc auth level connect",
583 context->allow_connect);
586 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
587 const struct dcesrv_interface *iface)
589 if (dce_call->context == NULL) {
590 return NT_STATUS_INTERNAL_ERROR;
594 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
595 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
597 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
601 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
602 const struct dcesrv_interface *iface)
604 if (dce_call->context == NULL) {
605 return NT_STATUS_INTERNAL_ERROR;
608 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
612 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
613 const struct dcesrv_interface *iface)
615 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
616 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
617 enum dcerpc_transport_t transport =
618 dcerpc_binding_get_transport(endpoint->ep_description);
619 struct dcesrv_connection_context *context = dce_call->context;
621 if (context == NULL) {
622 return NT_STATUS_INTERNAL_ERROR;
625 if (transport == NCALRPC) {
626 context->allow_connect = true;
631 * allow overwrite per interface
632 * allow dcerpc auth level connect:<interface>
634 context->allow_connect = false;
635 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
636 "allow dcerpc auth level connect",
638 context->allow_connect);
642 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
643 const struct dcesrv_interface *iface)
645 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
646 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
647 enum dcerpc_transport_t transport =
648 dcerpc_binding_get_transport(endpoint->ep_description);
649 struct dcesrv_connection_context *context = dce_call->context;
651 if (context == NULL) {
652 return NT_STATUS_INTERNAL_ERROR;
655 if (transport == NCALRPC) {
656 context->allow_connect = true;
661 * allow overwrite per interface
662 * allow dcerpc auth level connect:<interface>
664 context->allow_connect = true;
665 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
666 "allow dcerpc auth level connect",
668 context->allow_connect);
673 handle a bind request
675 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
677 struct ncacn_packet pkt;
678 struct data_blob_list_item *rep;
680 uint32_t extra_flags = 0;
681 uint16_t max_req = 0;
682 uint16_t max_rep = 0;
683 const char *ep_prefix = "";
684 const char *endpoint = NULL;
685 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
686 struct dcerpc_ack_ctx *ack_features = NULL;
689 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
691 call->pkt.u.bind.auth_info.length,
692 0, /* required flags */
693 DCERPC_PFC_FLAG_FIRST |
694 DCERPC_PFC_FLAG_LAST |
695 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
696 0x08 | /* this is not defined, but should be ignored */
697 DCERPC_PFC_FLAG_CONC_MPX |
698 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
699 DCERPC_PFC_FLAG_MAYBE |
700 DCERPC_PFC_FLAG_OBJECT_UUID);
701 if (!NT_STATUS_IS_OK(status)) {
702 return dcesrv_bind_nak(call,
703 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
706 /* max_recv_frag and max_xmit_frag result always in the same value! */
707 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
708 call->pkt.u.bind.max_recv_frag);
710 * The values are between 2048 and 5840 tested against Windows 2012R2
711 * via ncacn_ip_tcp on port 135.
713 max_req = MAX(2048, max_req);
714 max_rep = MIN(max_req, call->conn->max_recv_frag);
715 /* They are truncated to an 8 byte boundary. */
718 /* max_recv_frag and max_xmit_frag result always in the same value! */
719 call->conn->max_recv_frag = max_rep;
720 call->conn->max_xmit_frag = max_rep;
723 if provided, check the assoc_group is valid
725 if (call->pkt.u.bind.assoc_group_id != 0) {
726 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
728 call->pkt.u.bind.assoc_group_id);
730 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
731 call->conn->dce_ctx);
733 if (call->conn->assoc_group == NULL) {
734 return dcesrv_bind_nak(call, 0);
737 if (call->pkt.u.bind.num_contexts < 1) {
738 return dcesrv_bind_nak(call, 0);
741 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
742 call->pkt.u.bind.num_contexts);
743 if (ack_ctx_list == NULL) {
744 return dcesrv_bind_nak(call, 0);
748 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
749 * dcesrv_check_or_create_context()) and do some protocol validation
750 * and set sane defaults.
752 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
753 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
754 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
755 bool is_feature = false;
756 uint64_t features = 0;
758 if (c->num_transfer_syntaxes == 0) {
759 return dcesrv_bind_nak(call, 0);
762 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
763 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
766 * It's only treated as bind time feature request, if the first
767 * transfer_syntax matches, all others are ignored.
769 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
775 if (ack_features != NULL) {
777 * Only one bind time feature context is allowed.
779 return dcesrv_bind_nak(call, 0);
783 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
784 a->reason.negotiate = 0;
785 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
786 /* not supported yet */
788 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
789 a->reason.negotiate |=
790 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
793 call->conn->bind_time_features = a->reason.negotiate;
797 * Try to negotiate one new presentation context.
799 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
800 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
801 return dcesrv_bind_nak(call, 0);
803 if (!NT_STATUS_IS_OK(status)) {
807 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
808 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
809 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
810 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
813 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
814 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
817 /* handle any authentication that is being requested */
818 if (!dcesrv_auth_bind(call)) {
819 struct dcesrv_auth *auth = &call->conn->auth_state;
821 TALLOC_FREE(call->context);
823 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
825 * With DCERPC_AUTH_LEVEL_NONE, we get the
826 * reject_reason in auth->auth_context_id.
828 return dcesrv_bind_nak(call, auth->auth_context_id);
832 * This must a be a temporary failure e.g. talloc or invalid
833 * configuration, e.g. no machine account.
835 return dcesrv_bind_nak(call,
836 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
839 /* setup a bind_ack */
840 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
842 pkt.call_id = call->pkt.call_id;
843 pkt.ptype = DCERPC_PKT_BIND_ACK;
844 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
845 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
846 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
847 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
849 endpoint = dcerpc_binding_get_string_option(
850 call->conn->endpoint->ep_description,
852 if (endpoint == NULL) {
856 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
858 * TODO: check if this is really needed
860 * Or if we should fix this in our idl files.
862 ep_prefix = "\\PIPE\\";
866 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
869 if (pkt.u.bind_ack.secondary_address == NULL) {
870 TALLOC_FREE(call->context);
871 return NT_STATUS_NO_MEMORY;
873 pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
874 pkt.u.bind_ack.ctx_list = ack_ctx_list;
875 pkt.u.bind_ack.auth_info = data_blob_null;
877 status = dcesrv_auth_bind_ack(call, &pkt);
878 if (!NT_STATUS_IS_OK(status)) {
879 TALLOC_FREE(call->context);
880 return dcesrv_bind_nak(call, 0);
883 rep = talloc_zero(call, struct data_blob_list_item);
885 TALLOC_FREE(call->context);
886 return NT_STATUS_NO_MEMORY;
889 status = ncacn_push_auth(&rep->blob, call, &pkt,
890 call->out_auth_info);
891 if (!NT_STATUS_IS_OK(status)) {
892 TALLOC_FREE(call->context);
896 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
898 DLIST_ADD_END(call->replies, rep);
899 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
901 if (call->conn->call_list && call->conn->call_list->replies) {
902 if (call->conn->transport.report_output_data) {
903 call->conn->transport.report_output_data(call->conn);
912 handle a auth3 request
914 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
918 if (!call->conn->allow_auth3) {
919 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
922 if (call->conn->auth_state.auth_finished) {
923 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
926 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
928 call->pkt.u.auth3.auth_info.length,
929 0, /* required flags */
930 DCERPC_PFC_FLAG_FIRST |
931 DCERPC_PFC_FLAG_LAST |
932 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
933 0x08 | /* this is not defined, but should be ignored */
934 DCERPC_PFC_FLAG_CONC_MPX |
935 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
936 DCERPC_PFC_FLAG_MAYBE |
937 DCERPC_PFC_FLAG_OBJECT_UUID);
938 if (!NT_STATUS_IS_OK(status)) {
939 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
942 /* handle the auth3 in the auth code */
943 if (!dcesrv_auth_auth3(call)) {
944 call->conn->auth_state.auth_invalid = true;
945 if (call->fault_code != 0) {
946 return dcesrv_fault_disconnect(call, call->fault_code);
952 /* we don't send a reply to a auth3 request, except by a
958 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
959 const struct dcerpc_bind *b,
960 const struct dcerpc_ctx_list *ctx,
961 struct dcerpc_ack_ctx *ack,
963 const struct ndr_syntax_id *supported_transfer)
966 struct dcesrv_connection_context *context;
967 const struct dcesrv_interface *iface;
970 const struct ndr_syntax_id *selected_transfer = NULL;
975 return NT_STATUS_INTERNAL_ERROR;
978 return NT_STATUS_INTERNAL_ERROR;
980 if (ctx->num_transfer_syntaxes < 1) {
981 return NT_STATUS_INTERNAL_ERROR;
984 return NT_STATUS_INTERNAL_ERROR;
986 if (supported_transfer == NULL) {
987 return NT_STATUS_INTERNAL_ERROR;
990 switch (ack->result) {
991 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
992 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
994 * We is already completed.
1001 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1002 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1004 if_version = ctx->abstract_syntax.if_version;
1005 uuid = ctx->abstract_syntax.uuid;
1007 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1008 if (iface == NULL) {
1009 char *uuid_str = GUID_string(call, &uuid);
1010 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1011 talloc_free(uuid_str);
1013 * We report this only via ack->result
1015 return NT_STATUS_OK;
1018 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1019 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1021 if (validate_only) {
1023 * We report this only via ack->result
1025 return NT_STATUS_OK;
1028 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1030 * we only do NDR encoded dcerpc for now.
1032 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1033 supported_transfer);
1035 selected_transfer = supported_transfer;
1040 context = dcesrv_find_context(call->conn, ctx->context_id);
1041 if (context != NULL) {
1042 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1043 &ctx->abstract_syntax);
1045 return NT_STATUS_RPC_PROTOCOL_ERROR;
1048 if (selected_transfer != NULL) {
1049 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1052 return NT_STATUS_RPC_PROTOCOL_ERROR;
1055 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1056 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1057 ack->syntax = context->transfer_syntax;
1061 * We report this only via ack->result
1063 return NT_STATUS_OK;
1066 if (selected_transfer == NULL) {
1068 * We report this only via ack->result
1070 return NT_STATUS_OK;
1073 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1074 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1076 /* add this context to the list of available context_ids */
1077 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1078 if (context == NULL) {
1079 return NT_STATUS_NO_MEMORY;
1081 context->conn = call->conn;
1082 context->context_id = ctx->context_id;
1083 context->iface = iface;
1084 context->transfer_syntax = *selected_transfer;
1085 context->private_data = NULL;
1086 DLIST_ADD(call->conn->contexts, context);
1087 call->context = context;
1088 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1090 dcesrv_prepare_context_auth(call);
1093 * Multiplex is supported by default
1095 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1097 status = iface->bind(call, iface, if_version);
1098 call->context = NULL;
1099 if (!NT_STATUS_IS_OK(status)) {
1100 /* we don't want to trigger the iface->unbind() hook */
1101 context->iface = NULL;
1102 talloc_free(context);
1104 * We report this only via ack->result
1106 return NT_STATUS_OK;
1109 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1110 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1111 ack->syntax = context->transfer_syntax;
1112 return NT_STATUS_OK;
1115 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1116 const struct dcerpc_bind *b,
1117 struct dcerpc_ack_ctx *ack_ctx_list)
1121 bool validate_only = false;
1122 bool preferred_ndr32;
1125 * Try to negotiate one new presentation context,
1126 * using our preferred transfer syntax.
1128 for (i = 0; i < b->num_contexts; i++) {
1129 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1130 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1132 status = dcesrv_check_or_create_context(call, b, c, a,
1134 call->conn->preferred_transfer);
1135 if (!NT_STATUS_IS_OK(status)) {
1139 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1141 * We managed to negotiate one context.
1145 validate_only = true;
1149 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1150 call->conn->preferred_transfer);
1151 if (preferred_ndr32) {
1155 return NT_STATUS_OK;
1159 * Try to negotiate one new presentation context,
1160 * using NDR 32 as fallback.
1162 for (i = 0; i < b->num_contexts; i++) {
1163 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1164 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1166 status = dcesrv_check_or_create_context(call, b, c, a,
1168 &ndr_transfer_syntax_ndr);
1169 if (!NT_STATUS_IS_OK(status)) {
1173 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1175 * We managed to negotiate one context.
1179 validate_only = true;
1183 return NT_STATUS_OK;
1187 handle a alter context request
1189 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1192 bool auth_ok = false;
1193 struct ncacn_packet pkt;
1194 uint32_t extra_flags = 0;
1195 struct data_blob_list_item *rep = NULL;
1196 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1199 if (!call->conn->allow_alter) {
1200 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1203 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1205 call->pkt.u.alter.auth_info.length,
1206 0, /* required flags */
1207 DCERPC_PFC_FLAG_FIRST |
1208 DCERPC_PFC_FLAG_LAST |
1209 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1210 0x08 | /* this is not defined, but should be ignored */
1211 DCERPC_PFC_FLAG_CONC_MPX |
1212 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1213 DCERPC_PFC_FLAG_MAYBE |
1214 DCERPC_PFC_FLAG_OBJECT_UUID);
1215 if (!NT_STATUS_IS_OK(status)) {
1216 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1219 auth_ok = dcesrv_auth_alter(call);
1221 if (call->fault_code != 0) {
1222 return dcesrv_fault_disconnect(call, call->fault_code);
1226 if (call->pkt.u.alter.num_contexts < 1) {
1227 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1230 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1231 call->pkt.u.alter.num_contexts);
1232 if (ack_ctx_list == NULL) {
1233 return NT_STATUS_NO_MEMORY;
1237 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1238 * dcesrv_check_or_create_context()) and do some protocol validation
1239 * and set sane defaults.
1241 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1242 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1243 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1245 if (c->num_transfer_syntaxes == 0) {
1246 return dcesrv_fault_disconnect(call,
1247 DCERPC_NCA_S_PROTO_ERROR);
1250 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1251 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1255 * Try to negotiate one new presentation context.
1257 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1258 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1259 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1261 if (!NT_STATUS_IS_OK(status)) {
1265 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1266 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1267 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1268 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1271 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1272 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1275 /* handle any authentication that is being requested */
1277 if (call->in_auth_info.auth_type !=
1278 call->conn->auth_state.auth_type)
1280 return dcesrv_fault_disconnect(call,
1281 DCERPC_FAULT_SEC_PKG_ERROR);
1283 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1286 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1287 pkt.auth_length = 0;
1288 pkt.call_id = call->pkt.call_id;
1289 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1290 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1291 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1292 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1293 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1294 pkt.u.alter_resp.secondary_address = "";
1295 pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1296 pkt.u.alter_resp.ctx_list = ack_ctx_list;
1297 pkt.u.alter_resp.auth_info = data_blob_null;
1299 status = dcesrv_auth_alter_ack(call, &pkt);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1304 rep = talloc_zero(call, struct data_blob_list_item);
1306 return NT_STATUS_NO_MEMORY;
1309 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1310 if (!NT_STATUS_IS_OK(status)) {
1314 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1316 DLIST_ADD_END(call->replies, rep);
1317 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1319 if (call->conn->call_list && call->conn->call_list->replies) {
1320 if (call->conn->transport.report_output_data) {
1321 call->conn->transport.report_output_data(call->conn);
1325 return NT_STATUS_OK;
1329 possibly save the call for inspection with ndrdump
1331 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1335 const char *dump_dir;
1336 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1340 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1342 call->context->iface->name,
1343 call->pkt.u.request.opnum,
1345 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1346 DEBUG(0,("RPC SAVED %s\n", fname));
1352 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1354 TALLOC_CTX *frame = talloc_stackframe();
1355 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1356 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1357 const struct dcerpc_sec_vt_pcontext pcontext = {
1358 .abstract_syntax = call->context->iface->syntax_id,
1359 .transfer_syntax = call->context->transfer_syntax,
1361 const struct dcerpc_sec_vt_header2 header2 =
1362 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1363 enum ndr_err_code ndr_err;
1364 struct dcerpc_sec_verification_trailer *vt = NULL;
1365 NTSTATUS status = NT_STATUS_OK;
1368 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1370 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1372 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1373 status = ndr_map_error2ntstatus(ndr_err);
1377 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1378 &pcontext, &header2);
1380 status = NT_STATUS_ACCESS_DENIED;
1389 handle a dcerpc request packet
1391 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1393 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1394 enum dcerpc_transport_t transport =
1395 dcerpc_binding_get_transport(endpoint->ep_description);
1396 struct ndr_pull *pull;
1399 if (!call->conn->allow_request) {
1400 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1403 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1404 if (call->conn->auth_state.gensec_security &&
1405 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1406 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1409 if (call->context == NULL) {
1410 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1411 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1414 switch (call->conn->auth_state.auth_level) {
1415 case DCERPC_AUTH_LEVEL_NONE:
1416 case DCERPC_AUTH_LEVEL_PACKET:
1417 case DCERPC_AUTH_LEVEL_INTEGRITY:
1418 case DCERPC_AUTH_LEVEL_PRIVACY:
1421 if (!call->context->allow_connect) {
1424 addr = tsocket_address_string(call->conn->remote_address,
1427 DEBUG(2, ("%s: restrict auth_level_connect access "
1428 "to [%s] with auth[type=0x%x,level=0x%x] "
1429 "on [%s] from [%s]\n",
1430 __func__, call->context->iface->name,
1431 call->conn->auth_state.auth_type,
1432 call->conn->auth_state.auth_level,
1433 derpc_transport_string_by_transport(transport),
1435 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1440 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1443 addr = tsocket_address_string(call->conn->remote_address, call);
1445 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1446 "to [%s] with auth[type=0x%x,level=0x%x] "
1447 "on [%s] from [%s]\n",
1449 call->context->min_auth_level,
1450 call->context->iface->name,
1451 call->conn->auth_state.auth_type,
1452 call->conn->auth_state.auth_level,
1453 derpc_transport_string_by_transport(transport),
1455 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1458 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1459 NT_STATUS_HAVE_NO_MEMORY(pull);
1461 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1463 call->ndr_pull = pull;
1465 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1466 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1469 status = dcesrv_check_verification_trailer(call);
1470 if (!NT_STATUS_IS_OK(status)) {
1471 uint32_t faultcode = DCERPC_FAULT_OTHER;
1472 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1473 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1475 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1476 nt_errstr(status)));
1477 return dcesrv_fault(call, faultcode);
1480 /* unravel the NDR for the packet */
1481 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 uint8_t extra_flags = 0;
1484 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1485 /* we got an unknown call */
1486 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1487 call->pkt.u.request.opnum,
1488 call->context->iface->name));
1489 dcesrv_save_call(call, "unknown");
1490 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1492 dcesrv_save_call(call, "pullfail");
1494 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1497 if (pull->offset != pull->data_size) {
1498 dcesrv_save_call(call, "extrabytes");
1499 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1500 pull->data_size - pull->offset));
1503 /* call the dispatch function */
1504 status = call->context->iface->dispatch(call, call, call->r);
1505 if (!NT_STATUS_IS_OK(status)) {
1506 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1507 call->context->iface->name,
1508 call->pkt.u.request.opnum,
1509 dcerpc_errstr(pull, call->fault_code)));
1510 return dcesrv_fault(call, call->fault_code);
1513 /* add the call to the pending list */
1514 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1516 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1517 return NT_STATUS_OK;
1520 return dcesrv_reply(call);
1525 remove the call from the right list when freed
1527 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1529 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1533 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1535 return conn->local_address;
1538 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1540 return conn->remote_address;
1544 process some input to a dcerpc endpoint server.
1546 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1547 struct ncacn_packet *pkt,
1551 struct dcesrv_call_state *call;
1552 struct dcesrv_call_state *existing = NULL;
1554 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1556 data_blob_free(&blob);
1558 return NT_STATUS_NO_MEMORY;
1560 call->conn = dce_conn;
1561 call->event_ctx = dce_conn->event_ctx;
1562 call->msg_ctx = dce_conn->msg_ctx;
1563 call->state_flags = call->conn->state_flags;
1564 call->time = timeval_current();
1565 call->list = DCESRV_LIST_NONE;
1567 talloc_steal(call, pkt);
1568 talloc_steal(call, blob.data);
1571 talloc_set_destructor(call, dcesrv_call_dequeue);
1573 if (call->conn->allow_bind) {
1575 * Only one bind is possible per connection
1577 call->conn->allow_bind = false;
1578 return dcesrv_bind(call);
1581 /* we have to check the signing here, before combining the
1583 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1584 if (!call->conn->allow_request) {
1585 return dcesrv_fault_disconnect(call,
1586 DCERPC_NCA_S_PROTO_ERROR);
1589 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1591 call->pkt.u.request.stub_and_verifier.length,
1592 0, /* required_flags */
1593 DCERPC_PFC_FLAG_FIRST |
1594 DCERPC_PFC_FLAG_LAST |
1595 DCERPC_PFC_FLAG_PENDING_CANCEL |
1596 0x08 | /* this is not defined, but should be ignored */
1597 DCERPC_PFC_FLAG_CONC_MPX |
1598 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1599 DCERPC_PFC_FLAG_MAYBE |
1600 DCERPC_PFC_FLAG_OBJECT_UUID);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 return dcesrv_fault_disconnect(call,
1603 DCERPC_NCA_S_PROTO_ERROR);
1606 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1608 * We don't use dcesrv_fault_disconnect()
1609 * here, because we don't want to set
1610 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1612 * Note that we don't check against the negotiated
1613 * max_recv_frag, but a hard coded value.
1615 dcesrv_call_disconnect_after(call,
1616 "dcesrv_auth_request - frag_length too large");
1617 return dcesrv_fault(call,
1618 DCERPC_NCA_S_PROTO_ERROR);
1621 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1622 if (dce_conn->pending_call_list != NULL) {
1624 * concurrent requests are only allowed
1625 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1627 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1628 dcesrv_call_disconnect_after(call,
1629 "dcesrv_auth_request - "
1630 "existing pending call without CONN_MPX");
1631 return dcesrv_fault(call,
1632 DCERPC_NCA_S_PROTO_ERROR);
1635 /* only one request is possible in the fragmented list */
1636 if (dce_conn->incoming_fragmented_call_list != NULL) {
1637 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1639 * Without DCERPC_PFC_FLAG_CONC_MPX
1640 * we need to return the FAULT on the
1641 * already existing call.
1643 * This is important to get the
1644 * call_id and context_id right.
1647 call = dce_conn->incoming_fragmented_call_list;
1649 dcesrv_call_disconnect_after(call,
1650 "dcesrv_auth_request - "
1651 "existing fragmented call");
1652 return dcesrv_fault(call,
1653 DCERPC_NCA_S_PROTO_ERROR);
1655 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1656 return dcesrv_fault_disconnect(call,
1657 DCERPC_FAULT_NO_CALL_ACTIVE);
1659 call->context = dcesrv_find_context(call->conn,
1660 call->pkt.u.request.context_id);
1661 if (call->context == NULL) {
1662 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1663 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1666 const struct dcerpc_request *nr = &call->pkt.u.request;
1667 const struct dcerpc_request *er = NULL;
1670 existing = dcesrv_find_fragmented_call(dce_conn,
1672 if (existing == NULL) {
1673 dcesrv_call_disconnect_after(call,
1674 "dcesrv_auth_request - "
1675 "no existing fragmented call");
1676 return dcesrv_fault(call,
1677 DCERPC_NCA_S_PROTO_ERROR);
1679 er = &existing->pkt.u.request;
1681 if (call->pkt.ptype != existing->pkt.ptype) {
1682 /* trying to play silly buggers are we? */
1683 return dcesrv_fault_disconnect(existing,
1684 DCERPC_NCA_S_PROTO_ERROR);
1686 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1689 return dcesrv_fault_disconnect(existing,
1690 DCERPC_NCA_S_PROTO_ERROR);
1692 if (nr->context_id != er->context_id) {
1693 return dcesrv_fault_disconnect(existing,
1694 DCERPC_NCA_S_PROTO_ERROR);
1696 if (nr->opnum != er->opnum) {
1697 return dcesrv_fault_disconnect(existing,
1698 DCERPC_NCA_S_PROTO_ERROR);
1703 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1705 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1707 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1708 payload_offset += 16;
1711 ok = dcesrv_auth_pkt_pull(call, &blob,
1712 0, /* required_flags */
1713 DCERPC_PFC_FLAG_FIRST |
1714 DCERPC_PFC_FLAG_LAST |
1715 DCERPC_PFC_FLAG_PENDING_CANCEL |
1716 0x08 | /* this is not defined, but should be ignored */
1717 DCERPC_PFC_FLAG_CONC_MPX |
1718 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1719 DCERPC_PFC_FLAG_MAYBE |
1720 DCERPC_PFC_FLAG_OBJECT_UUID,
1722 &call->pkt.u.request.stub_and_verifier);
1725 * We don't use dcesrv_fault_disconnect()
1726 * here, because we don't want to set
1727 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1729 dcesrv_call_disconnect_after(call,
1730 "dcesrv_auth_request - failed");
1731 if (call->fault_code == 0) {
1732 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1734 return dcesrv_fault(call, call->fault_code);
1738 /* see if this is a continued packet */
1739 if (existing != NULL) {
1740 struct dcerpc_request *er = &existing->pkt.u.request;
1741 const struct dcerpc_request *nr = &call->pkt.u.request;
1747 * Up to 4 MByte are allowed by all fragments
1749 available = dce_conn->max_total_request_size;
1750 if (er->stub_and_verifier.length > available) {
1751 dcesrv_call_disconnect_after(existing,
1752 "dcesrv_auth_request - existing payload too large");
1753 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1755 available -= er->stub_and_verifier.length;
1756 if (nr->alloc_hint > available) {
1757 dcesrv_call_disconnect_after(existing,
1758 "dcesrv_auth_request - alloc hint too large");
1759 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1761 if (nr->stub_and_verifier.length > available) {
1762 dcesrv_call_disconnect_after(existing,
1763 "dcesrv_auth_request - new payload too large");
1764 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1766 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1767 /* allocate at least 1 byte */
1768 alloc_hint = MAX(alloc_hint, 1);
1769 alloc_size = er->stub_and_verifier.length +
1770 nr->stub_and_verifier.length;
1771 alloc_size = MAX(alloc_size, alloc_hint);
1773 er->stub_and_verifier.data =
1774 talloc_realloc(existing,
1775 er->stub_and_verifier.data,
1776 uint8_t, alloc_size);
1777 if (er->stub_and_verifier.data == NULL) {
1779 return dcesrv_fault_with_flags(existing,
1780 DCERPC_FAULT_OUT_OF_RESOURCES,
1781 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1783 memcpy(er->stub_and_verifier.data +
1784 er->stub_and_verifier.length,
1785 nr->stub_and_verifier.data,
1786 nr->stub_and_verifier.length);
1787 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1789 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1795 /* this may not be the last pdu in the chain - if its isn't then
1796 just put it on the incoming_fragmented_call_list and wait for the rest */
1797 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1798 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1800 * Up to 4 MByte are allowed by all fragments
1802 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1803 dcesrv_call_disconnect_after(call,
1804 "dcesrv_auth_request - initial alloc hint too large");
1805 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1807 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1808 return NT_STATUS_OK;
1811 /* This removes any fragments we may have had stashed away */
1812 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1814 switch (call->pkt.ptype) {
1815 case DCERPC_PKT_BIND:
1816 status = dcesrv_bind_nak(call,
1817 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1819 case DCERPC_PKT_AUTH3:
1820 status = dcesrv_auth3(call);
1822 case DCERPC_PKT_ALTER:
1823 status = dcesrv_alter(call);
1825 case DCERPC_PKT_REQUEST:
1826 status = dcesrv_request(call);
1828 case DCERPC_PKT_CO_CANCEL:
1829 case DCERPC_PKT_ORPHANED:
1831 * Window just ignores CO_CANCEL and ORPHANED,
1834 status = NT_STATUS_OK;
1837 case DCERPC_PKT_BIND_ACK:
1838 case DCERPC_PKT_BIND_NAK:
1839 case DCERPC_PKT_ALTER_RESP:
1840 case DCERPC_PKT_RESPONSE:
1841 case DCERPC_PKT_FAULT:
1842 case DCERPC_PKT_SHUTDOWN:
1844 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1848 /* if we are going to be sending a reply then add
1849 it to the list of pending calls. We add it to the end to keep the call
1850 list in the order we will answer */
1851 if (!NT_STATUS_IS_OK(status)) {
1858 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1859 struct loadparm_context *lp_ctx,
1860 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1863 struct dcesrv_context *dce_ctx;
1866 if (!endpoint_servers) {
1867 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1868 return NT_STATUS_INTERNAL_ERROR;
1871 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1872 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1874 if (uid_wrapper_enabled()) {
1875 setenv("UID_WRAPPER_MYUID", "1", 1);
1877 dce_ctx->initial_euid = geteuid();
1878 if (uid_wrapper_enabled()) {
1879 unsetenv("UID_WRAPPER_MYUID");
1882 dce_ctx->endpoint_list = NULL;
1883 dce_ctx->lp_ctx = lp_ctx;
1884 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1885 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1886 dce_ctx->broken_connections = NULL;
1888 for (i=0;endpoint_servers[i];i++) {
1889 const struct dcesrv_endpoint_server *ep_server;
1891 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1893 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1894 return NT_STATUS_INTERNAL_ERROR;
1897 status = ep_server->init_server(dce_ctx, ep_server);
1898 if (!NT_STATUS_IS_OK(status)) {
1899 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1900 nt_errstr(status)));
1905 *_dce_ctx = dce_ctx;
1906 return NT_STATUS_OK;
1909 /* the list of currently registered DCERPC endpoint servers.
1911 static struct ep_server {
1912 struct dcesrv_endpoint_server *ep_server;
1913 } *ep_servers = NULL;
1914 static int num_ep_servers;
1917 register a DCERPC endpoint server.
1919 The 'name' can be later used by other backends to find the operations
1920 structure for this backend.
1923 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
1926 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1927 /* its already registered! */
1928 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1930 return NT_STATUS_OBJECT_NAME_COLLISION;
1933 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1935 smb_panic("out of memory in dcerpc_register");
1938 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1939 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1943 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1946 return NT_STATUS_OK;
1950 return the operations structure for a named backend of the specified type
1952 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1956 for (i=0;i<num_ep_servers;i++) {
1957 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1958 return ep_servers[i].ep_server;
1965 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1967 static bool initialized;
1968 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1969 STATIC_dcerpc_server_MODULES_PROTO;
1970 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1971 init_module_fn *shared_init;
1978 shared_init = load_samba_modules(NULL, "dcerpc_server");
1980 run_init_functions(static_init);
1981 run_init_functions(shared_init);
1983 talloc_free(shared_init);
1987 return the DCERPC module version, and the size of some critical types
1988 This can be used by endpoint server modules to either detect compilation errors, or provide
1989 multiple implementations for different smbd compilation options in one module
1991 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1993 static const struct dcesrv_critical_sizes critical_sizes = {
1994 DCERPC_MODULE_VERSION,
1995 sizeof(struct dcesrv_context),
1996 sizeof(struct dcesrv_endpoint),
1997 sizeof(struct dcesrv_endpoint_server),
1998 sizeof(struct dcesrv_interface),
1999 sizeof(struct dcesrv_if_list),
2000 sizeof(struct dcesrv_connection),
2001 sizeof(struct dcesrv_call_state),
2002 sizeof(struct dcesrv_auth),
2003 sizeof(struct dcesrv_handle)
2006 return &critical_sizes;
2009 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2011 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2012 struct stream_connection *srv_conn;
2013 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2014 struct stream_connection);
2016 dce_conn->allow_bind = false;
2017 dce_conn->allow_auth3 = false;
2018 dce_conn->allow_alter = false;
2019 dce_conn->allow_request = false;
2021 if (dce_conn->pending_call_list == NULL) {
2022 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2024 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2025 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2029 if (dce_conn->terminate != NULL) {
2033 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2035 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2036 if (dce_conn->terminate == NULL) {
2037 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2039 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2042 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2044 struct dcesrv_connection *cur, *next;
2046 next = dce_ctx->broken_connections;
2047 while (next != NULL) {
2051 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2052 struct dcesrv_connection_context *context_cur, *context_next;
2054 context_next = cur->contexts;
2055 while (context_next != NULL) {
2056 context_cur = context_next;
2057 context_next = context_cur->next;
2059 dcesrv_connection_context_destructor(context_cur);
2063 dcesrv_terminate_connection(cur, cur->terminate);
2067 /* We need this include to be able to compile on some plateforms
2068 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2070 * It has to be that deep because otherwise we have a conflict on
2071 * const struct dcesrv_interface declaration.
2072 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2073 * which conflict with the bind used before.
2075 #include "system/network.h"
2077 struct dcesrv_sock_reply_state {
2078 struct dcesrv_connection *dce_conn;
2079 struct dcesrv_call_state *call;
2083 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2084 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2086 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2088 struct dcesrv_call_state *call;
2090 call = dce_conn->call_list;
2091 if (!call || !call->replies) {
2095 while (call->replies) {
2096 struct data_blob_list_item *rep = call->replies;
2097 struct dcesrv_sock_reply_state *substate;
2098 struct tevent_req *subreq;
2100 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2102 dcesrv_terminate_connection(dce_conn, "no memory");
2106 substate->dce_conn = dce_conn;
2107 substate->call = NULL;
2109 DLIST_REMOVE(call->replies, rep);
2111 if (call->replies == NULL && call->terminate_reason == NULL) {
2112 substate->call = call;
2115 substate->iov.iov_base = (void *) rep->blob.data;
2116 substate->iov.iov_len = rep->blob.length;
2118 subreq = tstream_writev_queue_send(substate,
2119 dce_conn->event_ctx,
2121 dce_conn->send_queue,
2124 dcesrv_terminate_connection(dce_conn, "no memory");
2127 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2131 if (call->terminate_reason != NULL) {
2132 struct tevent_req *subreq;
2134 subreq = tevent_queue_wait_send(call,
2135 dce_conn->event_ctx,
2136 dce_conn->send_queue);
2138 dcesrv_terminate_connection(dce_conn, __location__);
2141 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2145 DLIST_REMOVE(call->conn->call_list, call);
2146 call->list = DCESRV_LIST_NONE;
2149 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2151 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2152 struct dcesrv_sock_reply_state);
2156 struct dcesrv_call_state *call = substate->call;
2158 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2159 TALLOC_FREE(subreq);
2161 status = map_nt_error_from_unix_common(sys_errno);
2162 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2166 talloc_free(substate);
2172 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2174 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2176 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2177 struct dcesrv_call_state);
2181 /* make sure we stop send queue before removing subreq */
2182 tevent_queue_stop(call->conn->send_queue);
2184 ok = tevent_queue_wait_recv(subreq);
2185 TALLOC_FREE(subreq);
2187 dcesrv_terminate_connection(call->conn, __location__);
2191 /* disconnect after 200 usecs */
2192 tv = timeval_current_ofs_usec(200);
2193 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2194 if (subreq == NULL) {
2195 dcesrv_terminate_connection(call->conn, __location__);
2198 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2202 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2204 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2205 struct dcesrv_call_state);
2208 ok = tevent_wakeup_recv(subreq);
2209 TALLOC_FREE(subreq);
2211 dcesrv_terminate_connection(call->conn, __location__);
2215 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2218 struct dcesrv_socket_context {
2219 const struct dcesrv_endpoint *endpoint;
2220 struct dcesrv_context *dcesrv_ctx;
2224 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2226 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2229 struct dcesrv_socket_context *dcesrv_sock =
2230 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2231 enum dcerpc_transport_t transport =
2232 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2233 struct dcesrv_connection *dcesrv_conn = NULL;
2235 struct tevent_req *subreq;
2236 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2238 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2240 if (!srv_conn->session_info) {
2241 status = auth_anonymous_session_info(srv_conn,
2243 &srv_conn->session_info);
2244 if (!NT_STATUS_IS_OK(status)) {
2245 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2246 nt_errstr(status)));
2247 stream_terminate_connection(srv_conn, nt_errstr(status));
2252 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2254 dcesrv_sock->endpoint,
2255 srv_conn->session_info,
2256 srv_conn->event.ctx,
2258 srv_conn->server_id,
2259 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2261 if (!NT_STATUS_IS_OK(status)) {
2262 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2263 nt_errstr(status)));
2264 stream_terminate_connection(srv_conn, nt_errstr(status));
2268 dcesrv_conn->transport.private_data = srv_conn;
2269 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2271 TALLOC_FREE(srv_conn->event.fde);
2273 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2274 if (!dcesrv_conn->send_queue) {
2275 status = NT_STATUS_NO_MEMORY;
2276 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2277 nt_errstr(status)));
2278 stream_terminate_connection(srv_conn, nt_errstr(status));
2282 if (transport == NCACN_NP) {
2283 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2284 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2285 &srv_conn->tstream);
2287 ret = tstream_bsd_existing_socket(dcesrv_conn,
2288 socket_get_fd(srv_conn->socket),
2289 &dcesrv_conn->stream);
2291 status = map_nt_error_from_unix_common(errno);
2292 DEBUG(0, ("dcesrv_sock_accept: "
2293 "failed to setup tstream: %s\n",
2294 nt_errstr(status)));
2295 stream_terminate_connection(srv_conn, nt_errstr(status));
2298 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2301 dcesrv_conn->local_address = srv_conn->local_address;
2302 dcesrv_conn->remote_address = srv_conn->remote_address;
2304 if (transport == NCALRPC) {
2309 sock_fd = socket_get_fd(srv_conn->socket);
2310 if (sock_fd == -1) {
2311 stream_terminate_connection(
2312 srv_conn, "socket_get_fd failed\n");
2316 ret = getpeereid(sock_fd, &uid, &gid);
2318 status = map_nt_error_from_unix_common(errno);
2319 DEBUG(0, ("dcesrv_sock_accept: "
2320 "getpeereid() failed for NCALRPC: %s\n",
2321 nt_errstr(status)));
2322 stream_terminate_connection(srv_conn, nt_errstr(status));
2325 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2326 struct tsocket_address *r = NULL;
2328 ret = tsocket_address_unix_from_path(dcesrv_conn,
2329 "/root/ncalrpc_as_system",
2332 status = map_nt_error_from_unix_common(errno);
2333 DEBUG(0, ("dcesrv_sock_accept: "
2334 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2335 nt_errstr(status)));
2336 stream_terminate_connection(srv_conn, nt_errstr(status));
2339 dcesrv_conn->remote_address = r;
2343 srv_conn->private_data = dcesrv_conn;
2345 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2347 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2348 dcesrv_conn->event_ctx,
2349 dcesrv_conn->stream);
2351 status = NT_STATUS_NO_MEMORY;
2352 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2353 nt_errstr(status)));
2354 stream_terminate_connection(srv_conn, nt_errstr(status));
2357 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2362 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2364 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2365 struct dcesrv_connection);
2366 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2367 struct ncacn_packet *pkt;
2371 if (dce_conn->terminate) {
2373 * if the current connection is broken
2374 * we need to clean it up before any other connection
2376 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2377 dcesrv_cleanup_broken_connections(dce_ctx);
2381 dcesrv_cleanup_broken_connections(dce_ctx);
2383 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2385 TALLOC_FREE(subreq);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2391 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2397 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2398 dce_conn->event_ctx,
2401 status = NT_STATUS_NO_MEMORY;
2402 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2405 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2408 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2410 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2411 struct dcesrv_connection);
2412 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2415 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2417 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2418 struct dcesrv_connection);
2419 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2423 static const struct stream_server_ops dcesrv_stream_ops = {
2425 .accept_connection = dcesrv_sock_accept,
2426 .recv_handler = dcesrv_sock_recv,
2427 .send_handler = dcesrv_sock_send,
2430 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2431 struct loadparm_context *lp_ctx,
2432 struct dcesrv_endpoint *e,
2433 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2435 struct dcesrv_socket_context *dcesrv_sock;
2438 const char *endpoint;
2440 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2441 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2443 /* remember the endpoint of this socket */
2444 dcesrv_sock->endpoint = e;
2445 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2447 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2449 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2450 model_ops, &dcesrv_stream_ops,
2451 "unix", endpoint, &port,
2452 lpcfg_socket_options(lp_ctx),
2454 if (!NT_STATUS_IS_OK(status)) {
2455 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2456 endpoint, nt_errstr(status)));
2462 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2463 struct loadparm_context *lp_ctx,
2464 struct dcesrv_endpoint *e,
2465 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2467 struct dcesrv_socket_context *dcesrv_sock;
2471 const char *endpoint;
2473 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2475 if (endpoint == NULL) {
2477 * No identifier specified: use DEFAULT.
2479 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2480 * no endpoint and let the epmapper worry about it.
2482 endpoint = "DEFAULT";
2483 status = dcerpc_binding_set_string_option(e->ep_description,
2486 if (!NT_STATUS_IS_OK(status)) {
2487 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2488 nt_errstr(status)));
2493 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2496 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2497 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2499 /* remember the endpoint of this socket */
2500 dcesrv_sock->endpoint = e;
2501 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2503 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2504 model_ops, &dcesrv_stream_ops,
2505 "unix", full_path, &port,
2506 lpcfg_socket_options(lp_ctx),
2508 if (!NT_STATUS_IS_OK(status)) {
2509 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2510 endpoint, full_path, nt_errstr(status)));
2515 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2516 struct loadparm_context *lp_ctx,
2517 struct dcesrv_endpoint *e,
2518 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2520 struct dcesrv_socket_context *dcesrv_sock;
2522 const char *endpoint;
2524 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2525 if (endpoint == NULL) {
2526 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2527 return NT_STATUS_INVALID_PARAMETER;
2530 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2531 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2533 /* remember the endpoint of this socket */
2534 dcesrv_sock->endpoint = e;
2535 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2537 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2538 model_ops, &dcesrv_stream_ops,
2541 if (!NT_STATUS_IS_OK(status)) {
2542 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2543 endpoint, nt_errstr(status)));
2547 return NT_STATUS_OK;
2551 add a socket address to the list of events, one event per dcerpc endpoint
2553 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2554 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2555 const char *address)
2557 struct dcesrv_socket_context *dcesrv_sock;
2560 const char *endpoint;
2563 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2564 if (endpoint != NULL) {
2565 port = atoi(endpoint);
2568 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2569 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2571 /* remember the endpoint of this socket */
2572 dcesrv_sock->endpoint = e;
2573 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2575 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2576 model_ops, &dcesrv_stream_ops,
2577 "ip", address, &port,
2578 lpcfg_socket_options(dce_ctx->lp_ctx),
2580 if (!NT_STATUS_IS_OK(status)) {
2581 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2582 address, port, nt_errstr(status)));
2586 snprintf(port_str, sizeof(port_str), "%u", port);
2588 status = dcerpc_binding_set_string_option(e->ep_description,
2589 "endpoint", port_str);
2590 if (!NT_STATUS_IS_OK(status)) {
2591 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2592 port_str, nt_errstr(status)));
2595 struct dcesrv_if_list *iface;
2596 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2597 address, port_str));
2598 for (iface = e->interface_list; iface; iface = iface->next) {
2599 DEBUGADD(4, ("%s ", iface->iface.name));
2601 DEBUGADD(4, ("\n"));
2604 return NT_STATUS_OK;
2607 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2609 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2610 struct loadparm_context *lp_ctx,
2611 struct dcesrv_endpoint *e,
2612 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2616 /* Add TCP/IP sockets */
2617 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2620 struct interface *ifaces;
2622 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2624 num_interfaces = iface_list_count(ifaces);
2625 for(i = 0; i < num_interfaces; i++) {
2626 const char *address = iface_list_n_ip(ifaces, i);
2627 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2628 NT_STATUS_NOT_OK_RETURN(status);
2634 wcard = iface_list_wildcard(dce_ctx);
2635 NT_STATUS_HAVE_NO_MEMORY(wcard);
2636 for (i=0; wcard[i]; i++) {
2637 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2638 if (NT_STATUS_IS_OK(status)) {
2643 if (num_binds == 0) {
2644 return NT_STATUS_INVALID_PARAMETER_MIX;
2648 return NT_STATUS_OK;
2651 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2652 struct loadparm_context *lp_ctx,
2653 struct dcesrv_endpoint *e,
2654 struct tevent_context *event_ctx,
2655 const struct model_ops *model_ops)
2657 enum dcerpc_transport_t transport =
2658 dcerpc_binding_get_transport(e->ep_description);
2660 switch (transport) {
2661 case NCACN_UNIX_STREAM:
2662 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2665 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2668 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2671 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2674 return NT_STATUS_NOT_SUPPORTED;
2680 * retrieve credentials from a dce_call
2682 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2684 return dce_call->conn->auth_state.session_info->credentials;
2688 * returns true if this is an authenticated call
2690 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2692 enum security_user_level level;
2693 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2694 return level >= SECURITY_USER;
2698 * retrieve account_name for a dce_call
2700 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2702 return dce_call->context->conn->auth_state.session_info->info->account_name;