tevent: release 0.16.1
[Samba.git] / librpc / rpc / dcesrv_core.c
blobc0a4150e3b3c02b13e9af4928149e9399c9d4788
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
8 Copyright (C) Samuel Cabrero <scabrero@samba.org> 2019
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "librpc/rpc/dcesrv_core.h"
26 #include "librpc/rpc/dcesrv_core_proto.h"
27 #include "librpc/rpc/dcerpc_util.h"
28 #include "librpc/gen_ndr/auth.h"
29 #include "auth/gensec/gensec.h"
30 #include "lib/util/dlinklist.h"
31 #include "libcli/security/security.h"
32 #include "param/param.h"
33 #include "lib/tsocket/tsocket.h"
34 #include "librpc/gen_ndr/ndr_dcerpc.h"
35 #include "lib/util/tevent_ntstatus.h"
36 #include "system/network.h"
37 #include "lib/util/idtree_random.h"
38 #include "nsswitch/winbind_client.h"
40 /**
41 * @file
42 * @brief DCERPC server
45 #undef DBGC_CLASS
46 #define DBGC_CLASS DBGC_RPC_SRV
48 #undef strcasecmp
50 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
51 const struct dcerpc_bind *b,
52 struct dcerpc_ack_ctx *ack_ctx_list);
55 see if two endpoints match
57 static bool endpoints_match(const struct dcerpc_binding *ep1,
58 const struct dcerpc_binding *ep2)
60 enum dcerpc_transport_t t1;
61 enum dcerpc_transport_t t2;
62 const char *e1;
63 const char *e2;
65 t1 = dcerpc_binding_get_transport(ep1);
66 t2 = dcerpc_binding_get_transport(ep2);
68 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
69 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
71 if (t1 != t2) {
72 return false;
75 if (!e1 || !e2) {
76 return e1 == e2;
79 if (strcasecmp(e1, e2) != 0) {
80 return false;
83 return true;
87 find an endpoint in the dcesrv_context
89 _PUBLIC_ NTSTATUS dcesrv_find_endpoint(struct dcesrv_context *dce_ctx,
90 const struct dcerpc_binding *ep_description,
91 struct dcesrv_endpoint **_out)
93 struct dcesrv_endpoint *ep = NULL;
94 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
95 if (endpoints_match(ep->ep_description, ep_description)) {
96 *_out = ep;
97 return NT_STATUS_OK;
100 return NT_STATUS_NOT_FOUND;
104 find a registered context_id from a bind or alter_context
106 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
107 uint16_t context_id)
109 struct dcesrv_connection_context *c;
110 for (c=conn->contexts;c;c=c->next) {
111 if (c->context_id == context_id) return c;
113 return NULL;
117 find the interface operations on any endpoint with this binding
119 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
120 struct dcerpc_binding *binding,
121 const struct dcesrv_interface *iface)
123 struct dcesrv_endpoint *ep;
124 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
125 if (endpoints_match(ep->ep_description, binding)) {
126 const struct dcesrv_interface *ret = NULL;
128 ret = find_interface_by_syntax_id(
129 ep, &iface->syntax_id);
130 if (ret != NULL) {
131 return ret;
135 return NULL;
139 find the interface operations on an endpoint by uuid
141 _PUBLIC_ const struct dcesrv_interface *find_interface_by_syntax_id(
142 const struct dcesrv_endpoint *endpoint,
143 const struct ndr_syntax_id *interface)
145 struct dcesrv_if_list *ifl;
146 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
147 if (ndr_syntax_id_equal(&ifl->iface->syntax_id, interface)) {
148 return ifl->iface;
151 return NULL;
155 find the earlier parts of a fragmented call awaiting reassembly
157 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
159 struct dcesrv_call_state *c;
160 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
161 if (c->pkt.call_id == call_id) {
162 return c;
165 return NULL;
169 find a pending request
171 static struct dcesrv_call_state *dcesrv_find_pending_call(
172 struct dcesrv_connection *dce_conn,
173 uint32_t call_id)
175 struct dcesrv_call_state *c = NULL;
177 for (c = dce_conn->pending_call_list; c != NULL; c = c->next) {
178 if (c->pkt.call_id == call_id) {
179 return c;
183 return NULL;
187 * register a principal for an auth_type
189 * In order to get used in dcesrv_mgmt_inq_princ_name()
191 _PUBLIC_ NTSTATUS dcesrv_auth_type_principal_register(struct dcesrv_context *dce_ctx,
192 enum dcerpc_AuthType auth_type,
193 const char *principal_name)
195 const char *existing = NULL;
196 struct dcesrv_ctx_principal *p = NULL;
198 existing = dcesrv_auth_type_principal_find(dce_ctx, auth_type);
199 if (existing != NULL) {
200 DBG_ERR("auth_type[%u] already registered with principal_name[%s]\n",
201 auth_type, existing);
202 return NT_STATUS_ALREADY_REGISTERED;
205 p = talloc_zero(dce_ctx, struct dcesrv_ctx_principal);
206 if (p == NULL) {
207 return NT_STATUS_NO_MEMORY;
209 p->auth_type = auth_type;
210 p->principal_name = talloc_strdup(p, principal_name);
211 if (p->principal_name == NULL) {
212 TALLOC_FREE(p);
213 return NT_STATUS_NO_MEMORY;
216 DLIST_ADD_END(dce_ctx->principal_list, p);
217 return NT_STATUS_OK;
220 _PUBLIC_ const char *dcesrv_auth_type_principal_find(struct dcesrv_context *dce_ctx,
221 enum dcerpc_AuthType auth_type)
223 struct dcesrv_ctx_principal *p = NULL;
225 for (p = dce_ctx->principal_list; p != NULL; p = p->next) {
226 if (p->auth_type == auth_type) {
227 return p->principal_name;
231 return NULL;
234 _PUBLIC_ NTSTATUS dcesrv_register_default_auth_types(struct dcesrv_context *dce_ctx,
235 const char *principal)
237 const char *realm = lpcfg_realm(dce_ctx->lp_ctx);
238 NTSTATUS status;
240 status = dcesrv_auth_type_principal_register(dce_ctx,
241 DCERPC_AUTH_TYPE_NTLMSSP,
242 principal);
243 if (!NT_STATUS_IS_OK(status)) {
244 return status;
246 status = dcesrv_auth_type_principal_register(dce_ctx,
247 DCERPC_AUTH_TYPE_SPNEGO,
248 principal);
249 if (!NT_STATUS_IS_OK(status)) {
250 return status;
253 if (realm == NULL || realm[0] == '\0') {
254 return NT_STATUS_OK;
257 status = dcesrv_auth_type_principal_register(dce_ctx,
258 DCERPC_AUTH_TYPE_KRB5,
259 principal);
260 if (!NT_STATUS_IS_OK(status)) {
261 return status;
264 return NT_STATUS_OK;
267 _PUBLIC_ NTSTATUS dcesrv_register_default_auth_types_machine_principal(struct dcesrv_context *dce_ctx)
269 const char *realm = lpcfg_realm(dce_ctx->lp_ctx);
270 const char *nb = lpcfg_netbios_name(dce_ctx->lp_ctx);
271 char *principal = NULL;
272 NTSTATUS status;
274 if (realm == NULL || realm[0] == '\0') {
275 return dcesrv_register_default_auth_types(dce_ctx, "");
278 principal = talloc_asprintf(talloc_tos(), "%s$@%s", nb, realm);
279 if (principal == NULL) {
280 return NT_STATUS_NO_MEMORY;
283 status = dcesrv_register_default_auth_types(dce_ctx, principal);
284 TALLOC_FREE(principal);
285 if (!NT_STATUS_IS_OK(status)) {
286 return status;
289 return NT_STATUS_OK;
293 register an interface on an endpoint
295 An endpoint is one unix domain socket (for ncalrpc), one TCP port
296 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
298 Each endpoint can have many interfaces such as netlogon, lsa or
299 samr. Some have essentially the full set.
301 This is driven from the set of interfaces listed in each IDL file
302 via the PIDL generated *__op_init_server() functions.
304 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
305 const char *ep_name,
306 const char *ncacn_np_secondary_endpoint,
307 const struct dcesrv_interface *iface,
308 const struct security_descriptor *sd)
310 struct dcerpc_binding *binding = NULL;
311 struct dcerpc_binding *binding2 = NULL;
312 NTSTATUS ret;
314 ret = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
315 if (NT_STATUS_IS_ERR(ret)) {
316 DBG_ERR("Trouble parsing binding string '%s'\n", ep_name);
317 goto out;
320 if (ncacn_np_secondary_endpoint != NULL) {
321 ret = dcerpc_parse_binding(dce_ctx,
322 ncacn_np_secondary_endpoint,
323 &binding2);
324 if (NT_STATUS_IS_ERR(ret)) {
325 DBG_ERR("Trouble parsing 2nd binding string '%s'\n",
326 ncacn_np_secondary_endpoint);
327 goto out;
331 ret = dcesrv_interface_register_b(dce_ctx,
332 binding,
333 binding2,
334 iface,
335 sd);
336 out:
337 TALLOC_FREE(binding);
338 TALLOC_FREE(binding2);
339 return ret;
342 _PUBLIC_ NTSTATUS dcesrv_interface_register_b(struct dcesrv_context *dce_ctx,
343 struct dcerpc_binding *binding,
344 struct dcerpc_binding *binding2,
345 const struct dcesrv_interface *iface,
346 const struct security_descriptor *sd)
348 struct dcesrv_endpoint *ep;
349 struct dcesrv_if_list *ifl;
350 bool add_ep = false;
351 NTSTATUS status;
352 enum dcerpc_transport_t transport;
353 char *ep_string = NULL;
354 bool use_single_process = true;
355 const char *ep_process_string;
358 * If we are not using handles, there is no need for force
359 * this service into using a single process.
361 * However, due to the way we listen for RPC packets, we can
362 * only do this if we have a single service per pipe or TCP
363 * port, so we still force a single combined process for
364 * ncalrpc.
366 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
367 use_single_process = false;
370 transport = dcerpc_binding_get_transport(binding);
371 if (transport == NCACN_IP_TCP) {
372 int port;
375 * First check if there is already a port specified, eg
376 * for epmapper on ncacn_ip_tcp:[135]
378 const char *endpoint
379 = dcerpc_binding_get_string_option(binding,
380 "endpoint");
381 if (endpoint == NULL) {
382 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
383 "rpc server port", iface->name, 0);
386 * For RPC services that are not set to use a single
387 * process, we do not default to using the 'rpc server
388 * port' because that would cause a double-bind on
389 * that port.
391 if (port == 0 && !use_single_process) {
392 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
394 if (port != 0) {
395 char port_str[6];
396 snprintf(port_str, sizeof(port_str), "%u", port);
397 status = dcerpc_binding_set_string_option(binding,
398 "endpoint",
399 port_str);
400 if (!NT_STATUS_IS_OK(status)) {
401 return status;
407 if (transport == NCACN_NP && binding2 != NULL) {
408 enum dcerpc_transport_t transport2;
410 transport2 = dcerpc_binding_get_transport(binding2);
411 SMB_ASSERT(transport2 == transport);
414 /* see if the interface is already registered on the endpoint */
415 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
416 char *binding_string = dcerpc_binding_string(dce_ctx, binding);
417 DBG_ERR("Interface '%s' already registered on endpoint '%s'\n",
418 iface->name, binding_string);
419 TALLOC_FREE(binding_string);
420 return NT_STATUS_OBJECT_NAME_COLLISION;
423 /* check if this endpoint exists
425 status = dcesrv_find_endpoint(dce_ctx, binding, &ep);
426 if (NT_STATUS_IS_OK(status)) {
428 * We want a new port on ncacn_ip_tcp for NETLOGON, so
429 * it can be multi-process. Other processes can also
430 * listen on distinct ports, if they have one forced
431 * in the code above with eg 'rpc server port:drsuapi = 1027'
433 * If we have multiple endpoints on port 0, they each
434 * get an epemeral port (currently by walking up from
435 * 1024).
437 * Because one endpoint can only have one process
438 * model, we add a new IP_TCP endpoint for each model.
440 * This works in conjunction with the forced overwrite
441 * of ep->use_single_process below.
443 if (ep->use_single_process != use_single_process
444 && transport == NCACN_IP_TCP) {
445 add_ep = true;
449 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || add_ep) {
450 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
451 if (!ep) {
452 return NT_STATUS_NO_MEMORY;
454 ep->ep_description = dcerpc_binding_dup(ep, binding);
455 if (transport == NCACN_NP && binding2 != NULL) {
456 ep->ep_2nd_description =
457 dcerpc_binding_dup(ep, binding2);
459 add_ep = true;
461 /* add mgmt interface */
462 ifl = talloc_zero(ep, struct dcesrv_if_list);
463 if (!ifl) {
464 TALLOC_FREE(ep);
465 return NT_STATUS_NO_MEMORY;
468 ifl->iface = talloc_memdup(ifl,
469 dcesrv_get_mgmt_interface(),
470 sizeof(struct dcesrv_interface));
471 if (ifl->iface == NULL) {
472 talloc_free(ep);
473 return NT_STATUS_NO_MEMORY;
476 DLIST_ADD(ep->interface_list, ifl);
477 } else if (!NT_STATUS_IS_OK(status)) {
478 DBG_NOTICE("Failed to find endpoint: %s\n", nt_errstr(status));
479 return status;
483 * By default don't force into a single process, but if any
484 * interface on this endpoint on this service uses handles
485 * (most do), then we must force into single process mode
487 * By overwriting this each time a new interface is added to
488 * this endpoint, we end up with the most restrictive setting.
490 if (use_single_process) {
491 ep->use_single_process = true;
494 /* talloc a new interface list element */
495 ifl = talloc_zero(ep, struct dcesrv_if_list);
496 if (!ifl) {
497 return NT_STATUS_NO_MEMORY;
500 /* copy the given interface struct to the one on the endpoints interface list */
501 ifl->iface = talloc_memdup(ifl,
502 iface,
503 sizeof(struct dcesrv_interface));
504 if (ifl->iface == NULL) {
505 talloc_free(ep);
506 return NT_STATUS_NO_MEMORY;
509 /* if we have a security descriptor given,
510 * we should see if we can set it up on the endpoint
512 if (sd != NULL) {
513 /* if there's currently no security descriptor given on the endpoint
514 * we try to set it
516 if (ep->sd == NULL) {
517 ep->sd = security_descriptor_copy(ep, sd);
520 /* if now there's no security descriptor given on the endpoint
521 * something goes wrong, either we failed to copy the security descriptor
522 * or there was already one on the endpoint
524 if (ep->sd != NULL) {
525 char *binding_string =
526 dcerpc_binding_string(dce_ctx, binding);
527 DBG_ERR("Interface '%s' failed to setup a security "
528 "descriptor on endpoint '%s'\n",
529 iface->name, binding_string);
530 TALLOC_FREE(binding_string);
531 if (add_ep) free(ep);
532 free(ifl);
533 return NT_STATUS_OBJECT_NAME_COLLISION;
537 /* finally add the interface on the endpoint */
538 DLIST_ADD(ep->interface_list, ifl);
540 /* if it's a new endpoint add it to the dcesrv_context */
541 if (add_ep) {
542 DLIST_ADD(dce_ctx->endpoint_list, ep);
545 /* Re-get the string as we may have set a port */
546 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
548 if (use_single_process) {
549 ep_process_string = "single process required";
550 } else {
551 ep_process_string = "multi process compatible";
554 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
555 iface->name, ep_string, ep_process_string);
556 TALLOC_FREE(ep_string);
558 return NT_STATUS_OK;
561 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
562 DATA_BLOB *session_key)
564 if (auth->session_info == NULL) {
565 return NT_STATUS_NO_USER_SESSION_KEY;
568 if (auth->session_info->session_key.length == 0) {
569 return NT_STATUS_NO_USER_SESSION_KEY;
572 *session_key = auth->session_info->session_key;
573 return NT_STATUS_OK;
576 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
577 DATA_BLOB *session_key)
579 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
580 return NT_STATUS_NO_USER_SESSION_KEY;
583 return dcesrv_session_info_session_key(auth, session_key);
586 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
587 DATA_BLOB *session_key)
589 return dcerpc_generic_session_key(session_key);
593 * Fetch the authentication session key if available.
595 * This is the key generated by a gensec authentication.
598 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
599 DATA_BLOB *session_key)
601 struct dcesrv_auth *auth = call->auth_state;
602 SMB_ASSERT(auth->auth_finished);
603 return dcesrv_session_info_session_key(auth, session_key);
607 * Fetch the transport session key if available.
608 * Typically this is the SMB session key
609 * or a fixed key for local transports.
611 * The key is always truncated to 16 bytes.
613 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
614 DATA_BLOB *session_key)
616 struct dcesrv_auth *auth = call->auth_state;
617 NTSTATUS status;
619 SMB_ASSERT(auth->auth_finished);
621 if (auth->session_key_fn == NULL) {
622 return NT_STATUS_NO_USER_SESSION_KEY;
625 status = auth->session_key_fn(auth, session_key);
626 if (!NT_STATUS_IS_OK(status)) {
627 return status;
630 session_key->length = MIN(session_key->length, 16);
632 return NT_STATUS_OK;
635 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
637 const struct dcesrv_endpoint *ep = conn->endpoint;
638 enum dcerpc_transport_t transport =
639 dcerpc_binding_get_transport(ep->ep_description);
640 struct dcesrv_auth *auth = NULL;
642 auth = talloc_zero(conn, struct dcesrv_auth);
643 if (auth == NULL) {
644 return NULL;
647 switch (transport) {
648 case NCACN_NP:
649 auth->session_key_fn = dcesrv_remote_session_key;
650 break;
651 case NCALRPC:
652 case NCACN_UNIX_STREAM:
653 auth->session_key_fn = dcesrv_local_fixed_session_key;
654 break;
655 default:
657 * All other's get a NULL pointer, which
658 * results in NT_STATUS_NO_USER_SESSION_KEY
660 break;
663 return auth;
667 connect to a dcerpc endpoint
669 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
670 TALLOC_CTX *mem_ctx,
671 const struct dcesrv_endpoint *ep,
672 struct auth_session_info *session_info,
673 struct tevent_context *event_ctx,
674 uint32_t state_flags,
675 struct dcesrv_connection **_p)
677 struct dcesrv_auth *auth = NULL;
678 struct dcesrv_connection *p = NULL;
680 if (!session_info) {
681 return NT_STATUS_ACCESS_DENIED;
684 p = talloc_zero(mem_ctx, struct dcesrv_connection);
685 if (p == NULL) {
686 goto nomem;
689 p->dce_ctx = dce_ctx;
690 p->endpoint = ep;
691 p->packet_log_dir = lpcfg_parm_string(dce_ctx->lp_ctx,
692 NULL,
693 "dcesrv",
694 "stubs directory");
695 p->event_ctx = event_ctx;
696 p->state_flags = state_flags;
697 p->allow_bind = true;
698 p->max_recv_frag = 5840;
699 p->max_xmit_frag = 5840;
700 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
702 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
703 NULL,
704 "dcesrv",
705 "header signing",
706 true);
707 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
708 NULL,
709 "dcesrv",
710 "max auth states",
711 2049);
713 auth = dcesrv_auth_create(p);
714 if (auth == NULL) {
715 goto nomem;
718 auth->session_info = talloc_reference(auth, session_info);
719 if (auth->session_info == NULL) {
720 goto nomem;
723 p->default_auth_state = auth;
725 p->preferred_transfer = dce_ctx->preferred_transfer;
727 *_p = p;
728 return NT_STATUS_OK;
729 nomem:
730 TALLOC_FREE(p);
731 return NT_STATUS_NO_MEMORY;
735 move a call from an existing linked list to the specified list. This
736 prevents bugs where we forget to remove the call from a previous
737 list when moving it.
739 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
740 enum dcesrv_call_list list)
742 switch (call->list) {
743 case DCESRV_LIST_NONE:
744 break;
745 case DCESRV_LIST_CALL_LIST:
746 DLIST_REMOVE(call->conn->call_list, call);
747 break;
748 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
749 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
750 break;
751 case DCESRV_LIST_PENDING_CALL_LIST:
752 DLIST_REMOVE(call->conn->pending_call_list, call);
753 break;
755 call->list = list;
756 switch (list) {
757 case DCESRV_LIST_NONE:
758 break;
759 case DCESRV_LIST_CALL_LIST:
760 DLIST_ADD_END(call->conn->call_list, call);
761 break;
762 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
763 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
764 break;
765 case DCESRV_LIST_PENDING_CALL_LIST:
766 DLIST_ADD_END(call->conn->pending_call_list, call);
767 break;
771 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
772 const char *reason)
774 struct dcesrv_auth *a = NULL;
776 if (call->conn->terminate != NULL) {
777 return;
780 call->conn->allow_bind = false;
781 call->conn->allow_alter = false;
783 call->conn->default_auth_state->auth_invalid = true;
785 for (a = call->conn->auth_states; a != NULL; a = a->next) {
786 a->auth_invalid = true;
789 call->terminate_reason = talloc_strdup(call, reason);
790 if (call->terminate_reason == NULL) {
791 call->terminate_reason = __location__;
796 return a dcerpc bind_nak
798 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
800 struct ncacn_packet pkt;
801 struct dcerpc_bind_nak_version version;
802 struct data_blob_list_item *rep;
803 NTSTATUS status;
804 static const uint8_t _pad[3] = { 0, };
807 * We add the call to the pending_call_list
808 * in order to defer the termination.
810 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
812 /* setup a bind_nak */
813 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
814 pkt.auth_length = 0;
815 pkt.call_id = call->pkt.call_id;
816 pkt.ptype = DCERPC_PKT_BIND_NAK;
817 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
818 pkt.u.bind_nak.reject_reason = reason;
819 version.rpc_vers = 5;
820 version.rpc_vers_minor = 0;
821 pkt.u.bind_nak.num_versions = 1;
822 pkt.u.bind_nak.versions = &version;
823 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
825 rep = talloc_zero(call, struct data_blob_list_item);
826 if (!rep) {
827 return NT_STATUS_NO_MEMORY;
830 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
831 if (!NT_STATUS_IS_OK(status)) {
832 return status;
835 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
837 DLIST_ADD_END(call->replies, rep);
838 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
840 if (call->conn->call_list && call->conn->call_list->replies) {
841 if (call->conn->transport.report_output_data) {
842 call->conn->transport.report_output_data(call->conn);
846 return NT_STATUS_OK;
849 static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
850 uint32_t fault_code,
851 uint8_t extra_flags,
852 const char *func,
853 const char *location)
855 const char *reason = NULL;
857 reason = talloc_asprintf(call, "%s:%s: fault=%u (%s) flags=0x%x",
858 func, location,
859 fault_code,
860 dcerpc_errstr(call, fault_code),
861 extra_flags);
862 if (reason == NULL) {
863 reason = location;
867 * We add the call to the pending_call_list
868 * in order to defer the termination.
871 dcesrv_call_disconnect_after(call, reason);
873 return dcesrv_fault_with_flags(call, fault_code, extra_flags);
876 #define dcesrv_fault_disconnect(call, fault_code) \
877 _dcesrv_fault_disconnect_flags(call, fault_code, \
878 DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
879 __func__, __location__)
880 #define dcesrv_fault_disconnect0(call, fault_code) \
881 _dcesrv_fault_disconnect_flags(call, fault_code, 0, \
882 __func__, __location__)
884 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
886 DLIST_REMOVE(c->conn->contexts, c);
888 if (c->iface && c->iface->unbind) {
889 c->iface->unbind(c, c->iface);
890 c->iface = NULL;
893 return 0;
896 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
898 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
899 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
900 enum dcerpc_transport_t transport =
901 dcerpc_binding_get_transport(endpoint->ep_description);
902 struct dcesrv_connection_context *context = dce_call->context;
903 const struct dcesrv_interface *iface = context->iface;
905 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
907 if (transport == NCALRPC) {
908 context->allow_connect = true;
909 return;
913 * allow overwrite per interface
914 * allow dcerpc auth level connect:<interface>
916 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
917 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
918 "allow dcerpc auth level connect",
919 iface->name,
920 context->allow_connect);
923 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
924 const struct dcesrv_interface *iface)
927 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
928 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
930 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
931 return NT_STATUS_OK;
934 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
935 const struct dcesrv_interface *iface)
937 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
938 return NT_STATUS_OK;
941 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
942 const struct dcesrv_interface *iface)
944 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
945 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
946 enum dcerpc_transport_t transport =
947 dcerpc_binding_get_transport(endpoint->ep_description);
949 if (transport == NCALRPC) {
950 context->allow_connect = true;
951 return NT_STATUS_OK;
955 * allow overwrite per interface
956 * allow dcerpc auth level connect:<interface>
958 context->allow_connect = false;
959 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
960 "allow dcerpc auth level connect",
961 iface->name,
962 context->allow_connect);
963 return NT_STATUS_OK;
966 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
967 const struct dcesrv_interface *iface)
969 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
970 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
971 enum dcerpc_transport_t transport =
972 dcerpc_binding_get_transport(endpoint->ep_description);
974 if (transport == NCALRPC) {
975 context->allow_connect = true;
976 return NT_STATUS_OK;
980 * allow overwrite per interface
981 * allow dcerpc auth level connect:<interface>
983 context->allow_connect = true;
984 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
985 "allow dcerpc auth level connect",
986 iface->name,
987 context->allow_connect);
988 return NT_STATUS_OK;
991 struct dcesrv_conn_auth_wait_context {
992 struct tevent_req *req;
993 bool done;
994 NTSTATUS status;
997 struct dcesrv_conn_auth_wait_state {
998 uint8_t dummy;
1001 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
1002 struct tevent_context *ev,
1003 void *private_data)
1005 struct dcesrv_conn_auth_wait_context *auth_wait =
1006 talloc_get_type_abort(private_data,
1007 struct dcesrv_conn_auth_wait_context);
1008 struct tevent_req *req = NULL;
1009 struct dcesrv_conn_auth_wait_state *state = NULL;
1011 req = tevent_req_create(mem_ctx, &state,
1012 struct dcesrv_conn_auth_wait_state);
1013 if (req == NULL) {
1014 return NULL;
1016 auth_wait->req = req;
1018 tevent_req_defer_callback(req, ev);
1020 if (!auth_wait->done) {
1021 return req;
1024 if (tevent_req_nterror(req, auth_wait->status)) {
1025 return tevent_req_post(req, ev);
1028 tevent_req_done(req);
1029 return tevent_req_post(req, ev);
1032 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
1034 return tevent_req_simple_recv_ntstatus(req);
1037 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
1039 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
1041 if (conn->wait_send != NULL) {
1042 return NT_STATUS_INTERNAL_ERROR;
1045 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
1046 if (auth_wait == NULL) {
1047 return NT_STATUS_NO_MEMORY;
1050 conn->wait_private = auth_wait;
1051 conn->wait_send = dcesrv_conn_auth_wait_send;
1052 conn->wait_recv = dcesrv_conn_auth_wait_recv;
1053 return NT_STATUS_OK;
1056 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
1057 NTSTATUS status)
1059 struct dcesrv_conn_auth_wait_context *auth_wait =
1060 talloc_get_type_abort(conn->wait_private,
1061 struct dcesrv_conn_auth_wait_context);
1063 auth_wait->done = true;
1064 auth_wait->status = status;
1066 if (auth_wait->req == NULL) {
1067 return;
1070 if (tevent_req_nterror(auth_wait->req, status)) {
1071 return;
1074 tevent_req_done(auth_wait->req);
1077 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
1079 static void dcesrv_bind_done(struct tevent_req *subreq);
1082 handle a bind request
1084 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
1086 struct dcesrv_connection *conn = call->conn;
1087 struct dcesrv_context *dce_ctx = conn->dce_ctx;
1088 struct ncacn_packet *pkt = &call->ack_pkt;
1089 NTSTATUS status;
1090 uint32_t extra_flags = 0;
1091 uint16_t max_req = 0;
1092 uint16_t max_rep = 0;
1093 struct dcerpc_binding *ep_2nd_description = NULL;
1094 const char *endpoint = NULL;
1095 struct dcesrv_auth *auth = call->auth_state;
1096 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1097 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1098 struct dcerpc_ack_ctx *ack_features = NULL;
1099 struct tevent_req *subreq = NULL;
1100 size_t i;
1102 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1103 DCERPC_PKT_BIND,
1104 call->pkt.u.bind.auth_info.length,
1105 0, /* required flags */
1106 DCERPC_PFC_FLAG_FIRST |
1107 DCERPC_PFC_FLAG_LAST |
1108 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1109 0x08 | /* this is not defined, but should be ignored */
1110 DCERPC_PFC_FLAG_CONC_MPX |
1111 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1112 DCERPC_PFC_FLAG_MAYBE |
1113 DCERPC_PFC_FLAG_OBJECT_UUID);
1114 if (!NT_STATUS_IS_OK(status)) {
1115 return dcesrv_bind_nak(call,
1116 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
1119 /* max_recv_frag and max_xmit_frag result always in the same value! */
1120 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
1121 call->pkt.u.bind.max_recv_frag);
1123 * The values are between 2048 and 5840 tested against Windows 2012R2
1124 * via ncacn_ip_tcp on port 135.
1126 max_req = MAX(2048, max_req);
1127 max_rep = MIN(max_req, conn->max_recv_frag);
1128 /* They are truncated to an 8 byte boundary. */
1129 max_rep &= 0xFFF8;
1131 /* max_recv_frag and max_xmit_frag result always in the same value! */
1132 conn->max_recv_frag = max_rep;
1133 conn->max_xmit_frag = max_rep;
1135 status = dce_ctx->callbacks->assoc_group.find(
1136 call, dce_ctx->callbacks->assoc_group.private_data);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
1139 call->pkt.u.bind.assoc_group_id, nt_errstr(status));
1140 return dcesrv_bind_nak(call, 0);
1143 if (call->pkt.u.bind.num_contexts < 1) {
1144 return dcesrv_bind_nak(call, 0);
1147 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1148 call->pkt.u.bind.num_contexts);
1149 if (ack_ctx_list == NULL) {
1150 return dcesrv_bind_nak(call, 0);
1154 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1155 * dcesrv_check_or_create_context()) and do some protocol validation
1156 * and set sane defaults.
1158 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1159 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1160 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1161 bool is_feature = false;
1162 uint64_t features = 0;
1164 if (c->num_transfer_syntaxes == 0) {
1165 return dcesrv_bind_nak(call, 0);
1168 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1169 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1172 * It's only treated as bind time feature request, if the first
1173 * transfer_syntax matches, all others are ignored.
1175 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1176 &features);
1177 if (!is_feature) {
1178 continue;
1181 if (ack_features != NULL) {
1183 * Only one bind time feature context is allowed.
1185 return dcesrv_bind_nak(call, 0);
1187 ack_features = a;
1189 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1190 a->reason.negotiate = 0;
1191 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1192 if (conn->max_auth_states != 0) {
1193 a->reason.negotiate |=
1194 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1197 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1198 a->reason.negotiate |=
1199 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1202 conn->assoc_group->bind_time_features = a->reason.negotiate;
1206 * Try to negotiate one new presentation context.
1208 * Deep in here we locate the iface (by uuid) that the client
1209 * requested, from the list of interfaces on the
1210 * call->conn->endpoint, and call iface->bind() on that iface.
1212 * call->conn was set up at the accept() of the socket, and
1213 * call->conn->endpoint has a list of interfaces restricted to
1214 * this port or pipe.
1216 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1217 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1218 return dcesrv_bind_nak(call, 0);
1220 if (!NT_STATUS_IS_OK(status)) {
1221 return status;
1225 * At this point we still don't know which interface (eg
1226 * netlogon, lsa, drsuapi) the caller requested in this bind!
1227 * The most recently added context is available as the first
1228 * element in the linked list at call->conn->contexts, that is
1229 * call->conn->contexts->iface, but they may not have
1230 * requested one at all!
1233 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1234 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1235 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1236 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1239 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1240 conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1244 * After finding the interface and setting up the NDR
1245 * transport negotiation etc, handle any authentication that
1246 * is being requested.
1248 if (!dcesrv_auth_bind(call)) {
1250 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1252 * With DCERPC_AUTH_LEVEL_NONE, we get the
1253 * reject_reason in auth->auth_context_id.
1255 return dcesrv_bind_nak(call, auth->auth_context_id);
1259 * This must a be a temporary failure e.g. talloc or invalid
1260 * configuration, e.g. no machine account.
1262 return dcesrv_bind_nak(call,
1263 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1266 /* setup a bind_ack */
1267 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(dce_ctx->lp_ctx));
1268 pkt->auth_length = 0;
1269 pkt->call_id = call->pkt.call_id;
1270 pkt->ptype = DCERPC_PKT_BIND_ACK;
1271 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1272 pkt->u.bind_ack.max_xmit_frag = conn->max_xmit_frag;
1273 pkt->u.bind_ack.max_recv_frag = conn->max_recv_frag;
1274 pkt->u.bind_ack.assoc_group_id = conn->assoc_group->id;
1276 ep_2nd_description = conn->endpoint->ep_2nd_description;
1277 if (ep_2nd_description == NULL) {
1278 ep_2nd_description = conn->endpoint->ep_description;
1281 endpoint = dcerpc_binding_get_string_option(
1282 ep_2nd_description,
1283 "endpoint");
1284 if (endpoint == NULL) {
1285 endpoint = "";
1288 pkt->u.bind_ack.secondary_address = endpoint;
1289 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1290 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1291 pkt->u.bind_ack.auth_info = data_blob_null;
1293 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 return dcesrv_bind_nak(call, 0);
1298 if (auth->auth_finished) {
1299 return dcesrv_auth_reply(call);
1302 cb->auth.become_root();
1303 subreq = gensec_update_send(call, call->event_ctx,
1304 auth->gensec_security,
1305 call->in_auth_info.credentials);
1306 cb->auth.unbecome_root();
1307 if (subreq == NULL) {
1308 return NT_STATUS_NO_MEMORY;
1310 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1312 return dcesrv_conn_auth_wait_setup(conn);
1315 static void dcesrv_bind_done(struct tevent_req *subreq)
1317 struct dcesrv_call_state *call =
1318 tevent_req_callback_data(subreq,
1319 struct dcesrv_call_state);
1320 struct dcesrv_connection *conn = call->conn;
1321 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1322 NTSTATUS status;
1324 cb->auth.become_root();
1325 status = gensec_update_recv(subreq, call,
1326 &call->out_auth_info->credentials);
1327 cb->auth.unbecome_root();
1328 TALLOC_FREE(subreq);
1330 status = dcesrv_auth_complete(call, status);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 status = dcesrv_bind_nak(call, 0);
1333 dcesrv_conn_auth_wait_finished(conn, status);
1334 return;
1337 status = dcesrv_auth_reply(call);
1338 dcesrv_conn_auth_wait_finished(conn, status);
1339 return;
1342 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1344 struct ncacn_packet *pkt = &call->ack_pkt;
1345 struct data_blob_list_item *rep = NULL;
1346 NTSTATUS status;
1348 rep = talloc_zero(call, struct data_blob_list_item);
1349 if (!rep) {
1350 return NT_STATUS_NO_MEMORY;
1353 status = dcerpc_ncacn_push_auth(&rep->blob,
1354 call,
1355 pkt,
1356 call->out_auth_info);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 return status;
1361 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1363 DLIST_ADD_END(call->replies, rep);
1364 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1366 if (call->conn->call_list && call->conn->call_list->replies) {
1367 if (call->conn->transport.report_output_data) {
1368 call->conn->transport.report_output_data(call->conn);
1372 return NT_STATUS_OK;
1376 static void dcesrv_auth3_done(struct tevent_req *subreq);
1379 handle a auth3 request
1381 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1383 struct dcesrv_connection *conn = call->conn;
1384 struct dcesrv_auth *auth = call->auth_state;
1385 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1386 struct tevent_req *subreq = NULL;
1387 NTSTATUS status;
1389 if (!auth->auth_started) {
1390 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1393 if (auth->auth_finished) {
1394 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1397 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1398 DCERPC_PKT_AUTH3,
1399 call->pkt.u.auth3.auth_info.length,
1400 0, /* required flags */
1401 DCERPC_PFC_FLAG_FIRST |
1402 DCERPC_PFC_FLAG_LAST |
1403 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1404 0x08 | /* this is not defined, but should be ignored */
1405 DCERPC_PFC_FLAG_CONC_MPX |
1406 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1407 DCERPC_PFC_FLAG_MAYBE |
1408 DCERPC_PFC_FLAG_OBJECT_UUID);
1409 if (!NT_STATUS_IS_OK(status)) {
1410 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1413 /* handle the auth3 in the auth code */
1414 if (!dcesrv_auth_prepare_auth3(call)) {
1416 * we don't send a reply to a auth3 request,
1417 * except by a fault.
1419 * In anycase we mark the connection as
1420 * invalid.
1422 auth->auth_invalid = true;
1423 if (call->fault_code != 0) {
1424 return dcesrv_fault_disconnect(call, call->fault_code);
1426 TALLOC_FREE(call);
1427 return NT_STATUS_OK;
1430 cb->auth.become_root();
1431 subreq = gensec_update_send(call, call->event_ctx,
1432 auth->gensec_security,
1433 call->in_auth_info.credentials);
1434 cb->auth.unbecome_root();
1435 if (subreq == NULL) {
1436 return NT_STATUS_NO_MEMORY;
1438 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1440 return dcesrv_conn_auth_wait_setup(conn);
1443 static void dcesrv_auth3_done(struct tevent_req *subreq)
1445 struct dcesrv_call_state *call =
1446 tevent_req_callback_data(subreq,
1447 struct dcesrv_call_state);
1448 struct dcesrv_connection *conn = call->conn;
1449 struct dcesrv_auth *auth = call->auth_state;
1450 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1451 NTSTATUS status;
1453 cb->auth.become_root();
1454 status = gensec_update_recv(subreq, call,
1455 &call->out_auth_info->credentials);
1456 cb->auth.unbecome_root();
1457 TALLOC_FREE(subreq);
1459 status = dcesrv_auth_complete(call, status);
1460 if (!NT_STATUS_IS_OK(status)) {
1462 * we don't send a reply to a auth3 request,
1463 * except by a fault.
1465 * In anycase we mark the connection as
1466 * invalid.
1468 auth->auth_invalid = true;
1469 if (call->fault_code != 0) {
1470 status = dcesrv_fault_disconnect(call, call->fault_code);
1471 dcesrv_conn_auth_wait_finished(conn, status);
1472 return;
1474 TALLOC_FREE(call);
1475 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1476 return;
1480 * we don't send a reply to a auth3 request.
1482 TALLOC_FREE(call);
1483 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1484 return;
1488 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1489 const struct dcerpc_bind *b,
1490 const struct dcerpc_ctx_list *ctx,
1491 struct dcerpc_ack_ctx *ack,
1492 bool validate_only,
1493 const struct ndr_syntax_id *supported_transfer)
1495 struct dcesrv_connection_context *context;
1496 const struct dcesrv_interface *iface;
1497 NTSTATUS status;
1498 const struct ndr_syntax_id *selected_transfer = NULL;
1499 size_t i;
1500 bool ok;
1502 if (b == NULL) {
1503 return NT_STATUS_INTERNAL_ERROR;
1505 if (ctx == NULL) {
1506 return NT_STATUS_INTERNAL_ERROR;
1508 if (ctx->num_transfer_syntaxes < 1) {
1509 return NT_STATUS_INTERNAL_ERROR;
1511 if (ack == NULL) {
1512 return NT_STATUS_INTERNAL_ERROR;
1514 if (supported_transfer == NULL) {
1515 return NT_STATUS_INTERNAL_ERROR;
1518 switch (ack->result) {
1519 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1520 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1522 * We is already completed.
1524 return NT_STATUS_OK;
1525 default:
1526 break;
1529 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1530 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1532 iface = find_interface_by_syntax_id(
1533 call->conn->endpoint, &ctx->abstract_syntax);
1534 if (iface == NULL) {
1535 struct ndr_syntax_id_buf buf;
1536 DBG_NOTICE("Request for unknown dcerpc interface %s\n",
1537 ndr_syntax_id_buf_string(
1538 &ctx->abstract_syntax, &buf));
1540 * We report this only via ack->result
1542 return NT_STATUS_OK;
1545 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1546 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1548 if (validate_only) {
1550 * We report this only via ack->result
1552 return NT_STATUS_OK;
1555 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1557 * we only do NDR encoded dcerpc for now.
1559 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1560 supported_transfer);
1561 if (ok) {
1562 selected_transfer = supported_transfer;
1563 break;
1567 context = dcesrv_find_context(call->conn, ctx->context_id);
1568 if (context != NULL) {
1569 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1570 &ctx->abstract_syntax);
1571 if (!ok) {
1572 return NT_STATUS_RPC_PROTOCOL_ERROR;
1575 if (selected_transfer != NULL) {
1576 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1577 selected_transfer);
1578 if (!ok) {
1579 return NT_STATUS_RPC_PROTOCOL_ERROR;
1582 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1583 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1584 ack->syntax = context->transfer_syntax;
1588 * We report this only via ack->result
1590 return NT_STATUS_OK;
1593 if (selected_transfer == NULL) {
1595 * We report this only via ack->result
1597 return NT_STATUS_OK;
1600 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1601 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1603 /* add this context to the list of available context_ids */
1604 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1605 if (context == NULL) {
1606 return NT_STATUS_NO_MEMORY;
1608 context->conn = call->conn;
1609 context->context_id = ctx->context_id;
1610 context->iface = iface;
1611 context->transfer_syntax = *selected_transfer;
1612 context->ndr64 = ndr_syntax_id_equal(&context->transfer_syntax,
1613 &ndr_transfer_syntax_ndr64);
1614 DLIST_ADD(call->conn->contexts, context);
1615 call->context = context;
1616 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1618 dcesrv_prepare_context_auth(call);
1621 * Multiplex is supported by default
1623 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1625 status = iface->bind(context, iface);
1626 call->context = NULL;
1627 if (!NT_STATUS_IS_OK(status)) {
1628 /* we don't want to trigger the iface->unbind() hook */
1629 context->iface = NULL;
1630 talloc_free(context);
1632 * We report this only via ack->result
1634 return NT_STATUS_OK;
1637 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1638 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1639 ack->syntax = context->transfer_syntax;
1640 return NT_STATUS_OK;
1643 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1644 const struct dcerpc_bind *b,
1645 struct dcerpc_ack_ctx *ack_ctx_list)
1647 NTSTATUS status;
1648 size_t i;
1649 bool validate_only = false;
1650 bool preferred_ndr32;
1653 * Try to negotiate one new presentation context,
1654 * using our preferred transfer syntax.
1656 for (i = 0; i < b->num_contexts; i++) {
1657 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1658 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1660 status = dcesrv_check_or_create_context(call, b, c, a,
1661 validate_only,
1662 call->conn->preferred_transfer);
1663 if (!NT_STATUS_IS_OK(status)) {
1664 return status;
1667 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1669 * We managed to negotiate one context.
1671 * => we're done.
1673 validate_only = true;
1677 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1678 call->conn->preferred_transfer);
1679 if (preferred_ndr32) {
1681 * We're done.
1683 return NT_STATUS_OK;
1687 * Try to negotiate one new presentation context,
1688 * using NDR 32 as fallback.
1690 for (i = 0; i < b->num_contexts; i++) {
1691 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1692 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1694 status = dcesrv_check_or_create_context(call, b, c, a,
1695 validate_only,
1696 &ndr_transfer_syntax_ndr);
1697 if (!NT_STATUS_IS_OK(status)) {
1698 return status;
1701 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1703 * We managed to negotiate one context.
1705 * => we're done.
1707 validate_only = true;
1711 return NT_STATUS_OK;
1714 static void dcesrv_alter_done(struct tevent_req *subreq);
1717 handle a alter context request
1719 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1721 struct dcesrv_connection *conn = call->conn;
1722 NTSTATUS status;
1723 bool auth_ok = false;
1724 struct ncacn_packet *pkt = &call->ack_pkt;
1725 uint32_t extra_flags = 0;
1726 struct dcesrv_auth *auth = call->auth_state;
1727 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1728 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1729 struct tevent_req *subreq = NULL;
1730 size_t i;
1732 if (!call->conn->allow_alter) {
1733 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1736 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1737 DCERPC_PKT_ALTER,
1738 call->pkt.u.alter.auth_info.length,
1739 0, /* required flags */
1740 DCERPC_PFC_FLAG_FIRST |
1741 DCERPC_PFC_FLAG_LAST |
1742 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1743 0x08 | /* this is not defined, but should be ignored */
1744 DCERPC_PFC_FLAG_CONC_MPX |
1745 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1746 DCERPC_PFC_FLAG_MAYBE |
1747 DCERPC_PFC_FLAG_OBJECT_UUID);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1752 auth_ok = dcesrv_auth_alter(call);
1753 if (!auth_ok) {
1754 if (call->fault_code != 0) {
1755 return dcesrv_fault_disconnect(call, call->fault_code);
1759 if (call->pkt.u.alter.num_contexts < 1) {
1760 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1763 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1764 call->pkt.u.alter.num_contexts);
1765 if (ack_ctx_list == NULL) {
1766 return NT_STATUS_NO_MEMORY;
1770 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1771 * dcesrv_check_or_create_context()) and do some protocol validation
1772 * and set sane defaults.
1774 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1775 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1776 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1778 if (c->num_transfer_syntaxes == 0) {
1779 return dcesrv_fault_disconnect(call,
1780 DCERPC_NCA_S_PROTO_ERROR);
1783 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1784 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1788 * Try to negotiate one new presentation context.
1790 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1791 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1792 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1794 if (!NT_STATUS_IS_OK(status)) {
1795 return status;
1798 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1799 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1800 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1801 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1804 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1805 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1808 /* handle any authentication that is being requested */
1809 if (!auth_ok) {
1810 if (call->in_auth_info.auth_type != auth->auth_type) {
1811 return dcesrv_fault_disconnect(call,
1812 DCERPC_FAULT_SEC_PKG_ERROR);
1814 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1817 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1818 pkt->auth_length = 0;
1819 pkt->call_id = call->pkt.call_id;
1820 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1821 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1822 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1823 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1824 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1825 pkt->u.alter_resp.secondary_address = "";
1826 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1827 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1828 pkt->u.alter_resp.auth_info = data_blob_null;
1830 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1831 if (!NT_STATUS_IS_OK(status)) {
1832 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1835 if (auth->auth_finished) {
1836 return dcesrv_auth_reply(call);
1839 cb->auth.become_root();
1840 subreq = gensec_update_send(call, call->event_ctx,
1841 auth->gensec_security,
1842 call->in_auth_info.credentials);
1843 cb->auth.unbecome_root();
1844 if (subreq == NULL) {
1845 return NT_STATUS_NO_MEMORY;
1847 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1849 return dcesrv_conn_auth_wait_setup(conn);
1852 static void dcesrv_alter_done(struct tevent_req *subreq)
1854 struct dcesrv_call_state *call =
1855 tevent_req_callback_data(subreq,
1856 struct dcesrv_call_state);
1857 struct dcesrv_connection *conn = call->conn;
1858 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1859 NTSTATUS status;
1861 cb->auth.become_root();
1862 status = gensec_update_recv(subreq, call,
1863 &call->out_auth_info->credentials);
1864 cb->auth.unbecome_root();
1865 TALLOC_FREE(subreq);
1867 status = dcesrv_auth_complete(call, status);
1868 if (!NT_STATUS_IS_OK(status)) {
1869 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1870 dcesrv_conn_auth_wait_finished(conn, status);
1871 return;
1874 status = dcesrv_auth_reply(call);
1875 dcesrv_conn_auth_wait_finished(conn, status);
1876 return;
1880 possibly save the call for inspection with ndrdump
1882 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1884 #ifdef DEVELOPER
1885 dcerpc_log_packet(call->conn->packet_log_dir,
1886 call->context->iface->name,
1887 call->pkt.u.request.opnum,
1888 NDR_IN,
1889 &call->pkt.u.request.stub_and_verifier,
1890 why);
1891 #endif
1894 #ifdef DEVELOPER
1896 Save the call for use as a seed for fuzzing.
1898 This is only enabled in a developer build, and only has effect if the
1899 "dcesrv fuzz directory" param is set.
1901 void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob,
1902 struct dcesrv_call_state *call,
1903 ndr_flags_type flags)
1905 const char *dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx,
1906 NULL,
1907 "dcesrv", "fuzz directory");
1909 dcerpc_save_ndr_fuzz_seed(call,
1910 call_blob,
1911 dump_dir,
1912 call->context->iface->name,
1913 flags,
1914 call->pkt.u.request.opnum,
1915 call->ndr_pull->flags & LIBNDR_FLAG_NDR64);
1917 #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1920 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1922 TALLOC_CTX *frame = talloc_stackframe();
1923 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1924 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1925 const struct dcerpc_sec_vt_pcontext pcontext = {
1926 .abstract_syntax = call->context->iface->syntax_id,
1927 .transfer_syntax = call->context->transfer_syntax,
1929 const struct dcerpc_sec_vt_header2 header2 =
1930 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1931 enum ndr_err_code ndr_err;
1932 struct dcerpc_sec_verification_trailer *vt = NULL;
1933 NTSTATUS status = NT_STATUS_OK;
1934 bool ok;
1936 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1938 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1939 frame, &vt);
1940 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1941 status = ndr_map_error2ntstatus(ndr_err);
1942 goto done;
1945 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1946 &pcontext, &header2);
1947 if (!ok) {
1948 status = NT_STATUS_ACCESS_DENIED;
1949 goto done;
1951 done:
1952 TALLOC_FREE(frame);
1953 return status;
1957 handle a dcerpc request packet
1959 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1961 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1962 struct dcesrv_auth *auth = call->auth_state;
1963 enum dcerpc_transport_t transport =
1964 dcerpc_binding_get_transport(endpoint->ep_description);
1965 struct ndr_pull *pull;
1966 bool turn_winbind_on = false;
1967 NTSTATUS status;
1969 if (auth->auth_invalid) {
1970 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1973 if (!auth->auth_finished) {
1974 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1977 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1978 if (auth->gensec_security != NULL &&
1979 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1980 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1983 if (call->context == NULL) {
1984 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1985 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1988 switch (auth->auth_level) {
1989 case DCERPC_AUTH_LEVEL_NONE:
1990 case DCERPC_AUTH_LEVEL_PACKET:
1991 case DCERPC_AUTH_LEVEL_INTEGRITY:
1992 case DCERPC_AUTH_LEVEL_PRIVACY:
1993 break;
1994 default:
1995 if (!call->context->allow_connect) {
1996 char *addr;
1998 addr = tsocket_address_string(call->conn->remote_address,
1999 call);
2001 DEBUG(2, ("%s: restrict auth_level_connect access "
2002 "to [%s] with auth[type=0x%x,level=0x%x] "
2003 "on [%s] from [%s]\n",
2004 __func__, call->context->iface->name,
2005 auth->auth_type,
2006 auth->auth_level,
2007 derpc_transport_string_by_transport(transport),
2008 addr));
2009 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2011 break;
2014 if (auth->auth_level < call->context->min_auth_level) {
2015 char *addr;
2017 addr = tsocket_address_string(call->conn->remote_address, call);
2019 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
2020 "to [%s] with auth[type=0x%x,level=0x%x] "
2021 "on [%s] from [%s]\n",
2022 __func__,
2023 call->context->min_auth_level,
2024 call->context->iface->name,
2025 auth->auth_type,
2026 auth->auth_level,
2027 derpc_transport_string_by_transport(transport),
2028 addr));
2029 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2032 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
2033 NT_STATUS_HAVE_NO_MEMORY(pull);
2035 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
2037 call->ndr_pull = pull;
2039 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
2040 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
2043 status = dcesrv_check_verification_trailer(call);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 uint32_t faultcode = DCERPC_FAULT_OTHER;
2046 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2047 faultcode = DCERPC_FAULT_ACCESS_DENIED;
2049 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
2050 nt_errstr(status)));
2051 return dcesrv_fault(call, faultcode);
2054 if (call->context->ndr64) {
2055 call->ndr_pull->flags |= LIBNDR_FLAG_NDR64;
2058 /* unravel the NDR for the packet */
2059 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
2060 if (!NT_STATUS_IS_OK(status)) {
2061 uint8_t extra_flags = 0;
2062 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
2063 /* we got an unknown call */
2064 DEBUG(3,(__location__ ": Unknown RPC call %"PRIu16" on %s\n",
2065 call->pkt.u.request.opnum,
2066 call->context->iface->name));
2067 dcesrv_save_call(call, "unknown");
2068 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
2069 } else {
2070 dcesrv_save_call(call, "pullfail");
2073 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
2076 dcesrv_save_ndr_fuzz_seed(call->pkt.u.request.stub_and_verifier,
2077 call,
2078 NDR_IN);
2080 if (pull->offset != pull->data_size) {
2081 dcesrv_save_call(call, "extrabytes");
2082 DEBUG(3,("Warning: %"PRIu32" extra bytes in incoming RPC request\n",
2083 pull->data_size - pull->offset));
2086 if (call->state_flags & DCESRV_CALL_STATE_FLAG_WINBIND_OFF) {
2087 bool winbind_active = !winbind_env_set();
2088 if (winbind_active) {
2089 DBG_DEBUG("turning winbind off\n");
2090 (void)winbind_off();
2091 turn_winbind_on = true;
2095 /* call the dispatch function */
2096 status = call->context->iface->dispatch(call, call, call->r);
2098 if (turn_winbind_on) {
2099 DBG_DEBUG("turning winbind on\n");
2100 (void)winbind_on();
2103 if (!NT_STATUS_IS_OK(status)) {
2104 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
2105 call->context->iface->name,
2106 call->pkt.u.request.opnum,
2107 dcerpc_errstr(pull, call->fault_code)));
2108 return dcesrv_fault(call, call->fault_code);
2111 /* add the call to the pending list */
2112 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
2114 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2115 return NT_STATUS_OK;
2118 return dcesrv_reply(call);
2123 remove the call from the right list when freed
2125 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
2127 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2128 return 0;
2131 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
2133 return conn->local_address;
2136 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
2138 return conn->remote_address;
2142 process some input to a dcerpc endpoint server.
2144 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2145 struct ncacn_packet *pkt,
2146 DATA_BLOB blob)
2148 NTSTATUS status;
2149 struct dcesrv_call_state *call;
2150 struct dcesrv_call_state *existing = NULL;
2151 size_t num_auth_ctx = 0;
2152 enum dcerpc_AuthType auth_type = 0;
2153 enum dcerpc_AuthLevel auth_level = 0;
2154 uint32_t auth_context_id = 0;
2155 bool auth_invalid = false;
2157 call = talloc_zero(dce_conn, struct dcesrv_call_state);
2158 if (!call) {
2159 data_blob_free(&blob);
2160 talloc_free(pkt);
2161 return NT_STATUS_NO_MEMORY;
2163 call->conn = dce_conn;
2164 call->event_ctx = dce_conn->event_ctx;
2165 call->state_flags = call->conn->state_flags;
2166 call->time = timeval_current();
2167 call->list = DCESRV_LIST_NONE;
2169 talloc_steal(call, pkt);
2170 talloc_steal(call, blob.data);
2171 call->pkt = *pkt;
2173 if (dce_conn->max_auth_states == 0) {
2174 call->auth_state = dce_conn->default_auth_state;
2175 } else if (call->pkt.auth_length == 0) {
2176 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2177 dce_conn->default_auth_level_connect != NULL)
2179 call->auth_state = dce_conn->default_auth_level_connect;
2180 } else {
2181 call->auth_state = dce_conn->default_auth_state;
2185 if (call->auth_state == NULL) {
2186 struct dcesrv_auth *a = NULL;
2187 bool check_type_level = true;
2189 auth_type = dcerpc_get_auth_type(&blob);
2190 auth_level = dcerpc_get_auth_level(&blob);
2191 auth_context_id = dcerpc_get_auth_context_id(&blob);
2193 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2194 if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
2195 check_type_level = false;
2197 dce_conn->default_auth_level_connect = NULL;
2198 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
2199 dce_conn->got_explicit_auth_level_connect = true;
2203 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2204 num_auth_ctx++;
2206 if (a->auth_context_id != auth_context_id) {
2207 continue;
2210 if (a->auth_type != auth_type) {
2211 auth_invalid = true;
2213 if (a->auth_level != auth_level) {
2214 auth_invalid = true;
2217 if (check_type_level && auth_invalid) {
2218 a->auth_invalid = true;
2221 DLIST_PROMOTE(dce_conn->auth_states, a);
2222 call->auth_state = a;
2223 break;
2227 if (call->auth_state == NULL) {
2228 struct dcesrv_auth *a = NULL;
2230 if (num_auth_ctx >= dce_conn->max_auth_states) {
2231 return dcesrv_fault_disconnect(call,
2232 DCERPC_NCA_S_PROTO_ERROR);
2235 a = dcesrv_auth_create(dce_conn);
2236 if (a == NULL) {
2237 talloc_free(call);
2238 return NT_STATUS_NO_MEMORY;
2240 DLIST_ADD(dce_conn->auth_states, a);
2241 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2243 * This can never be valid.
2245 auth_invalid = true;
2246 a->auth_invalid = true;
2248 call->auth_state = a;
2251 talloc_set_destructor(call, dcesrv_call_dequeue);
2253 if (call->conn->allow_bind) {
2255 * Only one bind is possible per connection
2257 call->conn->allow_bind = false;
2258 return dcesrv_bind(call);
2261 /* we have to check the signing here, before combining the
2262 pdus */
2263 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2264 dcesrv_default_auth_state_prepare_request(call);
2266 if (call->auth_state->auth_started &&
2267 !call->auth_state->auth_finished) {
2268 return dcesrv_fault_disconnect(call,
2269 DCERPC_NCA_S_PROTO_ERROR);
2272 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2273 DCERPC_PKT_REQUEST,
2274 call->pkt.u.request.stub_and_verifier.length,
2275 0, /* required_flags */
2276 DCERPC_PFC_FLAG_FIRST |
2277 DCERPC_PFC_FLAG_LAST |
2278 DCERPC_PFC_FLAG_PENDING_CANCEL |
2279 0x08 | /* this is not defined, but should be ignored */
2280 DCERPC_PFC_FLAG_CONC_MPX |
2281 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2282 DCERPC_PFC_FLAG_MAYBE |
2283 DCERPC_PFC_FLAG_OBJECT_UUID);
2284 if (!NT_STATUS_IS_OK(status)) {
2285 return dcesrv_fault_disconnect(call,
2286 DCERPC_NCA_S_PROTO_ERROR);
2289 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2291 * We don't use dcesrv_fault_disconnect()
2292 * here, because we don't want to set
2293 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2295 * Note that we don't check against the negotiated
2296 * max_recv_frag, but a hard coded value.
2298 return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2301 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2302 if (dce_conn->pending_call_list != NULL) {
2304 * concurrent requests are only allowed
2305 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2307 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2308 return dcesrv_fault_disconnect0(call,
2309 DCERPC_NCA_S_PROTO_ERROR);
2312 /* only one request is possible in the fragmented list */
2313 if (dce_conn->incoming_fragmented_call_list != NULL) {
2314 call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
2316 existing = dcesrv_find_fragmented_call(dce_conn,
2317 call->pkt.call_id);
2318 if (existing != NULL && call->auth_state != existing->auth_state) {
2319 call->context = dcesrv_find_context(call->conn,
2320 call->pkt.u.request.context_id);
2322 if (call->pkt.auth_length != 0 && existing->context == call->context) {
2323 call->fault_code = DCERPC_FAULT_SEC_PKG_ERROR;
2326 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2328 * Without DCERPC_PFC_FLAG_CONC_MPX
2329 * we need to return the FAULT on the
2330 * already existing call.
2332 * This is important to get the
2333 * call_id and context_id right.
2335 dce_conn->incoming_fragmented_call_list->fault_code = call->fault_code;
2336 TALLOC_FREE(call);
2337 call = dce_conn->incoming_fragmented_call_list;
2339 if (existing != NULL) {
2340 call->context = existing->context;
2342 return dcesrv_fault_disconnect0(call, call->fault_code);
2344 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2345 return dcesrv_fault_disconnect(call,
2346 DCERPC_FAULT_NO_CALL_ACTIVE);
2348 call->context = dcesrv_find_context(call->conn,
2349 call->pkt.u.request.context_id);
2350 if (call->context == NULL) {
2351 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2352 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2354 } else {
2355 int cmp;
2357 existing = dcesrv_find_fragmented_call(dce_conn,
2358 call->pkt.call_id);
2359 if (existing == NULL) {
2360 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2362 * Without DCERPC_PFC_FLAG_CONC_MPX
2363 * we need to return the FAULT on the
2364 * already existing call.
2366 * This is important to get the
2367 * call_id and context_id right.
2369 if (dce_conn->incoming_fragmented_call_list != NULL) {
2370 TALLOC_FREE(call);
2371 call = dce_conn->incoming_fragmented_call_list;
2373 return dcesrv_fault_disconnect0(call,
2374 DCERPC_NCA_S_PROTO_ERROR);
2376 if (dce_conn->incoming_fragmented_call_list != NULL) {
2377 return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2379 call->context = dcesrv_find_context(call->conn,
2380 call->pkt.u.request.context_id);
2381 if (call->context == NULL) {
2382 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2383 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2385 if (auth_invalid) {
2386 return dcesrv_fault_disconnect0(call,
2387 DCERPC_FAULT_ACCESS_DENIED);
2389 return dcesrv_fault_disconnect0(call,
2390 DCERPC_NCA_S_PROTO_ERROR);
2393 if (call->pkt.ptype != existing->pkt.ptype) {
2394 /* trying to play silly buggers are we? */
2395 return dcesrv_fault_disconnect(existing,
2396 DCERPC_NCA_S_PROTO_ERROR);
2398 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2399 sizeof(pkt->drep));
2400 if (cmp != 0) {
2401 return dcesrv_fault_disconnect(existing,
2402 DCERPC_NCA_S_PROTO_ERROR);
2404 call->auth_state = existing->auth_state;
2405 call->context = existing->context;
2409 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2410 bool ok;
2411 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2413 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2414 payload_offset += 16;
2417 ok = dcesrv_auth_pkt_pull(call, &blob,
2418 0, /* required_flags */
2419 DCERPC_PFC_FLAG_FIRST |
2420 DCERPC_PFC_FLAG_LAST |
2421 DCERPC_PFC_FLAG_PENDING_CANCEL |
2422 0x08 | /* this is not defined, but should be ignored */
2423 DCERPC_PFC_FLAG_CONC_MPX |
2424 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2425 DCERPC_PFC_FLAG_MAYBE |
2426 DCERPC_PFC_FLAG_OBJECT_UUID,
2427 payload_offset,
2428 &call->pkt.u.request.stub_and_verifier);
2429 if (!ok) {
2431 * We don't use dcesrv_fault_disconnect()
2432 * here, because we don't want to set
2433 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2435 if (call->fault_code == 0) {
2436 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2438 return dcesrv_fault_disconnect0(call, call->fault_code);
2442 /* see if this is a continued packet */
2443 if (existing != NULL) {
2444 struct dcerpc_request *er = &existing->pkt.u.request;
2445 const struct dcerpc_request *nr = &call->pkt.u.request;
2446 size_t available;
2447 size_t alloc_size;
2448 size_t alloc_hint;
2451 * Up to 4 MByte are allowed by all fragments
2453 available = dce_conn->max_total_request_size;
2454 if (er->stub_and_verifier.length > available) {
2455 return dcesrv_fault_disconnect0(existing,
2456 DCERPC_FAULT_ACCESS_DENIED);
2458 available -= er->stub_and_verifier.length;
2459 if (nr->alloc_hint > available) {
2460 return dcesrv_fault_disconnect0(existing,
2461 DCERPC_FAULT_ACCESS_DENIED);
2463 if (nr->stub_and_verifier.length > available) {
2464 return dcesrv_fault_disconnect0(existing,
2465 DCERPC_FAULT_ACCESS_DENIED);
2467 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2468 /* allocate at least 1 byte */
2469 alloc_hint = MAX(alloc_hint, 1);
2470 alloc_size = er->stub_and_verifier.length +
2471 nr->stub_and_verifier.length;
2472 alloc_size = MAX(alloc_size, alloc_hint);
2474 er->stub_and_verifier.data =
2475 talloc_realloc(existing,
2476 er->stub_and_verifier.data,
2477 uint8_t, alloc_size);
2478 if (er->stub_and_verifier.data == NULL) {
2479 TALLOC_FREE(call);
2480 return dcesrv_fault_with_flags(existing,
2481 DCERPC_FAULT_OUT_OF_RESOURCES,
2482 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2484 memcpy(er->stub_and_verifier.data +
2485 er->stub_and_verifier.length,
2486 nr->stub_and_verifier.data,
2487 nr->stub_and_verifier.length);
2488 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2490 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2492 TALLOC_FREE(call);
2493 call = existing;
2496 /* this may not be the last pdu in the chain - if its isn't then
2497 just put it on the incoming_fragmented_call_list and wait for the rest */
2498 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2499 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2501 * Up to 4 MByte are allowed by all fragments
2503 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2504 return dcesrv_fault_disconnect0(call,
2505 DCERPC_FAULT_ACCESS_DENIED);
2507 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2508 return NT_STATUS_OK;
2511 /* This removes any fragments we may have had stashed away */
2512 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2514 switch (call->pkt.ptype) {
2515 case DCERPC_PKT_BIND:
2516 status = dcesrv_bind_nak(call,
2517 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2518 break;
2519 case DCERPC_PKT_AUTH3:
2520 status = dcesrv_auth3(call);
2521 break;
2522 case DCERPC_PKT_ALTER:
2523 status = dcesrv_alter(call);
2524 break;
2525 case DCERPC_PKT_REQUEST:
2526 status = dcesrv_request(call);
2527 break;
2528 case DCERPC_PKT_CO_CANCEL:
2529 existing = dcesrv_find_fragmented_call(dce_conn,
2530 call->pkt.call_id);
2531 if (existing != NULL) {
2533 * If the call is still waiting for
2534 * more fragments, it's not pending yet,
2535 * for now we just remember we got CO_CANCEL,
2536 * but ignore it otherwise.
2538 * This matches what windows is doing...
2540 existing->got_co_cancel = true;
2541 SMB_ASSERT(existing->subreq == NULL);
2542 existing = NULL;
2544 existing = dcesrv_find_pending_call(dce_conn,
2545 call->pkt.call_id);
2546 if (existing != NULL) {
2548 * Give the backend a chance to react
2549 * on CO_CANCEL, but note it's ignored
2550 * by default.
2552 existing->got_co_cancel = true;
2553 if (existing->subreq != NULL) {
2554 tevent_req_cancel(existing->subreq);
2556 existing = NULL;
2558 status = NT_STATUS_OK;
2559 TALLOC_FREE(call);
2560 break;
2561 case DCERPC_PKT_ORPHANED:
2562 existing = dcesrv_find_fragmented_call(dce_conn,
2563 call->pkt.call_id);
2564 if (existing != NULL) {
2566 * If the call is still waiting for
2567 * more fragments, it's not pending yet,
2568 * for now we just remember we got ORPHANED,
2569 * but ignore it otherwise.
2571 * This matches what windows is doing...
2573 existing->got_orphaned = true;
2574 SMB_ASSERT(existing->subreq == NULL);
2575 existing = NULL;
2577 existing = dcesrv_find_pending_call(dce_conn,
2578 call->pkt.call_id);
2579 if (existing != NULL) {
2581 * Give the backend a chance to react
2582 * on ORPHANED, but note it's ignored
2583 * by default.
2585 existing->got_orphaned = true;
2586 if (existing->subreq != NULL) {
2587 tevent_req_cancel(existing->subreq);
2589 existing = NULL;
2591 status = NT_STATUS_OK;
2592 TALLOC_FREE(call);
2593 break;
2594 case DCERPC_PKT_BIND_ACK:
2595 case DCERPC_PKT_BIND_NAK:
2596 case DCERPC_PKT_ALTER_RESP:
2597 case DCERPC_PKT_RESPONSE:
2598 case DCERPC_PKT_FAULT:
2599 case DCERPC_PKT_SHUTDOWN:
2600 default:
2601 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2602 break;
2605 /* if we are going to be sending a reply then add
2606 it to the list of pending calls. We add it to the end to keep the call
2607 list in the order we will answer */
2608 if (!NT_STATUS_IS_OK(status)) {
2609 talloc_free(call);
2612 return status;
2615 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2616 struct loadparm_context *lp_ctx,
2617 struct dcesrv_context_callbacks *cb,
2618 struct dcesrv_context **_dce_ctx)
2620 struct dcesrv_context *dce_ctx;
2622 if (cb == NULL) {
2623 return NT_STATUS_INVALID_PARAMETER;
2626 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2627 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2629 if (uid_wrapper_enabled()) {
2630 setenv("UID_WRAPPER_MYUID", "1", 1);
2632 dce_ctx->initial_euid = geteuid();
2633 if (uid_wrapper_enabled()) {
2634 unsetenv("UID_WRAPPER_MYUID");
2637 dce_ctx->endpoint_list = NULL;
2638 dce_ctx->lp_ctx = lp_ctx;
2639 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2640 if (dce_ctx->assoc_groups_idr == NULL) {
2641 TALLOC_FREE(dce_ctx);
2642 return NT_STATUS_NO_MEMORY;
2644 dce_ctx->broken_connections = NULL;
2645 dce_ctx->callbacks = cb;
2648 * For now we only support NDR32.
2650 dce_ctx->preferred_transfer = &ndr_transfer_syntax_ndr;
2652 *_dce_ctx = dce_ctx;
2653 return NT_STATUS_OK;
2657 * @brief Set callback functions on an existing dcesrv_context
2659 * This allows to reset callbacks initially set via
2660 * dcesrv_init_context()
2662 * @param[in] dce_ctx The context to set the callbacks on
2663 * @param[in] cb The callbacks to set on dce_ctx
2665 _PUBLIC_ void dcesrv_context_set_callbacks(
2666 struct dcesrv_context *dce_ctx,
2667 struct dcesrv_context_callbacks *cb)
2669 dce_ctx->callbacks = cb;
2672 _PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
2673 const char **endpoint_servers)
2675 NTSTATUS status;
2676 int i;
2678 if (endpoint_servers == NULL) {
2679 DBG_ERR("No endpoint servers configured\n");
2680 return NT_STATUS_INTERNAL_ERROR;
2683 for (i=0;endpoint_servers[i];i++) {
2684 status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]);
2685 if (!NT_STATUS_IS_OK(status)) {
2686 DBG_ERR("failed to init endpoint server = '%s': %s\n",
2687 endpoint_servers[i], nt_errstr(status));
2688 return status;
2692 return NT_STATUS_OK;
2695 /* the list of currently registered DCERPC endpoint servers.
2697 static struct ep_server {
2698 struct dcesrv_endpoint_server *ep_server;
2699 } *ep_servers = NULL;
2700 static int num_ep_servers = 0;
2702 _PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers(
2703 struct dcesrv_context *dce_ctx)
2705 NTSTATUS status;
2706 int i;
2708 for (i = 0; i < num_ep_servers; i++) {
2709 status = dcesrv_init_ep_server(dce_ctx,
2710 ep_servers[i].ep_server->name);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 return status;
2716 return NT_STATUS_OK;
2719 _PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
2720 const char *ep_server_name)
2722 struct dcesrv_endpoint_server *ep_server = NULL;
2723 NTSTATUS status;
2725 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2726 dcesrv_ep_server_byname(ep_server_name));
2727 if (ep_server == NULL) {
2728 DBG_ERR("Failed to find endpoint server '%s'\n",
2729 ep_server_name);
2730 return NT_STATUS_INTERNAL_ERROR;
2733 if (ep_server->initialized) {
2734 return NT_STATUS_OK;
2737 status = ep_server->init_server(dce_ctx, ep_server);
2738 if (!NT_STATUS_IS_OK(status)) {
2739 DBG_ERR("Failed to init endpoint server '%s': %s\n",
2740 ep_server_name, nt_errstr(status));
2741 return status;
2744 ep_server->initialized = true;
2746 return NT_STATUS_OK;
2749 _PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers(
2750 struct dcesrv_context *dce_ctx)
2752 NTSTATUS status;
2753 int i;
2755 for (i = 0; i < num_ep_servers; i++) {
2756 status = dcesrv_shutdown_ep_server(dce_ctx,
2757 ep_servers[i].ep_server->name);
2758 if (!NT_STATUS_IS_OK(status)) {
2759 return status;
2763 return NT_STATUS_OK;
2766 _PUBLIC_ NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
2767 const char *ep_server_name)
2769 struct dcesrv_endpoint_server *ep_server = NULL;
2770 NTSTATUS status;
2772 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2773 dcesrv_ep_server_byname(ep_server_name));
2774 if (ep_server == NULL) {
2775 DBG_ERR("Failed to find endpoint server '%s'\n",
2776 ep_server_name);
2777 return NT_STATUS_INTERNAL_ERROR;
2780 if (!ep_server->initialized) {
2781 return NT_STATUS_OK;
2784 DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2785 ep_server_name);
2787 status = ep_server->shutdown_server(dce_ctx, ep_server);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2790 ep_server_name, nt_errstr(status));
2791 return status;
2794 ep_server->initialized = false;
2796 return NT_STATUS_OK;
2800 register a DCERPC endpoint server.
2802 The 'name' can be later used by other backends to find the operations
2803 structure for this backend.
2806 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2809 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2810 /* its already registered! */
2811 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2812 ep_server->name));
2813 return NT_STATUS_OBJECT_NAME_COLLISION;
2816 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2817 if (!ep_servers) {
2818 smb_panic("out of memory in dcerpc_register");
2821 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2822 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2824 num_ep_servers++;
2826 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2827 ep_server->name));
2829 return NT_STATUS_OK;
2833 return the operations structure for a named backend of the specified type
2835 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2837 int i;
2839 for (i=0;i<num_ep_servers;i++) {
2840 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2841 return ep_servers[i].ep_server;
2845 return NULL;
2849 return the DCERPC module version, and the size of some critical types
2850 This can be used by endpoint server modules to either detect compilation errors, or provide
2851 multiple implementations for different smbd compilation options in one module
2853 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2855 static const struct dcesrv_critical_sizes critical_sizes = {
2856 DCERPC_MODULE_VERSION,
2857 sizeof(struct dcesrv_context),
2858 sizeof(struct dcesrv_endpoint),
2859 sizeof(struct dcesrv_endpoint_server),
2860 sizeof(struct dcesrv_interface),
2861 sizeof(struct dcesrv_if_list),
2862 sizeof(struct dcesrv_connection),
2863 sizeof(struct dcesrv_call_state),
2864 sizeof(struct dcesrv_auth),
2865 sizeof(struct dcesrv_handle)
2868 return &critical_sizes;
2871 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2873 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2874 struct dcesrv_call_state *c = NULL, *n = NULL;
2875 struct dcesrv_auth *a = NULL;
2877 dce_conn->wait_send = NULL;
2878 dce_conn->wait_recv = NULL;
2879 dce_conn->wait_private = NULL;
2881 dce_conn->allow_bind = false;
2882 dce_conn->allow_alter = false;
2884 dce_conn->default_auth_state->auth_invalid = true;
2886 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2887 a->auth_invalid = true;
2890 no_pending:
2891 if (dce_conn->pending_call_list == NULL) {
2892 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2894 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2895 dce_conn->transport.terminate_connection(dce_conn,
2896 full_reason ? full_reason : reason);
2897 return;
2900 if (dce_conn->terminate != NULL) {
2901 return;
2904 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2905 reason));
2906 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2907 if (dce_conn->terminate == NULL) {
2908 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2910 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2912 for (c = dce_conn->pending_call_list; c != NULL; c = n) {
2913 n = c->next;
2915 c->got_disconnect = true;
2916 if (c->subreq != NULL) {
2917 tevent_req_cancel(c->subreq);
2921 if (dce_conn->pending_call_list == NULL) {
2923 * tevent_req_cancel() was able to made progress
2924 * and we don't have pending calls anymore.
2926 goto no_pending;
2930 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2932 struct dcesrv_connection *cur, *next;
2934 next = dce_ctx->broken_connections;
2935 while (next != NULL) {
2936 cur = next;
2937 next = cur->next;
2939 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2940 struct dcesrv_connection_context *context_cur, *context_next;
2942 context_next = cur->contexts;
2943 while (context_next != NULL) {
2944 context_cur = context_next;
2945 context_next = context_cur->next;
2947 dcesrv_connection_context_destructor(context_cur);
2951 dcesrv_terminate_connection(cur, cur->terminate);
2955 struct dcesrv_sock_reply_state {
2956 struct dcesrv_connection *dce_conn;
2957 struct dcesrv_call_state *call;
2958 struct iovec iov;
2961 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2962 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2964 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2966 struct dcesrv_call_state *call;
2968 call = dce_conn->call_list;
2969 if (!call || !call->replies) {
2970 return;
2973 while (call->replies) {
2974 struct data_blob_list_item *rep = call->replies;
2975 struct dcesrv_sock_reply_state *substate;
2976 struct tevent_req *subreq;
2978 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2979 if (!substate) {
2980 dcesrv_terminate_connection(dce_conn, "no memory");
2981 return;
2984 substate->dce_conn = dce_conn;
2985 substate->call = NULL;
2987 DLIST_REMOVE(call->replies, rep);
2989 if (call->replies == NULL && call->terminate_reason == NULL) {
2990 substate->call = call;
2993 substate->iov.iov_base = (void *) rep->blob.data;
2994 substate->iov.iov_len = rep->blob.length;
2996 subreq = tstream_writev_queue_send(substate,
2997 dce_conn->event_ctx,
2998 dce_conn->stream,
2999 dce_conn->send_queue,
3000 &substate->iov, 1);
3001 if (!subreq) {
3002 dcesrv_terminate_connection(dce_conn, "no memory");
3003 return;
3005 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
3006 substate);
3009 if (call->terminate_reason != NULL) {
3010 struct tevent_req *subreq;
3012 subreq = tevent_queue_wait_send(call,
3013 dce_conn->event_ctx,
3014 dce_conn->send_queue);
3015 if (!subreq) {
3016 dcesrv_terminate_connection(dce_conn, __location__);
3017 return;
3019 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
3020 call);
3023 DLIST_REMOVE(call->conn->call_list, call);
3024 call->list = DCESRV_LIST_NONE;
3027 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
3029 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
3030 struct dcesrv_sock_reply_state);
3031 int ret;
3032 int sys_errno;
3033 NTSTATUS status;
3034 struct dcesrv_call_state *call = substate->call;
3036 ret = tstream_writev_queue_recv(subreq, &sys_errno);
3037 TALLOC_FREE(subreq);
3038 if (ret == -1) {
3039 status = map_nt_error_from_unix_common(sys_errno);
3040 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
3041 return;
3044 talloc_free(substate);
3045 if (call) {
3046 talloc_free(call);
3050 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
3052 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
3054 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
3055 struct dcesrv_call_state);
3056 bool ok;
3057 struct timeval tv;
3059 /* make sure we stop send queue before removing subreq */
3060 tevent_queue_stop(call->conn->send_queue);
3062 ok = tevent_queue_wait_recv(subreq);
3063 TALLOC_FREE(subreq);
3064 if (!ok) {
3065 dcesrv_terminate_connection(call->conn, __location__);
3066 return;
3069 /* disconnect after 200 usecs */
3070 tv = timeval_current_ofs_usec(200);
3071 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
3072 if (subreq == NULL) {
3073 dcesrv_terminate_connection(call->conn, __location__);
3074 return;
3076 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
3077 call);
3080 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
3082 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
3083 struct dcesrv_call_state);
3084 bool ok;
3086 ok = tevent_wakeup_recv(subreq);
3087 TALLOC_FREE(subreq);
3088 if (!ok) {
3089 dcesrv_terminate_connection(call->conn, __location__);
3090 return;
3093 dcesrv_terminate_connection(call->conn, call->terminate_reason);
3096 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
3098 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
3100 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3101 struct dcesrv_connection);
3102 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3103 struct ncacn_packet *pkt;
3104 DATA_BLOB buffer;
3105 NTSTATUS status;
3107 if (dce_conn->terminate) {
3109 * if the current connection is broken
3110 * we need to clean it up before any other connection
3112 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3113 dcesrv_cleanup_broken_connections(dce_ctx);
3114 return;
3117 dcesrv_cleanup_broken_connections(dce_ctx);
3119 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
3120 &pkt, &buffer);
3121 TALLOC_FREE(subreq);
3122 if (!NT_STATUS_IS_OK(status)) {
3123 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3124 return;
3127 dcesrv_loop_next_packet(dce_conn, pkt, buffer);
3131 * @brief Start the dcesrv loop, inducing the bind as a blob
3133 * Like dcesrv_connection_loop_start() but used from connections
3134 * where the caller has already read the dcerpc bind packet from
3135 * the socket and is available as a DATA_BLOB.
3137 * @param[in] dce_conn The connection to start
3138 * @param[in] pkt The parsed bind packet
3139 * @param[in] buffer The full binary bind including auth data
3141 void dcesrv_loop_next_packet(
3142 struct dcesrv_connection *dce_conn,
3143 struct ncacn_packet *pkt,
3144 DATA_BLOB buffer)
3146 struct tevent_req *subreq = NULL;
3147 NTSTATUS status;
3149 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
3150 if (!NT_STATUS_IS_OK(status)) {
3151 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3152 return;
3156 * This is used to block the connection during
3157 * pending authentication.
3159 if (dce_conn->wait_send != NULL) {
3160 subreq = dce_conn->wait_send(dce_conn,
3161 dce_conn->event_ctx,
3162 dce_conn->wait_private);
3163 if (!subreq) {
3164 status = NT_STATUS_NO_MEMORY;
3165 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3166 return;
3168 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
3169 return;
3172 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
3173 dce_conn->event_ctx,
3174 dce_conn->stream);
3175 if (!subreq) {
3176 status = NT_STATUS_NO_MEMORY;
3177 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3178 return;
3180 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
3183 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
3185 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3186 struct dcesrv_connection);
3187 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3188 NTSTATUS status;
3190 if (dce_conn->terminate) {
3192 * if the current connection is broken
3193 * we need to clean it up before any other connection
3195 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3196 dcesrv_cleanup_broken_connections(dce_ctx);
3197 return;
3200 dcesrv_cleanup_broken_connections(dce_ctx);
3202 status = dce_conn->wait_recv(subreq);
3203 dce_conn->wait_send = NULL;
3204 dce_conn->wait_recv = NULL;
3205 dce_conn->wait_private = NULL;
3206 TALLOC_FREE(subreq);
3207 if (!NT_STATUS_IS_OK(status)) {
3208 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3209 return;
3212 status = dcesrv_connection_loop_start(dce_conn);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3215 return;
3220 * retrieve credentials from a dce_call
3222 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3224 struct dcesrv_auth *auth = dce_call->auth_state;
3225 SMB_ASSERT(auth->auth_finished);
3226 return auth->session_info->credentials;
3230 * returns true if this is an authenticated call
3232 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3234 struct dcesrv_auth *auth = dce_call->auth_state;
3235 enum security_user_level level;
3236 SMB_ASSERT(auth->auth_finished);
3237 level = security_session_user_level(auth->session_info, NULL);
3238 return level >= SECURITY_USER;
3242 * retrieve account_name for a dce_call
3244 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3246 struct dcesrv_auth *auth = dce_call->auth_state;
3247 SMB_ASSERT(auth->auth_finished);
3248 return auth->session_info->info->account_name;
3252 * retrieve session_info from a dce_call
3254 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3256 struct dcesrv_auth *auth = dce_call->auth_state;
3257 SMB_ASSERT(auth->auth_finished);
3258 return auth->session_info;
3262 * retrieve auth type/level from a dce_call
3264 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3265 enum dcerpc_AuthType *auth_type,
3266 enum dcerpc_AuthLevel *auth_level)
3268 struct dcesrv_auth *auth = dce_call->auth_state;
3270 SMB_ASSERT(auth->auth_finished);
3272 if (auth_type != NULL) {
3273 *auth_type = auth->auth_type;
3275 if (auth_level != NULL) {
3276 *auth_level = auth->auth_level;
3280 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
3282 struct tevent_req *subreq;
3284 subreq = dcerpc_read_ncacn_packet_send(conn,
3285 conn->event_ctx,
3286 conn->stream);
3287 if (subreq == NULL) {
3288 return NT_STATUS_NO_MEMORY;
3290 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
3292 return NT_STATUS_OK;
3295 _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
3297 NTSTATUS status;
3298 struct ndr_pull *pull = NULL;
3299 struct ndr_push *push = NULL;
3300 struct data_blob_list_item *rep = NULL;
3302 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier,
3303 call);
3304 if (pull == NULL) {
3305 return NT_STATUS_NO_MEMORY;
3308 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
3310 call->ndr_pull = pull;
3312 /* unravel the NDR for the packet */
3313 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
3314 if (!NT_STATUS_IS_OK(status)) {
3315 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3316 call->context->iface->name,
3317 call->pkt.u.request.opnum,
3318 dcerpc_errstr(call, call->fault_code));
3319 return dcerpc_fault_to_nt_status(call->fault_code);
3322 status = call->context->iface->local(call, call, call->r);
3323 if (!NT_STATUS_IS_OK(status)) {
3324 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3325 call->context->iface->name,
3326 call->pkt.u.request.opnum,
3327 dcerpc_errstr(call, call->fault_code));
3328 return dcerpc_fault_to_nt_status(call->fault_code);
3331 /* This can never go async for now! */
3332 SMB_ASSERT(!(call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC));
3334 /* call the reply function */
3335 status = call->context->iface->reply(call, call, call->r);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3338 call->context->iface->name,
3339 call->pkt.u.request.opnum,
3340 dcerpc_errstr(call, call->fault_code));
3341 return dcerpc_fault_to_nt_status(call->fault_code);
3344 push = ndr_push_init_ctx(call);
3345 if (push == NULL) {
3346 return NT_STATUS_NO_MEMORY;
3349 push->ptr_count = call->ndr_pull->ptr_count;
3351 status = call->context->iface->ndr_push(call, call, push, call->r);
3352 if (!NT_STATUS_IS_OK(status)) {
3353 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3354 call->context->iface->name,
3355 call->pkt.u.request.opnum,
3356 dcerpc_errstr(call, call->fault_code));
3357 return dcerpc_fault_to_nt_status(call->fault_code);
3360 rep = talloc_zero(call, struct data_blob_list_item);
3361 if (rep == NULL) {
3362 return NT_STATUS_NO_MEMORY;
3365 rep->blob = ndr_push_blob(push);
3366 DLIST_ADD_END(call->replies, rep);
3368 return NT_STATUS_OK;