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);
1092 status = iface->bind(call, iface, if_version);
1093 call->context = NULL;
1094 if (!NT_STATUS_IS_OK(status)) {
1095 /* we don't want to trigger the iface->unbind() hook */
1096 context->iface = NULL;
1097 talloc_free(context);
1099 * We report this only via ack->result
1101 return NT_STATUS_OK;
1104 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1105 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1106 ack->syntax = context->transfer_syntax;
1107 return NT_STATUS_OK;
1110 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1111 const struct dcerpc_bind *b,
1112 struct dcerpc_ack_ctx *ack_ctx_list)
1116 bool validate_only = false;
1117 bool preferred_ndr32;
1120 * Try to negotiate one new presentation context,
1121 * using our preferred transfer syntax.
1123 for (i = 0; i < b->num_contexts; i++) {
1124 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1125 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1127 status = dcesrv_check_or_create_context(call, b, c, a,
1129 call->conn->preferred_transfer);
1130 if (!NT_STATUS_IS_OK(status)) {
1134 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1136 * We managed to negotiate one context.
1140 validate_only = true;
1144 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1145 call->conn->preferred_transfer);
1146 if (preferred_ndr32) {
1150 return NT_STATUS_OK;
1154 * Try to negotiate one new presentation context,
1155 * using NDR 32 as fallback.
1157 for (i = 0; i < b->num_contexts; i++) {
1158 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1159 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1161 status = dcesrv_check_or_create_context(call, b, c, a,
1163 &ndr_transfer_syntax_ndr);
1164 if (!NT_STATUS_IS_OK(status)) {
1168 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1170 * We managed to negotiate one context.
1174 validate_only = true;
1178 return NT_STATUS_OK;
1182 handle a alter context request
1184 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1187 bool auth_ok = false;
1188 struct ncacn_packet pkt;
1189 uint32_t extra_flags = 0;
1190 struct data_blob_list_item *rep = NULL;
1191 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1194 if (!call->conn->allow_alter) {
1195 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1198 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1200 call->pkt.u.alter.auth_info.length,
1201 0, /* required flags */
1202 DCERPC_PFC_FLAG_FIRST |
1203 DCERPC_PFC_FLAG_LAST |
1204 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1205 0x08 | /* this is not defined, but should be ignored */
1206 DCERPC_PFC_FLAG_CONC_MPX |
1207 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1208 DCERPC_PFC_FLAG_MAYBE |
1209 DCERPC_PFC_FLAG_OBJECT_UUID);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1214 auth_ok = dcesrv_auth_alter(call);
1216 if (call->fault_code != 0) {
1217 return dcesrv_fault_disconnect(call, call->fault_code);
1221 if (call->pkt.u.alter.num_contexts < 1) {
1222 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1225 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1226 call->pkt.u.alter.num_contexts);
1227 if (ack_ctx_list == NULL) {
1228 return NT_STATUS_NO_MEMORY;
1232 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1233 * dcesrv_check_or_create_context()) and do some protocol validation
1234 * and set sane defaults.
1236 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1237 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1238 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1240 if (c->num_transfer_syntaxes == 0) {
1241 return dcesrv_fault_disconnect(call,
1242 DCERPC_NCA_S_PROTO_ERROR);
1245 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1246 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1250 * Try to negotiate one new presentation context.
1252 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1253 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1254 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1256 if (!NT_STATUS_IS_OK(status)) {
1260 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1261 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1262 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1263 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1266 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1267 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1270 /* handle any authentication that is being requested */
1272 if (call->in_auth_info.auth_type !=
1273 call->conn->auth_state.auth_type)
1275 return dcesrv_fault_disconnect(call,
1276 DCERPC_FAULT_SEC_PKG_ERROR);
1278 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1281 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1282 pkt.auth_length = 0;
1283 pkt.call_id = call->pkt.call_id;
1284 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1285 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1286 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1287 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1288 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1289 pkt.u.alter_resp.secondary_address = "";
1290 pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1291 pkt.u.alter_resp.ctx_list = ack_ctx_list;
1292 pkt.u.alter_resp.auth_info = data_blob_null;
1294 status = dcesrv_auth_alter_ack(call, &pkt);
1295 if (!NT_STATUS_IS_OK(status)) {
1296 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1299 rep = talloc_zero(call, struct data_blob_list_item);
1301 return NT_STATUS_NO_MEMORY;
1304 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1305 if (!NT_STATUS_IS_OK(status)) {
1309 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1311 DLIST_ADD_END(call->replies, rep);
1312 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1314 if (call->conn->call_list && call->conn->call_list->replies) {
1315 if (call->conn->transport.report_output_data) {
1316 call->conn->transport.report_output_data(call->conn);
1320 return NT_STATUS_OK;
1324 possibly save the call for inspection with ndrdump
1326 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1330 const char *dump_dir;
1331 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1335 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1337 call->context->iface->name,
1338 call->pkt.u.request.opnum,
1340 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1341 DEBUG(0,("RPC SAVED %s\n", fname));
1347 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1349 TALLOC_CTX *frame = talloc_stackframe();
1350 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1351 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1352 const struct dcerpc_sec_vt_pcontext pcontext = {
1353 .abstract_syntax = call->context->iface->syntax_id,
1354 .transfer_syntax = call->context->transfer_syntax,
1356 const struct dcerpc_sec_vt_header2 header2 =
1357 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1358 enum ndr_err_code ndr_err;
1359 struct dcerpc_sec_verification_trailer *vt = NULL;
1360 NTSTATUS status = NT_STATUS_OK;
1363 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1365 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1367 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1368 status = ndr_map_error2ntstatus(ndr_err);
1372 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1373 &pcontext, &header2);
1375 status = NT_STATUS_ACCESS_DENIED;
1384 handle a dcerpc request packet
1386 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1388 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1389 enum dcerpc_transport_t transport =
1390 dcerpc_binding_get_transport(endpoint->ep_description);
1391 struct ndr_pull *pull;
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 if (call->context == NULL) {
1405 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1406 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1409 switch (call->conn->auth_state.auth_level) {
1410 case DCERPC_AUTH_LEVEL_NONE:
1411 case DCERPC_AUTH_LEVEL_PACKET:
1412 case DCERPC_AUTH_LEVEL_INTEGRITY:
1413 case DCERPC_AUTH_LEVEL_PRIVACY:
1416 if (!call->context->allow_connect) {
1419 addr = tsocket_address_string(call->conn->remote_address,
1422 DEBUG(2, ("%s: restrict auth_level_connect access "
1423 "to [%s] with auth[type=0x%x,level=0x%x] "
1424 "on [%s] from [%s]\n",
1425 __func__, call->context->iface->name,
1426 call->conn->auth_state.auth_type,
1427 call->conn->auth_state.auth_level,
1428 derpc_transport_string_by_transport(transport),
1430 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1435 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1438 addr = tsocket_address_string(call->conn->remote_address, call);
1440 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1441 "to [%s] with auth[type=0x%x,level=0x%x] "
1442 "on [%s] from [%s]\n",
1444 call->context->min_auth_level,
1445 call->context->iface->name,
1446 call->conn->auth_state.auth_type,
1447 call->conn->auth_state.auth_level,
1448 derpc_transport_string_by_transport(transport),
1450 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1453 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1454 NT_STATUS_HAVE_NO_MEMORY(pull);
1456 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1458 call->ndr_pull = pull;
1460 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1461 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1464 status = dcesrv_check_verification_trailer(call);
1465 if (!NT_STATUS_IS_OK(status)) {
1466 uint32_t faultcode = DCERPC_FAULT_OTHER;
1467 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1468 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1470 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1471 nt_errstr(status)));
1472 return dcesrv_fault(call, faultcode);
1475 /* unravel the NDR for the packet */
1476 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 uint8_t extra_flags = 0;
1479 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1480 /* we got an unknown call */
1481 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1482 call->pkt.u.request.opnum,
1483 call->context->iface->name));
1484 dcesrv_save_call(call, "unknown");
1485 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1487 dcesrv_save_call(call, "pullfail");
1489 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1492 if (pull->offset != pull->data_size) {
1493 dcesrv_save_call(call, "extrabytes");
1494 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1495 pull->data_size - pull->offset));
1498 /* call the dispatch function */
1499 status = call->context->iface->dispatch(call, call, call->r);
1500 if (!NT_STATUS_IS_OK(status)) {
1501 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1502 call->context->iface->name,
1503 call->pkt.u.request.opnum,
1504 dcerpc_errstr(pull, call->fault_code)));
1505 return dcesrv_fault(call, call->fault_code);
1508 /* add the call to the pending list */
1509 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1511 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1512 return NT_STATUS_OK;
1515 return dcesrv_reply(call);
1520 remove the call from the right list when freed
1522 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1524 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1528 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1530 return conn->local_address;
1533 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1535 return conn->remote_address;
1539 process some input to a dcerpc endpoint server.
1541 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1542 struct ncacn_packet *pkt,
1546 struct dcesrv_call_state *call;
1547 struct dcesrv_call_state *existing = NULL;
1549 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1551 data_blob_free(&blob);
1553 return NT_STATUS_NO_MEMORY;
1555 call->conn = dce_conn;
1556 call->event_ctx = dce_conn->event_ctx;
1557 call->msg_ctx = dce_conn->msg_ctx;
1558 call->state_flags = call->conn->state_flags;
1559 call->time = timeval_current();
1560 call->list = DCESRV_LIST_NONE;
1562 talloc_steal(call, pkt);
1563 talloc_steal(call, blob.data);
1566 talloc_set_destructor(call, dcesrv_call_dequeue);
1568 if (call->conn->allow_bind) {
1570 * Only one bind is possible per connection
1572 call->conn->allow_bind = false;
1573 return dcesrv_bind(call);
1576 /* we have to check the signing here, before combining the
1578 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1579 if (!call->conn->allow_request) {
1580 return dcesrv_fault_disconnect(call,
1581 DCERPC_NCA_S_PROTO_ERROR);
1584 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1586 call->pkt.u.request.stub_and_verifier.length,
1587 0, /* required_flags */
1588 DCERPC_PFC_FLAG_FIRST |
1589 DCERPC_PFC_FLAG_LAST |
1590 DCERPC_PFC_FLAG_PENDING_CANCEL |
1591 0x08 | /* this is not defined, but should be ignored */
1592 DCERPC_PFC_FLAG_CONC_MPX |
1593 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1594 DCERPC_PFC_FLAG_MAYBE |
1595 DCERPC_PFC_FLAG_OBJECT_UUID);
1596 if (!NT_STATUS_IS_OK(status)) {
1597 return dcesrv_fault_disconnect(call,
1598 DCERPC_NCA_S_PROTO_ERROR);
1601 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1603 * We don't use dcesrv_fault_disconnect()
1604 * here, because we don't want to set
1605 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1607 * Note that we don't check against the negotiated
1608 * max_recv_frag, but a hard coded value.
1610 dcesrv_call_disconnect_after(call,
1611 "dcesrv_auth_request - frag_length too large");
1612 return dcesrv_fault(call,
1613 DCERPC_NCA_S_PROTO_ERROR);
1616 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1617 /* only one request is possible in the fragmented list */
1618 if (dce_conn->incoming_fragmented_call_list != NULL) {
1620 call = dce_conn->incoming_fragmented_call_list;
1621 dcesrv_call_disconnect_after(call,
1622 "dcesrv_auth_request - "
1623 "existing fragmented call");
1624 return dcesrv_fault(call,
1625 DCERPC_NCA_S_PROTO_ERROR);
1627 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1628 return dcesrv_fault_disconnect(call,
1629 DCERPC_FAULT_NO_CALL_ACTIVE);
1631 call->context = dcesrv_find_context(call->conn,
1632 call->pkt.u.request.context_id);
1633 if (call->context == NULL) {
1634 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1635 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1638 const struct dcerpc_request *nr = &call->pkt.u.request;
1639 const struct dcerpc_request *er = NULL;
1642 existing = dcesrv_find_fragmented_call(dce_conn,
1644 if (existing == NULL) {
1645 dcesrv_call_disconnect_after(call,
1646 "dcesrv_auth_request - "
1647 "no existing fragmented call");
1648 return dcesrv_fault(call,
1649 DCERPC_NCA_S_PROTO_ERROR);
1651 er = &existing->pkt.u.request;
1653 if (call->pkt.ptype != existing->pkt.ptype) {
1654 /* trying to play silly buggers are we? */
1655 return dcesrv_fault_disconnect(existing,
1656 DCERPC_NCA_S_PROTO_ERROR);
1658 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1661 return dcesrv_fault_disconnect(existing,
1662 DCERPC_NCA_S_PROTO_ERROR);
1664 if (nr->context_id != er->context_id) {
1665 return dcesrv_fault_disconnect(existing,
1666 DCERPC_NCA_S_PROTO_ERROR);
1668 if (nr->opnum != er->opnum) {
1669 return dcesrv_fault_disconnect(existing,
1670 DCERPC_NCA_S_PROTO_ERROR);
1675 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1677 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1679 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1680 payload_offset += 16;
1683 ok = dcesrv_auth_pkt_pull(call, &blob,
1684 0, /* required_flags */
1685 DCERPC_PFC_FLAG_FIRST |
1686 DCERPC_PFC_FLAG_LAST |
1687 DCERPC_PFC_FLAG_PENDING_CANCEL |
1688 0x08 | /* this is not defined, but should be ignored */
1689 DCERPC_PFC_FLAG_CONC_MPX |
1690 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1691 DCERPC_PFC_FLAG_MAYBE |
1692 DCERPC_PFC_FLAG_OBJECT_UUID,
1694 &call->pkt.u.request.stub_and_verifier);
1697 * We don't use dcesrv_fault_disconnect()
1698 * here, because we don't want to set
1699 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1701 dcesrv_call_disconnect_after(call,
1702 "dcesrv_auth_request - failed");
1703 if (call->fault_code == 0) {
1704 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1706 return dcesrv_fault(call, call->fault_code);
1710 /* see if this is a continued packet */
1711 if (existing != NULL) {
1712 struct dcerpc_request *er = &existing->pkt.u.request;
1713 const struct dcerpc_request *nr = &call->pkt.u.request;
1719 * Up to 4 MByte are allowed by all fragments
1721 available = dce_conn->max_total_request_size;
1722 if (er->stub_and_verifier.length > available) {
1723 dcesrv_call_disconnect_after(existing,
1724 "dcesrv_auth_request - existing payload too large");
1725 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1727 available -= er->stub_and_verifier.length;
1728 if (nr->alloc_hint > available) {
1729 dcesrv_call_disconnect_after(existing,
1730 "dcesrv_auth_request - alloc hint too large");
1731 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1733 if (nr->stub_and_verifier.length > available) {
1734 dcesrv_call_disconnect_after(existing,
1735 "dcesrv_auth_request - new payload too large");
1736 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1738 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1739 /* allocate at least 1 byte */
1740 alloc_hint = MAX(alloc_hint, 1);
1741 alloc_size = er->stub_and_verifier.length +
1742 nr->stub_and_verifier.length;
1743 alloc_size = MAX(alloc_size, alloc_hint);
1745 er->stub_and_verifier.data =
1746 talloc_realloc(existing,
1747 er->stub_and_verifier.data,
1748 uint8_t, alloc_size);
1749 if (er->stub_and_verifier.data == NULL) {
1751 return dcesrv_fault_with_flags(existing,
1752 DCERPC_FAULT_OUT_OF_RESOURCES,
1753 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1755 memcpy(er->stub_and_verifier.data +
1756 er->stub_and_verifier.length,
1757 nr->stub_and_verifier.data,
1758 nr->stub_and_verifier.length);
1759 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1761 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1767 /* this may not be the last pdu in the chain - if its isn't then
1768 just put it on the incoming_fragmented_call_list and wait for the rest */
1769 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1770 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1772 * Up to 4 MByte are allowed by all fragments
1774 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1775 dcesrv_call_disconnect_after(call,
1776 "dcesrv_auth_request - initial alloc hint too large");
1777 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1779 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1780 return NT_STATUS_OK;
1783 /* This removes any fragments we may have had stashed away */
1784 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1786 switch (call->pkt.ptype) {
1787 case DCERPC_PKT_BIND:
1788 status = dcesrv_bind_nak(call,
1789 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1791 case DCERPC_PKT_AUTH3:
1792 status = dcesrv_auth3(call);
1794 case DCERPC_PKT_ALTER:
1795 status = dcesrv_alter(call);
1797 case DCERPC_PKT_REQUEST:
1798 status = dcesrv_request(call);
1800 case DCERPC_PKT_CO_CANCEL:
1801 case DCERPC_PKT_ORPHANED:
1803 * Window just ignores CO_CANCEL and ORPHANED,
1806 status = NT_STATUS_OK;
1809 case DCERPC_PKT_BIND_ACK:
1810 case DCERPC_PKT_BIND_NAK:
1811 case DCERPC_PKT_ALTER_RESP:
1812 case DCERPC_PKT_RESPONSE:
1813 case DCERPC_PKT_FAULT:
1814 case DCERPC_PKT_SHUTDOWN:
1816 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1820 /* if we are going to be sending a reply then add
1821 it to the list of pending calls. We add it to the end to keep the call
1822 list in the order we will answer */
1823 if (!NT_STATUS_IS_OK(status)) {
1830 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1831 struct loadparm_context *lp_ctx,
1832 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1835 struct dcesrv_context *dce_ctx;
1838 if (!endpoint_servers) {
1839 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1840 return NT_STATUS_INTERNAL_ERROR;
1843 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1844 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1846 if (uid_wrapper_enabled()) {
1847 setenv("UID_WRAPPER_MYUID", "1", 1);
1849 dce_ctx->initial_euid = geteuid();
1850 if (uid_wrapper_enabled()) {
1851 unsetenv("UID_WRAPPER_MYUID");
1854 dce_ctx->endpoint_list = NULL;
1855 dce_ctx->lp_ctx = lp_ctx;
1856 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1857 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1858 dce_ctx->broken_connections = NULL;
1860 for (i=0;endpoint_servers[i];i++) {
1861 const struct dcesrv_endpoint_server *ep_server;
1863 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1865 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1866 return NT_STATUS_INTERNAL_ERROR;
1869 status = ep_server->init_server(dce_ctx, ep_server);
1870 if (!NT_STATUS_IS_OK(status)) {
1871 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1872 nt_errstr(status)));
1877 *_dce_ctx = dce_ctx;
1878 return NT_STATUS_OK;
1881 /* the list of currently registered DCERPC endpoint servers.
1883 static struct ep_server {
1884 struct dcesrv_endpoint_server *ep_server;
1885 } *ep_servers = NULL;
1886 static int num_ep_servers;
1889 register a DCERPC endpoint server.
1891 The 'name' can be later used by other backends to find the operations
1892 structure for this backend.
1894 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1896 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1898 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1900 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1901 /* its already registered! */
1902 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1904 return NT_STATUS_OBJECT_NAME_COLLISION;
1907 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1909 smb_panic("out of memory in dcerpc_register");
1912 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1913 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1917 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1920 return NT_STATUS_OK;
1924 return the operations structure for a named backend of the specified type
1926 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1930 for (i=0;i<num_ep_servers;i++) {
1931 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1932 return ep_servers[i].ep_server;
1939 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1941 static bool initialized;
1942 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1943 STATIC_dcerpc_server_MODULES_PROTO;
1944 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1945 init_module_fn *shared_init;
1952 shared_init = load_samba_modules(NULL, "dcerpc_server");
1954 run_init_functions(static_init);
1955 run_init_functions(shared_init);
1957 talloc_free(shared_init);
1961 return the DCERPC module version, and the size of some critical types
1962 This can be used by endpoint server modules to either detect compilation errors, or provide
1963 multiple implementations for different smbd compilation options in one module
1965 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1967 static const struct dcesrv_critical_sizes critical_sizes = {
1968 DCERPC_MODULE_VERSION,
1969 sizeof(struct dcesrv_context),
1970 sizeof(struct dcesrv_endpoint),
1971 sizeof(struct dcesrv_endpoint_server),
1972 sizeof(struct dcesrv_interface),
1973 sizeof(struct dcesrv_if_list),
1974 sizeof(struct dcesrv_connection),
1975 sizeof(struct dcesrv_call_state),
1976 sizeof(struct dcesrv_auth),
1977 sizeof(struct dcesrv_handle)
1980 return &critical_sizes;
1983 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1985 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1986 struct stream_connection *srv_conn;
1987 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1988 struct stream_connection);
1990 dce_conn->allow_bind = false;
1991 dce_conn->allow_auth3 = false;
1992 dce_conn->allow_alter = false;
1993 dce_conn->allow_request = false;
1995 if (dce_conn->pending_call_list == NULL) {
1996 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1998 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1999 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2003 if (dce_conn->terminate != NULL) {
2007 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2009 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2010 if (dce_conn->terminate == NULL) {
2011 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2013 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2016 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2018 struct dcesrv_connection *cur, *next;
2020 next = dce_ctx->broken_connections;
2021 while (next != NULL) {
2025 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2026 struct dcesrv_connection_context *context_cur, *context_next;
2028 context_next = cur->contexts;
2029 while (context_next != NULL) {
2030 context_cur = context_next;
2031 context_next = context_cur->next;
2033 dcesrv_connection_context_destructor(context_cur);
2037 dcesrv_terminate_connection(cur, cur->terminate);
2041 /* We need this include to be able to compile on some plateforms
2042 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2044 * It has to be that deep because otherwise we have a conflict on
2045 * const struct dcesrv_interface declaration.
2046 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2047 * which conflict with the bind used before.
2049 #include "system/network.h"
2051 struct dcesrv_sock_reply_state {
2052 struct dcesrv_connection *dce_conn;
2053 struct dcesrv_call_state *call;
2057 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2058 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2060 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2062 struct dcesrv_call_state *call;
2064 call = dce_conn->call_list;
2065 if (!call || !call->replies) {
2069 while (call->replies) {
2070 struct data_blob_list_item *rep = call->replies;
2071 struct dcesrv_sock_reply_state *substate;
2072 struct tevent_req *subreq;
2074 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2076 dcesrv_terminate_connection(dce_conn, "no memory");
2080 substate->dce_conn = dce_conn;
2081 substate->call = NULL;
2083 DLIST_REMOVE(call->replies, rep);
2085 if (call->replies == NULL && call->terminate_reason == NULL) {
2086 substate->call = call;
2089 substate->iov.iov_base = (void *) rep->blob.data;
2090 substate->iov.iov_len = rep->blob.length;
2092 subreq = tstream_writev_queue_send(substate,
2093 dce_conn->event_ctx,
2095 dce_conn->send_queue,
2098 dcesrv_terminate_connection(dce_conn, "no memory");
2101 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2105 if (call->terminate_reason != NULL) {
2106 struct tevent_req *subreq;
2108 subreq = tevent_queue_wait_send(call,
2109 dce_conn->event_ctx,
2110 dce_conn->send_queue);
2112 dcesrv_terminate_connection(dce_conn, __location__);
2115 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2119 DLIST_REMOVE(call->conn->call_list, call);
2120 call->list = DCESRV_LIST_NONE;
2123 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2125 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2126 struct dcesrv_sock_reply_state);
2130 struct dcesrv_call_state *call = substate->call;
2132 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2133 TALLOC_FREE(subreq);
2135 status = map_nt_error_from_unix_common(sys_errno);
2136 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2140 talloc_free(substate);
2146 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2148 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2150 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2151 struct dcesrv_call_state);
2155 /* make sure we stop send queue before removing subreq */
2156 tevent_queue_stop(call->conn->send_queue);
2158 ok = tevent_queue_wait_recv(subreq);
2159 TALLOC_FREE(subreq);
2161 dcesrv_terminate_connection(call->conn, __location__);
2165 /* disconnect after 200 usecs */
2166 tv = timeval_current_ofs_usec(200);
2167 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2168 if (subreq == NULL) {
2169 dcesrv_terminate_connection(call->conn, __location__);
2172 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2176 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2178 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2179 struct dcesrv_call_state);
2182 ok = tevent_wakeup_recv(subreq);
2183 TALLOC_FREE(subreq);
2185 dcesrv_terminate_connection(call->conn, __location__);
2189 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2192 struct dcesrv_socket_context {
2193 const struct dcesrv_endpoint *endpoint;
2194 struct dcesrv_context *dcesrv_ctx;
2198 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2200 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2203 struct dcesrv_socket_context *dcesrv_sock =
2204 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2205 enum dcerpc_transport_t transport =
2206 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2207 struct dcesrv_connection *dcesrv_conn = NULL;
2209 struct tevent_req *subreq;
2210 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2212 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2214 if (!srv_conn->session_info) {
2215 status = auth_anonymous_session_info(srv_conn,
2217 &srv_conn->session_info);
2218 if (!NT_STATUS_IS_OK(status)) {
2219 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2220 nt_errstr(status)));
2221 stream_terminate_connection(srv_conn, nt_errstr(status));
2226 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2228 dcesrv_sock->endpoint,
2229 srv_conn->session_info,
2230 srv_conn->event.ctx,
2232 srv_conn->server_id,
2233 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2235 if (!NT_STATUS_IS_OK(status)) {
2236 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2237 nt_errstr(status)));
2238 stream_terminate_connection(srv_conn, nt_errstr(status));
2242 dcesrv_conn->transport.private_data = srv_conn;
2243 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2245 TALLOC_FREE(srv_conn->event.fde);
2247 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2248 if (!dcesrv_conn->send_queue) {
2249 status = NT_STATUS_NO_MEMORY;
2250 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2251 nt_errstr(status)));
2252 stream_terminate_connection(srv_conn, nt_errstr(status));
2256 if (transport == NCACN_NP) {
2257 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2258 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2259 &srv_conn->tstream);
2261 ret = tstream_bsd_existing_socket(dcesrv_conn,
2262 socket_get_fd(srv_conn->socket),
2263 &dcesrv_conn->stream);
2265 status = map_nt_error_from_unix_common(errno);
2266 DEBUG(0, ("dcesrv_sock_accept: "
2267 "failed to setup tstream: %s\n",
2268 nt_errstr(status)));
2269 stream_terminate_connection(srv_conn, nt_errstr(status));
2272 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2275 dcesrv_conn->local_address = srv_conn->local_address;
2276 dcesrv_conn->remote_address = srv_conn->remote_address;
2278 if (transport == NCALRPC) {
2283 sock_fd = socket_get_fd(srv_conn->socket);
2284 if (sock_fd == -1) {
2285 stream_terminate_connection(
2286 srv_conn, "socket_get_fd failed\n");
2290 ret = getpeereid(sock_fd, &uid, &gid);
2292 status = map_nt_error_from_unix_common(errno);
2293 DEBUG(0, ("dcesrv_sock_accept: "
2294 "getpeereid() failed for NCALRPC: %s\n",
2295 nt_errstr(status)));
2296 stream_terminate_connection(srv_conn, nt_errstr(status));
2299 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2300 struct tsocket_address *r = NULL;
2302 ret = tsocket_address_unix_from_path(dcesrv_conn,
2303 "/root/ncalrpc_as_system",
2306 status = map_nt_error_from_unix_common(errno);
2307 DEBUG(0, ("dcesrv_sock_accept: "
2308 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2309 nt_errstr(status)));
2310 stream_terminate_connection(srv_conn, nt_errstr(status));
2313 dcesrv_conn->remote_address = r;
2317 srv_conn->private_data = dcesrv_conn;
2319 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2321 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2322 dcesrv_conn->event_ctx,
2323 dcesrv_conn->stream);
2325 status = NT_STATUS_NO_MEMORY;
2326 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2327 nt_errstr(status)));
2328 stream_terminate_connection(srv_conn, nt_errstr(status));
2331 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2336 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2338 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2339 struct dcesrv_connection);
2340 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2341 struct ncacn_packet *pkt;
2345 if (dce_conn->terminate) {
2347 * if the current connection is broken
2348 * we need to clean it up before any other connection
2350 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2351 dcesrv_cleanup_broken_connections(dce_ctx);
2355 dcesrv_cleanup_broken_connections(dce_ctx);
2357 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2359 TALLOC_FREE(subreq);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2365 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2366 if (!NT_STATUS_IS_OK(status)) {
2367 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2371 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2372 dce_conn->event_ctx,
2375 status = NT_STATUS_NO_MEMORY;
2376 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2379 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2382 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2384 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2385 struct dcesrv_connection);
2386 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2389 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2391 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2392 struct dcesrv_connection);
2393 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2397 static const struct stream_server_ops dcesrv_stream_ops = {
2399 .accept_connection = dcesrv_sock_accept,
2400 .recv_handler = dcesrv_sock_recv,
2401 .send_handler = dcesrv_sock_send,
2404 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2405 struct loadparm_context *lp_ctx,
2406 struct dcesrv_endpoint *e,
2407 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2409 struct dcesrv_socket_context *dcesrv_sock;
2412 const char *endpoint;
2414 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2415 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2417 /* remember the endpoint of this socket */
2418 dcesrv_sock->endpoint = e;
2419 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2421 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2423 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2424 model_ops, &dcesrv_stream_ops,
2425 "unix", endpoint, &port,
2426 lpcfg_socket_options(lp_ctx),
2428 if (!NT_STATUS_IS_OK(status)) {
2429 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2430 endpoint, nt_errstr(status)));
2436 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2437 struct loadparm_context *lp_ctx,
2438 struct dcesrv_endpoint *e,
2439 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2441 struct dcesrv_socket_context *dcesrv_sock;
2445 const char *endpoint;
2447 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2449 if (endpoint == NULL) {
2451 * No identifier specified: use DEFAULT.
2453 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2454 * no endpoint and let the epmapper worry about it.
2456 endpoint = "DEFAULT";
2457 status = dcerpc_binding_set_string_option(e->ep_description,
2460 if (!NT_STATUS_IS_OK(status)) {
2461 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2462 nt_errstr(status)));
2467 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2470 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2471 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2473 /* remember the endpoint of this socket */
2474 dcesrv_sock->endpoint = e;
2475 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2477 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2478 model_ops, &dcesrv_stream_ops,
2479 "unix", full_path, &port,
2480 lpcfg_socket_options(lp_ctx),
2482 if (!NT_STATUS_IS_OK(status)) {
2483 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2484 endpoint, full_path, nt_errstr(status)));
2489 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2490 struct loadparm_context *lp_ctx,
2491 struct dcesrv_endpoint *e,
2492 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2494 struct dcesrv_socket_context *dcesrv_sock;
2496 const char *endpoint;
2498 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2499 if (endpoint == NULL) {
2500 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2501 return NT_STATUS_INVALID_PARAMETER;
2504 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2505 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2507 /* remember the endpoint of this socket */
2508 dcesrv_sock->endpoint = e;
2509 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2511 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2512 model_ops, &dcesrv_stream_ops,
2515 if (!NT_STATUS_IS_OK(status)) {
2516 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2517 endpoint, nt_errstr(status)));
2521 return NT_STATUS_OK;
2525 add a socket address to the list of events, one event per dcerpc endpoint
2527 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2528 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2529 const char *address)
2531 struct dcesrv_socket_context *dcesrv_sock;
2534 const char *endpoint;
2537 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2538 if (endpoint != NULL) {
2539 port = atoi(endpoint);
2542 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2543 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2545 /* remember the endpoint of this socket */
2546 dcesrv_sock->endpoint = e;
2547 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2549 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2550 model_ops, &dcesrv_stream_ops,
2551 "ip", address, &port,
2552 lpcfg_socket_options(dce_ctx->lp_ctx),
2554 if (!NT_STATUS_IS_OK(status)) {
2555 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2556 address, port, nt_errstr(status)));
2560 snprintf(port_str, sizeof(port_str), "%u", port);
2562 status = dcerpc_binding_set_string_option(e->ep_description,
2563 "endpoint", port_str);
2564 if (!NT_STATUS_IS_OK(status)) {
2565 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2566 port_str, nt_errstr(status)));
2570 return NT_STATUS_OK;
2573 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2575 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2576 struct loadparm_context *lp_ctx,
2577 struct dcesrv_endpoint *e,
2578 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2582 /* Add TCP/IP sockets */
2583 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2586 struct interface *ifaces;
2588 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2590 num_interfaces = iface_list_count(ifaces);
2591 for(i = 0; i < num_interfaces; i++) {
2592 const char *address = iface_list_n_ip(ifaces, i);
2593 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2594 NT_STATUS_NOT_OK_RETURN(status);
2600 wcard = iface_list_wildcard(dce_ctx);
2601 NT_STATUS_HAVE_NO_MEMORY(wcard);
2602 for (i=0; wcard[i]; i++) {
2603 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2604 if (NT_STATUS_IS_OK(status)) {
2609 if (num_binds == 0) {
2610 return NT_STATUS_INVALID_PARAMETER_MIX;
2614 return NT_STATUS_OK;
2617 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2618 struct loadparm_context *lp_ctx,
2619 struct dcesrv_endpoint *e,
2620 struct tevent_context *event_ctx,
2621 const struct model_ops *model_ops)
2623 enum dcerpc_transport_t transport =
2624 dcerpc_binding_get_transport(e->ep_description);
2626 switch (transport) {
2627 case NCACN_UNIX_STREAM:
2628 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2631 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2634 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2637 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2640 return NT_STATUS_NOT_SUPPORTED;
2646 * retrieve credentials from a dce_call
2648 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2650 return dce_call->conn->auth_state.session_info->credentials;
2654 * returns true if this is an authenticated call
2656 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2658 enum security_user_level level;
2659 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2660 return level >= SECURITY_USER;
2664 * retrieve account_name for a dce_call
2666 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2668 return dce_call->context->conn->auth_state.session_info->info->account_name;