s3:smb2_server: allow logoff, close, unlock, cancel and echo on expired sessions
[Samba.git] / source4 / rpc_server / dcerpc_server.c
blob24eaa65459e466fd651e023ddd68819bdb8d18a9
1 /*
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/>.
23 #include "includes.h"
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"
44 #include "../lib/util/tevent_ntstatus.h"
46 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
47 const struct dcerpc_bind *b,
48 struct dcerpc_ack_ctx *ack_ctx_list);
51 find an association group given a assoc_group_id
53 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
54 uint32_t id)
56 void *id_ptr;
58 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
59 if (id_ptr == NULL) {
60 return NULL;
62 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
66 take a reference to an existing association group
68 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
69 struct dcesrv_context *dce_ctx,
70 uint32_t id)
72 struct dcesrv_assoc_group *assoc_group;
74 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
75 if (assoc_group == NULL) {
76 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
77 return NULL;
79 return talloc_reference(mem_ctx, assoc_group);
82 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
84 int ret;
85 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
86 if (ret != 0) {
87 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
88 assoc_group->id));
90 return 0;
94 allocate a new association group
96 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
97 struct dcesrv_context *dce_ctx)
99 struct dcesrv_assoc_group *assoc_group;
100 int id;
102 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
103 if (assoc_group == NULL) {
104 return NULL;
107 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
108 if (id == -1) {
109 talloc_free(assoc_group);
110 DEBUG(0,(__location__ ": Out of association groups!\n"));
111 return NULL;
114 assoc_group->id = id;
115 assoc_group->dce_ctx = dce_ctx;
117 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
119 return assoc_group;
124 see if two endpoints match
126 static bool endpoints_match(const struct dcerpc_binding *ep1,
127 const struct dcerpc_binding *ep2)
129 enum dcerpc_transport_t t1;
130 enum dcerpc_transport_t t2;
131 const char *e1;
132 const char *e2;
134 t1 = dcerpc_binding_get_transport(ep1);
135 t2 = dcerpc_binding_get_transport(ep2);
137 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
138 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
140 if (t1 != t2) {
141 return false;
144 if (!e1 || !e2) {
145 return e1 == e2;
148 if (strcasecmp(e1, e2) != 0) {
149 return false;
152 return true;
156 find an endpoint in the dcesrv_context
158 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
159 const struct dcerpc_binding *ep_description)
161 struct dcesrv_endpoint *ep;
162 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
163 if (endpoints_match(ep->ep_description, ep_description)) {
164 return ep;
167 return NULL;
171 find a registered context_id from a bind or alter_context
173 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
174 uint16_t context_id)
176 struct dcesrv_connection_context *c;
177 for (c=conn->contexts;c;c=c->next) {
178 if (c->context_id == context_id) return c;
180 return NULL;
184 see if a uuid and if_version match to an interface
186 static bool interface_match(const struct dcesrv_interface *if1,
187 const struct dcesrv_interface *if2)
189 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
190 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
194 find the interface operations on any endpoint with this binding
196 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
197 struct dcerpc_binding *binding,
198 const struct dcesrv_interface *iface)
200 struct dcesrv_endpoint *ep;
201 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
202 if (endpoints_match(ep->ep_description, binding)) {
203 struct dcesrv_if_list *ifl;
204 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
205 if (interface_match(&(ifl->iface), iface)) {
206 return &(ifl->iface);
211 return NULL;
215 see if a uuid and if_version match to an interface
217 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
218 const struct GUID *uuid, uint32_t if_version)
220 return (iface->syntax_id.if_version == if_version &&
221 GUID_equal(&iface->syntax_id.uuid, uuid));
225 find the interface operations on an endpoint by uuid
227 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
228 const struct GUID *uuid, uint32_t if_version)
230 struct dcesrv_if_list *ifl;
231 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
232 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
233 return &(ifl->iface);
236 return NULL;
240 find the earlier parts of a fragmented call awaiting reassembily
242 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
244 struct dcesrv_call_state *c;
245 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
246 if (c->pkt.call_id == call_id) {
247 return c;
250 return NULL;
254 register an interface on an endpoint
256 An endpoint is one unix domain socket (for ncalrpc), one TCP port
257 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
259 Each endpoint can have many interfaces such as netlogon, lsa or
260 samr. Some have essentially the full set.
262 This is driven from the set of interfaces listed in each IDL file
263 via the PIDL generated *__op_init_server() functions.
265 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
266 const char *ep_name,
267 const struct dcesrv_interface *iface,
268 const struct security_descriptor *sd)
270 struct dcesrv_endpoint *ep;
271 struct dcesrv_if_list *ifl;
272 struct dcerpc_binding *binding;
273 bool add_ep = false;
274 NTSTATUS status;
275 enum dcerpc_transport_t transport;
276 char *ep_string = NULL;
277 bool use_single_process = true;
278 const char *ep_process_string;
281 * If we are not using handles, there is no need for force
282 * this service into using a single process.
284 * However, due to the way we listen for RPC packets, we can
285 * only do this if we have a single service per pipe or TCP
286 * port, so we still force a single combined process for
287 * ncalrpc.
289 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
290 use_single_process = false;
293 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
295 if (NT_STATUS_IS_ERR(status)) {
296 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
297 return status;
300 transport = dcerpc_binding_get_transport(binding);
301 if (transport == NCACN_IP_TCP) {
302 int port;
303 char port_str[6];
306 * First check if there is already a port specified, eg
307 * for epmapper on ncacn_ip_tcp:[135]
309 const char *endpoint
310 = dcerpc_binding_get_string_option(binding,
311 "endpoint");
312 if (endpoint == NULL) {
313 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
314 "rpc server port", iface->name, 0);
317 * For RPC services that are not set to use a single
318 * process, we do not default to using the 'rpc server
319 * port' because that would cause a double-bind on
320 * that port.
322 if (port == 0 && !use_single_process) {
323 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
325 if (port != 0) {
326 snprintf(port_str, sizeof(port_str), "%u", port);
327 status = dcerpc_binding_set_string_option(binding,
328 "endpoint",
329 port_str);
330 if (!NT_STATUS_IS_OK(status)) {
331 return status;
337 /* see if the interface is already registered on the endpoint */
338 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
339 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
340 iface->name, ep_name));
341 return NT_STATUS_OBJECT_NAME_COLLISION;
344 /* check if this endpoint exists
346 ep = find_endpoint(dce_ctx, binding);
348 if (ep != NULL) {
350 * We want a new port on ncacn_ip_tcp for NETLOGON, so
351 * it can be multi-process. Other processes can also
352 * listen on distinct ports, if they have one forced
353 * in the code above with eg 'rpc server port:drsuapi = 1027'
355 * If we have mulitiple endpoints on port 0, they each
356 * get an epemeral port (currently by walking up from
357 * 1024).
359 * Because one endpoint can only have one process
360 * model, we add a new IP_TCP endpoint for each model.
362 * This woks in conjunction with the forced overwrite
363 * of ep->use_single_process below.
365 if (ep->use_single_process != use_single_process
366 && transport == NCACN_IP_TCP) {
367 add_ep = true;
371 if (ep == NULL || add_ep) {
372 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
373 if (!ep) {
374 return NT_STATUS_NO_MEMORY;
376 ZERO_STRUCTP(ep);
377 ep->ep_description = talloc_move(ep, &binding);
378 add_ep = true;
380 /* add mgmt interface */
381 ifl = talloc_zero(ep, struct dcesrv_if_list);
382 if (!ifl) {
383 return NT_STATUS_NO_MEMORY;
386 ifl->iface = dcesrv_get_mgmt_interface();
388 DLIST_ADD(ep->interface_list, ifl);
392 * By default don't force into a single process, but if any
393 * interface on this endpoint on this service uses handles
394 * (most do), then we must force into single process mode
396 * By overwriting this each time a new interface is added to
397 * this endpoint, we end up with the most restrictive setting.
399 if (use_single_process) {
400 ep->use_single_process = true;
403 /* talloc a new interface list element */
404 ifl = talloc_zero(ep, struct dcesrv_if_list);
405 if (!ifl) {
406 return NT_STATUS_NO_MEMORY;
409 /* copy the given interface struct to the one on the endpoints interface list */
410 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
412 /* if we have a security descriptor given,
413 * we should see if we can set it up on the endpoint
415 if (sd != NULL) {
416 /* if there's currently no security descriptor given on the endpoint
417 * we try to set it
419 if (ep->sd == NULL) {
420 ep->sd = security_descriptor_copy(ep, sd);
423 /* if now there's no security descriptor given on the endpoint
424 * something goes wrong, either we failed to copy the security descriptor
425 * or there was already one on the endpoint
427 if (ep->sd != NULL) {
428 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
429 " on endpoint '%s'\n",
430 iface->name, ep_name));
431 if (add_ep) free(ep);
432 free(ifl);
433 return NT_STATUS_OBJECT_NAME_COLLISION;
437 /* finally add the interface on the endpoint */
438 DLIST_ADD(ep->interface_list, ifl);
440 /* if it's a new endpoint add it to the dcesrv_context */
441 if (add_ep) {
442 DLIST_ADD(dce_ctx->endpoint_list, ep);
445 /* Re-get the string as we may have set a port */
446 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
448 if (use_single_process) {
449 ep_process_string = "single process required";
450 } else {
451 ep_process_string = "multi process compatible";
454 DBG_INFO("dcesrv_interface_register: interface '%s' "
455 "registered on endpoint '%s' (%s)\n",
456 iface->name, ep_string, ep_process_string);
457 TALLOC_FREE(ep_string);
459 return NT_STATUS_OK;
462 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
463 DATA_BLOB *session_key)
465 if (p->auth_state.session_info->session_key.length) {
466 *session_key = p->auth_state.session_info->session_key;
467 return NT_STATUS_OK;
469 return NT_STATUS_NO_USER_SESSION_KEY;
473 fetch the user session key - may be default (above) or the SMB session key
475 The key is always truncated to 16 bytes
477 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
478 DATA_BLOB *session_key)
480 NTSTATUS status = p->auth_state.session_key(p, session_key);
481 if (!NT_STATUS_IS_OK(status)) {
482 return status;
485 session_key->length = MIN(session_key->length, 16);
487 return NT_STATUS_OK;
491 connect to a dcerpc endpoint
493 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
494 TALLOC_CTX *mem_ctx,
495 const struct dcesrv_endpoint *ep,
496 struct auth_session_info *session_info,
497 struct tevent_context *event_ctx,
498 struct imessaging_context *msg_ctx,
499 struct server_id server_id,
500 uint32_t state_flags,
501 struct dcesrv_connection **_p)
503 struct dcesrv_connection *p;
505 if (!session_info) {
506 return NT_STATUS_ACCESS_DENIED;
509 p = talloc_zero(mem_ctx, struct dcesrv_connection);
510 NT_STATUS_HAVE_NO_MEMORY(p);
512 if (!talloc_reference(p, session_info)) {
513 talloc_free(p);
514 return NT_STATUS_NO_MEMORY;
517 p->dce_ctx = dce_ctx;
518 p->endpoint = ep;
519 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
520 p->auth_state.session_info = session_info;
521 p->auth_state.session_key = dcesrv_generic_session_key;
522 p->event_ctx = event_ctx;
523 p->msg_ctx = msg_ctx;
524 p->server_id = server_id;
525 p->state_flags = state_flags;
526 p->allow_bind = true;
527 p->max_recv_frag = 5840;
528 p->max_xmit_frag = 5840;
529 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
532 * For now we only support NDR32.
534 p->preferred_transfer = &ndr_transfer_syntax_ndr;
536 *_p = p;
537 return NT_STATUS_OK;
541 move a call from an existing linked list to the specified list. This
542 prevents bugs where we forget to remove the call from a previous
543 list when moving it.
545 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
546 enum dcesrv_call_list list)
548 switch (call->list) {
549 case DCESRV_LIST_NONE:
550 break;
551 case DCESRV_LIST_CALL_LIST:
552 DLIST_REMOVE(call->conn->call_list, call);
553 break;
554 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
555 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
556 break;
557 case DCESRV_LIST_PENDING_CALL_LIST:
558 DLIST_REMOVE(call->conn->pending_call_list, call);
559 break;
561 call->list = list;
562 switch (list) {
563 case DCESRV_LIST_NONE:
564 break;
565 case DCESRV_LIST_CALL_LIST:
566 DLIST_ADD_END(call->conn->call_list, call);
567 break;
568 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
569 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
570 break;
571 case DCESRV_LIST_PENDING_CALL_LIST:
572 DLIST_ADD_END(call->conn->pending_call_list, call);
573 break;
577 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
578 const char *reason)
580 if (call->conn->terminate != NULL) {
581 return;
584 call->conn->allow_bind = false;
585 call->conn->allow_alter = false;
586 call->conn->allow_auth3 = false;
587 call->conn->allow_request = false;
589 call->terminate_reason = talloc_strdup(call, reason);
590 if (call->terminate_reason == NULL) {
591 call->terminate_reason = __location__;
596 return a dcerpc bind_nak
598 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
600 struct ncacn_packet pkt;
601 struct dcerpc_bind_nak_version version;
602 struct data_blob_list_item *rep;
603 NTSTATUS status;
604 static const uint8_t _pad[3] = { 0, };
607 * We add the call to the pending_call_list
608 * in order to defer the termination.
610 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
612 /* setup a bind_nak */
613 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
614 pkt.auth_length = 0;
615 pkt.call_id = call->pkt.call_id;
616 pkt.ptype = DCERPC_PKT_BIND_NAK;
617 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
618 pkt.u.bind_nak.reject_reason = reason;
619 version.rpc_vers = 5;
620 version.rpc_vers_minor = 0;
621 pkt.u.bind_nak.num_versions = 1;
622 pkt.u.bind_nak.versions = &version;
623 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
625 rep = talloc_zero(call, struct data_blob_list_item);
626 if (!rep) {
627 return NT_STATUS_NO_MEMORY;
630 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
631 if (!NT_STATUS_IS_OK(status)) {
632 return status;
635 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
637 DLIST_ADD_END(call->replies, rep);
638 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
640 if (call->conn->call_list && call->conn->call_list->replies) {
641 if (call->conn->transport.report_output_data) {
642 call->conn->transport.report_output_data(call->conn);
646 return NT_STATUS_OK;
649 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
650 uint32_t fault_code)
653 * We add the call to the pending_call_list
654 * in order to defer the termination.
656 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
658 return dcesrv_fault_with_flags(call, fault_code,
659 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
662 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
664 DLIST_REMOVE(c->conn->contexts, c);
666 if (c->iface && c->iface->unbind) {
667 c->iface->unbind(c, c->iface);
668 c->iface = NULL;
671 return 0;
674 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
676 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
677 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
678 enum dcerpc_transport_t transport =
679 dcerpc_binding_get_transport(endpoint->ep_description);
680 struct dcesrv_connection_context *context = dce_call->context;
681 const struct dcesrv_interface *iface = context->iface;
683 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
685 if (transport == NCALRPC) {
686 context->allow_connect = true;
687 return;
691 * allow overwrite per interface
692 * allow dcerpc auth level connect:<interface>
694 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
695 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
696 "allow dcerpc auth level connect",
697 iface->name,
698 context->allow_connect);
701 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
702 const struct dcesrv_interface *iface)
704 if (dce_call->context == NULL) {
705 return NT_STATUS_INTERNAL_ERROR;
709 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
710 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
712 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
713 return NT_STATUS_OK;
716 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
717 const struct dcesrv_interface *iface)
719 if (dce_call->context == NULL) {
720 return NT_STATUS_INTERNAL_ERROR;
723 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
724 return NT_STATUS_OK;
727 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
728 const struct dcesrv_interface *iface)
730 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
731 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
732 enum dcerpc_transport_t transport =
733 dcerpc_binding_get_transport(endpoint->ep_description);
734 struct dcesrv_connection_context *context = dce_call->context;
736 if (context == NULL) {
737 return NT_STATUS_INTERNAL_ERROR;
740 if (transport == NCALRPC) {
741 context->allow_connect = true;
742 return NT_STATUS_OK;
746 * allow overwrite per interface
747 * allow dcerpc auth level connect:<interface>
749 context->allow_connect = false;
750 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
751 "allow dcerpc auth level connect",
752 iface->name,
753 context->allow_connect);
754 return NT_STATUS_OK;
757 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
758 const struct dcesrv_interface *iface)
760 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
761 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
762 enum dcerpc_transport_t transport =
763 dcerpc_binding_get_transport(endpoint->ep_description);
764 struct dcesrv_connection_context *context = dce_call->context;
766 if (context == NULL) {
767 return NT_STATUS_INTERNAL_ERROR;
770 if (transport == NCALRPC) {
771 context->allow_connect = true;
772 return NT_STATUS_OK;
776 * allow overwrite per interface
777 * allow dcerpc auth level connect:<interface>
779 context->allow_connect = true;
780 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
781 "allow dcerpc auth level connect",
782 iface->name,
783 context->allow_connect);
784 return NT_STATUS_OK;
787 struct dcesrv_conn_auth_wait_context {
788 struct tevent_req *req;
789 bool done;
790 NTSTATUS status;
793 struct dcesrv_conn_auth_wait_state {
794 uint8_t dummy;
797 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
798 struct tevent_context *ev,
799 void *private_data)
801 struct dcesrv_conn_auth_wait_context *auth_wait =
802 talloc_get_type_abort(private_data,
803 struct dcesrv_conn_auth_wait_context);
804 struct tevent_req *req = NULL;
805 struct dcesrv_conn_auth_wait_state *state = NULL;
807 req = tevent_req_create(mem_ctx, &state,
808 struct dcesrv_conn_auth_wait_state);
809 if (req == NULL) {
810 return NULL;
812 auth_wait->req = req;
814 tevent_req_defer_callback(req, ev);
816 if (!auth_wait->done) {
817 return req;
820 if (tevent_req_nterror(req, auth_wait->status)) {
821 return tevent_req_post(req, ev);
824 tevent_req_done(req);
825 return tevent_req_post(req, ev);
828 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
830 return tevent_req_simple_recv_ntstatus(req);
833 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
835 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
837 if (conn->wait_send != NULL) {
838 return NT_STATUS_INTERNAL_ERROR;
841 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
842 if (auth_wait == NULL) {
843 return NT_STATUS_NO_MEMORY;
846 conn->wait_private = auth_wait;
847 conn->wait_send = dcesrv_conn_auth_wait_send;
848 conn->wait_recv = dcesrv_conn_auth_wait_recv;
849 return NT_STATUS_OK;
852 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
853 NTSTATUS status)
855 struct dcesrv_conn_auth_wait_context *auth_wait =
856 talloc_get_type_abort(conn->wait_private,
857 struct dcesrv_conn_auth_wait_context);
859 auth_wait->done = true;
860 auth_wait->status = status;
862 if (auth_wait->req == NULL) {
863 return;
866 if (tevent_req_nterror(auth_wait->req, status)) {
867 return;
870 tevent_req_done(auth_wait->req);
873 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
875 static void dcesrv_bind_done(struct tevent_req *subreq);
878 handle a bind request
880 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
882 struct dcesrv_connection *conn = call->conn;
883 struct ncacn_packet *pkt = &call->ack_pkt;
884 NTSTATUS status;
885 uint32_t extra_flags = 0;
886 uint16_t max_req = 0;
887 uint16_t max_rep = 0;
888 const char *ep_prefix = "";
889 const char *endpoint = NULL;
890 struct dcesrv_auth *auth = &call->conn->auth_state;
891 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
892 struct dcerpc_ack_ctx *ack_features = NULL;
893 struct tevent_req *subreq = NULL;
894 size_t i;
896 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
897 DCERPC_PKT_BIND,
898 call->pkt.u.bind.auth_info.length,
899 0, /* required flags */
900 DCERPC_PFC_FLAG_FIRST |
901 DCERPC_PFC_FLAG_LAST |
902 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
903 0x08 | /* this is not defined, but should be ignored */
904 DCERPC_PFC_FLAG_CONC_MPX |
905 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
906 DCERPC_PFC_FLAG_MAYBE |
907 DCERPC_PFC_FLAG_OBJECT_UUID);
908 if (!NT_STATUS_IS_OK(status)) {
909 return dcesrv_bind_nak(call,
910 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
913 /* max_recv_frag and max_xmit_frag result always in the same value! */
914 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
915 call->pkt.u.bind.max_recv_frag);
917 * The values are between 2048 and 5840 tested against Windows 2012R2
918 * via ncacn_ip_tcp on port 135.
920 max_req = MAX(2048, max_req);
921 max_rep = MIN(max_req, call->conn->max_recv_frag);
922 /* They are truncated to an 8 byte boundary. */
923 max_rep &= 0xFFF8;
925 /* max_recv_frag and max_xmit_frag result always in the same value! */
926 call->conn->max_recv_frag = max_rep;
927 call->conn->max_xmit_frag = max_rep;
930 if provided, check the assoc_group is valid
932 if (call->pkt.u.bind.assoc_group_id != 0) {
933 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
934 call->conn->dce_ctx,
935 call->pkt.u.bind.assoc_group_id);
936 } else {
937 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
938 call->conn->dce_ctx);
942 * The NETLOGON server does not use handles and so
943 * there is no need to support association groups, but
944 * we need to give back a number regardless.
946 * We have to do this when it is not run as a single process,
947 * because then it can't see the other valid association
948 * groups. We handle this genericly for all endpoints not
949 * running in single process mode.
951 * We know which endpoint we are on even before checking the
952 * iface UUID, so for simplicity we enforce the same policy
953 * for all interfaces on the endpoint.
955 * This means that where NETLOGON
956 * shares an endpoint (such as ncalrpc or of 'lsa over
957 * netlogon' is set) we will still check association groups.
961 if (call->conn->assoc_group == NULL &&
962 !call->conn->endpoint->use_single_process) {
963 call->conn->assoc_group
964 = dcesrv_assoc_group_new(call->conn,
965 call->conn->dce_ctx);
967 if (call->conn->assoc_group == NULL) {
968 return dcesrv_bind_nak(call, 0);
971 if (call->pkt.u.bind.num_contexts < 1) {
972 return dcesrv_bind_nak(call, 0);
975 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
976 call->pkt.u.bind.num_contexts);
977 if (ack_ctx_list == NULL) {
978 return dcesrv_bind_nak(call, 0);
982 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
983 * dcesrv_check_or_create_context()) and do some protocol validation
984 * and set sane defaults.
986 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
987 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
988 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
989 bool is_feature = false;
990 uint64_t features = 0;
992 if (c->num_transfer_syntaxes == 0) {
993 return dcesrv_bind_nak(call, 0);
996 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
997 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1000 * It's only treated as bind time feature request, if the first
1001 * transfer_syntax matches, all others are ignored.
1003 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1004 &features);
1005 if (!is_feature) {
1006 continue;
1009 if (ack_features != NULL) {
1011 * Only one bind time feature context is allowed.
1013 return dcesrv_bind_nak(call, 0);
1015 ack_features = a;
1017 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1018 a->reason.negotiate = 0;
1019 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1020 /* not supported yet */
1022 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1023 a->reason.negotiate |=
1024 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1027 call->conn->bind_time_features = a->reason.negotiate;
1031 * Try to negotiate one new presentation context.
1033 * Deep in here we locate the iface (by uuid) that the client
1034 * requested, from the list of interfaces on the
1035 * call->conn->endpoint, and call iface->bind() on that iface.
1037 * call->conn was set up at the accept() of the socket, and
1038 * call->conn->endpoint has a list of interfaces restricted to
1039 * this port or pipe.
1041 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1042 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1043 return dcesrv_bind_nak(call, 0);
1045 if (!NT_STATUS_IS_OK(status)) {
1046 return status;
1050 * At this point we still don't know which interface (eg
1051 * netlogon, lsa, drsuapi) the caller requested in this bind!
1052 * The most recently added context is available as the first
1053 * element in the linked list at call->conn->contexts, that is
1054 * call->conn->contexts->iface, but they may not have
1055 * requested one at all!
1058 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1059 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1060 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1061 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1064 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1065 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1069 * After finding the interface and setting up the NDR
1070 * transport negotiation etc, handle any authentication that
1071 * is being requested.
1073 if (!dcesrv_auth_bind(call)) {
1075 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1077 * With DCERPC_AUTH_LEVEL_NONE, we get the
1078 * reject_reason in auth->auth_context_id.
1080 return dcesrv_bind_nak(call, auth->auth_context_id);
1084 * This must a be a temporary failure e.g. talloc or invalid
1085 * configuration, e.g. no machine account.
1087 return dcesrv_bind_nak(call,
1088 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1091 /* setup a bind_ack */
1092 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1093 pkt->auth_length = 0;
1094 pkt->call_id = call->pkt.call_id;
1095 pkt->ptype = DCERPC_PKT_BIND_ACK;
1096 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1097 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1098 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1099 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1101 endpoint = dcerpc_binding_get_string_option(
1102 call->conn->endpoint->ep_description,
1103 "endpoint");
1104 if (endpoint == NULL) {
1105 endpoint = "";
1108 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1110 * TODO: check if this is really needed
1112 * Or if we should fix this in our idl files.
1114 ep_prefix = "\\PIPE\\";
1115 endpoint += 6;
1118 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1119 ep_prefix,
1120 endpoint);
1121 if (pkt->u.bind_ack.secondary_address == NULL) {
1122 return NT_STATUS_NO_MEMORY;
1124 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1125 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1126 pkt->u.bind_ack.auth_info = data_blob_null;
1128 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 return dcesrv_bind_nak(call, 0);
1133 if (auth->auth_finished) {
1134 return dcesrv_auth_reply(call);
1137 subreq = gensec_update_send(call, call->event_ctx,
1138 auth->gensec_security,
1139 call->in_auth_info.credentials);
1140 if (subreq == NULL) {
1141 return NT_STATUS_NO_MEMORY;
1143 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1145 return dcesrv_conn_auth_wait_setup(conn);
1148 static void dcesrv_bind_done(struct tevent_req *subreq)
1150 struct dcesrv_call_state *call =
1151 tevent_req_callback_data(subreq,
1152 struct dcesrv_call_state);
1153 struct dcesrv_connection *conn = call->conn;
1154 NTSTATUS status;
1156 status = gensec_update_recv(subreq, call,
1157 &call->out_auth_info->credentials);
1158 TALLOC_FREE(subreq);
1160 status = dcesrv_auth_complete(call, status);
1161 if (!NT_STATUS_IS_OK(status)) {
1162 status = dcesrv_bind_nak(call, 0);
1163 dcesrv_conn_auth_wait_finished(conn, status);
1164 return;
1167 status = dcesrv_auth_reply(call);
1168 dcesrv_conn_auth_wait_finished(conn, status);
1169 return;
1172 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1174 struct ncacn_packet *pkt = &call->ack_pkt;
1175 struct data_blob_list_item *rep = NULL;
1176 NTSTATUS status;
1178 rep = talloc_zero(call, struct data_blob_list_item);
1179 if (!rep) {
1180 return NT_STATUS_NO_MEMORY;
1183 status = ncacn_push_auth(&rep->blob, call, pkt,
1184 call->out_auth_info);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 return status;
1189 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1191 DLIST_ADD_END(call->replies, rep);
1192 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1194 if (call->conn->call_list && call->conn->call_list->replies) {
1195 if (call->conn->transport.report_output_data) {
1196 call->conn->transport.report_output_data(call->conn);
1200 return NT_STATUS_OK;
1204 static void dcesrv_auth3_done(struct tevent_req *subreq);
1207 handle a auth3 request
1209 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1211 struct dcesrv_connection *conn = call->conn;
1212 struct dcesrv_auth *auth = &call->conn->auth_state;
1213 struct tevent_req *subreq = NULL;
1214 NTSTATUS status;
1216 if (!call->conn->allow_auth3) {
1217 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1220 if (call->conn->auth_state.auth_finished) {
1221 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1224 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1225 DCERPC_PKT_AUTH3,
1226 call->pkt.u.auth3.auth_info.length,
1227 0, /* required flags */
1228 DCERPC_PFC_FLAG_FIRST |
1229 DCERPC_PFC_FLAG_LAST |
1230 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1231 0x08 | /* this is not defined, but should be ignored */
1232 DCERPC_PFC_FLAG_CONC_MPX |
1233 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1234 DCERPC_PFC_FLAG_MAYBE |
1235 DCERPC_PFC_FLAG_OBJECT_UUID);
1236 if (!NT_STATUS_IS_OK(status)) {
1237 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1240 /* handle the auth3 in the auth code */
1241 if (!dcesrv_auth_prepare_auth3(call)) {
1243 * we don't send a reply to a auth3 request,
1244 * except by a fault.
1246 * In anycase we mark the connection as
1247 * invalid.
1249 call->conn->auth_state.auth_invalid = true;
1250 if (call->fault_code != 0) {
1251 return dcesrv_fault_disconnect(call, call->fault_code);
1253 TALLOC_FREE(call);
1254 return NT_STATUS_OK;
1257 subreq = gensec_update_send(call, call->event_ctx,
1258 auth->gensec_security,
1259 call->in_auth_info.credentials);
1260 if (subreq == NULL) {
1261 return NT_STATUS_NO_MEMORY;
1263 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1265 return dcesrv_conn_auth_wait_setup(conn);
1268 static void dcesrv_auth3_done(struct tevent_req *subreq)
1270 struct dcesrv_call_state *call =
1271 tevent_req_callback_data(subreq,
1272 struct dcesrv_call_state);
1273 struct dcesrv_connection *conn = call->conn;
1274 NTSTATUS status;
1276 status = gensec_update_recv(subreq, call,
1277 &call->out_auth_info->credentials);
1278 TALLOC_FREE(subreq);
1280 status = dcesrv_auth_complete(call, status);
1281 if (!NT_STATUS_IS_OK(status)) {
1283 * we don't send a reply to a auth3 request,
1284 * except by a fault.
1286 * In anycase we mark the connection as
1287 * invalid.
1289 call->conn->auth_state.auth_invalid = true;
1290 if (call->fault_code != 0) {
1291 status = dcesrv_fault_disconnect(call, call->fault_code);
1292 dcesrv_conn_auth_wait_finished(conn, status);
1293 return;
1295 TALLOC_FREE(call);
1296 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1297 return;
1301 * we don't send a reply to a auth3 request.
1303 TALLOC_FREE(call);
1304 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1305 return;
1309 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1310 const struct dcerpc_bind *b,
1311 const struct dcerpc_ctx_list *ctx,
1312 struct dcerpc_ack_ctx *ack,
1313 bool validate_only,
1314 const struct ndr_syntax_id *supported_transfer)
1316 uint32_t if_version;
1317 struct dcesrv_connection_context *context;
1318 const struct dcesrv_interface *iface;
1319 struct GUID uuid;
1320 NTSTATUS status;
1321 const struct ndr_syntax_id *selected_transfer = NULL;
1322 size_t i;
1323 bool ok;
1325 if (b == NULL) {
1326 return NT_STATUS_INTERNAL_ERROR;
1328 if (ctx == NULL) {
1329 return NT_STATUS_INTERNAL_ERROR;
1331 if (ctx->num_transfer_syntaxes < 1) {
1332 return NT_STATUS_INTERNAL_ERROR;
1334 if (ack == NULL) {
1335 return NT_STATUS_INTERNAL_ERROR;
1337 if (supported_transfer == NULL) {
1338 return NT_STATUS_INTERNAL_ERROR;
1341 switch (ack->result) {
1342 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1343 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1345 * We is already completed.
1347 return NT_STATUS_OK;
1348 default:
1349 break;
1352 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1353 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1355 if_version = ctx->abstract_syntax.if_version;
1356 uuid = ctx->abstract_syntax.uuid;
1358 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1359 if (iface == NULL) {
1360 char *uuid_str = GUID_string(call, &uuid);
1361 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1362 talloc_free(uuid_str);
1364 * We report this only via ack->result
1366 return NT_STATUS_OK;
1369 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1370 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1372 if (validate_only) {
1374 * We report this only via ack->result
1376 return NT_STATUS_OK;
1379 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1381 * we only do NDR encoded dcerpc for now.
1383 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1384 supported_transfer);
1385 if (ok) {
1386 selected_transfer = supported_transfer;
1387 break;
1391 context = dcesrv_find_context(call->conn, ctx->context_id);
1392 if (context != NULL) {
1393 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1394 &ctx->abstract_syntax);
1395 if (!ok) {
1396 return NT_STATUS_RPC_PROTOCOL_ERROR;
1399 if (selected_transfer != NULL) {
1400 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1401 selected_transfer);
1402 if (!ok) {
1403 return NT_STATUS_RPC_PROTOCOL_ERROR;
1406 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1407 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1408 ack->syntax = context->transfer_syntax;
1412 * We report this only via ack->result
1414 return NT_STATUS_OK;
1417 if (selected_transfer == NULL) {
1419 * We report this only via ack->result
1421 return NT_STATUS_OK;
1424 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1425 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1427 /* add this context to the list of available context_ids */
1428 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1429 if (context == NULL) {
1430 return NT_STATUS_NO_MEMORY;
1432 context->conn = call->conn;
1433 context->context_id = ctx->context_id;
1434 context->iface = iface;
1435 context->transfer_syntax = *selected_transfer;
1436 context->private_data = NULL;
1437 DLIST_ADD(call->conn->contexts, context);
1438 call->context = context;
1439 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1441 dcesrv_prepare_context_auth(call);
1444 * Multiplex is supported by default
1446 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1448 status = iface->bind(call, iface, if_version);
1449 call->context = NULL;
1450 if (!NT_STATUS_IS_OK(status)) {
1451 /* we don't want to trigger the iface->unbind() hook */
1452 context->iface = NULL;
1453 talloc_free(context);
1455 * We report this only via ack->result
1457 return NT_STATUS_OK;
1460 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1461 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1462 ack->syntax = context->transfer_syntax;
1463 return NT_STATUS_OK;
1466 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1467 const struct dcerpc_bind *b,
1468 struct dcerpc_ack_ctx *ack_ctx_list)
1470 NTSTATUS status;
1471 size_t i;
1472 bool validate_only = false;
1473 bool preferred_ndr32;
1476 * Try to negotiate one new presentation context,
1477 * using our preferred transfer syntax.
1479 for (i = 0; i < b->num_contexts; i++) {
1480 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1481 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1483 status = dcesrv_check_or_create_context(call, b, c, a,
1484 validate_only,
1485 call->conn->preferred_transfer);
1486 if (!NT_STATUS_IS_OK(status)) {
1487 return status;
1490 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1492 * We managed to negotiate one context.
1494 * => we're done.
1496 validate_only = true;
1500 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1501 call->conn->preferred_transfer);
1502 if (preferred_ndr32) {
1504 * We're done.
1506 return NT_STATUS_OK;
1510 * Try to negotiate one new presentation context,
1511 * using NDR 32 as fallback.
1513 for (i = 0; i < b->num_contexts; i++) {
1514 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1515 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1517 status = dcesrv_check_or_create_context(call, b, c, a,
1518 validate_only,
1519 &ndr_transfer_syntax_ndr);
1520 if (!NT_STATUS_IS_OK(status)) {
1521 return status;
1524 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1526 * We managed to negotiate one context.
1528 * => we're done.
1530 validate_only = true;
1534 return NT_STATUS_OK;
1537 static void dcesrv_alter_done(struct tevent_req *subreq);
1540 handle a alter context request
1542 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1544 struct dcesrv_connection *conn = call->conn;
1545 NTSTATUS status;
1546 bool auth_ok = false;
1547 struct ncacn_packet *pkt = &call->ack_pkt;
1548 uint32_t extra_flags = 0;
1549 struct dcesrv_auth *auth = &call->conn->auth_state;
1550 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1551 struct tevent_req *subreq = NULL;
1552 size_t i;
1554 if (!call->conn->allow_alter) {
1555 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1558 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1559 DCERPC_PKT_ALTER,
1560 call->pkt.u.alter.auth_info.length,
1561 0, /* required flags */
1562 DCERPC_PFC_FLAG_FIRST |
1563 DCERPC_PFC_FLAG_LAST |
1564 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1565 0x08 | /* this is not defined, but should be ignored */
1566 DCERPC_PFC_FLAG_CONC_MPX |
1567 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1568 DCERPC_PFC_FLAG_MAYBE |
1569 DCERPC_PFC_FLAG_OBJECT_UUID);
1570 if (!NT_STATUS_IS_OK(status)) {
1571 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1574 auth_ok = dcesrv_auth_alter(call);
1575 if (!auth_ok) {
1576 if (call->fault_code != 0) {
1577 return dcesrv_fault_disconnect(call, call->fault_code);
1581 if (call->pkt.u.alter.num_contexts < 1) {
1582 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1585 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1586 call->pkt.u.alter.num_contexts);
1587 if (ack_ctx_list == NULL) {
1588 return NT_STATUS_NO_MEMORY;
1592 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1593 * dcesrv_check_or_create_context()) and do some protocol validation
1594 * and set sane defaults.
1596 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1597 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1598 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1600 if (c->num_transfer_syntaxes == 0) {
1601 return dcesrv_fault_disconnect(call,
1602 DCERPC_NCA_S_PROTO_ERROR);
1605 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1606 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1610 * Try to negotiate one new presentation context.
1612 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1613 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1614 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 return status;
1620 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1621 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1622 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1623 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1626 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1627 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1630 /* handle any authentication that is being requested */
1631 if (!auth_ok) {
1632 if (call->in_auth_info.auth_type !=
1633 call->conn->auth_state.auth_type)
1635 return dcesrv_fault_disconnect(call,
1636 DCERPC_FAULT_SEC_PKG_ERROR);
1638 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1641 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1642 pkt->auth_length = 0;
1643 pkt->call_id = call->pkt.call_id;
1644 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1645 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1646 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1647 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1648 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1649 pkt->u.alter_resp.secondary_address = "";
1650 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1651 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1652 pkt->u.alter_resp.auth_info = data_blob_null;
1654 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1655 if (!NT_STATUS_IS_OK(status)) {
1656 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1659 if (auth->auth_finished) {
1660 return dcesrv_auth_reply(call);
1663 subreq = gensec_update_send(call, call->event_ctx,
1664 auth->gensec_security,
1665 call->in_auth_info.credentials);
1666 if (subreq == NULL) {
1667 return NT_STATUS_NO_MEMORY;
1669 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1671 return dcesrv_conn_auth_wait_setup(conn);
1674 static void dcesrv_alter_done(struct tevent_req *subreq)
1676 struct dcesrv_call_state *call =
1677 tevent_req_callback_data(subreq,
1678 struct dcesrv_call_state);
1679 struct dcesrv_connection *conn = call->conn;
1680 NTSTATUS status;
1682 status = gensec_update_recv(subreq, call,
1683 &call->out_auth_info->credentials);
1684 TALLOC_FREE(subreq);
1686 status = dcesrv_auth_complete(call, status);
1687 if (!NT_STATUS_IS_OK(status)) {
1688 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1689 dcesrv_conn_auth_wait_finished(conn, status);
1690 return;
1693 status = dcesrv_auth_reply(call);
1694 dcesrv_conn_auth_wait_finished(conn, status);
1695 return;
1699 possibly save the call for inspection with ndrdump
1701 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1703 #ifdef DEVELOPER
1704 char *fname;
1705 const char *dump_dir;
1706 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1707 if (!dump_dir) {
1708 return;
1710 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1711 dump_dir,
1712 call->context->iface->name,
1713 call->pkt.u.request.opnum,
1714 why);
1715 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1716 DEBUG(0,("RPC SAVED %s\n", fname));
1718 talloc_free(fname);
1719 #endif
1722 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1724 TALLOC_CTX *frame = talloc_stackframe();
1725 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1726 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1727 const struct dcerpc_sec_vt_pcontext pcontext = {
1728 .abstract_syntax = call->context->iface->syntax_id,
1729 .transfer_syntax = call->context->transfer_syntax,
1731 const struct dcerpc_sec_vt_header2 header2 =
1732 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1733 enum ndr_err_code ndr_err;
1734 struct dcerpc_sec_verification_trailer *vt = NULL;
1735 NTSTATUS status = NT_STATUS_OK;
1736 bool ok;
1738 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1740 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1741 frame, &vt);
1742 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1743 status = ndr_map_error2ntstatus(ndr_err);
1744 goto done;
1747 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1748 &pcontext, &header2);
1749 if (!ok) {
1750 status = NT_STATUS_ACCESS_DENIED;
1751 goto done;
1753 done:
1754 TALLOC_FREE(frame);
1755 return status;
1759 handle a dcerpc request packet
1761 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1763 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1764 enum dcerpc_transport_t transport =
1765 dcerpc_binding_get_transport(endpoint->ep_description);
1766 struct ndr_pull *pull;
1767 NTSTATUS status;
1769 if (!call->conn->allow_request) {
1770 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1773 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1774 if (call->conn->auth_state.gensec_security &&
1775 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1776 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1779 if (call->context == NULL) {
1780 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1781 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1784 switch (call->conn->auth_state.auth_level) {
1785 case DCERPC_AUTH_LEVEL_NONE:
1786 case DCERPC_AUTH_LEVEL_PACKET:
1787 case DCERPC_AUTH_LEVEL_INTEGRITY:
1788 case DCERPC_AUTH_LEVEL_PRIVACY:
1789 break;
1790 default:
1791 if (!call->context->allow_connect) {
1792 char *addr;
1794 addr = tsocket_address_string(call->conn->remote_address,
1795 call);
1797 DEBUG(2, ("%s: restrict auth_level_connect access "
1798 "to [%s] with auth[type=0x%x,level=0x%x] "
1799 "on [%s] from [%s]\n",
1800 __func__, call->context->iface->name,
1801 call->conn->auth_state.auth_type,
1802 call->conn->auth_state.auth_level,
1803 derpc_transport_string_by_transport(transport),
1804 addr));
1805 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1807 break;
1810 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1811 char *addr;
1813 addr = tsocket_address_string(call->conn->remote_address, call);
1815 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1816 "to [%s] with auth[type=0x%x,level=0x%x] "
1817 "on [%s] from [%s]\n",
1818 __func__,
1819 call->context->min_auth_level,
1820 call->context->iface->name,
1821 call->conn->auth_state.auth_type,
1822 call->conn->auth_state.auth_level,
1823 derpc_transport_string_by_transport(transport),
1824 addr));
1825 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1828 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1829 NT_STATUS_HAVE_NO_MEMORY(pull);
1831 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1833 call->ndr_pull = pull;
1835 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1836 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1839 status = dcesrv_check_verification_trailer(call);
1840 if (!NT_STATUS_IS_OK(status)) {
1841 uint32_t faultcode = DCERPC_FAULT_OTHER;
1842 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1843 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1845 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1846 nt_errstr(status)));
1847 return dcesrv_fault(call, faultcode);
1850 /* unravel the NDR for the packet */
1851 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1852 if (!NT_STATUS_IS_OK(status)) {
1853 uint8_t extra_flags = 0;
1854 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1855 /* we got an unknown call */
1856 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1857 call->pkt.u.request.opnum,
1858 call->context->iface->name));
1859 dcesrv_save_call(call, "unknown");
1860 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1861 } else {
1862 dcesrv_save_call(call, "pullfail");
1864 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1867 if (pull->offset != pull->data_size) {
1868 dcesrv_save_call(call, "extrabytes");
1869 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1870 pull->data_size - pull->offset));
1873 /* call the dispatch function */
1874 status = call->context->iface->dispatch(call, call, call->r);
1875 if (!NT_STATUS_IS_OK(status)) {
1876 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1877 call->context->iface->name,
1878 call->pkt.u.request.opnum,
1879 dcerpc_errstr(pull, call->fault_code)));
1880 return dcesrv_fault(call, call->fault_code);
1883 /* add the call to the pending list */
1884 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1886 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1887 return NT_STATUS_OK;
1890 return dcesrv_reply(call);
1895 remove the call from the right list when freed
1897 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1899 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1900 return 0;
1903 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1905 return conn->local_address;
1908 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1910 return conn->remote_address;
1914 process some input to a dcerpc endpoint server.
1916 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1917 struct ncacn_packet *pkt,
1918 DATA_BLOB blob)
1920 NTSTATUS status;
1921 struct dcesrv_call_state *call;
1922 struct dcesrv_call_state *existing = NULL;
1924 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1925 if (!call) {
1926 data_blob_free(&blob);
1927 talloc_free(pkt);
1928 return NT_STATUS_NO_MEMORY;
1930 call->conn = dce_conn;
1931 call->event_ctx = dce_conn->event_ctx;
1932 call->msg_ctx = dce_conn->msg_ctx;
1933 call->state_flags = call->conn->state_flags;
1934 call->time = timeval_current();
1935 call->list = DCESRV_LIST_NONE;
1937 talloc_steal(call, pkt);
1938 talloc_steal(call, blob.data);
1939 call->pkt = *pkt;
1941 talloc_set_destructor(call, dcesrv_call_dequeue);
1943 if (call->conn->allow_bind) {
1945 * Only one bind is possible per connection
1947 call->conn->allow_bind = false;
1948 return dcesrv_bind(call);
1951 /* we have to check the signing here, before combining the
1952 pdus */
1953 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1954 if (!call->conn->allow_request) {
1955 return dcesrv_fault_disconnect(call,
1956 DCERPC_NCA_S_PROTO_ERROR);
1959 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1960 DCERPC_PKT_REQUEST,
1961 call->pkt.u.request.stub_and_verifier.length,
1962 0, /* required_flags */
1963 DCERPC_PFC_FLAG_FIRST |
1964 DCERPC_PFC_FLAG_LAST |
1965 DCERPC_PFC_FLAG_PENDING_CANCEL |
1966 0x08 | /* this is not defined, but should be ignored */
1967 DCERPC_PFC_FLAG_CONC_MPX |
1968 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1969 DCERPC_PFC_FLAG_MAYBE |
1970 DCERPC_PFC_FLAG_OBJECT_UUID);
1971 if (!NT_STATUS_IS_OK(status)) {
1972 return dcesrv_fault_disconnect(call,
1973 DCERPC_NCA_S_PROTO_ERROR);
1976 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1978 * We don't use dcesrv_fault_disconnect()
1979 * here, because we don't want to set
1980 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1982 * Note that we don't check against the negotiated
1983 * max_recv_frag, but a hard coded value.
1985 dcesrv_call_disconnect_after(call,
1986 "dcesrv_auth_request - frag_length too large");
1987 return dcesrv_fault(call,
1988 DCERPC_NCA_S_PROTO_ERROR);
1991 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1992 if (dce_conn->pending_call_list != NULL) {
1994 * concurrent requests are only allowed
1995 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1997 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1998 dcesrv_call_disconnect_after(call,
1999 "dcesrv_auth_request - "
2000 "existing pending call without CONN_MPX");
2001 return dcesrv_fault(call,
2002 DCERPC_NCA_S_PROTO_ERROR);
2005 /* only one request is possible in the fragmented list */
2006 if (dce_conn->incoming_fragmented_call_list != NULL) {
2007 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2009 * Without DCERPC_PFC_FLAG_CONC_MPX
2010 * we need to return the FAULT on the
2011 * already existing call.
2013 * This is important to get the
2014 * call_id and context_id right.
2016 TALLOC_FREE(call);
2017 call = dce_conn->incoming_fragmented_call_list;
2019 dcesrv_call_disconnect_after(call,
2020 "dcesrv_auth_request - "
2021 "existing fragmented call");
2022 return dcesrv_fault(call,
2023 DCERPC_NCA_S_PROTO_ERROR);
2025 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2026 return dcesrv_fault_disconnect(call,
2027 DCERPC_FAULT_NO_CALL_ACTIVE);
2029 call->context = dcesrv_find_context(call->conn,
2030 call->pkt.u.request.context_id);
2031 if (call->context == NULL) {
2032 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2033 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2035 } else {
2036 const struct dcerpc_request *nr = &call->pkt.u.request;
2037 const struct dcerpc_request *er = NULL;
2038 int cmp;
2040 existing = dcesrv_find_fragmented_call(dce_conn,
2041 call->pkt.call_id);
2042 if (existing == NULL) {
2043 dcesrv_call_disconnect_after(call,
2044 "dcesrv_auth_request - "
2045 "no existing fragmented call");
2046 return dcesrv_fault(call,
2047 DCERPC_NCA_S_PROTO_ERROR);
2049 er = &existing->pkt.u.request;
2051 if (call->pkt.ptype != existing->pkt.ptype) {
2052 /* trying to play silly buggers are we? */
2053 return dcesrv_fault_disconnect(existing,
2054 DCERPC_NCA_S_PROTO_ERROR);
2056 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2057 sizeof(pkt->drep));
2058 if (cmp != 0) {
2059 return dcesrv_fault_disconnect(existing,
2060 DCERPC_NCA_S_PROTO_ERROR);
2062 if (nr->context_id != er->context_id) {
2063 return dcesrv_fault_disconnect(existing,
2064 DCERPC_NCA_S_PROTO_ERROR);
2066 if (nr->opnum != er->opnum) {
2067 return dcesrv_fault_disconnect(existing,
2068 DCERPC_NCA_S_PROTO_ERROR);
2073 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2074 bool ok;
2075 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2077 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2078 payload_offset += 16;
2081 ok = dcesrv_auth_pkt_pull(call, &blob,
2082 0, /* required_flags */
2083 DCERPC_PFC_FLAG_FIRST |
2084 DCERPC_PFC_FLAG_LAST |
2085 DCERPC_PFC_FLAG_PENDING_CANCEL |
2086 0x08 | /* this is not defined, but should be ignored */
2087 DCERPC_PFC_FLAG_CONC_MPX |
2088 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2089 DCERPC_PFC_FLAG_MAYBE |
2090 DCERPC_PFC_FLAG_OBJECT_UUID,
2091 payload_offset,
2092 &call->pkt.u.request.stub_and_verifier);
2093 if (!ok) {
2095 * We don't use dcesrv_fault_disconnect()
2096 * here, because we don't want to set
2097 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2099 dcesrv_call_disconnect_after(call,
2100 "dcesrv_auth_request - failed");
2101 if (call->fault_code == 0) {
2102 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2104 return dcesrv_fault(call, call->fault_code);
2108 /* see if this is a continued packet */
2109 if (existing != NULL) {
2110 struct dcerpc_request *er = &existing->pkt.u.request;
2111 const struct dcerpc_request *nr = &call->pkt.u.request;
2112 size_t available;
2113 size_t alloc_size;
2114 size_t alloc_hint;
2117 * Up to 4 MByte are allowed by all fragments
2119 available = dce_conn->max_total_request_size;
2120 if (er->stub_and_verifier.length > available) {
2121 dcesrv_call_disconnect_after(existing,
2122 "dcesrv_auth_request - existing payload too large");
2123 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2125 available -= er->stub_and_verifier.length;
2126 if (nr->alloc_hint > available) {
2127 dcesrv_call_disconnect_after(existing,
2128 "dcesrv_auth_request - alloc hint too large");
2129 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2131 if (nr->stub_and_verifier.length > available) {
2132 dcesrv_call_disconnect_after(existing,
2133 "dcesrv_auth_request - new payload too large");
2134 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2136 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2137 /* allocate at least 1 byte */
2138 alloc_hint = MAX(alloc_hint, 1);
2139 alloc_size = er->stub_and_verifier.length +
2140 nr->stub_and_verifier.length;
2141 alloc_size = MAX(alloc_size, alloc_hint);
2143 er->stub_and_verifier.data =
2144 talloc_realloc(existing,
2145 er->stub_and_verifier.data,
2146 uint8_t, alloc_size);
2147 if (er->stub_and_verifier.data == NULL) {
2148 TALLOC_FREE(call);
2149 return dcesrv_fault_with_flags(existing,
2150 DCERPC_FAULT_OUT_OF_RESOURCES,
2151 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2153 memcpy(er->stub_and_verifier.data +
2154 er->stub_and_verifier.length,
2155 nr->stub_and_verifier.data,
2156 nr->stub_and_verifier.length);
2157 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2159 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2161 TALLOC_FREE(call);
2162 call = existing;
2165 /* this may not be the last pdu in the chain - if its isn't then
2166 just put it on the incoming_fragmented_call_list and wait for the rest */
2167 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2168 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2170 * Up to 4 MByte are allowed by all fragments
2172 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2173 dcesrv_call_disconnect_after(call,
2174 "dcesrv_auth_request - initial alloc hint too large");
2175 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2177 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2178 return NT_STATUS_OK;
2181 /* This removes any fragments we may have had stashed away */
2182 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2184 switch (call->pkt.ptype) {
2185 case DCERPC_PKT_BIND:
2186 status = dcesrv_bind_nak(call,
2187 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2188 break;
2189 case DCERPC_PKT_AUTH3:
2190 status = dcesrv_auth3(call);
2191 break;
2192 case DCERPC_PKT_ALTER:
2193 status = dcesrv_alter(call);
2194 break;
2195 case DCERPC_PKT_REQUEST:
2196 status = dcesrv_request(call);
2197 break;
2198 case DCERPC_PKT_CO_CANCEL:
2199 case DCERPC_PKT_ORPHANED:
2201 * Window just ignores CO_CANCEL and ORPHANED,
2202 * so we do...
2204 status = NT_STATUS_OK;
2205 TALLOC_FREE(call);
2206 break;
2207 case DCERPC_PKT_BIND_ACK:
2208 case DCERPC_PKT_BIND_NAK:
2209 case DCERPC_PKT_ALTER_RESP:
2210 case DCERPC_PKT_RESPONSE:
2211 case DCERPC_PKT_FAULT:
2212 case DCERPC_PKT_SHUTDOWN:
2213 default:
2214 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2215 break;
2218 /* if we are going to be sending a reply then add
2219 it to the list of pending calls. We add it to the end to keep the call
2220 list in the order we will answer */
2221 if (!NT_STATUS_IS_OK(status)) {
2222 talloc_free(call);
2225 return status;
2228 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2229 struct loadparm_context *lp_ctx,
2230 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2232 NTSTATUS status;
2233 struct dcesrv_context *dce_ctx;
2234 int i;
2236 if (!endpoint_servers) {
2237 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2238 return NT_STATUS_INTERNAL_ERROR;
2241 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2242 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2244 if (uid_wrapper_enabled()) {
2245 setenv("UID_WRAPPER_MYUID", "1", 1);
2247 dce_ctx->initial_euid = geteuid();
2248 if (uid_wrapper_enabled()) {
2249 unsetenv("UID_WRAPPER_MYUID");
2252 dce_ctx->endpoint_list = NULL;
2253 dce_ctx->lp_ctx = lp_ctx;
2254 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2255 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2256 dce_ctx->broken_connections = NULL;
2258 for (i=0;endpoint_servers[i];i++) {
2259 const struct dcesrv_endpoint_server *ep_server;
2261 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2262 if (!ep_server) {
2263 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2264 return NT_STATUS_INTERNAL_ERROR;
2267 status = ep_server->init_server(dce_ctx, ep_server);
2268 if (!NT_STATUS_IS_OK(status)) {
2269 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2270 nt_errstr(status)));
2271 return status;
2275 *_dce_ctx = dce_ctx;
2276 return NT_STATUS_OK;
2279 /* the list of currently registered DCERPC endpoint servers.
2281 static struct ep_server {
2282 struct dcesrv_endpoint_server *ep_server;
2283 } *ep_servers = NULL;
2284 static int num_ep_servers;
2287 register a DCERPC endpoint server.
2289 The 'name' can be later used by other backends to find the operations
2290 structure for this backend.
2293 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2296 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2297 /* its already registered! */
2298 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2299 ep_server->name));
2300 return NT_STATUS_OBJECT_NAME_COLLISION;
2303 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2304 if (!ep_servers) {
2305 smb_panic("out of memory in dcerpc_register");
2308 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2309 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2311 num_ep_servers++;
2313 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2314 ep_server->name));
2316 return NT_STATUS_OK;
2320 return the operations structure for a named backend of the specified type
2322 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2324 int i;
2326 for (i=0;i<num_ep_servers;i++) {
2327 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2328 return ep_servers[i].ep_server;
2332 return NULL;
2335 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2337 static bool initialized;
2338 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2339 STATIC_dcerpc_server_MODULES_PROTO;
2340 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2341 init_module_fn *shared_init;
2343 if (initialized) {
2344 return;
2346 initialized = true;
2348 shared_init = load_samba_modules(NULL, "dcerpc_server");
2350 run_init_functions(NULL, static_init);
2351 run_init_functions(NULL, shared_init);
2353 talloc_free(shared_init);
2357 return the DCERPC module version, and the size of some critical types
2358 This can be used by endpoint server modules to either detect compilation errors, or provide
2359 multiple implementations for different smbd compilation options in one module
2361 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2363 static const struct dcesrv_critical_sizes critical_sizes = {
2364 DCERPC_MODULE_VERSION,
2365 sizeof(struct dcesrv_context),
2366 sizeof(struct dcesrv_endpoint),
2367 sizeof(struct dcesrv_endpoint_server),
2368 sizeof(struct dcesrv_interface),
2369 sizeof(struct dcesrv_if_list),
2370 sizeof(struct dcesrv_connection),
2371 sizeof(struct dcesrv_call_state),
2372 sizeof(struct dcesrv_auth),
2373 sizeof(struct dcesrv_handle)
2376 return &critical_sizes;
2379 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2381 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2382 struct stream_connection *srv_conn;
2383 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2384 struct stream_connection);
2386 dce_conn->wait_send = NULL;
2387 dce_conn->wait_recv = NULL;
2388 dce_conn->wait_private = NULL;
2390 dce_conn->allow_bind = false;
2391 dce_conn->allow_auth3 = false;
2392 dce_conn->allow_alter = false;
2393 dce_conn->allow_request = false;
2395 if (dce_conn->pending_call_list == NULL) {
2396 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2398 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2399 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2400 return;
2403 if (dce_conn->terminate != NULL) {
2404 return;
2407 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2408 reason));
2409 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2410 if (dce_conn->terminate == NULL) {
2411 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2413 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2416 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2418 struct dcesrv_connection *cur, *next;
2420 next = dce_ctx->broken_connections;
2421 while (next != NULL) {
2422 cur = next;
2423 next = cur->next;
2425 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2426 struct dcesrv_connection_context *context_cur, *context_next;
2428 context_next = cur->contexts;
2429 while (context_next != NULL) {
2430 context_cur = context_next;
2431 context_next = context_cur->next;
2433 dcesrv_connection_context_destructor(context_cur);
2437 dcesrv_terminate_connection(cur, cur->terminate);
2441 /* We need this include to be able to compile on some plateforms
2442 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2443 * correctly.
2444 * It has to be that deep because otherwise we have a conflict on
2445 * const struct dcesrv_interface declaration.
2446 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2447 * which conflict with the bind used before.
2449 #include "system/network.h"
2451 struct dcesrv_sock_reply_state {
2452 struct dcesrv_connection *dce_conn;
2453 struct dcesrv_call_state *call;
2454 struct iovec iov;
2457 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2458 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2460 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2462 struct dcesrv_call_state *call;
2464 call = dce_conn->call_list;
2465 if (!call || !call->replies) {
2466 return;
2469 while (call->replies) {
2470 struct data_blob_list_item *rep = call->replies;
2471 struct dcesrv_sock_reply_state *substate;
2472 struct tevent_req *subreq;
2474 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2475 if (!substate) {
2476 dcesrv_terminate_connection(dce_conn, "no memory");
2477 return;
2480 substate->dce_conn = dce_conn;
2481 substate->call = NULL;
2483 DLIST_REMOVE(call->replies, rep);
2485 if (call->replies == NULL && call->terminate_reason == NULL) {
2486 substate->call = call;
2489 substate->iov.iov_base = (void *) rep->blob.data;
2490 substate->iov.iov_len = rep->blob.length;
2492 subreq = tstream_writev_queue_send(substate,
2493 dce_conn->event_ctx,
2494 dce_conn->stream,
2495 dce_conn->send_queue,
2496 &substate->iov, 1);
2497 if (!subreq) {
2498 dcesrv_terminate_connection(dce_conn, "no memory");
2499 return;
2501 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2502 substate);
2505 if (call->terminate_reason != NULL) {
2506 struct tevent_req *subreq;
2508 subreq = tevent_queue_wait_send(call,
2509 dce_conn->event_ctx,
2510 dce_conn->send_queue);
2511 if (!subreq) {
2512 dcesrv_terminate_connection(dce_conn, __location__);
2513 return;
2515 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2516 call);
2519 DLIST_REMOVE(call->conn->call_list, call);
2520 call->list = DCESRV_LIST_NONE;
2523 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2525 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2526 struct dcesrv_sock_reply_state);
2527 int ret;
2528 int sys_errno;
2529 NTSTATUS status;
2530 struct dcesrv_call_state *call = substate->call;
2532 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2533 TALLOC_FREE(subreq);
2534 if (ret == -1) {
2535 status = map_nt_error_from_unix_common(sys_errno);
2536 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2537 return;
2540 talloc_free(substate);
2541 if (call) {
2542 talloc_free(call);
2546 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2548 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2550 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2551 struct dcesrv_call_state);
2552 bool ok;
2553 struct timeval tv;
2555 /* make sure we stop send queue before removing subreq */
2556 tevent_queue_stop(call->conn->send_queue);
2558 ok = tevent_queue_wait_recv(subreq);
2559 TALLOC_FREE(subreq);
2560 if (!ok) {
2561 dcesrv_terminate_connection(call->conn, __location__);
2562 return;
2565 /* disconnect after 200 usecs */
2566 tv = timeval_current_ofs_usec(200);
2567 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2568 if (subreq == NULL) {
2569 dcesrv_terminate_connection(call->conn, __location__);
2570 return;
2572 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2573 call);
2576 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2578 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2579 struct dcesrv_call_state);
2580 bool ok;
2582 ok = tevent_wakeup_recv(subreq);
2583 TALLOC_FREE(subreq);
2584 if (!ok) {
2585 dcesrv_terminate_connection(call->conn, __location__);
2586 return;
2589 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2592 struct dcesrv_socket_context {
2593 const struct dcesrv_endpoint *endpoint;
2594 struct dcesrv_context *dcesrv_ctx;
2598 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2600 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2602 NTSTATUS status;
2603 struct dcesrv_socket_context *dcesrv_sock =
2604 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2605 enum dcerpc_transport_t transport =
2606 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2607 struct dcesrv_connection *dcesrv_conn = NULL;
2608 int ret;
2609 struct tevent_req *subreq;
2610 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2612 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2614 if (!srv_conn->session_info) {
2615 status = auth_anonymous_session_info(srv_conn,
2616 lp_ctx,
2617 &srv_conn->session_info);
2618 if (!NT_STATUS_IS_OK(status)) {
2619 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2620 nt_errstr(status)));
2621 stream_terminate_connection(srv_conn, nt_errstr(status));
2622 return;
2627 * This fills in dcesrv_conn->endpoint with the endpoint
2628 * associated with the socket. From this point on we know
2629 * which (group of) services we are handling, but not the
2630 * specific interface.
2633 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2634 srv_conn,
2635 dcesrv_sock->endpoint,
2636 srv_conn->session_info,
2637 srv_conn->event.ctx,
2638 srv_conn->msg_ctx,
2639 srv_conn->server_id,
2640 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2641 &dcesrv_conn);
2642 if (!NT_STATUS_IS_OK(status)) {
2643 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2644 nt_errstr(status)));
2645 stream_terminate_connection(srv_conn, nt_errstr(status));
2646 return;
2649 dcesrv_conn->transport.private_data = srv_conn;
2650 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2652 TALLOC_FREE(srv_conn->event.fde);
2654 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2655 if (!dcesrv_conn->send_queue) {
2656 status = NT_STATUS_NO_MEMORY;
2657 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2658 nt_errstr(status)));
2659 stream_terminate_connection(srv_conn, nt_errstr(status));
2660 return;
2663 if (transport == NCACN_NP) {
2664 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2665 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2666 &srv_conn->tstream);
2667 } else {
2668 ret = tstream_bsd_existing_socket(dcesrv_conn,
2669 socket_get_fd(srv_conn->socket),
2670 &dcesrv_conn->stream);
2671 if (ret == -1) {
2672 status = map_nt_error_from_unix_common(errno);
2673 DEBUG(0, ("dcesrv_sock_accept: "
2674 "failed to setup tstream: %s\n",
2675 nt_errstr(status)));
2676 stream_terminate_connection(srv_conn, nt_errstr(status));
2677 return;
2679 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2682 dcesrv_conn->local_address = srv_conn->local_address;
2683 dcesrv_conn->remote_address = srv_conn->remote_address;
2685 if (transport == NCALRPC) {
2686 uid_t uid;
2687 gid_t gid;
2688 int sock_fd;
2690 sock_fd = socket_get_fd(srv_conn->socket);
2691 if (sock_fd == -1) {
2692 stream_terminate_connection(
2693 srv_conn, "socket_get_fd failed\n");
2694 return;
2697 ret = getpeereid(sock_fd, &uid, &gid);
2698 if (ret == -1) {
2699 status = map_nt_error_from_unix_common(errno);
2700 DEBUG(0, ("dcesrv_sock_accept: "
2701 "getpeereid() failed for NCALRPC: %s\n",
2702 nt_errstr(status)));
2703 stream_terminate_connection(srv_conn, nt_errstr(status));
2704 return;
2706 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2707 struct tsocket_address *r = NULL;
2709 ret = tsocket_address_unix_from_path(dcesrv_conn,
2710 AS_SYSTEM_MAGIC_PATH_TOKEN,
2711 &r);
2712 if (ret == -1) {
2713 status = map_nt_error_from_unix_common(errno);
2714 DEBUG(0, ("dcesrv_sock_accept: "
2715 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2716 nt_errstr(status)));
2717 stream_terminate_connection(srv_conn, nt_errstr(status));
2718 return;
2720 dcesrv_conn->remote_address = r;
2724 srv_conn->private_data = dcesrv_conn;
2726 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2728 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2729 dcesrv_conn->event_ctx,
2730 dcesrv_conn->stream);
2731 if (!subreq) {
2732 status = NT_STATUS_NO_MEMORY;
2733 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2734 nt_errstr(status)));
2735 stream_terminate_connection(srv_conn, nt_errstr(status));
2736 return;
2738 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2740 return;
2743 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2745 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2747 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2748 struct dcesrv_connection);
2749 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2750 struct ncacn_packet *pkt;
2751 DATA_BLOB buffer;
2752 NTSTATUS status;
2754 if (dce_conn->terminate) {
2756 * if the current connection is broken
2757 * we need to clean it up before any other connection
2759 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2760 dcesrv_cleanup_broken_connections(dce_ctx);
2761 return;
2764 dcesrv_cleanup_broken_connections(dce_ctx);
2766 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2767 &pkt, &buffer);
2768 TALLOC_FREE(subreq);
2769 if (!NT_STATUS_IS_OK(status)) {
2770 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2771 return;
2774 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2775 if (!NT_STATUS_IS_OK(status)) {
2776 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2777 return;
2781 * This is used to block the connection during
2782 * pending authentication.
2784 if (dce_conn->wait_send != NULL) {
2785 subreq = dce_conn->wait_send(dce_conn,
2786 dce_conn->event_ctx,
2787 dce_conn->wait_private);
2788 if (!subreq) {
2789 status = NT_STATUS_NO_MEMORY;
2790 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2791 return;
2793 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2794 return;
2797 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2798 dce_conn->event_ctx,
2799 dce_conn->stream);
2800 if (!subreq) {
2801 status = NT_STATUS_NO_MEMORY;
2802 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2803 return;
2805 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2808 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2810 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2811 struct dcesrv_connection);
2812 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2813 NTSTATUS status;
2815 if (dce_conn->terminate) {
2817 * if the current connection is broken
2818 * we need to clean it up before any other connection
2820 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2821 dcesrv_cleanup_broken_connections(dce_ctx);
2822 return;
2825 dcesrv_cleanup_broken_connections(dce_ctx);
2827 status = dce_conn->wait_recv(subreq);
2828 dce_conn->wait_send = NULL;
2829 dce_conn->wait_recv = NULL;
2830 dce_conn->wait_private = NULL;
2831 TALLOC_FREE(subreq);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2834 return;
2837 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2838 dce_conn->event_ctx,
2839 dce_conn->stream);
2840 if (!subreq) {
2841 status = NT_STATUS_NO_MEMORY;
2842 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2843 return;
2845 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2848 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2850 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2851 struct dcesrv_connection);
2852 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2855 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2857 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2858 struct dcesrv_connection);
2859 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2863 static const struct stream_server_ops dcesrv_stream_ops = {
2864 .name = "rpc",
2865 .accept_connection = dcesrv_sock_accept,
2866 .recv_handler = dcesrv_sock_recv,
2867 .send_handler = dcesrv_sock_send,
2870 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2871 struct loadparm_context *lp_ctx,
2872 struct dcesrv_endpoint *e,
2873 struct tevent_context *event_ctx,
2874 const struct model_ops *model_ops,
2875 void *process_context)
2877 struct dcesrv_socket_context *dcesrv_sock;
2878 uint16_t port = 1;
2879 NTSTATUS status;
2880 const char *endpoint;
2882 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2883 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2885 /* remember the endpoint of this socket */
2886 dcesrv_sock->endpoint = e;
2887 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2889 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2891 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2892 model_ops, &dcesrv_stream_ops,
2893 "unix", endpoint, &port,
2894 lpcfg_socket_options(lp_ctx),
2895 dcesrv_sock, process_context);
2896 if (!NT_STATUS_IS_OK(status)) {
2897 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2898 endpoint, nt_errstr(status)));
2901 return status;
2904 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2905 struct loadparm_context *lp_ctx,
2906 struct dcesrv_endpoint *e,
2907 struct tevent_context *event_ctx,
2908 const struct model_ops *model_ops,
2909 void *process_context)
2911 struct dcesrv_socket_context *dcesrv_sock;
2912 uint16_t port = 1;
2913 char *full_path;
2914 NTSTATUS status;
2915 const char *endpoint;
2917 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2919 if (endpoint == NULL) {
2921 * No identifier specified: use DEFAULT.
2923 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2924 * no endpoint and let the epmapper worry about it.
2926 endpoint = "DEFAULT";
2927 status = dcerpc_binding_set_string_option(e->ep_description,
2928 "endpoint",
2929 endpoint);
2930 if (!NT_STATUS_IS_OK(status)) {
2931 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2932 nt_errstr(status)));
2933 return status;
2937 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2938 endpoint);
2940 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2941 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2943 /* remember the endpoint of this socket */
2944 dcesrv_sock->endpoint = e;
2945 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2947 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2948 model_ops, &dcesrv_stream_ops,
2949 "unix", full_path, &port,
2950 lpcfg_socket_options(lp_ctx),
2951 dcesrv_sock, process_context);
2952 if (!NT_STATUS_IS_OK(status)) {
2953 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2954 endpoint, full_path, nt_errstr(status)));
2956 return status;
2959 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2960 struct loadparm_context *lp_ctx,
2961 struct dcesrv_endpoint *e,
2962 struct tevent_context *event_ctx,
2963 const struct model_ops *model_ops,
2964 void *process_context)
2966 struct dcesrv_socket_context *dcesrv_sock;
2967 NTSTATUS status;
2968 const char *endpoint;
2970 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2971 if (endpoint == NULL) {
2972 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2973 return NT_STATUS_INVALID_PARAMETER;
2976 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2977 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2979 /* remember the endpoint of this socket */
2980 dcesrv_sock->endpoint = e;
2981 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2983 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2984 model_ops, &dcesrv_stream_ops,
2985 endpoint,
2986 dcesrv_sock, process_context);
2987 if (!NT_STATUS_IS_OK(status)) {
2988 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2989 endpoint, nt_errstr(status)));
2990 return status;
2993 return NT_STATUS_OK;
2997 add a socket address to the list of events, one event per dcerpc endpoint
2999 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx,
3000 struct dcesrv_endpoint *e,
3001 struct tevent_context *event_ctx,
3002 const struct model_ops *model_ops,
3003 const char *address,
3004 void *process_context)
3006 struct dcesrv_socket_context *dcesrv_sock;
3007 uint16_t port = 0;
3008 NTSTATUS status;
3009 const char *endpoint;
3010 char port_str[6];
3012 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
3013 if (endpoint != NULL) {
3014 port = atoi(endpoint);
3017 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
3018 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
3020 /* remember the endpoint of this socket */
3021 dcesrv_sock->endpoint = e;
3022 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
3024 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
3025 model_ops, &dcesrv_stream_ops,
3026 "ip", address, &port,
3027 lpcfg_socket_options(dce_ctx->lp_ctx),
3028 dcesrv_sock, process_context);
3029 if (!NT_STATUS_IS_OK(status)) {
3030 struct dcesrv_if_list *iface;
3031 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
3032 address, port));
3033 for (iface = e->interface_list; iface; iface = iface->next) {
3034 DEBUGADD(0, ("%s ", iface->iface.name));
3036 DEBUGADD(0, ("failed - %s",
3037 nt_errstr(status)));
3038 return status;
3041 snprintf(port_str, sizeof(port_str), "%u", port);
3043 status = dcerpc_binding_set_string_option(e->ep_description,
3044 "endpoint", port_str);
3045 if (!NT_STATUS_IS_OK(status)) {
3046 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
3047 port_str, nt_errstr(status)));
3048 return status;
3049 } else {
3050 struct dcesrv_if_list *iface;
3051 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
3052 address, port_str));
3053 for (iface = e->interface_list; iface; iface = iface->next) {
3054 DEBUGADD(4, ("%s ", iface->iface.name));
3056 DEBUGADD(4, ("\n"));
3059 return NT_STATUS_OK;
3062 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
3064 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
3065 struct loadparm_context *lp_ctx,
3066 struct dcesrv_endpoint *e,
3067 struct tevent_context *event_ctx,
3068 const struct model_ops *model_ops,
3069 void *process_context)
3071 NTSTATUS status;
3073 /* Add TCP/IP sockets */
3074 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
3075 int num_interfaces;
3076 int i;
3077 struct interface *ifaces;
3079 load_interface_list(dce_ctx, lp_ctx, &ifaces);
3081 num_interfaces = iface_list_count(ifaces);
3082 for(i = 0; i < num_interfaces; i++) {
3083 const char *address = iface_list_n_ip(ifaces, i);
3084 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3085 model_ops, address,
3086 process_context);
3087 NT_STATUS_NOT_OK_RETURN(status);
3089 } else {
3090 char **wcard;
3091 int i;
3092 int num_binds = 0;
3093 wcard = iface_list_wildcard(dce_ctx);
3094 NT_STATUS_HAVE_NO_MEMORY(wcard);
3095 for (i=0; wcard[i]; i++) {
3096 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx,
3097 model_ops, wcard[i],
3098 process_context);
3099 if (NT_STATUS_IS_OK(status)) {
3100 num_binds++;
3103 talloc_free(wcard);
3104 if (num_binds == 0) {
3105 return NT_STATUS_INVALID_PARAMETER_MIX;
3109 return NT_STATUS_OK;
3112 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
3113 struct loadparm_context *lp_ctx,
3114 struct dcesrv_endpoint *e,
3115 struct tevent_context *event_ctx,
3116 const struct model_ops *model_ops,
3117 void *process_context)
3119 enum dcerpc_transport_t transport =
3120 dcerpc_binding_get_transport(e->ep_description);
3122 switch (transport) {
3123 case NCACN_UNIX_STREAM:
3124 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx,
3125 model_ops, process_context);
3127 case NCALRPC:
3128 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx,
3129 model_ops, process_context);
3131 case NCACN_IP_TCP:
3132 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx,
3133 model_ops, process_context);
3135 case NCACN_NP:
3136 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx,
3137 model_ops, process_context);
3139 default:
3140 return NT_STATUS_NOT_SUPPORTED;
3146 * retrieve credentials from a dce_call
3148 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3150 return dce_call->conn->auth_state.session_info->credentials;
3154 * returns true if this is an authenticated call
3156 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3158 enum security_user_level level;
3159 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
3160 return level >= SECURITY_USER;
3164 * retrieve account_name for a dce_call
3166 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3168 return dce_call->context->conn->auth_state.session_info->info->account_name;