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;
1393 struct dcesrv_connection_context *context;
1395 if (!call->conn->allow_request) {
1396 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1399 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1400 if (call->conn->auth_state.gensec_security &&
1401 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1402 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1405 context = dcesrv_find_context(call->conn, call->pkt.u.request.context_id);
1406 if (context == NULL) {
1407 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1408 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1411 switch (call->conn->auth_state.auth_level) {
1412 case DCERPC_AUTH_LEVEL_NONE:
1413 case DCERPC_AUTH_LEVEL_PACKET:
1414 case DCERPC_AUTH_LEVEL_INTEGRITY:
1415 case DCERPC_AUTH_LEVEL_PRIVACY:
1418 if (!context->allow_connect) {
1421 addr = tsocket_address_string(call->conn->remote_address,
1424 DEBUG(2, ("%s: restrict auth_level_connect access "
1425 "to [%s] with auth[type=0x%x,level=0x%x] "
1426 "on [%s] from [%s]\n",
1427 __func__, context->iface->name,
1428 call->conn->auth_state.auth_type,
1429 call->conn->auth_state.auth_level,
1430 derpc_transport_string_by_transport(transport),
1432 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1437 if (call->conn->auth_state.auth_level < context->min_auth_level) {
1440 addr = tsocket_address_string(call->conn->remote_address, call);
1442 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1443 "to [%s] with auth[type=0x%x,level=0x%x] "
1444 "on [%s] from [%s]\n",
1446 context->min_auth_level,
1447 context->iface->name,
1448 call->conn->auth_state.auth_type,
1449 call->conn->auth_state.auth_level,
1450 derpc_transport_string_by_transport(transport),
1452 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1455 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1456 NT_STATUS_HAVE_NO_MEMORY(pull);
1458 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1460 call->context = context;
1461 call->ndr_pull = pull;
1463 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1464 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1467 status = dcesrv_check_verification_trailer(call);
1468 if (!NT_STATUS_IS_OK(status)) {
1469 uint32_t faultcode = DCERPC_FAULT_OTHER;
1470 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1471 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1473 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1474 nt_errstr(status)));
1475 return dcesrv_fault(call, faultcode);
1478 /* unravel the NDR for the packet */
1479 status = context->iface->ndr_pull(call, call, pull, &call->r);
1480 if (!NT_STATUS_IS_OK(status)) {
1481 uint8_t extra_flags = 0;
1482 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1483 /* we got an unknown call */
1484 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1485 call->pkt.u.request.opnum, context->iface->name));
1486 dcesrv_save_call(call, "unknown");
1487 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1489 dcesrv_save_call(call, "pullfail");
1491 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1494 if (pull->offset != pull->data_size) {
1495 dcesrv_save_call(call, "extrabytes");
1496 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1497 pull->data_size - pull->offset));
1500 /* call the dispatch function */
1501 status = context->iface->dispatch(call, call, call->r);
1502 if (!NT_STATUS_IS_OK(status)) {
1503 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1504 context->iface->name,
1505 call->pkt.u.request.opnum,
1506 dcerpc_errstr(pull, call->fault_code)));
1507 return dcesrv_fault(call, call->fault_code);
1510 /* add the call to the pending list */
1511 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1513 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1514 return NT_STATUS_OK;
1517 return dcesrv_reply(call);
1522 remove the call from the right list when freed
1524 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1526 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1530 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1532 return conn->local_address;
1535 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1537 return conn->remote_address;
1541 process some input to a dcerpc endpoint server.
1543 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1544 struct ncacn_packet *pkt,
1548 struct dcesrv_call_state *call;
1549 struct dcesrv_call_state *existing = NULL;
1551 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1553 data_blob_free(&blob);
1555 return NT_STATUS_NO_MEMORY;
1557 call->conn = dce_conn;
1558 call->event_ctx = dce_conn->event_ctx;
1559 call->msg_ctx = dce_conn->msg_ctx;
1560 call->state_flags = call->conn->state_flags;
1561 call->time = timeval_current();
1562 call->list = DCESRV_LIST_NONE;
1564 talloc_steal(call, pkt);
1565 talloc_steal(call, blob.data);
1568 talloc_set_destructor(call, dcesrv_call_dequeue);
1570 if (call->conn->allow_bind) {
1572 * Only one bind is possible per connection
1574 call->conn->allow_bind = false;
1575 return dcesrv_bind(call);
1578 /* we have to check the signing here, before combining the
1580 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1581 if (!call->conn->allow_request) {
1582 return dcesrv_fault_disconnect(call,
1583 DCERPC_NCA_S_PROTO_ERROR);
1586 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1588 call->pkt.u.request.stub_and_verifier.length,
1589 0, /* required_flags */
1590 DCERPC_PFC_FLAG_FIRST |
1591 DCERPC_PFC_FLAG_LAST |
1592 DCERPC_PFC_FLAG_PENDING_CANCEL |
1593 0x08 | /* this is not defined, but should be ignored */
1594 DCERPC_PFC_FLAG_CONC_MPX |
1595 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1596 DCERPC_PFC_FLAG_MAYBE |
1597 DCERPC_PFC_FLAG_OBJECT_UUID);
1598 if (!NT_STATUS_IS_OK(status)) {
1599 return dcesrv_fault_disconnect(call,
1600 DCERPC_NCA_S_PROTO_ERROR);
1603 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1605 * We don't use dcesrv_fault_disconnect()
1606 * here, because we don't want to set
1607 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1609 * Note that we don't check against the negotiated
1610 * max_recv_frag, but a hard coded value.
1612 dcesrv_call_disconnect_after(call,
1613 "dcesrv_auth_request - frag_length too large");
1614 return dcesrv_fault(call,
1615 DCERPC_NCA_S_PROTO_ERROR);
1618 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1619 /* only one request is possible in the fragmented list */
1620 if (dce_conn->incoming_fragmented_call_list != NULL) {
1622 call = dce_conn->incoming_fragmented_call_list;
1623 dcesrv_call_disconnect_after(call,
1624 "dcesrv_auth_request - "
1625 "existing fragmented call");
1626 return dcesrv_fault(call,
1627 DCERPC_NCA_S_PROTO_ERROR);
1629 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1630 return dcesrv_fault_disconnect(call,
1631 DCERPC_FAULT_NO_CALL_ACTIVE);
1634 const struct dcerpc_request *nr = &call->pkt.u.request;
1635 const struct dcerpc_request *er = NULL;
1638 existing = dcesrv_find_fragmented_call(dce_conn,
1640 if (existing == NULL) {
1641 dcesrv_call_disconnect_after(call,
1642 "dcesrv_auth_request - "
1643 "no existing fragmented call");
1644 return dcesrv_fault(call,
1645 DCERPC_NCA_S_PROTO_ERROR);
1647 er = &existing->pkt.u.request;
1649 if (call->pkt.ptype != existing->pkt.ptype) {
1650 /* trying to play silly buggers are we? */
1651 return dcesrv_fault_disconnect(existing,
1652 DCERPC_NCA_S_PROTO_ERROR);
1654 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1657 return dcesrv_fault_disconnect(existing,
1658 DCERPC_NCA_S_PROTO_ERROR);
1660 if (nr->context_id != er->context_id) {
1661 return dcesrv_fault_disconnect(existing,
1662 DCERPC_NCA_S_PROTO_ERROR);
1664 if (nr->opnum != er->opnum) {
1665 return dcesrv_fault_disconnect(existing,
1666 DCERPC_NCA_S_PROTO_ERROR);
1671 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1673 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1675 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1676 payload_offset += 16;
1679 ok = dcesrv_auth_pkt_pull(call, &blob,
1680 0, /* required_flags */
1681 DCERPC_PFC_FLAG_FIRST |
1682 DCERPC_PFC_FLAG_LAST |
1683 DCERPC_PFC_FLAG_PENDING_CANCEL |
1684 0x08 | /* this is not defined, but should be ignored */
1685 DCERPC_PFC_FLAG_CONC_MPX |
1686 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1687 DCERPC_PFC_FLAG_MAYBE |
1688 DCERPC_PFC_FLAG_OBJECT_UUID,
1690 &call->pkt.u.request.stub_and_verifier);
1693 * We don't use dcesrv_fault_disconnect()
1694 * here, because we don't want to set
1695 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1697 dcesrv_call_disconnect_after(call,
1698 "dcesrv_auth_request - failed");
1699 if (call->fault_code == 0) {
1700 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1702 return dcesrv_fault(call, call->fault_code);
1706 /* see if this is a continued packet */
1707 if (existing != NULL) {
1708 struct dcerpc_request *er = &existing->pkt.u.request;
1709 const struct dcerpc_request *nr = &call->pkt.u.request;
1715 * Up to 4 MByte are allowed by all fragments
1717 available = dce_conn->max_total_request_size;
1718 if (er->stub_and_verifier.length > available) {
1719 dcesrv_call_disconnect_after(existing,
1720 "dcesrv_auth_request - existing payload too large");
1721 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1723 available -= er->stub_and_verifier.length;
1724 if (nr->alloc_hint > available) {
1725 dcesrv_call_disconnect_after(existing,
1726 "dcesrv_auth_request - alloc hint too large");
1727 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1729 if (nr->stub_and_verifier.length > available) {
1730 dcesrv_call_disconnect_after(existing,
1731 "dcesrv_auth_request - new payload too large");
1732 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1734 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1735 /* allocate at least 1 byte */
1736 alloc_hint = MAX(alloc_hint, 1);
1737 alloc_size = er->stub_and_verifier.length +
1738 nr->stub_and_verifier.length;
1739 alloc_size = MAX(alloc_size, alloc_hint);
1741 er->stub_and_verifier.data =
1742 talloc_realloc(existing,
1743 er->stub_and_verifier.data,
1744 uint8_t, alloc_size);
1745 if (er->stub_and_verifier.data == NULL) {
1747 return dcesrv_fault_with_flags(existing,
1748 DCERPC_FAULT_OUT_OF_RESOURCES,
1749 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1751 memcpy(er->stub_and_verifier.data +
1752 er->stub_and_verifier.length,
1753 nr->stub_and_verifier.data,
1754 nr->stub_and_verifier.length);
1755 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1757 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1763 /* this may not be the last pdu in the chain - if its isn't then
1764 just put it on the incoming_fragmented_call_list and wait for the rest */
1765 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1766 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1768 * Up to 4 MByte are allowed by all fragments
1770 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1771 dcesrv_call_disconnect_after(call,
1772 "dcesrv_auth_request - initial alloc hint too large");
1773 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1775 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1776 return NT_STATUS_OK;
1779 /* This removes any fragments we may have had stashed away */
1780 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1782 switch (call->pkt.ptype) {
1783 case DCERPC_PKT_BIND:
1784 status = dcesrv_bind_nak(call,
1785 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1787 case DCERPC_PKT_AUTH3:
1788 status = dcesrv_auth3(call);
1790 case DCERPC_PKT_ALTER:
1791 status = dcesrv_alter(call);
1793 case DCERPC_PKT_REQUEST:
1794 status = dcesrv_request(call);
1796 case DCERPC_PKT_CO_CANCEL:
1797 case DCERPC_PKT_ORPHANED:
1799 * Window just ignores CO_CANCEL and ORPHANED,
1802 status = NT_STATUS_OK;
1805 case DCERPC_PKT_BIND_ACK:
1806 case DCERPC_PKT_BIND_NAK:
1807 case DCERPC_PKT_ALTER_RESP:
1808 case DCERPC_PKT_RESPONSE:
1809 case DCERPC_PKT_FAULT:
1810 case DCERPC_PKT_SHUTDOWN:
1812 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1816 /* if we are going to be sending a reply then add
1817 it to the list of pending calls. We add it to the end to keep the call
1818 list in the order we will answer */
1819 if (!NT_STATUS_IS_OK(status)) {
1826 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1827 struct loadparm_context *lp_ctx,
1828 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1831 struct dcesrv_context *dce_ctx;
1834 if (!endpoint_servers) {
1835 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1836 return NT_STATUS_INTERNAL_ERROR;
1839 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
1840 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
1842 if (uid_wrapper_enabled()) {
1843 setenv("UID_WRAPPER_MYUID", "1", 1);
1845 dce_ctx->initial_euid = geteuid();
1846 if (uid_wrapper_enabled()) {
1847 unsetenv("UID_WRAPPER_MYUID");
1850 dce_ctx->endpoint_list = NULL;
1851 dce_ctx->lp_ctx = lp_ctx;
1852 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
1853 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
1854 dce_ctx->broken_connections = NULL;
1856 for (i=0;endpoint_servers[i];i++) {
1857 const struct dcesrv_endpoint_server *ep_server;
1859 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
1861 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
1862 return NT_STATUS_INTERNAL_ERROR;
1865 status = ep_server->init_server(dce_ctx, ep_server);
1866 if (!NT_STATUS_IS_OK(status)) {
1867 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
1868 nt_errstr(status)));
1873 *_dce_ctx = dce_ctx;
1874 return NT_STATUS_OK;
1877 /* the list of currently registered DCERPC endpoint servers.
1879 static struct ep_server {
1880 struct dcesrv_endpoint_server *ep_server;
1881 } *ep_servers = NULL;
1882 static int num_ep_servers;
1885 register a DCERPC endpoint server.
1887 The 'name' can be later used by other backends to find the operations
1888 structure for this backend.
1890 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1892 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const void *_ep_server)
1894 const struct dcesrv_endpoint_server *ep_server = _ep_server;
1896 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
1897 /* its already registered! */
1898 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1900 return NT_STATUS_OBJECT_NAME_COLLISION;
1903 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
1905 smb_panic("out of memory in dcerpc_register");
1908 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
1909 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
1913 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1916 return NT_STATUS_OK;
1920 return the operations structure for a named backend of the specified type
1922 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
1926 for (i=0;i<num_ep_servers;i++) {
1927 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
1928 return ep_servers[i].ep_server;
1935 void dcerpc_server_init(struct loadparm_context *lp_ctx)
1937 static bool initialized;
1938 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1939 STATIC_dcerpc_server_MODULES_PROTO;
1940 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
1941 init_module_fn *shared_init;
1948 shared_init = load_samba_modules(NULL, "dcerpc_server");
1950 run_init_functions(static_init);
1951 run_init_functions(shared_init);
1953 talloc_free(shared_init);
1957 return the DCERPC module version, and the size of some critical types
1958 This can be used by endpoint server modules to either detect compilation errors, or provide
1959 multiple implementations for different smbd compilation options in one module
1961 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
1963 static const struct dcesrv_critical_sizes critical_sizes = {
1964 DCERPC_MODULE_VERSION,
1965 sizeof(struct dcesrv_context),
1966 sizeof(struct dcesrv_endpoint),
1967 sizeof(struct dcesrv_endpoint_server),
1968 sizeof(struct dcesrv_interface),
1969 sizeof(struct dcesrv_if_list),
1970 sizeof(struct dcesrv_connection),
1971 sizeof(struct dcesrv_call_state),
1972 sizeof(struct dcesrv_auth),
1973 sizeof(struct dcesrv_handle)
1976 return &critical_sizes;
1979 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
1981 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
1982 struct stream_connection *srv_conn;
1983 srv_conn = talloc_get_type(dce_conn->transport.private_data,
1984 struct stream_connection);
1986 dce_conn->allow_bind = false;
1987 dce_conn->allow_auth3 = false;
1988 dce_conn->allow_alter = false;
1989 dce_conn->allow_request = false;
1991 if (dce_conn->pending_call_list == NULL) {
1992 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
1994 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
1995 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
1999 if (dce_conn->terminate != NULL) {
2003 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2005 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2006 if (dce_conn->terminate == NULL) {
2007 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2009 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2012 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2014 struct dcesrv_connection *cur, *next;
2016 next = dce_ctx->broken_connections;
2017 while (next != NULL) {
2021 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2022 struct dcesrv_connection_context *context_cur, *context_next;
2024 context_next = cur->contexts;
2025 while (context_next != NULL) {
2026 context_cur = context_next;
2027 context_next = context_cur->next;
2029 dcesrv_connection_context_destructor(context_cur);
2033 dcesrv_terminate_connection(cur, cur->terminate);
2037 /* We need this include to be able to compile on some plateforms
2038 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2040 * It has to be that deep because otherwise we have a conflict on
2041 * const struct dcesrv_interface declaration.
2042 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2043 * which conflict with the bind used before.
2045 #include "system/network.h"
2047 struct dcesrv_sock_reply_state {
2048 struct dcesrv_connection *dce_conn;
2049 struct dcesrv_call_state *call;
2053 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2054 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2056 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2058 struct dcesrv_call_state *call;
2060 call = dce_conn->call_list;
2061 if (!call || !call->replies) {
2065 while (call->replies) {
2066 struct data_blob_list_item *rep = call->replies;
2067 struct dcesrv_sock_reply_state *substate;
2068 struct tevent_req *subreq;
2070 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2072 dcesrv_terminate_connection(dce_conn, "no memory");
2076 substate->dce_conn = dce_conn;
2077 substate->call = NULL;
2079 DLIST_REMOVE(call->replies, rep);
2081 if (call->replies == NULL && call->terminate_reason == NULL) {
2082 substate->call = call;
2085 substate->iov.iov_base = (void *) rep->blob.data;
2086 substate->iov.iov_len = rep->blob.length;
2088 subreq = tstream_writev_queue_send(substate,
2089 dce_conn->event_ctx,
2091 dce_conn->send_queue,
2094 dcesrv_terminate_connection(dce_conn, "no memory");
2097 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2101 if (call->terminate_reason != NULL) {
2102 struct tevent_req *subreq;
2104 subreq = tevent_queue_wait_send(call,
2105 dce_conn->event_ctx,
2106 dce_conn->send_queue);
2108 dcesrv_terminate_connection(dce_conn, __location__);
2111 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2115 DLIST_REMOVE(call->conn->call_list, call);
2116 call->list = DCESRV_LIST_NONE;
2119 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2121 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2122 struct dcesrv_sock_reply_state);
2126 struct dcesrv_call_state *call = substate->call;
2128 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2129 TALLOC_FREE(subreq);
2131 status = map_nt_error_from_unix_common(sys_errno);
2132 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2136 talloc_free(substate);
2142 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2144 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2146 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2147 struct dcesrv_call_state);
2151 /* make sure we stop send queue before removing subreq */
2152 tevent_queue_stop(call->conn->send_queue);
2154 ok = tevent_queue_wait_recv(subreq);
2155 TALLOC_FREE(subreq);
2157 dcesrv_terminate_connection(call->conn, __location__);
2161 /* disconnect after 200 usecs */
2162 tv = timeval_current_ofs_usec(200);
2163 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2164 if (subreq == NULL) {
2165 dcesrv_terminate_connection(call->conn, __location__);
2168 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2172 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2174 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2175 struct dcesrv_call_state);
2178 ok = tevent_wakeup_recv(subreq);
2179 TALLOC_FREE(subreq);
2181 dcesrv_terminate_connection(call->conn, __location__);
2185 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2188 struct dcesrv_socket_context {
2189 const struct dcesrv_endpoint *endpoint;
2190 struct dcesrv_context *dcesrv_ctx;
2194 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2196 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2199 struct dcesrv_socket_context *dcesrv_sock =
2200 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2201 enum dcerpc_transport_t transport =
2202 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2203 struct dcesrv_connection *dcesrv_conn = NULL;
2205 struct tevent_req *subreq;
2206 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2208 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2210 if (!srv_conn->session_info) {
2211 status = auth_anonymous_session_info(srv_conn,
2213 &srv_conn->session_info);
2214 if (!NT_STATUS_IS_OK(status)) {
2215 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2216 nt_errstr(status)));
2217 stream_terminate_connection(srv_conn, nt_errstr(status));
2222 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2224 dcesrv_sock->endpoint,
2225 srv_conn->session_info,
2226 srv_conn->event.ctx,
2228 srv_conn->server_id,
2229 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2231 if (!NT_STATUS_IS_OK(status)) {
2232 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2233 nt_errstr(status)));
2234 stream_terminate_connection(srv_conn, nt_errstr(status));
2238 dcesrv_conn->transport.private_data = srv_conn;
2239 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2241 TALLOC_FREE(srv_conn->event.fde);
2243 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2244 if (!dcesrv_conn->send_queue) {
2245 status = NT_STATUS_NO_MEMORY;
2246 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2247 nt_errstr(status)));
2248 stream_terminate_connection(srv_conn, nt_errstr(status));
2252 if (transport == NCACN_NP) {
2253 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2254 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2255 &srv_conn->tstream);
2257 ret = tstream_bsd_existing_socket(dcesrv_conn,
2258 socket_get_fd(srv_conn->socket),
2259 &dcesrv_conn->stream);
2261 status = map_nt_error_from_unix_common(errno);
2262 DEBUG(0, ("dcesrv_sock_accept: "
2263 "failed to setup tstream: %s\n",
2264 nt_errstr(status)));
2265 stream_terminate_connection(srv_conn, nt_errstr(status));
2268 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2271 dcesrv_conn->local_address = srv_conn->local_address;
2272 dcesrv_conn->remote_address = srv_conn->remote_address;
2274 if (transport == NCALRPC) {
2279 sock_fd = socket_get_fd(srv_conn->socket);
2280 if (sock_fd == -1) {
2281 stream_terminate_connection(
2282 srv_conn, "socket_get_fd failed\n");
2286 ret = getpeereid(sock_fd, &uid, &gid);
2288 status = map_nt_error_from_unix_common(errno);
2289 DEBUG(0, ("dcesrv_sock_accept: "
2290 "getpeereid() failed for NCALRPC: %s\n",
2291 nt_errstr(status)));
2292 stream_terminate_connection(srv_conn, nt_errstr(status));
2295 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2296 struct tsocket_address *r = NULL;
2298 ret = tsocket_address_unix_from_path(dcesrv_conn,
2299 "/root/ncalrpc_as_system",
2302 status = map_nt_error_from_unix_common(errno);
2303 DEBUG(0, ("dcesrv_sock_accept: "
2304 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2305 nt_errstr(status)));
2306 stream_terminate_connection(srv_conn, nt_errstr(status));
2309 dcesrv_conn->remote_address = r;
2313 srv_conn->private_data = dcesrv_conn;
2315 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2317 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2318 dcesrv_conn->event_ctx,
2319 dcesrv_conn->stream);
2321 status = NT_STATUS_NO_MEMORY;
2322 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2323 nt_errstr(status)));
2324 stream_terminate_connection(srv_conn, nt_errstr(status));
2327 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2332 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2334 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2335 struct dcesrv_connection);
2336 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2337 struct ncacn_packet *pkt;
2341 if (dce_conn->terminate) {
2343 * if the current connection is broken
2344 * we need to clean it up before any other connection
2346 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2347 dcesrv_cleanup_broken_connections(dce_ctx);
2351 dcesrv_cleanup_broken_connections(dce_ctx);
2353 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2355 TALLOC_FREE(subreq);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2361 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2367 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2368 dce_conn->event_ctx,
2371 status = NT_STATUS_NO_MEMORY;
2372 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2375 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2378 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2380 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2381 struct dcesrv_connection);
2382 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2385 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2387 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2388 struct dcesrv_connection);
2389 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2393 static const struct stream_server_ops dcesrv_stream_ops = {
2395 .accept_connection = dcesrv_sock_accept,
2396 .recv_handler = dcesrv_sock_recv,
2397 .send_handler = dcesrv_sock_send,
2400 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2401 struct loadparm_context *lp_ctx,
2402 struct dcesrv_endpoint *e,
2403 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2405 struct dcesrv_socket_context *dcesrv_sock;
2408 const char *endpoint;
2410 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2411 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2413 /* remember the endpoint of this socket */
2414 dcesrv_sock->endpoint = e;
2415 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2417 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2419 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2420 model_ops, &dcesrv_stream_ops,
2421 "unix", endpoint, &port,
2422 lpcfg_socket_options(lp_ctx),
2424 if (!NT_STATUS_IS_OK(status)) {
2425 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2426 endpoint, nt_errstr(status)));
2432 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2433 struct loadparm_context *lp_ctx,
2434 struct dcesrv_endpoint *e,
2435 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2437 struct dcesrv_socket_context *dcesrv_sock;
2441 const char *endpoint;
2443 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2445 if (endpoint == NULL) {
2447 * No identifier specified: use DEFAULT.
2449 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2450 * no endpoint and let the epmapper worry about it.
2452 endpoint = "DEFAULT";
2453 status = dcerpc_binding_set_string_option(e->ep_description,
2456 if (!NT_STATUS_IS_OK(status)) {
2457 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2458 nt_errstr(status)));
2463 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2466 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2467 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2469 /* remember the endpoint of this socket */
2470 dcesrv_sock->endpoint = e;
2471 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2473 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2474 model_ops, &dcesrv_stream_ops,
2475 "unix", full_path, &port,
2476 lpcfg_socket_options(lp_ctx),
2478 if (!NT_STATUS_IS_OK(status)) {
2479 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2480 endpoint, full_path, nt_errstr(status)));
2485 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2486 struct loadparm_context *lp_ctx,
2487 struct dcesrv_endpoint *e,
2488 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2490 struct dcesrv_socket_context *dcesrv_sock;
2492 const char *endpoint;
2494 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2495 if (endpoint == NULL) {
2496 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2497 return NT_STATUS_INVALID_PARAMETER;
2500 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2501 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2503 /* remember the endpoint of this socket */
2504 dcesrv_sock->endpoint = e;
2505 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2507 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2508 model_ops, &dcesrv_stream_ops,
2511 if (!NT_STATUS_IS_OK(status)) {
2512 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2513 endpoint, nt_errstr(status)));
2517 return NT_STATUS_OK;
2521 add a socket address to the list of events, one event per dcerpc endpoint
2523 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2524 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2525 const char *address)
2527 struct dcesrv_socket_context *dcesrv_sock;
2530 const char *endpoint;
2533 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2534 if (endpoint != NULL) {
2535 port = atoi(endpoint);
2538 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2539 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2541 /* remember the endpoint of this socket */
2542 dcesrv_sock->endpoint = e;
2543 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2545 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2546 model_ops, &dcesrv_stream_ops,
2547 "ip", address, &port,
2548 lpcfg_socket_options(dce_ctx->lp_ctx),
2550 if (!NT_STATUS_IS_OK(status)) {
2551 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2552 address, port, nt_errstr(status)));
2556 snprintf(port_str, sizeof(port_str), "%u", port);
2558 status = dcerpc_binding_set_string_option(e->ep_description,
2559 "endpoint", port_str);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2562 port_str, nt_errstr(status)));
2566 return NT_STATUS_OK;
2569 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2571 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2572 struct loadparm_context *lp_ctx,
2573 struct dcesrv_endpoint *e,
2574 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2578 /* Add TCP/IP sockets */
2579 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2582 struct interface *ifaces;
2584 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2586 num_interfaces = iface_list_count(ifaces);
2587 for(i = 0; i < num_interfaces; i++) {
2588 const char *address = iface_list_n_ip(ifaces, i);
2589 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2590 NT_STATUS_NOT_OK_RETURN(status);
2596 wcard = iface_list_wildcard(dce_ctx);
2597 NT_STATUS_HAVE_NO_MEMORY(wcard);
2598 for (i=0; wcard[i]; i++) {
2599 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2600 if (NT_STATUS_IS_OK(status)) {
2605 if (num_binds == 0) {
2606 return NT_STATUS_INVALID_PARAMETER_MIX;
2610 return NT_STATUS_OK;
2613 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2614 struct loadparm_context *lp_ctx,
2615 struct dcesrv_endpoint *e,
2616 struct tevent_context *event_ctx,
2617 const struct model_ops *model_ops)
2619 enum dcerpc_transport_t transport =
2620 dcerpc_binding_get_transport(e->ep_description);
2622 switch (transport) {
2623 case NCACN_UNIX_STREAM:
2624 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2627 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2630 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2633 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2636 return NT_STATUS_NOT_SUPPORTED;
2642 * retrieve credentials from a dce_call
2644 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2646 return dce_call->conn->auth_state.session_info->credentials;
2650 * returns true if this is an authenticated call
2652 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2654 enum security_user_level level;
2655 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2656 return level >= SECURITY_USER;
2660 * retrieve account_name for a dce_call
2662 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2664 return dce_call->context->conn->auth_state.session_info->info->account_name;