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 /* not supported yet */
792 call->conn->bind_time_features = a->reason.negotiate;
796 * Try to negotiate one new presentation context.
798 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
799 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
800 return dcesrv_bind_nak(call, 0);
802 if (!NT_STATUS_IS_OK(status)) {
806 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
807 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
808 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
809 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
812 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
813 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
816 /* handle any authentication that is being requested */
817 if (!dcesrv_auth_bind(call)) {
818 struct dcesrv_auth *auth = &call->conn->auth_state;
820 TALLOC_FREE(call->context);
822 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
824 * With DCERPC_AUTH_LEVEL_NONE, we get the
825 * reject_reason in auth->auth_context_id.
827 return dcesrv_bind_nak(call, auth->auth_context_id);
831 * This must a be a temporary failure e.g. talloc or invalid
832 * configuration, e.g. no machine account.
834 return dcesrv_bind_nak(call,
835 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
838 /* setup a bind_ack */
839 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
841 pkt.call_id = call->pkt.call_id;
842 pkt.ptype = DCERPC_PKT_BIND_ACK;
843 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
844 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
845 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
846 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
848 endpoint = dcerpc_binding_get_string_option(
849 call->conn->endpoint->ep_description,
851 if (endpoint == NULL) {
855 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
857 * TODO: check if this is really needed
859 * Or if we should fix this in our idl files.
861 ep_prefix = "\\PIPE\\";
865 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
868 if (pkt.u.bind_ack.secondary_address == NULL) {
869 TALLOC_FREE(call->context);
870 return NT_STATUS_NO_MEMORY;
872 pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
873 pkt.u.bind_ack.ctx_list = ack_ctx_list;
874 pkt.u.bind_ack.auth_info = data_blob_null;
876 status = dcesrv_auth_bind_ack(call, &pkt);
877 if (!NT_STATUS_IS_OK(status)) {
878 TALLOC_FREE(call->context);
879 return dcesrv_bind_nak(call, 0);
882 rep = talloc_zero(call, struct data_blob_list_item);
884 TALLOC_FREE(call->context);
885 return NT_STATUS_NO_MEMORY;
888 status = ncacn_push_auth(&rep->blob, call, &pkt,
889 call->out_auth_info);
890 if (!NT_STATUS_IS_OK(status)) {
891 TALLOC_FREE(call->context);
895 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
897 DLIST_ADD_END(call->replies, rep);
898 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
900 if (call->conn->call_list && call->conn->call_list->replies) {
901 if (call->conn->transport.report_output_data) {
902 call->conn->transport.report_output_data(call->conn);
911 handle a auth3 request
913 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
917 if (!call->conn->allow_auth3) {
918 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
921 if (call->conn->auth_state.auth_finished) {
922 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
925 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
927 call->pkt.u.auth3.auth_info.length,
928 0, /* required flags */
929 DCERPC_PFC_FLAG_FIRST |
930 DCERPC_PFC_FLAG_LAST |
931 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
932 0x08 | /* this is not defined, but should be ignored */
933 DCERPC_PFC_FLAG_CONC_MPX |
934 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
935 DCERPC_PFC_FLAG_MAYBE |
936 DCERPC_PFC_FLAG_OBJECT_UUID);
937 if (!NT_STATUS_IS_OK(status)) {
938 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
941 /* handle the auth3 in the auth code */
942 if (!dcesrv_auth_auth3(call)) {
943 call->conn->auth_state.auth_invalid = true;
944 if (call->fault_code != 0) {
945 return dcesrv_fault_disconnect(call, call->fault_code);
951 /* we don't send a reply to a auth3 request, except by a
957 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
958 const struct dcerpc_bind *b,
959 const struct dcerpc_ctx_list *ctx,
960 struct dcerpc_ack_ctx *ack,
962 const struct ndr_syntax_id *supported_transfer)
965 struct dcesrv_connection_context *context;
966 const struct dcesrv_interface *iface;
969 const struct ndr_syntax_id *selected_transfer = NULL;
974 return NT_STATUS_INTERNAL_ERROR;
977 return NT_STATUS_INTERNAL_ERROR;
979 if (ctx->num_transfer_syntaxes < 1) {
980 return NT_STATUS_INTERNAL_ERROR;
983 return NT_STATUS_INTERNAL_ERROR;
985 if (supported_transfer == NULL) {
986 return NT_STATUS_INTERNAL_ERROR;
989 switch (ack->result) {
990 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
991 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
993 * We is already completed.
1000 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1001 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1003 if_version = ctx->abstract_syntax.if_version;
1004 uuid = ctx->abstract_syntax.uuid;
1006 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1007 if (iface == NULL) {
1008 char *uuid_str = GUID_string(call, &uuid);
1009 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1010 talloc_free(uuid_str);
1012 * We report this only via ack->result
1014 return NT_STATUS_OK;
1017 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1018 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1020 if (validate_only) {
1022 * We report this only via ack->result
1024 return NT_STATUS_OK;
1027 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1029 * we only do NDR encoded dcerpc for now.
1031 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1032 supported_transfer);
1034 selected_transfer = supported_transfer;
1039 context = dcesrv_find_context(call->conn, ctx->context_id);
1040 if (context != NULL) {
1041 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1042 &ctx->abstract_syntax);
1044 return NT_STATUS_RPC_PROTOCOL_ERROR;
1047 if (selected_transfer != NULL) {
1048 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1051 return NT_STATUS_RPC_PROTOCOL_ERROR;
1054 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1055 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1056 ack->syntax = context->transfer_syntax;
1060 * We report this only via ack->result
1062 return NT_STATUS_OK;
1065 if (selected_transfer == NULL) {
1067 * We report this only via ack->result
1069 return NT_STATUS_OK;
1072 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1073 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1075 /* add this context to the list of available context_ids */
1076 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1077 if (context == NULL) {
1078 return NT_STATUS_NO_MEMORY;
1080 context->conn = call->conn;
1081 context->context_id = ctx->context_id;
1082 context->iface = iface;
1083 context->transfer_syntax = *selected_transfer;
1084 context->private_data = NULL;
1085 DLIST_ADD(call->conn->contexts, context);
1086 call->context = context;
1087 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1089 dcesrv_prepare_context_auth(call);
1091 status = iface->bind(call, iface, if_version);
1092 call->context = NULL;
1093 if (!NT_STATUS_IS_OK(status)) {
1094 /* we don't want to trigger the iface->unbind() hook */
1095 context->iface = NULL;
1096 talloc_free(context);
1098 * We report this only via ack->result
1100 return NT_STATUS_OK;
1103 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1104 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1105 ack->syntax = context->transfer_syntax;
1106 return NT_STATUS_OK;
1109 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1110 const struct dcerpc_bind *b,
1111 struct dcerpc_ack_ctx *ack_ctx_list)
1115 bool validate_only = false;
1116 bool preferred_ndr32;
1119 * Try to negotiate one new presentation context,
1120 * using our preferred transfer syntax.
1122 for (i = 0; i < b->num_contexts; i++) {
1123 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1124 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1126 status = dcesrv_check_or_create_context(call, b, c, a,
1128 call->conn->preferred_transfer);
1129 if (!NT_STATUS_IS_OK(status)) {
1133 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1135 * We managed to negotiate one context.
1139 validate_only = true;
1143 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1144 call->conn->preferred_transfer);
1145 if (preferred_ndr32) {
1149 return NT_STATUS_OK;
1153 * Try to negotiate one new presentation context,
1154 * using NDR 32 as fallback.
1156 for (i = 0; i < b->num_contexts; i++) {
1157 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1158 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1160 status = dcesrv_check_or_create_context(call, b, c, a,
1162 &ndr_transfer_syntax_ndr);
1163 if (!NT_STATUS_IS_OK(status)) {
1167 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1169 * We managed to negotiate one context.
1173 validate_only = true;
1177 return NT_STATUS_OK;
1181 handle a alter context request
1183 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1186 bool auth_ok = false;
1187 struct ncacn_packet pkt;
1188 uint32_t extra_flags = 0;
1189 struct data_blob_list_item *rep = NULL;
1190 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1193 if (!call->conn->allow_alter) {
1194 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1197 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1199 call->pkt.u.alter.auth_info.length,
1200 0, /* required flags */
1201 DCERPC_PFC_FLAG_FIRST |
1202 DCERPC_PFC_FLAG_LAST |
1203 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1204 0x08 | /* this is not defined, but should be ignored */
1205 DCERPC_PFC_FLAG_CONC_MPX |
1206 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1207 DCERPC_PFC_FLAG_MAYBE |
1208 DCERPC_PFC_FLAG_OBJECT_UUID);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1213 auth_ok = dcesrv_auth_alter(call);
1215 if (call->fault_code != 0) {
1216 return dcesrv_fault_disconnect(call, call->fault_code);
1220 if (call->pkt.u.alter.num_contexts < 1) {
1221 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1224 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1225 call->pkt.u.alter.num_contexts);
1226 if (ack_ctx_list == NULL) {
1227 return NT_STATUS_NO_MEMORY;
1231 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1232 * dcesrv_check_or_create_context()) and do some protocol validation
1233 * and set sane defaults.
1235 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1236 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1237 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1239 if (c->num_transfer_syntaxes == 0) {
1240 return dcesrv_fault_disconnect(call,
1241 DCERPC_NCA_S_PROTO_ERROR);
1244 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1245 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1249 * Try to negotiate one new presentation context.
1251 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1252 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1253 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1255 if (!NT_STATUS_IS_OK(status)) {
1259 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1260 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1261 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1262 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1265 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1266 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1269 /* handle any authentication that is being requested */
1271 if (call->in_auth_info.auth_type !=
1272 call->conn->auth_state.auth_type)
1274 return dcesrv_fault_disconnect(call,
1275 DCERPC_FAULT_SEC_PKG_ERROR);
1277 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1280 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1281 pkt.auth_length = 0;
1282 pkt.call_id = call->pkt.call_id;
1283 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1284 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1285 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1286 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1287 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1288 pkt.u.alter_resp.secondary_address = "";
1289 pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1290 pkt.u.alter_resp.ctx_list = ack_ctx_list;
1291 pkt.u.alter_resp.auth_info = data_blob_null;
1293 status = dcesrv_auth_alter_ack(call, &pkt);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1298 rep = talloc_zero(call, struct data_blob_list_item);
1300 return NT_STATUS_NO_MEMORY;
1303 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1304 if (!NT_STATUS_IS_OK(status)) {
1308 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1310 DLIST_ADD_END(call->replies, rep);
1311 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1313 if (call->conn->call_list && call->conn->call_list->replies) {
1314 if (call->conn->transport.report_output_data) {
1315 call->conn->transport.report_output_data(call->conn);
1319 return NT_STATUS_OK;
1323 possibly save the call for inspection with ndrdump
1325 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1329 const char *dump_dir;
1330 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1334 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1336 call->context->iface->name,
1337 call->pkt.u.request.opnum,
1339 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1340 DEBUG(0,("RPC SAVED %s\n", fname));
1346 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1348 TALLOC_CTX *frame = talloc_stackframe();
1349 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1350 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1351 const struct dcerpc_sec_vt_pcontext pcontext = {
1352 .abstract_syntax = call->context->iface->syntax_id,
1353 .transfer_syntax = call->context->transfer_syntax,
1355 const struct dcerpc_sec_vt_header2 header2 =
1356 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1357 enum ndr_err_code ndr_err;
1358 struct dcerpc_sec_verification_trailer *vt = NULL;
1359 NTSTATUS status = NT_STATUS_OK;
1362 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1364 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1366 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1367 status = ndr_map_error2ntstatus(ndr_err);
1371 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1372 &pcontext, &header2);
1374 status = NT_STATUS_ACCESS_DENIED;
1383 handle a dcerpc request packet
1385 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1387 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1388 enum dcerpc_transport_t transport =
1389 dcerpc_binding_get_transport(endpoint->ep_description);
1390 struct ndr_pull *pull;
1392 struct dcesrv_connection_context *context;
1394 if (!call->conn->allow_request) {
1395 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1398 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1399 if (call->conn->auth_state.gensec_security &&
1400 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1401 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1404 context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1405 if (context == NULL) {
1406 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1407 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1410 switch (call->conn->auth_state.auth_level) {
1411 case DCERPC_AUTH_LEVEL_NONE:
1412 case DCERPC_AUTH_LEVEL_PACKET:
1413 case DCERPC_AUTH_LEVEL_INTEGRITY:
1414 case DCERPC_AUTH_LEVEL_PRIVACY:
1417 if (!context->allow_connect) {
1420 addr = tsocket_address_string(call->conn->remote_address,
1423 DEBUG(2, ("%s: restrict auth_level_connect access "
1424 "to [%s] with auth[type=0x%x,level=0x%x] "
1425 "on [%s] from [%s]\n",
1426 __func__, context->iface->name,
1427 call->conn->auth_state.auth_type,
1428 call->conn->auth_state.auth_level,
1429 derpc_transport_string_by_transport(transport),
1431 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1436 if (call->conn->auth_state.auth_level < context->min_auth_level) {
1439 addr = tsocket_address_string(call->conn->remote_address, call);
1441 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1442 "to [%s] with auth[type=0x%x,level=0x%x] "
1443 "on [%s] from [%s]\n",
1445 context->min_auth_level,
1446 context->iface->name,
1447 call->conn->auth_state.auth_type,
1448 call->conn->auth_state.auth_level,
1449 derpc_transport_string_by_transport(transport),
1451 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1454 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1455 NT_STATUS_HAVE_NO_MEMORY(pull);
1457 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1459 call->context = context;
1460 call->ndr_pull = pull;
1462 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1463 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1466 status = dcesrv_check_verification_trailer(call);
1467 if (!NT_STATUS_IS_OK(status)) {
1468 uint32_t faultcode = DCERPC_FAULT_OTHER;
1469 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1470 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1472 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1473 nt_errstr(status)));
1474 return dcesrv_fault(call, faultcode);
1477 /* unravel the NDR for the packet */
1478 status = context->iface->ndr_pull(call, call, pull, &call->r);
1479 if (!NT_STATUS_IS_OK(status)) {
1480 uint8_t extra_flags = 0;
1481 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1482 /* we got an unknown call */
1483 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1484 call->pkt.u.request.opnum, context->iface->name));
1485 dcesrv_save_call(call, "unknown");
1486 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1488 dcesrv_save_call(call, "pullfail");
1490 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1493 if (pull->offset != pull->data_size) {
1494 dcesrv_save_call(call, "extrabytes");
1495 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1496 pull->data_size - pull->offset));
1499 /* call the dispatch function */
1500 status = context->iface->dispatch(call, call, call->r);
1501 if (!NT_STATUS_IS_OK(status)) {
1502 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1503 context->iface->name,
1504 call->pkt.u.request.opnum,
1505 dcerpc_errstr(pull, call->fault_code)));
1506 return dcesrv_fault(call, call->fault_code);
1509 /* add the call to the pending list */
1510 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1512 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1513 return NT_STATUS_OK;
1516 return dcesrv_reply(call);
1521 remove the call from the right list when freed
1523 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1525 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1529 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1531 return conn->local_address;
1534 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1536 return conn->remote_address;
1540 process some input to a dcerpc endpoint server.
1542 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1543 struct ncacn_packet *pkt,
1547 struct dcesrv_call_state *call;
1548 struct dcesrv_call_state *existing = NULL;
1550 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1552 data_blob_free(&blob);
1554 return NT_STATUS_NO_MEMORY;
1556 call->conn = dce_conn;
1557 call->event_ctx = dce_conn->event_ctx;
1558 call->msg_ctx = dce_conn->msg_ctx;
1559 call->state_flags = call->conn->state_flags;
1560 call->time = timeval_current();
1561 call->list = DCESRV_LIST_NONE;
1563 talloc_steal(call, pkt);
1564 talloc_steal(call, blob.data);
1567 talloc_set_destructor(call, dcesrv_call_dequeue);
1569 if (call->conn->allow_bind) {
1571 * Only one bind is possible per connection
1573 call->conn->allow_bind = false;
1574 return dcesrv_bind(call);
1577 /* we have to check the signing here, before combining the
1579 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1580 if (!call->conn->allow_request) {
1581 return dcesrv_fault_disconnect(call,
1582 DCERPC_NCA_S_PROTO_ERROR);
1585 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1587 call->pkt.u.request.stub_and_verifier.length,
1588 0, /* required_flags */
1589 DCERPC_PFC_FLAG_FIRST |
1590 DCERPC_PFC_FLAG_LAST |
1591 DCERPC_PFC_FLAG_PENDING_CANCEL |
1592 0x08 | /* this is not defined, but should be ignored */
1593 DCERPC_PFC_FLAG_CONC_MPX |
1594 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1595 DCERPC_PFC_FLAG_MAYBE |
1596 DCERPC_PFC_FLAG_OBJECT_UUID);
1597 if (!NT_STATUS_IS_OK(status)) {
1598 return dcesrv_fault_disconnect(call,
1599 DCERPC_NCA_S_PROTO_ERROR);
1602 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1604 * We don't use dcesrv_fault_disconnect()
1605 * here, because we don't want to set
1606 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1608 * Note that we don't check against the negotiated
1609 * max_recv_frag, but a hard coded value.
1611 dcesrv_call_disconnect_after(call,
1612 "dcesrv_auth_request - frag_length too large");
1613 return dcesrv_fault(call,
1614 DCERPC_NCA_S_PROTO_ERROR);
1617 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1618 /* only one request is possible in the fragmented list */
1619 if (dce_conn->incoming_fragmented_call_list != NULL) {
1621 call = dce_conn->incoming_fragmented_call_list;
1622 dcesrv_call_disconnect_after(call,
1623 "dcesrv_auth_request - "
1624 "existing fragmented call");
1625 return dcesrv_fault(call,
1626 DCERPC_NCA_S_PROTO_ERROR);
1628 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1629 return dcesrv_fault_disconnect(call,
1630 DCERPC_FAULT_NO_CALL_ACTIVE);
1633 const struct dcerpc_request *nr = &call->pkt.u.request;
1634 const struct dcerpc_request *er = NULL;
1637 existing = dcesrv_find_fragmented_call(dce_conn,
1639 if (existing == NULL) {
1640 dcesrv_call_disconnect_after(call,
1641 "dcesrv_auth_request - "
1642 "no existing fragmented call");
1643 return dcesrv_fault(call,
1644 DCERPC_NCA_S_PROTO_ERROR);
1646 er = &existing->pkt.u.request;
1648 if (call->pkt.ptype != existing->pkt.ptype) {
1649 /* trying to play silly buggers are we? */
1650 return dcesrv_fault_disconnect(existing,
1651 DCERPC_NCA_S_PROTO_ERROR);
1653 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1656 return dcesrv_fault_disconnect(existing,
1657 DCERPC_NCA_S_PROTO_ERROR);
1659 if (nr->context_id != er->context_id) {
1660 return dcesrv_fault_disconnect(existing,
1661 DCERPC_NCA_S_PROTO_ERROR);
1663 if (nr->opnum != er->opnum) {
1664 return dcesrv_fault_disconnect(existing,
1665 DCERPC_NCA_S_PROTO_ERROR);
1670 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1672 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1674 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1675 payload_offset += 16;
1678 ok = dcesrv_auth_pkt_pull(call, &blob,
1679 0, /* required_flags */
1680 DCERPC_PFC_FLAG_FIRST |
1681 DCERPC_PFC_FLAG_LAST |
1682 DCERPC_PFC_FLAG_PENDING_CANCEL |
1683 0x08 | /* this is not defined, but should be ignored */
1684 DCERPC_PFC_FLAG_CONC_MPX |
1685 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1686 DCERPC_PFC_FLAG_MAYBE |
1687 DCERPC_PFC_FLAG_OBJECT_UUID,
1689 &call->pkt.u.request.stub_and_verifier);
1692 * We don't use dcesrv_fault_disconnect()
1693 * here, because we don't want to set
1694 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1696 dcesrv_call_disconnect_after(call,
1697 "dcesrv_auth_request - failed");
1698 if (call->fault_code == 0) {
1699 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1701 return dcesrv_fault(call, call->fault_code);
1705 /* see if this is a continued packet */
1706 if (existing != NULL) {
1707 struct dcerpc_request *er = &existing->pkt.u.request;
1708 const struct dcerpc_request *nr = &call->pkt.u.request;
1714 * Up to 4 MByte are allowed by all fragments
1716 available = dce_conn->max_total_request_size;
1717 if (er->stub_and_verifier.length > available) {
1718 dcesrv_call_disconnect_after(existing,
1719 "dcesrv_auth_request - existing payload too large");
1720 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1722 available -= er->stub_and_verifier.length;
1723 if (nr->alloc_hint > available) {
1724 dcesrv_call_disconnect_after(existing,
1725 "dcesrv_auth_request - alloc hint too large");
1726 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1728 if (nr->stub_and_verifier.length > available) {
1729 dcesrv_call_disconnect_after(existing,
1730 "dcesrv_auth_request - new payload too large");
1731 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1733 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1734 /* allocate at least 1 byte */
1735 alloc_hint = MAX(alloc_hint, 1);
1736 alloc_size = er->stub_and_verifier.length +
1737 nr->stub_and_verifier.length;
1738 alloc_size = MAX(alloc_size, alloc_hint);
1740 er->stub_and_verifier.data =
1741 talloc_realloc(existing,
1742 er->stub_and_verifier.data,
1743 uint8_t, alloc_size);
1744 if (er->stub_and_verifier.data == NULL) {
1746 return dcesrv_fault_with_flags(existing,
1747 DCERPC_FAULT_OUT_OF_RESOURCES,
1748 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1750 memcpy(er->stub_and_verifier.data +
1751 er->stub_and_verifier.length,
1752 nr->stub_and_verifier.data,
1753 nr->stub_and_verifier.length);
1754 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1756 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1762 /* this may not be the last pdu in the chain - if its isn't then
1763 just put it on the incoming_fragmented_call_list and wait for the rest */
1764 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1765 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1767 * Up to 4 MByte are allowed by all fragments
1769 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1770 dcesrv_call_disconnect_after(call,
1771 "dcesrv_auth_request - initial alloc hint too large");
1772 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1774 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1775 return NT_STATUS_OK;
1778 /* This removes any fragments we may have had stashed away */
1779 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1781 switch (call->pkt.ptype) {
1782 case DCERPC_PKT_BIND:
1783 status = dcesrv_bind_nak(call,
1784 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1786 case DCERPC_PKT_AUTH3:
1787 status = dcesrv_auth3(call);
1789 case DCERPC_PKT_ALTER:
1790 status = dcesrv_alter(call);
1792 case DCERPC_PKT_REQUEST:
1793 status = dcesrv_request(call);
1795 case DCERPC_PKT_CO_CANCEL:
1796 case DCERPC_PKT_ORPHANED:
1798 * Window just ignores CO_CANCEL and ORPHANED,
1801 status = NT_STATUS_OK;
1804 case DCERPC_PKT_BIND_ACK:
1805 case DCERPC_PKT_BIND_NAK:
1806 case DCERPC_PKT_ALTER_RESP:
1807 case DCERPC_PKT_RESPONSE:
1808 case DCERPC_PKT_FAULT:
1809 case DCERPC_PKT_SHUTDOWN:
1811 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1815 /* if we are going to be sending a reply then add
1816 it to the list of pending calls. We add it to the end to keep the call
1817 list in the order we will answer */
1818 if (!NT_STATUS_IS_OK(status)) {
1825 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1826 struct loadparm_context *lp_ctx,
1827 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1830 struct dcesrv_context *dce_ctx;
1833 if (!endpoint_servers) {
1834 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1835 return NT_STATUS_INTERNAL_ERROR;
1838 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1839 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1841 if (uid_wrapper_enabled()) {
1842 setenv("UID_WRAPPER_MYUID", "1", 1);
1844 dce_ctx->initial_euid = geteuid();
1845 if (uid_wrapper_enabled()) {
1846 unsetenv("UID_WRAPPER_MYUID");
1849 dce_ctx->endpoint_list = NULL;
1850 dce_ctx->lp_ctx = lp_ctx;
1851 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1852 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1853 dce_ctx->broken_connections = NULL;
1855 for (i=0;endpoint_servers[i];i++) {
1856 const struct dcesrv_endpoint_server *ep_server;
1858 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1860 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1861 return NT_STATUS_INTERNAL_ERROR;
1864 status = ep_server->init_server(dce_ctx, ep_server);
1865 if (!NT_STATUS_IS_OK(status)) {
1866 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1867 nt_errstr(status)));
1872 *_dce_ctx = dce_ctx;
1873 return NT_STATUS_OK;
1876 /* the list of currently registered DCERPC endpoint servers.
1878 static struct ep_server {
1879 struct dcesrv_endpoint_server *ep_server;
1880 } *ep_servers = NULL;
1881 static int num_ep_servers;
1884 register a DCERPC endpoint server.
1886 The 'name' can be later used by other backends to find the operations
1887 structure for this backend.
1889 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1891 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1893 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1895 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1896 /* its already registered! */
1897 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1899 return NT_STATUS_OBJECT_NAME_COLLISION;
1902 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1904 smb_panic("out of memory in dcerpc_register");
1907 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1908 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1912 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1915 return NT_STATUS_OK;
1919 return the operations structure for a named backend of the specified type
1921 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1925 for (i=0;i<num_ep_servers;i++) {
1926 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1927 return ep_servers[i].ep_server;
1934 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1936 static bool initialized;
1937 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1938 STATIC_dcerpc_server_MODULES_PROTO;
1939 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1940 init_module_fn *shared_init;
1947 shared_init = load_samba_modules(NULL, "dcerpc_server");
1949 run_init_functions(static_init);
1950 run_init_functions(shared_init);
1952 talloc_free(shared_init);
1956 return the DCERPC module version, and the size of some critical types
1957 This can be used by endpoint server modules to either detect compilation errors, or provide
1958 multiple implementations for different smbd compilation options in one module
1960 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1962 static const struct dcesrv_critical_sizes critical_sizes = {
1963 DCERPC_MODULE_VERSION,
1964 sizeof(struct dcesrv_context),
1965 sizeof(struct dcesrv_endpoint),
1966 sizeof(struct dcesrv_endpoint_server),
1967 sizeof(struct dcesrv_interface),
1968 sizeof(struct dcesrv_if_list),
1969 sizeof(struct dcesrv_connection),
1970 sizeof(struct dcesrv_call_state),
1971 sizeof(struct dcesrv_auth),
1972 sizeof(struct dcesrv_handle)
1975 return &critical_sizes;
1978 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1980 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1981 struct stream_connection *srv_conn;
1982 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1983 struct stream_connection);
1985 dce_conn->allow_bind = false;
1986 dce_conn->allow_auth3 = false;
1987 dce_conn->allow_alter = false;
1988 dce_conn->allow_request = false;
1990 if (dce_conn->pending_call_list == NULL) {
1991 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1993 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1994 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1998 if (dce_conn->terminate != NULL) {
2002 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2004 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2005 if (dce_conn->terminate == NULL) {
2006 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2008 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2011 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2013 struct dcesrv_connection *cur, *next;
2015 next = dce_ctx->broken_connections;
2016 while (next != NULL) {
2020 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2021 struct dcesrv_connection_context *context_cur, *context_next;
2023 context_next = cur->contexts;
2024 while (context_next != NULL) {
2025 context_cur = context_next;
2026 context_next = context_cur->next;
2028 dcesrv_connection_context_destructor(context_cur);
2032 dcesrv_terminate_connection(cur, cur->terminate);
2036 /* We need this include to be able to compile on some plateforms
2037 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2039 * It has to be that deep because otherwise we have a conflict on
2040 * const struct dcesrv_interface declaration.
2041 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2042 * which conflict with the bind used before.
2044 #include "system/network.h"
2046 struct dcesrv_sock_reply_state {
2047 struct dcesrv_connection *dce_conn;
2048 struct dcesrv_call_state *call;
2052 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2053 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2055 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2057 struct dcesrv_call_state *call;
2059 call = dce_conn->call_list;
2060 if (!call || !call->replies) {
2064 while (call->replies) {
2065 struct data_blob_list_item *rep = call->replies;
2066 struct dcesrv_sock_reply_state *substate;
2067 struct tevent_req *subreq;
2069 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2071 dcesrv_terminate_connection(dce_conn, "no memory");
2075 substate->dce_conn = dce_conn;
2076 substate->call = NULL;
2078 DLIST_REMOVE(call->replies, rep);
2080 if (call->replies == NULL && call->terminate_reason == NULL) {
2081 substate->call = call;
2084 substate->iov.iov_base = (void *) rep->blob.data;
2085 substate->iov.iov_len = rep->blob.length;
2087 subreq = tstream_writev_queue_send(substate,
2088 dce_conn->event_ctx,
2090 dce_conn->send_queue,
2093 dcesrv_terminate_connection(dce_conn, "no memory");
2096 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2100 if (call->terminate_reason != NULL) {
2101 struct tevent_req *subreq;
2103 subreq = tevent_queue_wait_send(call,
2104 dce_conn->event_ctx,
2105 dce_conn->send_queue);
2107 dcesrv_terminate_connection(dce_conn, __location__);
2110 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2114 DLIST_REMOVE(call->conn->call_list, call);
2115 call->list = DCESRV_LIST_NONE;
2118 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2120 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2121 struct dcesrv_sock_reply_state);
2125 struct dcesrv_call_state *call = substate->call;
2127 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2128 TALLOC_FREE(subreq);
2130 status = map_nt_error_from_unix_common(sys_errno);
2131 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2135 talloc_free(substate);
2141 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2143 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2145 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2146 struct dcesrv_call_state);
2150 /* make sure we stop send queue before removing subreq */
2151 tevent_queue_stop(call->conn->send_queue);
2153 ok = tevent_queue_wait_recv(subreq);
2154 TALLOC_FREE(subreq);
2156 dcesrv_terminate_connection(call->conn, __location__);
2160 /* disconnect after 200 usecs */
2161 tv = timeval_current_ofs_usec(200);
2162 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2163 if (subreq == NULL) {
2164 dcesrv_terminate_connection(call->conn, __location__);
2167 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2171 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2173 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2174 struct dcesrv_call_state);
2177 ok = tevent_wakeup_recv(subreq);
2178 TALLOC_FREE(subreq);
2180 dcesrv_terminate_connection(call->conn, __location__);
2184 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2187 struct dcesrv_socket_context {
2188 const struct dcesrv_endpoint *endpoint;
2189 struct dcesrv_context *dcesrv_ctx;
2193 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2195 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2198 struct dcesrv_socket_context *dcesrv_sock =
2199 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2200 enum dcerpc_transport_t transport =
2201 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2202 struct dcesrv_connection *dcesrv_conn = NULL;
2204 struct tevent_req *subreq;
2205 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2207 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2209 if (!srv_conn->session_info) {
2210 status = auth_anonymous_session_info(srv_conn,
2212 &srv_conn->session_info);
2213 if (!NT_STATUS_IS_OK(status)) {
2214 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2215 nt_errstr(status)));
2216 stream_terminate_connection(srv_conn, nt_errstr(status));
2221 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2223 dcesrv_sock->endpoint,
2224 srv_conn->session_info,
2225 srv_conn->event.ctx,
2227 srv_conn->server_id,
2228 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2230 if (!NT_STATUS_IS_OK(status)) {
2231 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2232 nt_errstr(status)));
2233 stream_terminate_connection(srv_conn, nt_errstr(status));
2237 dcesrv_conn->transport.private_data = srv_conn;
2238 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2240 TALLOC_FREE(srv_conn->event.fde);
2242 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2243 if (!dcesrv_conn->send_queue) {
2244 status = NT_STATUS_NO_MEMORY;
2245 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2246 nt_errstr(status)));
2247 stream_terminate_connection(srv_conn, nt_errstr(status));
2251 if (transport == NCACN_NP) {
2252 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2253 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2254 &srv_conn->tstream);
2256 ret = tstream_bsd_existing_socket(dcesrv_conn,
2257 socket_get_fd(srv_conn->socket),
2258 &dcesrv_conn->stream);
2260 status = map_nt_error_from_unix_common(errno);
2261 DEBUG(0, ("dcesrv_sock_accept: "
2262 "failed to setup tstream: %s\n",
2263 nt_errstr(status)));
2264 stream_terminate_connection(srv_conn, nt_errstr(status));
2267 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2270 dcesrv_conn->local_address = srv_conn->local_address;
2271 dcesrv_conn->remote_address = srv_conn->remote_address;
2273 if (transport == NCALRPC) {
2278 sock_fd = socket_get_fd(srv_conn->socket);
2279 if (sock_fd == -1) {
2280 stream_terminate_connection(
2281 srv_conn, "socket_get_fd failed\n");
2285 ret = getpeereid(sock_fd, &uid, &gid);
2287 status = map_nt_error_from_unix_common(errno);
2288 DEBUG(0, ("dcesrv_sock_accept: "
2289 "getpeereid() failed for NCALRPC: %s\n",
2290 nt_errstr(status)));
2291 stream_terminate_connection(srv_conn, nt_errstr(status));
2294 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2295 struct tsocket_address *r = NULL;
2297 ret = tsocket_address_unix_from_path(dcesrv_conn,
2298 "/root/ncalrpc_as_system",
2301 status = map_nt_error_from_unix_common(errno);
2302 DEBUG(0, ("dcesrv_sock_accept: "
2303 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2304 nt_errstr(status)));
2305 stream_terminate_connection(srv_conn, nt_errstr(status));
2308 dcesrv_conn->remote_address = r;
2312 srv_conn->private_data = dcesrv_conn;
2314 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2316 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2317 dcesrv_conn->event_ctx,
2318 dcesrv_conn->stream);
2320 status = NT_STATUS_NO_MEMORY;
2321 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2322 nt_errstr(status)));
2323 stream_terminate_connection(srv_conn, nt_errstr(status));
2326 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2331 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2333 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2334 struct dcesrv_connection);
2335 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2336 struct ncacn_packet *pkt;
2340 if (dce_conn->terminate) {
2342 * if the current connection is broken
2343 * we need to clean it up before any other connection
2345 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2346 dcesrv_cleanup_broken_connections(dce_ctx);
2350 dcesrv_cleanup_broken_connections(dce_ctx);
2352 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2354 TALLOC_FREE(subreq);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2360 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2361 if (!NT_STATUS_IS_OK(status)) {
2362 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2366 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2367 dce_conn->event_ctx,
2370 status = NT_STATUS_NO_MEMORY;
2371 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2374 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2377 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2379 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2380 struct dcesrv_connection);
2381 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2384 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2386 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2387 struct dcesrv_connection);
2388 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2392 static const struct stream_server_ops dcesrv_stream_ops = {
2394 .accept_connection = dcesrv_sock_accept,
2395 .recv_handler = dcesrv_sock_recv,
2396 .send_handler = dcesrv_sock_send,
2399 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2400 struct loadparm_context *lp_ctx,
2401 struct dcesrv_endpoint *e,
2402 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2404 struct dcesrv_socket_context *dcesrv_sock;
2407 const char *endpoint;
2409 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2410 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2412 /* remember the endpoint of this socket */
2413 dcesrv_sock->endpoint = e;
2414 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2416 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2418 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2419 model_ops, &dcesrv_stream_ops,
2420 "unix", endpoint, &port,
2421 lpcfg_socket_options(lp_ctx),
2423 if (!NT_STATUS_IS_OK(status)) {
2424 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2425 endpoint, nt_errstr(status)));
2431 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2432 struct loadparm_context *lp_ctx,
2433 struct dcesrv_endpoint *e,
2434 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2436 struct dcesrv_socket_context *dcesrv_sock;
2440 const char *endpoint;
2442 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2444 if (endpoint == NULL) {
2446 * No identifier specified: use DEFAULT.
2448 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2449 * no endpoint and let the epmapper worry about it.
2451 endpoint = "DEFAULT";
2452 status = dcerpc_binding_set_string_option(e->ep_description,
2455 if (!NT_STATUS_IS_OK(status)) {
2456 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2457 nt_errstr(status)));
2462 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2465 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2466 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2468 /* remember the endpoint of this socket */
2469 dcesrv_sock->endpoint = e;
2470 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2472 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2473 model_ops, &dcesrv_stream_ops,
2474 "unix", full_path, &port,
2475 lpcfg_socket_options(lp_ctx),
2477 if (!NT_STATUS_IS_OK(status)) {
2478 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2479 endpoint, full_path, nt_errstr(status)));
2484 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2485 struct loadparm_context *lp_ctx,
2486 struct dcesrv_endpoint *e,
2487 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2489 struct dcesrv_socket_context *dcesrv_sock;
2491 const char *endpoint;
2493 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2494 if (endpoint == NULL) {
2495 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2496 return NT_STATUS_INVALID_PARAMETER;
2499 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2500 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2502 /* remember the endpoint of this socket */
2503 dcesrv_sock->endpoint = e;
2504 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2506 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2507 model_ops, &dcesrv_stream_ops,
2510 if (!NT_STATUS_IS_OK(status)) {
2511 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2512 endpoint, nt_errstr(status)));
2516 return NT_STATUS_OK;
2520 add a socket address to the list of events, one event per dcerpc endpoint
2522 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2523 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2524 const char *address)
2526 struct dcesrv_socket_context *dcesrv_sock;
2529 const char *endpoint;
2532 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2533 if (endpoint != NULL) {
2534 port = atoi(endpoint);
2537 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2538 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2540 /* remember the endpoint of this socket */
2541 dcesrv_sock->endpoint = e;
2542 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2544 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2545 model_ops, &dcesrv_stream_ops,
2546 "ip", address, &port,
2547 lpcfg_socket_options(dce_ctx->lp_ctx),
2549 if (!NT_STATUS_IS_OK(status)) {
2550 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2551 address, port, nt_errstr(status)));
2555 snprintf(port_str, sizeof(port_str), "%u", port);
2557 status = dcerpc_binding_set_string_option(e->ep_description,
2558 "endpoint", port_str);
2559 if (!NT_STATUS_IS_OK(status)) {
2560 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2561 port_str, nt_errstr(status)));
2565 return NT_STATUS_OK;
2568 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2570 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2571 struct loadparm_context *lp_ctx,
2572 struct dcesrv_endpoint *e,
2573 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2577 /* Add TCP/IP sockets */
2578 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2581 struct interface *ifaces;
2583 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2585 num_interfaces = iface_list_count(ifaces);
2586 for(i = 0; i < num_interfaces; i++) {
2587 const char *address = iface_list_n_ip(ifaces, i);
2588 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2589 NT_STATUS_NOT_OK_RETURN(status);
2595 wcard = iface_list_wildcard(dce_ctx);
2596 NT_STATUS_HAVE_NO_MEMORY(wcard);
2597 for (i=0; wcard[i]; i++) {
2598 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2599 if (NT_STATUS_IS_OK(status)) {
2604 if (num_binds == 0) {
2605 return NT_STATUS_INVALID_PARAMETER_MIX;
2609 return NT_STATUS_OK;
2612 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2613 struct loadparm_context *lp_ctx,
2614 struct dcesrv_endpoint *e,
2615 struct tevent_context *event_ctx,
2616 const struct model_ops *model_ops)
2618 enum dcerpc_transport_t transport =
2619 dcerpc_binding_get_transport(e->ep_description);
2621 switch (transport) {
2622 case NCACN_UNIX_STREAM:
2623 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2626 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2629 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2632 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2635 return NT_STATUS_NOT_SUPPORTED;
2641 * retrieve credentials from a dce_call
2643 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2645 return dce_call->conn->auth_state.session_info->credentials;
2649 * returns true if this is an authenticated call
2651 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2653 enum security_user_level level;
2654 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2655 return level >= SECURITY_USER;
2659 * retrieve account_name for a dce_call
2661 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2663 return dce_call->context->conn->auth_state.session_info->info->account_name;