s3-libnet: avoid using lp_dns_hostname() in join code
[samba.git] / librpc / rpc / dcesrv_core.c
blob66478001640d039bfbf856c4148139d8f8a68efb
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"
39 #include "libcli/smb/tstream_smbXcli_np.h"
41 /**
42 * @file
43 * @brief DCERPC server
46 #undef DBGC_CLASS
47 #define DBGC_CLASS DBGC_RPC_SRV
49 #undef strcasecmp
51 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
52 const struct dcerpc_bind *b,
53 struct dcerpc_ack_ctx *ack_ctx_list);
56 see if two endpoints match
58 static bool endpoints_match(const struct dcerpc_binding *ep1,
59 const struct dcerpc_binding *ep2)
61 enum dcerpc_transport_t t1;
62 enum dcerpc_transport_t t2;
63 const char *e1;
64 const char *e2;
66 t1 = dcerpc_binding_get_transport(ep1);
67 t2 = dcerpc_binding_get_transport(ep2);
69 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
70 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
72 if (t1 != t2) {
73 return false;
76 if (!e1 || !e2) {
77 return e1 == e2;
80 if (strcasecmp(e1, e2) != 0) {
81 return false;
84 return true;
88 find an endpoint in the dcesrv_context
90 _PUBLIC_ NTSTATUS dcesrv_find_endpoint(struct dcesrv_context *dce_ctx,
91 const struct dcerpc_binding *ep_description,
92 struct dcesrv_endpoint **_out)
94 struct dcesrv_endpoint *ep = NULL;
95 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
96 if (endpoints_match(ep->ep_description, ep_description)) {
97 *_out = ep;
98 return NT_STATUS_OK;
101 return NT_STATUS_NOT_FOUND;
105 find a registered context_id from a bind or alter_context
107 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
108 uint16_t context_id)
110 struct dcesrv_connection_context *c;
111 for (c=conn->contexts;c;c=c->next) {
112 if (c->context_id == context_id) return c;
114 return NULL;
118 find the interface operations on any endpoint with this binding
120 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
121 struct dcerpc_binding *binding,
122 const struct dcesrv_interface *iface)
124 struct dcesrv_endpoint *ep;
125 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
126 if (endpoints_match(ep->ep_description, binding)) {
127 const struct dcesrv_interface *ret = NULL;
129 ret = find_interface_by_syntax_id(
130 ep, &iface->syntax_id);
131 if (ret != NULL) {
132 return ret;
136 return NULL;
140 find the interface operations on an endpoint by uuid
142 _PUBLIC_ const struct dcesrv_interface *find_interface_by_syntax_id(
143 const struct dcesrv_endpoint *endpoint,
144 const struct ndr_syntax_id *interface)
146 struct dcesrv_if_list *ifl;
147 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
148 if (ndr_syntax_id_equal(&ifl->iface->syntax_id, interface)) {
149 return ifl->iface;
152 return NULL;
156 find the earlier parts of a fragmented call awaiting reassembly
158 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
160 struct dcesrv_call_state *c;
161 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
162 if (c->pkt.call_id == call_id) {
163 return c;
166 return NULL;
170 find a pending request
172 static struct dcesrv_call_state *dcesrv_find_pending_call(
173 struct dcesrv_connection *dce_conn,
174 uint32_t call_id)
176 struct dcesrv_call_state *c = NULL;
178 for (c = dce_conn->pending_call_list; c != NULL; c = c->next) {
179 if (c->pkt.call_id == call_id) {
180 return c;
184 return NULL;
188 * register a principal for an auth_type
190 * In order to get used in dcesrv_mgmt_inq_princ_name()
192 _PUBLIC_ NTSTATUS dcesrv_auth_type_principal_register(struct dcesrv_context *dce_ctx,
193 enum dcerpc_AuthType auth_type,
194 const char *principal_name)
196 const char *existing = NULL;
197 struct dcesrv_ctx_principal *p = NULL;
199 existing = dcesrv_auth_type_principal_find(dce_ctx, auth_type);
200 if (existing != NULL) {
201 DBG_ERR("auth_type[%u] already registered with principal_name[%s]\n",
202 auth_type, existing);
203 return NT_STATUS_ALREADY_REGISTERED;
206 p = talloc_zero(dce_ctx, struct dcesrv_ctx_principal);
207 if (p == NULL) {
208 return NT_STATUS_NO_MEMORY;
210 p->auth_type = auth_type;
211 p->principal_name = talloc_strdup(p, principal_name);
212 if (p->principal_name == NULL) {
213 TALLOC_FREE(p);
214 return NT_STATUS_NO_MEMORY;
217 DLIST_ADD_END(dce_ctx->principal_list, p);
218 return NT_STATUS_OK;
221 _PUBLIC_ const char *dcesrv_auth_type_principal_find(struct dcesrv_context *dce_ctx,
222 enum dcerpc_AuthType auth_type)
224 struct dcesrv_ctx_principal *p = NULL;
226 for (p = dce_ctx->principal_list; p != NULL; p = p->next) {
227 if (p->auth_type == auth_type) {
228 return p->principal_name;
232 return NULL;
235 _PUBLIC_ NTSTATUS dcesrv_register_default_auth_types(struct dcesrv_context *dce_ctx,
236 const char *principal)
238 const char *realm = lpcfg_realm(dce_ctx->lp_ctx);
239 NTSTATUS status;
241 status = dcesrv_auth_type_principal_register(dce_ctx,
242 DCERPC_AUTH_TYPE_NTLMSSP,
243 principal);
244 if (!NT_STATUS_IS_OK(status)) {
245 return status;
247 status = dcesrv_auth_type_principal_register(dce_ctx,
248 DCERPC_AUTH_TYPE_SPNEGO,
249 principal);
250 if (!NT_STATUS_IS_OK(status)) {
251 return status;
254 if (realm == NULL || realm[0] == '\0') {
255 return NT_STATUS_OK;
258 status = dcesrv_auth_type_principal_register(dce_ctx,
259 DCERPC_AUTH_TYPE_KRB5,
260 principal);
261 if (!NT_STATUS_IS_OK(status)) {
262 return status;
265 return NT_STATUS_OK;
268 _PUBLIC_ NTSTATUS dcesrv_register_default_auth_types_machine_principal(struct dcesrv_context *dce_ctx)
270 const char *realm = lpcfg_realm(dce_ctx->lp_ctx);
271 const char *nb = lpcfg_netbios_name(dce_ctx->lp_ctx);
272 char *principal = NULL;
273 NTSTATUS status;
275 if (realm == NULL || realm[0] == '\0') {
276 return dcesrv_register_default_auth_types(dce_ctx, "");
279 principal = talloc_asprintf(talloc_tos(), "%s$@%s", nb, realm);
280 if (principal == NULL) {
281 return NT_STATUS_NO_MEMORY;
284 status = dcesrv_register_default_auth_types(dce_ctx, principal);
285 TALLOC_FREE(principal);
286 if (!NT_STATUS_IS_OK(status)) {
287 return status;
290 return NT_STATUS_OK;
294 register an interface on an endpoint
296 An endpoint is one unix domain socket (for ncalrpc), one TCP port
297 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
299 Each endpoint can have many interfaces such as netlogon, lsa or
300 samr. Some have essentially the full set.
302 This is driven from the set of interfaces listed in each IDL file
303 via the PIDL generated *__op_init_server() functions.
305 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
306 const char *ep_name,
307 const char *ncacn_np_secondary_endpoint,
308 const struct dcesrv_interface *iface,
309 const struct security_descriptor *sd)
311 struct dcerpc_binding *binding = NULL;
312 struct dcerpc_binding *binding2 = NULL;
313 NTSTATUS ret;
315 ret = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
316 if (NT_STATUS_IS_ERR(ret)) {
317 DBG_ERR("Trouble parsing binding string '%s'\n", ep_name);
318 goto out;
321 if (ncacn_np_secondary_endpoint != NULL) {
322 ret = dcerpc_parse_binding(dce_ctx,
323 ncacn_np_secondary_endpoint,
324 &binding2);
325 if (NT_STATUS_IS_ERR(ret)) {
326 DBG_ERR("Trouble parsing 2nd binding string '%s'\n",
327 ncacn_np_secondary_endpoint);
328 goto out;
332 ret = dcesrv_interface_register_b(dce_ctx,
333 binding,
334 binding2,
335 iface,
336 sd);
337 out:
338 TALLOC_FREE(binding);
339 TALLOC_FREE(binding2);
340 return ret;
343 _PUBLIC_ NTSTATUS dcesrv_interface_register_b(struct dcesrv_context *dce_ctx,
344 struct dcerpc_binding *binding,
345 struct dcerpc_binding *binding2,
346 const struct dcesrv_interface *iface,
347 const struct security_descriptor *sd)
349 struct dcesrv_endpoint *ep;
350 struct dcesrv_if_list *ifl;
351 bool add_ep = false;
352 NTSTATUS status;
353 enum dcerpc_transport_t transport;
354 char *ep_string = NULL;
355 bool use_single_process = true;
356 const char *ep_process_string;
359 * If we are not using handles, there is no need for force
360 * this service into using a single process.
362 * However, due to the way we listen for RPC packets, we can
363 * only do this if we have a single service per pipe or TCP
364 * port, so we still force a single combined process for
365 * ncalrpc.
367 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
368 use_single_process = false;
371 transport = dcerpc_binding_get_transport(binding);
372 if (transport == NCACN_IP_TCP) {
373 int port;
376 * First check if there is already a port specified, eg
377 * for epmapper on ncacn_ip_tcp:[135]
379 const char *endpoint
380 = dcerpc_binding_get_string_option(binding,
381 "endpoint");
382 if (endpoint == NULL) {
383 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
384 "rpc server port", iface->name, 0);
387 * For RPC services that are not set to use a single
388 * process, we do not default to using the 'rpc server
389 * port' because that would cause a double-bind on
390 * that port.
392 if (port == 0 && !use_single_process) {
393 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
395 if (port != 0) {
396 char port_str[6];
397 snprintf(port_str, sizeof(port_str), "%u", port);
398 status = dcerpc_binding_set_string_option(binding,
399 "endpoint",
400 port_str);
401 if (!NT_STATUS_IS_OK(status)) {
402 return status;
408 if (transport == NCACN_NP && binding2 != NULL) {
409 enum dcerpc_transport_t transport2;
411 transport2 = dcerpc_binding_get_transport(binding2);
412 SMB_ASSERT(transport2 == transport);
415 /* see if the interface is already registered on the endpoint */
416 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
417 char *binding_string = dcerpc_binding_string(dce_ctx, binding);
418 DBG_ERR("Interface '%s' already registered on endpoint '%s'\n",
419 iface->name, binding_string);
420 TALLOC_FREE(binding_string);
421 return NT_STATUS_OBJECT_NAME_COLLISION;
424 /* check if this endpoint exists
426 status = dcesrv_find_endpoint(dce_ctx, binding, &ep);
427 if (NT_STATUS_IS_OK(status)) {
429 * We want a new port on ncacn_ip_tcp for NETLOGON, so
430 * it can be multi-process. Other processes can also
431 * listen on distinct ports, if they have one forced
432 * in the code above with eg 'rpc server port:drsuapi = 1027'
434 * If we have multiple endpoints on port 0, they each
435 * get an epemeral port (currently by walking up from
436 * 1024).
438 * Because one endpoint can only have one process
439 * model, we add a new IP_TCP endpoint for each model.
441 * This works in conjunction with the forced overwrite
442 * of ep->use_single_process below.
444 if (ep->use_single_process != use_single_process
445 && transport == NCACN_IP_TCP) {
446 add_ep = true;
450 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || add_ep) {
451 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
452 if (!ep) {
453 return NT_STATUS_NO_MEMORY;
455 ep->ep_description = dcerpc_binding_dup(ep, binding);
456 if (transport == NCACN_NP && binding2 != NULL) {
457 ep->ep_2nd_description =
458 dcerpc_binding_dup(ep, binding2);
460 add_ep = true;
462 /* add mgmt interface */
463 ifl = talloc_zero(ep, struct dcesrv_if_list);
464 if (!ifl) {
465 TALLOC_FREE(ep);
466 return NT_STATUS_NO_MEMORY;
469 ifl->iface = talloc_memdup(ifl,
470 dcesrv_get_mgmt_interface(),
471 sizeof(struct dcesrv_interface));
472 if (ifl->iface == NULL) {
473 talloc_free(ep);
474 return NT_STATUS_NO_MEMORY;
477 DLIST_ADD(ep->interface_list, ifl);
478 } else if (!NT_STATUS_IS_OK(status)) {
479 DBG_NOTICE("Failed to find endpoint: %s\n", nt_errstr(status));
480 return status;
484 * By default don't force into a single process, but if any
485 * interface on this endpoint on this service uses handles
486 * (most do), then we must force into single process mode
488 * By overwriting this each time a new interface is added to
489 * this endpoint, we end up with the most restrictive setting.
491 if (use_single_process) {
492 ep->use_single_process = true;
495 /* talloc a new interface list element */
496 ifl = talloc_zero(ep, struct dcesrv_if_list);
497 if (!ifl) {
498 return NT_STATUS_NO_MEMORY;
501 /* copy the given interface struct to the one on the endpoints interface list */
502 ifl->iface = talloc_memdup(ifl,
503 iface,
504 sizeof(struct dcesrv_interface));
505 if (ifl->iface == NULL) {
506 talloc_free(ep);
507 return NT_STATUS_NO_MEMORY;
510 /* if we have a security descriptor given,
511 * we should see if we can set it up on the endpoint
513 if (sd != NULL) {
514 /* if there's currently no security descriptor given on the endpoint
515 * we try to set it
517 if (ep->sd == NULL) {
518 ep->sd = security_descriptor_copy(ep, sd);
521 /* if now there's no security descriptor given on the endpoint
522 * something goes wrong, either we failed to copy the security descriptor
523 * or there was already one on the endpoint
525 if (ep->sd != NULL) {
526 char *binding_string =
527 dcerpc_binding_string(dce_ctx, binding);
528 DBG_ERR("Interface '%s' failed to setup a security "
529 "descriptor on endpoint '%s'\n",
530 iface->name, binding_string);
531 TALLOC_FREE(binding_string);
532 if (add_ep) free(ep);
533 free(ifl);
534 return NT_STATUS_OBJECT_NAME_COLLISION;
538 /* finally add the interface on the endpoint */
539 DLIST_ADD(ep->interface_list, ifl);
541 /* if it's a new endpoint add it to the dcesrv_context */
542 if (add_ep) {
543 DLIST_ADD(dce_ctx->endpoint_list, ep);
546 /* Re-get the string as we may have set a port */
547 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
549 if (use_single_process) {
550 ep_process_string = "single process required";
551 } else {
552 ep_process_string = "multi process compatible";
555 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
556 iface->name, ep_string, ep_process_string);
557 TALLOC_FREE(ep_string);
559 return NT_STATUS_OK;
562 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
563 DATA_BLOB *session_key)
565 if (auth->session_info == NULL) {
566 return NT_STATUS_NO_USER_SESSION_KEY;
569 if (auth->session_info->session_key.length == 0) {
570 return NT_STATUS_NO_USER_SESSION_KEY;
573 *session_key = auth->session_info->session_key;
574 return NT_STATUS_OK;
577 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
578 DATA_BLOB *session_key)
580 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
581 return NT_STATUS_NO_USER_SESSION_KEY;
584 return dcesrv_session_info_session_key(auth, session_key);
587 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
588 DATA_BLOB *session_key)
590 return dcerpc_generic_session_key(session_key);
594 * Fetch the authentication session key if available.
596 * This is the key generated by a gensec authentication.
599 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
600 DATA_BLOB *session_key)
602 struct dcesrv_auth *auth = call->auth_state;
603 SMB_ASSERT(auth->auth_finished);
604 return dcesrv_session_info_session_key(auth, session_key);
608 * Fetch the transport session key if available.
609 * Typically this is the SMB session key
610 * or a fixed key for local transports.
612 * The key is always truncated to 16 bytes.
614 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
615 DATA_BLOB *session_key)
617 struct dcesrv_auth *auth = call->auth_state;
618 NTSTATUS status;
620 SMB_ASSERT(auth->auth_finished);
622 if (auth->session_key_fn == NULL) {
623 return NT_STATUS_NO_USER_SESSION_KEY;
626 status = auth->session_key_fn(auth, session_key);
627 if (!NT_STATUS_IS_OK(status)) {
628 return status;
631 session_key->length = MIN(session_key->length, 16);
633 return NT_STATUS_OK;
636 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
638 const struct dcesrv_endpoint *ep = conn->endpoint;
639 enum dcerpc_transport_t transport =
640 dcerpc_binding_get_transport(ep->ep_description);
641 struct dcesrv_auth *auth = NULL;
643 auth = talloc_zero(conn, struct dcesrv_auth);
644 if (auth == NULL) {
645 return NULL;
648 switch (transport) {
649 case NCACN_NP:
650 auth->session_key_fn = dcesrv_remote_session_key;
651 break;
652 case NCALRPC:
653 case NCACN_UNIX_STREAM:
654 auth->session_key_fn = dcesrv_local_fixed_session_key;
655 break;
656 default:
658 * All other's get a NULL pointer, which
659 * results in NT_STATUS_NO_USER_SESSION_KEY
661 break;
664 return auth;
668 connect to a dcerpc endpoint
670 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
671 TALLOC_CTX *mem_ctx,
672 const struct dcesrv_endpoint *ep,
673 struct auth_session_info *session_info,
674 struct tevent_context *event_ctx,
675 uint32_t state_flags,
676 struct dcesrv_connection **_p)
678 struct dcesrv_auth *auth = NULL;
679 struct dcesrv_connection *p = NULL;
680 enum dcerpc_transport_t transport =
681 dcerpc_binding_get_transport(ep->ep_description);
683 if (!session_info) {
684 return NT_STATUS_ACCESS_DENIED;
687 p = talloc_zero(mem_ctx, struct dcesrv_connection);
688 if (p == NULL) {
689 goto nomem;
692 p->dce_ctx = dce_ctx;
693 p->endpoint = ep;
694 p->packet_log_dir = lpcfg_parm_string(dce_ctx->lp_ctx,
695 NULL,
696 "dcesrv",
697 "stubs directory");
698 p->event_ctx = event_ctx;
699 p->state_flags = state_flags;
700 p->allow_bind = true;
701 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
703 * SMB uses 4280, while all others use 5480
704 * note that p->transport_max_recv_frag is fixed
705 * for the lifetime of the connection, it's not
706 * negotiated by bind.
708 if (transport == NCACN_NP) {
709 p->transport_max_recv_frag = TSTREAM_SMBXCLI_NP_MAX_BUF_SIZE;
710 } else {
711 p->transport_max_recv_frag = DCERPC_FRAG_MAX_SIZE;
713 /* these might be overwritten by BIND */
714 p->max_recv_frag = p->transport_max_recv_frag;
715 p->max_xmit_frag = p->transport_max_recv_frag;
717 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
718 NULL,
719 "dcesrv",
720 "header signing",
721 true);
722 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
723 NULL,
724 "dcesrv",
725 "max auth states",
726 2049);
728 auth = dcesrv_auth_create(p);
729 if (auth == NULL) {
730 goto nomem;
733 auth->session_info = talloc_reference(auth, session_info);
734 if (auth->session_info == NULL) {
735 goto nomem;
738 p->default_auth_state = auth;
740 p->preferred_transfer = dce_ctx->preferred_transfer;
742 *_p = p;
743 return NT_STATUS_OK;
744 nomem:
745 TALLOC_FREE(p);
746 return NT_STATUS_NO_MEMORY;
750 move a call from an existing linked list to the specified list. This
751 prevents bugs where we forget to remove the call from a previous
752 list when moving it.
754 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
755 enum dcesrv_call_list list)
757 switch (call->list) {
758 case DCESRV_LIST_NONE:
759 break;
760 case DCESRV_LIST_CALL_LIST:
761 DLIST_REMOVE(call->conn->call_list, call);
762 break;
763 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
764 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
765 break;
766 case DCESRV_LIST_PENDING_CALL_LIST:
767 DLIST_REMOVE(call->conn->pending_call_list, call);
768 break;
770 call->list = list;
771 switch (list) {
772 case DCESRV_LIST_NONE:
773 break;
774 case DCESRV_LIST_CALL_LIST:
775 DLIST_ADD_END(call->conn->call_list, call);
776 break;
777 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
778 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
779 break;
780 case DCESRV_LIST_PENDING_CALL_LIST:
781 DLIST_ADD_END(call->conn->pending_call_list, call);
782 break;
786 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
787 const char *reason)
789 struct dcesrv_auth *a = NULL;
791 if (call->conn->terminate != NULL) {
792 return;
795 call->conn->allow_bind = false;
796 call->conn->allow_alter = false;
798 call->conn->default_auth_state->auth_invalid = true;
800 for (a = call->conn->auth_states; a != NULL; a = a->next) {
801 a->auth_invalid = true;
804 call->terminate_reason = talloc_strdup(call, reason);
805 if (call->terminate_reason == NULL) {
806 call->terminate_reason = __location__;
811 return a dcerpc bind_nak
813 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
815 struct ncacn_packet pkt;
816 struct dcerpc_bind_nak_version version;
817 struct data_blob_list_item *rep;
818 NTSTATUS status;
819 static const uint8_t _pad[3] = { 0, };
822 * We add the call to the pending_call_list
823 * in order to defer the termination.
825 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
827 /* setup a bind_nak */
828 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
829 pkt.auth_length = 0;
830 pkt.call_id = call->pkt.call_id;
831 pkt.ptype = DCERPC_PKT_BIND_NAK;
832 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
833 pkt.u.bind_nak.reject_reason = reason;
834 version.rpc_vers = 5;
835 version.rpc_vers_minor = 0;
836 pkt.u.bind_nak.num_versions = 1;
837 pkt.u.bind_nak.versions = &version;
838 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
840 rep = talloc_zero(call, struct data_blob_list_item);
841 if (!rep) {
842 return NT_STATUS_NO_MEMORY;
845 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
846 if (!NT_STATUS_IS_OK(status)) {
847 return status;
850 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
852 DLIST_ADD_END(call->replies, rep);
853 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
855 if (call->conn->call_list && call->conn->call_list->replies) {
856 if (call->conn->transport.report_output_data) {
857 call->conn->transport.report_output_data(call->conn);
861 return NT_STATUS_OK;
864 static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
865 uint32_t fault_code,
866 uint8_t extra_flags,
867 const char *func,
868 const char *location)
870 const char *reason = NULL;
872 reason = talloc_asprintf(call, "%s:%s: fault=%u (%s) flags=0x%x",
873 func, location,
874 fault_code,
875 dcerpc_errstr(call, fault_code),
876 extra_flags);
877 if (reason == NULL) {
878 reason = location;
882 * We add the call to the pending_call_list
883 * in order to defer the termination.
886 dcesrv_call_disconnect_after(call, reason);
888 return dcesrv_fault_with_flags(call, fault_code, extra_flags);
891 #define dcesrv_fault_disconnect(call, fault_code) \
892 _dcesrv_fault_disconnect_flags(call, fault_code, \
893 DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
894 __func__, __location__)
895 #define dcesrv_fault_disconnect0(call, fault_code) \
896 _dcesrv_fault_disconnect_flags(call, fault_code, 0, \
897 __func__, __location__)
899 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
901 DLIST_REMOVE(c->conn->contexts, c);
903 if (c->iface && c->iface->unbind) {
904 c->iface->unbind(c, c->iface);
905 c->iface = NULL;
908 return 0;
911 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
913 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
914 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
915 enum dcerpc_transport_t transport =
916 dcerpc_binding_get_transport(endpoint->ep_description);
917 struct dcesrv_connection_context *context = dce_call->context;
918 const struct dcesrv_interface *iface = context->iface;
920 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
922 if (transport == NCALRPC) {
923 context->allow_connect = true;
924 return;
928 * allow overwrite per interface
929 * allow dcerpc auth level connect:<interface>
931 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
932 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
933 "allow dcerpc auth level connect",
934 iface->name,
935 context->allow_connect);
938 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
939 const struct dcesrv_interface *iface)
942 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
943 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
945 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
946 return NT_STATUS_OK;
949 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
950 const struct dcesrv_interface *iface)
952 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
953 return NT_STATUS_OK;
956 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
957 const struct dcesrv_interface *iface)
959 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
960 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
961 enum dcerpc_transport_t transport =
962 dcerpc_binding_get_transport(endpoint->ep_description);
964 if (transport == NCALRPC) {
965 context->allow_connect = true;
966 return NT_STATUS_OK;
970 * allow overwrite per interface
971 * allow dcerpc auth level connect:<interface>
973 context->allow_connect = false;
974 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
975 "allow dcerpc auth level connect",
976 iface->name,
977 context->allow_connect);
978 return NT_STATUS_OK;
981 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
982 const struct dcesrv_interface *iface)
984 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
985 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
986 enum dcerpc_transport_t transport =
987 dcerpc_binding_get_transport(endpoint->ep_description);
989 if (transport == NCALRPC) {
990 context->allow_connect = true;
991 return NT_STATUS_OK;
995 * allow overwrite per interface
996 * allow dcerpc auth level connect:<interface>
998 context->allow_connect = true;
999 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
1000 "allow dcerpc auth level connect",
1001 iface->name,
1002 context->allow_connect);
1003 return NT_STATUS_OK;
1006 struct dcesrv_conn_auth_wait_context {
1007 struct tevent_req *req;
1008 bool done;
1009 NTSTATUS status;
1012 struct dcesrv_conn_auth_wait_state {
1013 uint8_t dummy;
1016 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
1017 struct tevent_context *ev,
1018 void *private_data)
1020 struct dcesrv_conn_auth_wait_context *auth_wait =
1021 talloc_get_type_abort(private_data,
1022 struct dcesrv_conn_auth_wait_context);
1023 struct tevent_req *req = NULL;
1024 struct dcesrv_conn_auth_wait_state *state = NULL;
1026 req = tevent_req_create(mem_ctx, &state,
1027 struct dcesrv_conn_auth_wait_state);
1028 if (req == NULL) {
1029 return NULL;
1031 auth_wait->req = req;
1033 tevent_req_defer_callback(req, ev);
1035 if (!auth_wait->done) {
1036 return req;
1039 if (tevent_req_nterror(req, auth_wait->status)) {
1040 return tevent_req_post(req, ev);
1043 tevent_req_done(req);
1044 return tevent_req_post(req, ev);
1047 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
1049 return tevent_req_simple_recv_ntstatus(req);
1052 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
1054 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
1056 if (conn->wait_send != NULL) {
1057 return NT_STATUS_INTERNAL_ERROR;
1060 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
1061 if (auth_wait == NULL) {
1062 return NT_STATUS_NO_MEMORY;
1065 conn->wait_private = auth_wait;
1066 conn->wait_send = dcesrv_conn_auth_wait_send;
1067 conn->wait_recv = dcesrv_conn_auth_wait_recv;
1068 return NT_STATUS_OK;
1071 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
1072 NTSTATUS status)
1074 struct dcesrv_conn_auth_wait_context *auth_wait =
1075 talloc_get_type_abort(conn->wait_private,
1076 struct dcesrv_conn_auth_wait_context);
1078 auth_wait->done = true;
1079 auth_wait->status = status;
1081 if (auth_wait->req == NULL) {
1082 return;
1085 if (tevent_req_nterror(auth_wait->req, status)) {
1086 return;
1089 tevent_req_done(auth_wait->req);
1092 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
1094 static void dcesrv_bind_done(struct tevent_req *subreq);
1097 handle a bind request
1099 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
1101 struct dcesrv_connection *conn = call->conn;
1102 struct dcesrv_context *dce_ctx = conn->dce_ctx;
1103 struct ncacn_packet *pkt = &call->ack_pkt;
1104 NTSTATUS status;
1105 uint32_t extra_flags = 0;
1106 uint16_t max_req = 0;
1107 uint16_t max_rep = 0;
1108 struct dcerpc_binding *ep_2nd_description = NULL;
1109 const char *endpoint = NULL;
1110 struct dcesrv_auth *auth = call->auth_state;
1111 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1112 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1113 struct dcerpc_ack_ctx *ack_features = NULL;
1114 struct tevent_req *subreq = NULL;
1115 size_t i;
1117 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1118 DCERPC_PKT_BIND,
1119 call->pkt.u.bind.auth_info.length,
1120 0, /* required flags */
1121 DCERPC_PFC_FLAG_FIRST |
1122 DCERPC_PFC_FLAG_LAST |
1123 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1124 0x08 | /* this is not defined, but should be ignored */
1125 DCERPC_PFC_FLAG_CONC_MPX |
1126 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1127 DCERPC_PFC_FLAG_MAYBE |
1128 DCERPC_PFC_FLAG_OBJECT_UUID);
1129 if (!NT_STATUS_IS_OK(status)) {
1130 return dcesrv_bind_nak(call,
1131 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
1135 * Note that BIND and ALTER allow frag_len up to UINT16_MAX,
1136 * so we don't check again frag_len against
1137 * call->conn->transport_max_recv_frag
1140 /* max_recv_frag and max_xmit_frag result always in the same value! */
1141 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
1142 call->pkt.u.bind.max_recv_frag);
1144 * The values are between 2048 and 5840 tested against Windows 2012R2
1145 * via ncacn_ip_tcp on port 135.
1147 * call->conn->transport_max_recv_frag stays fixed at 5840 (4280 for SMB)
1149 max_req = MAX(2048, max_req);
1150 max_rep = MIN(max_req, conn->max_recv_frag);
1151 /* They are truncated to an 8 byte boundary. */
1152 max_rep &= 0xFFF8;
1154 /* max_recv_frag and max_xmit_frag result always in the same value! */
1155 conn->max_recv_frag = max_rep;
1156 conn->max_xmit_frag = max_rep;
1158 status = dce_ctx->callbacks->assoc_group.find(
1159 call, dce_ctx->callbacks->assoc_group.private_data);
1160 if (!NT_STATUS_IS_OK(status)) {
1161 char *raddr = NULL;
1163 raddr = tsocket_address_string(call->conn->remote_address, call);
1165 endpoint = dcerpc_binding_get_string_option(
1166 call->conn->endpoint->ep_description,
1167 "endpoint");
1169 DBG_WARNING("Failed to find assoc_group 0x%08x on ep[%s] raddr[%s]: %s\n",
1170 call->pkt.u.bind.assoc_group_id,
1171 endpoint, raddr, nt_errstr(status));
1172 return dcesrv_bind_nak(call, 0);
1175 if (call->pkt.u.bind.num_contexts < 1) {
1176 return dcesrv_bind_nak(call,
1177 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
1180 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1181 call->pkt.u.bind.num_contexts);
1182 if (ack_ctx_list == NULL) {
1183 return dcesrv_bind_nak(call, 0);
1187 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1188 * dcesrv_check_or_create_context()) and do some protocol validation
1189 * and set sane defaults.
1191 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1192 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1193 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1194 bool is_feature = false;
1195 uint64_t features = 0;
1197 if (c->num_transfer_syntaxes == 0) {
1198 return dcesrv_bind_nak(call, 0);
1201 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1202 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1205 * It's only treated as bind time feature request, if the first
1206 * transfer_syntax matches, all others are ignored.
1208 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1209 &features);
1210 if (!is_feature) {
1211 continue;
1214 if (ack_features != NULL) {
1216 * Only one bind time feature context is allowed.
1218 return dcesrv_bind_nak(call, 0);
1220 ack_features = a;
1222 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1223 a->reason.negotiate = 0;
1224 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1225 if (conn->max_auth_states != 0) {
1226 a->reason.negotiate |=
1227 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1230 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1231 a->reason.negotiate |=
1232 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1235 conn->assoc_group->bind_time_features = a->reason.negotiate;
1239 * Try to negotiate one new presentation context.
1241 * Deep in here we locate the iface (by uuid) that the client
1242 * requested, from the list of interfaces on the
1243 * call->conn->endpoint, and call iface->bind() on that iface.
1245 * call->conn was set up at the accept() of the socket, and
1246 * call->conn->endpoint has a list of interfaces restricted to
1247 * this port or pipe.
1249 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1250 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1251 return dcesrv_bind_nak(call, 0);
1253 if (!NT_STATUS_IS_OK(status)) {
1254 return status;
1258 * At this point we still don't know which interface (eg
1259 * netlogon, lsa, drsuapi) the caller requested in this bind!
1260 * The most recently added context is available as the first
1261 * element in the linked list at call->conn->contexts, that is
1262 * call->conn->contexts->iface, but they may not have
1263 * requested one at all!
1266 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1267 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1268 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1269 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1272 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1273 conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1277 * After finding the interface and setting up the NDR
1278 * transport negotiation etc, handle any authentication that
1279 * is being requested.
1281 if (!dcesrv_auth_bind(call)) {
1283 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1285 * With DCERPC_AUTH_LEVEL_NONE, we get the
1286 * reject_reason in auth->auth_context_id.
1288 return dcesrv_bind_nak(call, auth->auth_context_id);
1292 * This must a be a temporary failure e.g. talloc or invalid
1293 * configuration, e.g. no machine account.
1295 return dcesrv_bind_nak(call,
1296 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1299 /* setup a bind_ack */
1300 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(dce_ctx->lp_ctx));
1301 pkt->auth_length = 0;
1302 pkt->call_id = call->pkt.call_id;
1303 pkt->ptype = DCERPC_PKT_BIND_ACK;
1304 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1305 pkt->u.bind_ack.max_xmit_frag = conn->max_xmit_frag;
1306 pkt->u.bind_ack.max_recv_frag = conn->max_recv_frag;
1307 pkt->u.bind_ack.assoc_group_id = conn->assoc_group->id;
1309 ep_2nd_description = conn->endpoint->ep_2nd_description;
1310 if (ep_2nd_description == NULL) {
1311 ep_2nd_description = conn->endpoint->ep_description;
1314 endpoint = dcerpc_binding_get_string_option(
1315 ep_2nd_description,
1316 "endpoint");
1317 if (endpoint == NULL) {
1318 endpoint = "";
1321 pkt->u.bind_ack.secondary_address = endpoint;
1322 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1323 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1324 pkt->u.bind_ack.auth_info = data_blob_null;
1326 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 return dcesrv_bind_nak(call, 0);
1331 if (auth->auth_finished) {
1332 return dcesrv_auth_reply(call);
1335 cb->auth.become_root();
1336 subreq = gensec_update_send(call, call->event_ctx,
1337 auth->gensec_security,
1338 call->in_auth_info.credentials);
1339 cb->auth.unbecome_root();
1340 if (subreq == NULL) {
1341 return NT_STATUS_NO_MEMORY;
1343 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1345 return dcesrv_conn_auth_wait_setup(conn);
1348 static void dcesrv_bind_done(struct tevent_req *subreq)
1350 struct dcesrv_call_state *call =
1351 tevent_req_callback_data(subreq,
1352 struct dcesrv_call_state);
1353 struct dcesrv_connection *conn = call->conn;
1354 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1355 NTSTATUS status;
1357 cb->auth.become_root();
1358 status = gensec_update_recv(subreq, call,
1359 &call->out_auth_info->credentials);
1360 cb->auth.unbecome_root();
1361 TALLOC_FREE(subreq);
1363 status = dcesrv_auth_complete(call, status);
1364 if (!NT_STATUS_IS_OK(status)) {
1365 status = dcesrv_bind_nak(call, DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM);
1366 dcesrv_conn_auth_wait_finished(conn, status);
1367 return;
1370 status = dcesrv_auth_reply(call);
1371 dcesrv_conn_auth_wait_finished(conn, status);
1372 return;
1375 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1377 struct ncacn_packet *pkt = &call->ack_pkt;
1378 struct data_blob_list_item *rep = NULL;
1379 NTSTATUS status;
1381 rep = talloc_zero(call, struct data_blob_list_item);
1382 if (!rep) {
1383 return NT_STATUS_NO_MEMORY;
1386 status = dcerpc_ncacn_push_auth(&rep->blob,
1387 call,
1388 pkt,
1389 call->out_auth_info);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 return status;
1394 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1396 DLIST_ADD_END(call->replies, rep);
1397 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1399 if (call->conn->call_list && call->conn->call_list->replies) {
1400 if (call->conn->transport.report_output_data) {
1401 call->conn->transport.report_output_data(call->conn);
1405 return NT_STATUS_OK;
1409 static void dcesrv_auth3_done(struct tevent_req *subreq);
1412 handle a auth3 request
1414 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1416 struct dcesrv_connection *conn = call->conn;
1417 struct dcesrv_auth *auth = call->auth_state;
1418 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1419 struct tevent_req *subreq = NULL;
1420 NTSTATUS status;
1422 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1423 DCERPC_PKT_AUTH3,
1424 call->pkt.u.auth3.auth_info.length,
1425 0, /* required flags */
1426 DCERPC_PFC_FLAG_FIRST |
1427 DCERPC_PFC_FLAG_LAST |
1428 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1429 0x08 | /* this is not defined, but should be ignored */
1430 DCERPC_PFC_FLAG_CONC_MPX |
1431 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1432 DCERPC_PFC_FLAG_MAYBE |
1433 DCERPC_PFC_FLAG_OBJECT_UUID);
1434 if (!NT_STATUS_IS_OK(status)) {
1435 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1438 /* handle the auth3 in the auth code */
1439 if (!dcesrv_auth_prepare_auth3(call)) {
1441 * we don't send a reply to a auth3 request,
1442 * except by a fault.
1444 * In anycase we mark the connection as
1445 * invalid.
1447 auth->auth_invalid = true;
1448 if (call->fault_code != 0) {
1449 return dcesrv_fault_disconnect(call, call->fault_code);
1451 TALLOC_FREE(call);
1452 return NT_STATUS_OK;
1455 cb->auth.become_root();
1456 subreq = gensec_update_send(call, call->event_ctx,
1457 auth->gensec_security,
1458 call->in_auth_info.credentials);
1459 cb->auth.unbecome_root();
1460 if (subreq == NULL) {
1461 return NT_STATUS_NO_MEMORY;
1463 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1465 return dcesrv_conn_auth_wait_setup(conn);
1468 static void dcesrv_auth3_done(struct tevent_req *subreq)
1470 struct dcesrv_call_state *call =
1471 tevent_req_callback_data(subreq,
1472 struct dcesrv_call_state);
1473 struct dcesrv_connection *conn = call->conn;
1474 struct dcesrv_auth *auth = call->auth_state;
1475 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1476 NTSTATUS status;
1478 cb->auth.become_root();
1479 status = gensec_update_recv(subreq, call,
1480 &call->out_auth_info->credentials);
1481 cb->auth.unbecome_root();
1482 TALLOC_FREE(subreq);
1484 status = dcesrv_auth_complete(call, status);
1485 if (!NT_STATUS_IS_OK(status)) {
1487 * we don't send a reply to a auth3 request,
1488 * except by a fault.
1490 * In anycase we mark the connection as
1491 * invalid.
1493 auth->auth_invalid = true;
1494 if (call->fault_code != 0) {
1495 status = dcesrv_fault_disconnect(call, call->fault_code);
1496 dcesrv_conn_auth_wait_finished(conn, status);
1497 return;
1499 TALLOC_FREE(call);
1500 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1501 return;
1505 * we don't send a reply to a auth3 request.
1507 TALLOC_FREE(call);
1508 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1509 return;
1513 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1514 const struct dcerpc_bind *b,
1515 const struct dcerpc_ctx_list *ctx,
1516 struct dcerpc_ack_ctx *ack,
1517 bool validate_only,
1518 const struct ndr_syntax_id *supported_transfer)
1520 struct dcesrv_connection_context *context;
1521 const struct dcesrv_interface *iface;
1522 NTSTATUS status;
1523 const struct ndr_syntax_id *selected_transfer = NULL;
1524 size_t i;
1525 bool ok;
1527 if (b == NULL) {
1528 return NT_STATUS_INTERNAL_ERROR;
1530 if (ctx == NULL) {
1531 return NT_STATUS_INTERNAL_ERROR;
1533 if (ctx->num_transfer_syntaxes < 1) {
1534 return NT_STATUS_INTERNAL_ERROR;
1536 if (ack == NULL) {
1537 return NT_STATUS_INTERNAL_ERROR;
1539 if (supported_transfer == NULL) {
1540 return NT_STATUS_INTERNAL_ERROR;
1543 switch (ack->result) {
1544 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1545 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1547 * We is already completed.
1549 return NT_STATUS_OK;
1550 default:
1551 break;
1554 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1555 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1557 iface = find_interface_by_syntax_id(
1558 call->conn->endpoint, &ctx->abstract_syntax);
1559 if (iface == NULL) {
1560 struct ndr_syntax_id_buf buf;
1561 DBG_NOTICE("Request for unknown dcerpc interface %s\n",
1562 ndr_syntax_id_buf_string(
1563 &ctx->abstract_syntax, &buf));
1565 * We report this only via ack->result
1567 return NT_STATUS_OK;
1570 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1571 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1573 if (validate_only) {
1575 * We report this only via ack->result
1577 return NT_STATUS_OK;
1580 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1582 * we only do NDR encoded dcerpc for now.
1584 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1585 supported_transfer);
1586 if (ok) {
1587 selected_transfer = supported_transfer;
1588 break;
1592 context = dcesrv_find_context(call->conn, ctx->context_id);
1593 if (context != NULL) {
1594 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1595 &ctx->abstract_syntax);
1596 if (!ok) {
1597 return NT_STATUS_RPC_PROTOCOL_ERROR;
1600 if (selected_transfer != NULL) {
1601 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1602 selected_transfer);
1603 if (!ok) {
1604 return NT_STATUS_RPC_PROTOCOL_ERROR;
1607 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1608 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1609 ack->syntax = context->transfer_syntax;
1613 * We report this only via ack->result
1615 return NT_STATUS_OK;
1618 if (selected_transfer == NULL) {
1620 * We report this only via ack->result
1622 return NT_STATUS_OK;
1625 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1626 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1628 /* add this context to the list of available context_ids */
1629 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1630 if (context == NULL) {
1631 return NT_STATUS_NO_MEMORY;
1633 context->conn = call->conn;
1634 context->context_id = ctx->context_id;
1635 context->iface = iface;
1636 context->transfer_syntax = *selected_transfer;
1637 context->ndr64 = ndr_syntax_id_equal(&context->transfer_syntax,
1638 &ndr_transfer_syntax_ndr64);
1639 DLIST_ADD(call->conn->contexts, context);
1640 call->context = context;
1641 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1643 dcesrv_prepare_context_auth(call);
1646 * Multiplex is supported by default
1648 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1650 status = iface->bind(context, iface);
1651 call->context = NULL;
1652 if (!NT_STATUS_IS_OK(status)) {
1653 /* we don't want to trigger the iface->unbind() hook */
1654 context->iface = NULL;
1655 talloc_free(context);
1657 * We report this only via ack->result
1659 return NT_STATUS_OK;
1662 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1663 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1664 ack->syntax = context->transfer_syntax;
1665 return NT_STATUS_OK;
1668 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1669 const struct dcerpc_bind *b,
1670 struct dcerpc_ack_ctx *ack_ctx_list)
1672 NTSTATUS status;
1673 size_t i;
1674 bool validate_only = false;
1675 bool preferred_ndr32;
1678 * Try to negotiate one new presentation context,
1679 * using our preferred transfer syntax.
1681 for (i = 0; i < b->num_contexts; i++) {
1682 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1683 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1685 status = dcesrv_check_or_create_context(call, b, c, a,
1686 validate_only,
1687 call->conn->preferred_transfer);
1688 if (!NT_STATUS_IS_OK(status)) {
1689 return status;
1692 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1694 * We managed to negotiate one context.
1696 * => we're done.
1698 validate_only = true;
1702 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1703 call->conn->preferred_transfer);
1704 if (preferred_ndr32) {
1706 * We're done.
1708 return NT_STATUS_OK;
1712 * Try to negotiate one new presentation context,
1713 * using NDR 32 as fallback.
1715 for (i = 0; i < b->num_contexts; i++) {
1716 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1717 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1719 status = dcesrv_check_or_create_context(call, b, c, a,
1720 validate_only,
1721 &ndr_transfer_syntax_ndr);
1722 if (!NT_STATUS_IS_OK(status)) {
1723 return status;
1726 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1728 * We managed to negotiate one context.
1730 * => we're done.
1732 validate_only = true;
1736 return NT_STATUS_OK;
1739 static void dcesrv_alter_done(struct tevent_req *subreq);
1742 handle a alter context request
1744 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1746 struct dcesrv_connection *conn = call->conn;
1747 NTSTATUS status;
1748 bool auth_ok = false;
1749 struct ncacn_packet *pkt = &call->ack_pkt;
1750 uint32_t extra_flags = 0;
1751 struct dcesrv_auth *auth = call->auth_state;
1752 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1753 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1754 struct tevent_req *subreq = NULL;
1755 size_t i;
1757 if (!call->conn->allow_alter) {
1758 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1761 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1762 DCERPC_PKT_ALTER,
1763 call->pkt.u.alter.auth_info.length,
1764 0, /* required flags */
1765 DCERPC_PFC_FLAG_FIRST |
1766 DCERPC_PFC_FLAG_LAST |
1767 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1768 0x08 | /* this is not defined, but should be ignored */
1769 DCERPC_PFC_FLAG_CONC_MPX |
1770 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1771 DCERPC_PFC_FLAG_MAYBE |
1772 DCERPC_PFC_FLAG_OBJECT_UUID);
1773 if (!NT_STATUS_IS_OK(status)) {
1774 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1778 * Note that BIND and ALTER allow frag_len up to UINT16_MAX,
1779 * so we don't check again frag_len against
1780 * call->conn->transport_max_recv_frag
1783 auth_ok = dcesrv_auth_alter(call);
1784 if (!auth_ok) {
1785 if (call->fault_code != 0) {
1786 return dcesrv_fault_disconnect(call, call->fault_code);
1790 if (call->pkt.u.alter.num_contexts < 1) {
1791 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1794 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1795 call->pkt.u.alter.num_contexts);
1796 if (ack_ctx_list == NULL) {
1797 return NT_STATUS_NO_MEMORY;
1801 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1802 * dcesrv_check_or_create_context()) and do some protocol validation
1803 * and set sane defaults.
1805 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1806 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1807 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1809 if (c->num_transfer_syntaxes == 0) {
1810 return dcesrv_fault_disconnect(call,
1811 DCERPC_NCA_S_PROTO_ERROR);
1814 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1815 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1819 * Try to negotiate one new presentation context.
1821 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1822 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1823 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1825 if (!NT_STATUS_IS_OK(status)) {
1826 return status;
1829 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1830 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1831 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1832 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1835 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1836 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1839 /* handle any authentication that is being requested */
1840 if (!auth_ok) {
1841 if (call->in_auth_info.auth_type != auth->auth_type) {
1842 return dcesrv_fault_disconnect(call,
1843 DCERPC_FAULT_SEC_PKG_ERROR);
1845 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1848 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1849 pkt->auth_length = 0;
1850 pkt->call_id = call->pkt.call_id;
1851 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1852 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1853 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1854 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1855 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1856 pkt->u.alter_resp.secondary_address = "";
1857 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1858 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1859 pkt->u.alter_resp.auth_info = data_blob_null;
1861 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1866 if (auth->auth_finished) {
1867 return dcesrv_auth_reply(call);
1870 cb->auth.become_root();
1871 subreq = gensec_update_send(call, call->event_ctx,
1872 auth->gensec_security,
1873 call->in_auth_info.credentials);
1874 cb->auth.unbecome_root();
1875 if (subreq == NULL) {
1876 return NT_STATUS_NO_MEMORY;
1878 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1880 return dcesrv_conn_auth_wait_setup(conn);
1883 static void dcesrv_alter_done(struct tevent_req *subreq)
1885 struct dcesrv_call_state *call =
1886 tevent_req_callback_data(subreq,
1887 struct dcesrv_call_state);
1888 struct dcesrv_connection *conn = call->conn;
1889 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1890 NTSTATUS status;
1892 cb->auth.become_root();
1893 status = gensec_update_recv(subreq, call,
1894 &call->out_auth_info->credentials);
1895 cb->auth.unbecome_root();
1896 TALLOC_FREE(subreq);
1898 status = dcesrv_auth_complete(call, status);
1899 if (!NT_STATUS_IS_OK(status)) {
1901 * NT_STATUS_ACCESS_DENIED from gensec means
1902 * a signing check or decryption failure,
1903 * which should result in DCERPC_FAULT_SEC_PKG_ERROR.
1905 * Any other status, e.g. NT_STATUS_LOGON_FAILURE or
1906 * NT_STATUS_INVALID_PARAMETER should result in
1907 * DCERPC_FAULT_ACCESS_DENIED.
1909 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1910 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1911 } else {
1912 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1914 dcesrv_conn_auth_wait_finished(conn, status);
1915 return;
1918 status = dcesrv_auth_reply(call);
1919 dcesrv_conn_auth_wait_finished(conn, status);
1920 return;
1924 possibly save the call for inspection with ndrdump
1926 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1928 #ifdef DEVELOPER
1929 dcerpc_log_packet(call->conn->packet_log_dir,
1930 call->context->iface->name,
1931 call->pkt.u.request.opnum,
1932 NDR_IN,
1933 &call->pkt.u.request.stub_and_verifier,
1934 why);
1935 #endif
1938 #ifdef DEVELOPER
1940 Save the call for use as a seed for fuzzing.
1942 This is only enabled in a developer build, and only has effect if the
1943 "dcesrv fuzz directory" param is set.
1945 void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob,
1946 struct dcesrv_call_state *call,
1947 ndr_flags_type flags)
1949 const char *dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx,
1950 NULL,
1951 "dcesrv", "fuzz directory");
1953 dcerpc_save_ndr_fuzz_seed(call,
1954 call_blob,
1955 dump_dir,
1956 call->context->iface->name,
1957 flags,
1958 call->pkt.u.request.opnum,
1959 call->ndr_pull->flags & LIBNDR_FLAG_NDR64);
1961 #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1964 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1966 TALLOC_CTX *frame = talloc_stackframe();
1967 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1968 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1969 const struct dcerpc_sec_vt_pcontext pcontext = {
1970 .abstract_syntax = call->context->iface->syntax_id,
1971 .transfer_syntax = call->context->transfer_syntax,
1973 const struct dcerpc_sec_vt_header2 header2 =
1974 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1975 enum ndr_err_code ndr_err;
1976 struct dcerpc_sec_verification_trailer *vt = NULL;
1977 NTSTATUS status = NT_STATUS_OK;
1978 bool ok;
1980 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1982 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1983 frame, &vt);
1984 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1985 status = ndr_map_error2ntstatus(ndr_err);
1986 goto done;
1989 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1990 &pcontext, &header2);
1991 if (!ok) {
1992 status = NT_STATUS_ACCESS_DENIED;
1993 goto done;
1995 done:
1996 TALLOC_FREE(frame);
1997 return status;
2001 handle a dcerpc request packet
2003 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
2005 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
2006 struct dcesrv_auth *auth = call->auth_state;
2007 enum dcerpc_transport_t transport =
2008 dcerpc_binding_get_transport(endpoint->ep_description);
2009 struct ndr_pull *pull;
2010 bool turn_winbind_on = false;
2011 NTSTATUS status;
2013 if (auth->auth_invalid) {
2014 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2017 if (!auth->auth_finished) {
2018 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2021 /* if authenticated, and the mech we use can't do async replies, don't use them... */
2022 if (auth->gensec_security != NULL &&
2023 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
2024 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
2027 if (call->context == NULL) {
2028 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2029 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2032 switch (auth->auth_level) {
2033 case DCERPC_AUTH_LEVEL_NONE:
2034 case DCERPC_AUTH_LEVEL_PACKET:
2035 case DCERPC_AUTH_LEVEL_INTEGRITY:
2036 case DCERPC_AUTH_LEVEL_PRIVACY:
2037 break;
2038 default:
2039 if (!call->context->allow_connect) {
2040 char *addr;
2042 addr = tsocket_address_string(call->conn->remote_address,
2043 call);
2045 DEBUG(2, ("%s: restrict auth_level_connect access "
2046 "to [%s] with auth[type=0x%x,level=0x%x] "
2047 "on [%s] from [%s]\n",
2048 __func__, call->context->iface->name,
2049 auth->auth_type,
2050 auth->auth_level,
2051 derpc_transport_string_by_transport(transport),
2052 addr));
2053 if (!call->conn->got_explicit_auth_level_non_connect) {
2055 * If there was is no auth context with
2056 * a level higher than DCERPC_AUTH_LEVEL_CONNECT,
2057 * the connection should be disconnected
2058 * after sending the fault.
2060 return dcesrv_fault_disconnect0(call,
2061 DCERPC_FAULT_ACCESS_DENIED);
2063 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2065 break;
2068 if (auth->auth_level < call->context->min_auth_level) {
2069 char *addr;
2071 addr = tsocket_address_string(call->conn->remote_address, call);
2073 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
2074 "to [%s] with auth[type=0x%x,level=0x%x] "
2075 "on [%s] from [%s]\n",
2076 __func__,
2077 call->context->min_auth_level,
2078 call->context->iface->name,
2079 auth->auth_type,
2080 auth->auth_level,
2081 derpc_transport_string_by_transport(transport),
2082 addr));
2083 if (!call->conn->got_explicit_auth_level_non_connect) {
2085 * If there was is no auth context with
2086 * a level higher than DCERPC_AUTH_LEVEL_CONNECT,
2087 * the connection should be disconnected
2088 * after sending the fault.
2090 return dcesrv_fault_disconnect0(call,
2091 DCERPC_FAULT_ACCESS_DENIED);
2093 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2096 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
2097 NT_STATUS_HAVE_NO_MEMORY(pull);
2099 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
2101 call->ndr_pull = pull;
2103 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
2104 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
2107 status = dcesrv_check_verification_trailer(call);
2108 if (!NT_STATUS_IS_OK(status)) {
2109 uint32_t faultcode = DCERPC_FAULT_OTHER;
2110 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2111 faultcode = DCERPC_FAULT_ACCESS_DENIED;
2113 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
2114 nt_errstr(status)));
2115 return dcesrv_fault(call, faultcode);
2118 if (call->context->ndr64) {
2119 call->ndr_pull->flags |= LIBNDR_FLAG_NDR64;
2122 /* unravel the NDR for the packet */
2123 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
2124 if (!NT_STATUS_IS_OK(status)) {
2125 uint8_t extra_flags = 0;
2126 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
2127 /* we got an unknown call */
2128 DEBUG(3,(__location__ ": Unknown RPC call %"PRIu16" on %s\n",
2129 call->pkt.u.request.opnum,
2130 call->context->iface->name));
2131 dcesrv_save_call(call, "unknown");
2132 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
2133 } else {
2134 dcesrv_save_call(call, "pullfail");
2137 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
2140 dcesrv_save_ndr_fuzz_seed(call->pkt.u.request.stub_and_verifier,
2141 call,
2142 NDR_IN);
2144 if (pull->offset != pull->data_size) {
2145 dcesrv_save_call(call, "extrabytes");
2146 DEBUG(3,("Warning: %"PRIu32" extra bytes in incoming RPC request\n",
2147 pull->data_size - pull->offset));
2150 if (call->state_flags & DCESRV_CALL_STATE_FLAG_WINBIND_OFF) {
2151 bool winbind_active = !winbind_env_set();
2152 if (winbind_active) {
2153 DBG_DEBUG("turning winbind off\n");
2154 (void)winbind_off();
2155 turn_winbind_on = true;
2159 /* call the dispatch function */
2160 status = call->context->iface->dispatch(call, call, call->r);
2162 if (turn_winbind_on) {
2163 DBG_DEBUG("turning winbind on\n");
2164 (void)winbind_on();
2167 if (!NT_STATUS_IS_OK(status)) {
2168 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
2169 call->context->iface->name,
2170 call->pkt.u.request.opnum,
2171 dcerpc_errstr(pull, call->fault_code)));
2172 return dcesrv_fault(call, call->fault_code);
2175 /* add the call to the pending list */
2176 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
2178 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2179 return NT_STATUS_OK;
2182 return dcesrv_reply(call);
2187 remove the call from the right list when freed
2189 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
2191 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2192 return 0;
2195 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
2197 return conn->local_address;
2200 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
2202 return conn->remote_address;
2206 process some input to a dcerpc endpoint server.
2208 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2209 struct ncacn_packet *pkt,
2210 DATA_BLOB blob)
2212 NTSTATUS status;
2213 struct dcesrv_call_state *call;
2214 struct dcesrv_call_state *existing = NULL;
2215 size_t num_auth_ctx = 0;
2216 enum dcerpc_AuthType auth_type = 0;
2217 enum dcerpc_AuthLevel auth_level = 0;
2218 uint32_t auth_context_id = 0;
2219 bool auth_invalid = false;
2221 call = talloc_zero(dce_conn, struct dcesrv_call_state);
2222 if (!call) {
2223 data_blob_free(&blob);
2224 talloc_free(pkt);
2225 return NT_STATUS_NO_MEMORY;
2227 call->conn = dce_conn;
2228 call->event_ctx = dce_conn->event_ctx;
2229 call->state_flags = call->conn->state_flags;
2230 call->time = timeval_current();
2231 call->list = DCESRV_LIST_NONE;
2233 talloc_steal(call, pkt);
2234 talloc_steal(call, blob.data);
2235 call->pkt = *pkt;
2237 if (dce_conn->max_auth_states == 0) {
2238 call->auth_state = dce_conn->default_auth_state;
2239 } else if (call->pkt.auth_length == 0) {
2240 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2241 dce_conn->default_auth_level_connect != NULL)
2243 call->auth_state = dce_conn->default_auth_level_connect;
2244 } else {
2245 call->auth_state = dce_conn->default_auth_state;
2249 if (call->auth_state == NULL) {
2250 struct dcesrv_auth *a = NULL;
2251 bool check_type_level = true;
2253 auth_type = dcerpc_get_auth_type(&blob);
2254 auth_level = dcerpc_get_auth_level(&blob);
2255 auth_context_id = dcerpc_get_auth_context_id(&blob);
2257 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2258 if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
2259 check_type_level = false;
2261 dce_conn->default_auth_level_connect = NULL;
2262 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
2263 dce_conn->got_explicit_auth_level_connect = true;
2264 } else if (auth_level >= DCERPC_AUTH_LEVEL_PACKET) {
2265 dce_conn->got_explicit_auth_level_non_connect = true;
2269 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2270 num_auth_ctx++;
2272 if (a->auth_context_id != auth_context_id) {
2273 continue;
2276 if (a->auth_type != auth_type) {
2277 auth_invalid = true;
2279 if (a->auth_level != auth_level) {
2280 auth_invalid = true;
2283 if (check_type_level && auth_invalid) {
2284 a->auth_invalid = true;
2287 DLIST_PROMOTE(dce_conn->auth_states, a);
2288 call->auth_state = a;
2289 break;
2293 if (call->auth_state == NULL) {
2294 struct dcesrv_auth *a = NULL;
2296 if (num_auth_ctx >= dce_conn->max_auth_states) {
2297 return dcesrv_fault_disconnect(call,
2298 DCERPC_NCA_S_PROTO_ERROR);
2301 a = dcesrv_auth_create(dce_conn);
2302 if (a == NULL) {
2303 talloc_free(call);
2304 return NT_STATUS_NO_MEMORY;
2306 DLIST_ADD(dce_conn->auth_states, a);
2307 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2309 * This can never be valid.
2311 auth_invalid = true;
2312 a->auth_invalid = true;
2314 call->auth_state = a;
2317 talloc_set_destructor(call, dcesrv_call_dequeue);
2319 if (call->conn->allow_bind) {
2321 * Only one bind is possible per connection
2323 call->conn->allow_bind = false;
2324 return dcesrv_bind(call);
2327 /* we have to check the signing here, before combining the
2328 pdus */
2329 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2330 dcesrv_default_auth_state_prepare_request(call);
2332 if (call->auth_state->auth_started &&
2333 !call->auth_state->auth_invalid &&
2334 !call->auth_state->auth_finished) {
2336 * We have this check here instead of
2337 * relying on the check in dcesrv_auth_pkt_pull()
2338 * because the fault should have context_id=0
2340 return dcesrv_fault_disconnect(call,
2341 DCERPC_NCA_S_PROTO_ERROR);
2344 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2345 DCERPC_PKT_REQUEST,
2346 call->pkt.u.request.stub_and_verifier.length,
2347 0, /* required_flags */
2348 DCERPC_PFC_FLAG_FIRST |
2349 DCERPC_PFC_FLAG_LAST |
2350 DCERPC_PFC_FLAG_PENDING_CANCEL |
2351 0x08 | /* this is not defined, but should be ignored */
2352 DCERPC_PFC_FLAG_CONC_MPX |
2353 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2354 DCERPC_PFC_FLAG_MAYBE |
2355 DCERPC_PFC_FLAG_OBJECT_UUID);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 return dcesrv_fault_disconnect(call,
2358 DCERPC_NCA_S_PROTO_ERROR);
2361 if (call->pkt.frag_length > call->conn->transport_max_recv_frag) {
2363 * We don't use dcesrv_fault_disconnect()
2364 * here, because we don't want to set
2365 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2367 * Note that we don't check against the negotiated
2368 * max_recv_frag, but a hard coded value from
2369 * the transport.
2371 return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2374 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2375 if (dce_conn->pending_call_list != NULL) {
2377 * concurrent requests are only allowed
2378 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2380 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2381 return dcesrv_fault_disconnect0(call,
2382 DCERPC_NCA_S_PROTO_ERROR);
2385 /* only one request is possible in the fragmented list */
2386 if (dce_conn->incoming_fragmented_call_list != NULL) {
2387 call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
2389 existing = dcesrv_find_fragmented_call(dce_conn,
2390 call->pkt.call_id);
2391 if (existing != NULL && call->auth_state != existing->auth_state) {
2392 call->context = dcesrv_find_context(call->conn,
2393 call->pkt.u.request.context_id);
2395 if (call->pkt.auth_length != 0 && existing->context == call->context) {
2396 call->fault_code = DCERPC_FAULT_SEC_PKG_ERROR;
2399 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2401 * Without DCERPC_PFC_FLAG_CONC_MPX
2402 * we need to return the FAULT on the
2403 * already existing call.
2405 * This is important to get the
2406 * call_id and context_id right.
2408 dce_conn->incoming_fragmented_call_list->fault_code = call->fault_code;
2409 TALLOC_FREE(call);
2410 call = dce_conn->incoming_fragmented_call_list;
2412 if (existing != NULL) {
2413 call->context = existing->context;
2415 return dcesrv_fault_disconnect0(call, call->fault_code);
2417 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2418 return dcesrv_fault_disconnect(call,
2419 DCERPC_FAULT_NO_CALL_ACTIVE);
2421 call->context = dcesrv_find_context(call->conn,
2422 call->pkt.u.request.context_id);
2423 if (call->context == NULL) {
2424 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2425 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2427 } else {
2428 int cmp;
2430 existing = dcesrv_find_fragmented_call(dce_conn,
2431 call->pkt.call_id);
2432 if (existing == NULL) {
2433 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2435 * Without DCERPC_PFC_FLAG_CONC_MPX
2436 * we need to return the FAULT on the
2437 * already existing call.
2439 * This is important to get the
2440 * call_id and context_id right.
2442 if (dce_conn->incoming_fragmented_call_list != NULL) {
2443 TALLOC_FREE(call);
2444 call = dce_conn->incoming_fragmented_call_list;
2446 return dcesrv_fault_disconnect0(call,
2447 DCERPC_NCA_S_PROTO_ERROR);
2449 if (dce_conn->incoming_fragmented_call_list != NULL) {
2450 return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2452 call->context = dcesrv_find_context(call->conn,
2453 call->pkt.u.request.context_id);
2454 if (call->context == NULL) {
2455 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2456 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2458 if (auth_invalid) {
2459 return dcesrv_fault_disconnect0(call,
2460 DCERPC_FAULT_ACCESS_DENIED);
2462 return dcesrv_fault_disconnect0(call,
2463 DCERPC_NCA_S_PROTO_ERROR);
2466 if (call->pkt.ptype != existing->pkt.ptype) {
2467 /* trying to play silly buggers are we? */
2468 return dcesrv_fault_disconnect(existing,
2469 DCERPC_NCA_S_PROTO_ERROR);
2471 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2472 sizeof(pkt->drep));
2473 if (cmp != 0) {
2474 return dcesrv_fault_disconnect(existing,
2475 DCERPC_NCA_S_PROTO_ERROR);
2477 call->auth_state = existing->auth_state;
2478 call->context = existing->context;
2482 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2483 bool ok;
2484 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2486 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2487 payload_offset += 16;
2490 ok = dcesrv_auth_pkt_pull(call, &blob,
2491 0, /* required_flags */
2492 DCERPC_PFC_FLAG_FIRST |
2493 DCERPC_PFC_FLAG_LAST |
2494 DCERPC_PFC_FLAG_PENDING_CANCEL |
2495 0x08 | /* this is not defined, but should be ignored */
2496 DCERPC_PFC_FLAG_CONC_MPX |
2497 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2498 DCERPC_PFC_FLAG_MAYBE |
2499 DCERPC_PFC_FLAG_OBJECT_UUID,
2500 payload_offset,
2501 &call->pkt.u.request.stub_and_verifier);
2502 if (!ok) {
2504 * We don't use dcesrv_fault_disconnect()
2505 * here, because we don't want to set
2506 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2508 if (call->fault_code == 0) {
2509 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2511 return dcesrv_fault_disconnect0(call, call->fault_code);
2515 /* see if this is a continued packet */
2516 if (existing != NULL) {
2517 struct dcerpc_request *er = &existing->pkt.u.request;
2518 const struct dcerpc_request *nr = &call->pkt.u.request;
2519 size_t available;
2520 size_t alloc_size;
2521 size_t alloc_hint;
2524 * Up to 4 MByte are allowed by all fragments
2526 available = dce_conn->max_total_request_size;
2527 if (er->stub_and_verifier.length > available) {
2528 return dcesrv_fault_disconnect0(existing,
2529 DCERPC_FAULT_ACCESS_DENIED);
2531 available -= er->stub_and_verifier.length;
2532 if (nr->alloc_hint > available) {
2533 return dcesrv_fault_disconnect0(existing,
2534 DCERPC_FAULT_ACCESS_DENIED);
2536 if (nr->stub_and_verifier.length > available) {
2537 return dcesrv_fault_disconnect0(existing,
2538 DCERPC_FAULT_ACCESS_DENIED);
2540 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2541 /* allocate at least 1 byte */
2542 alloc_hint = MAX(alloc_hint, 1);
2543 alloc_size = er->stub_and_verifier.length +
2544 nr->stub_and_verifier.length;
2545 alloc_size = MAX(alloc_size, alloc_hint);
2547 er->stub_and_verifier.data =
2548 talloc_realloc(existing,
2549 er->stub_and_verifier.data,
2550 uint8_t, alloc_size);
2551 if (er->stub_and_verifier.data == NULL) {
2552 TALLOC_FREE(call);
2553 return dcesrv_fault_with_flags(existing,
2554 DCERPC_FAULT_OUT_OF_RESOURCES,
2555 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2557 memcpy(er->stub_and_verifier.data +
2558 er->stub_and_verifier.length,
2559 nr->stub_and_verifier.data,
2560 nr->stub_and_verifier.length);
2561 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2563 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2565 TALLOC_FREE(call);
2566 call = existing;
2569 /* this may not be the last pdu in the chain - if its isn't then
2570 just put it on the incoming_fragmented_call_list and wait for the rest */
2571 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2572 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2574 * Up to 4 MByte are allowed by all fragments
2576 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2577 return dcesrv_fault_disconnect0(call,
2578 DCERPC_FAULT_ACCESS_DENIED);
2580 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2581 return NT_STATUS_OK;
2584 /* This removes any fragments we may have had stashed away */
2585 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2587 switch (call->pkt.ptype) {
2588 case DCERPC_PKT_BIND:
2589 status = dcesrv_bind_nak(call,
2590 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2591 break;
2592 case DCERPC_PKT_AUTH3:
2593 status = dcesrv_auth3(call);
2594 break;
2595 case DCERPC_PKT_ALTER:
2596 status = dcesrv_alter(call);
2597 break;
2598 case DCERPC_PKT_REQUEST:
2599 status = dcesrv_request(call);
2600 break;
2601 case DCERPC_PKT_CO_CANCEL:
2602 existing = dcesrv_find_fragmented_call(dce_conn,
2603 call->pkt.call_id);
2604 if (existing != NULL) {
2606 * If the call is still waiting for
2607 * more fragments, it's not pending yet,
2608 * for now we just remember we got CO_CANCEL,
2609 * but ignore it otherwise.
2611 * This matches what windows is doing...
2613 existing->got_co_cancel = true;
2614 SMB_ASSERT(existing->subreq == NULL);
2615 existing = NULL;
2617 existing = dcesrv_find_pending_call(dce_conn,
2618 call->pkt.call_id);
2619 if (existing != NULL) {
2621 * Give the backend a chance to react
2622 * on CO_CANCEL, but note it's ignored
2623 * by default.
2625 existing->got_co_cancel = true;
2626 if (existing->subreq != NULL) {
2627 tevent_req_cancel(existing->subreq);
2629 existing = NULL;
2631 status = NT_STATUS_OK;
2632 TALLOC_FREE(call);
2633 break;
2634 case DCERPC_PKT_ORPHANED:
2635 existing = dcesrv_find_fragmented_call(dce_conn,
2636 call->pkt.call_id);
2637 if (existing != NULL) {
2639 * If the call is still waiting for
2640 * more fragments, it's not pending yet,
2641 * for now we just remember we got ORPHANED,
2642 * but ignore it otherwise.
2644 * This matches what windows is doing...
2646 existing->got_orphaned = true;
2647 SMB_ASSERT(existing->subreq == NULL);
2648 existing = NULL;
2650 existing = dcesrv_find_pending_call(dce_conn,
2651 call->pkt.call_id);
2652 if (existing != NULL) {
2654 * Give the backend a chance to react
2655 * on ORPHANED, but note it's ignored
2656 * by default.
2658 existing->got_orphaned = true;
2659 if (existing->subreq != NULL) {
2660 tevent_req_cancel(existing->subreq);
2662 existing = NULL;
2664 status = NT_STATUS_OK;
2665 TALLOC_FREE(call);
2666 break;
2667 case DCERPC_PKT_BIND_ACK:
2668 case DCERPC_PKT_BIND_NAK:
2669 case DCERPC_PKT_ALTER_RESP:
2670 case DCERPC_PKT_RESPONSE:
2671 case DCERPC_PKT_FAULT:
2672 case DCERPC_PKT_SHUTDOWN:
2673 default:
2674 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2675 break;
2678 /* if we are going to be sending a reply then add
2679 it to the list of pending calls. We add it to the end to keep the call
2680 list in the order we will answer */
2681 if (!NT_STATUS_IS_OK(status)) {
2682 talloc_free(call);
2685 return status;
2688 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2689 struct loadparm_context *lp_ctx,
2690 struct dcesrv_context_callbacks *cb,
2691 struct dcesrv_context **_dce_ctx)
2693 struct dcesrv_context *dce_ctx;
2695 if (cb == NULL) {
2696 return NT_STATUS_INVALID_PARAMETER;
2699 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2700 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2702 if (uid_wrapper_enabled()) {
2703 setenv("UID_WRAPPER_MYUID", "1", 1);
2705 dce_ctx->initial_euid = geteuid();
2706 if (uid_wrapper_enabled()) {
2707 unsetenv("UID_WRAPPER_MYUID");
2710 dce_ctx->endpoint_list = NULL;
2711 dce_ctx->lp_ctx = lp_ctx;
2712 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2713 if (dce_ctx->assoc_groups_idr == NULL) {
2714 TALLOC_FREE(dce_ctx);
2715 return NT_STATUS_NO_MEMORY;
2717 dce_ctx->broken_connections = NULL;
2718 dce_ctx->callbacks = cb;
2721 * For now we only support NDR32.
2723 dce_ctx->preferred_transfer = &ndr_transfer_syntax_ndr;
2725 *_dce_ctx = dce_ctx;
2726 return NT_STATUS_OK;
2730 * @brief Set callback functions on an existing dcesrv_context
2732 * This allows to reset callbacks initially set via
2733 * dcesrv_init_context()
2735 * @param[in] dce_ctx The context to set the callbacks on
2736 * @param[in] cb The callbacks to set on dce_ctx
2738 _PUBLIC_ void dcesrv_context_set_callbacks(
2739 struct dcesrv_context *dce_ctx,
2740 struct dcesrv_context_callbacks *cb)
2742 dce_ctx->callbacks = cb;
2745 _PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
2746 const char **endpoint_servers)
2748 NTSTATUS status;
2749 int i;
2751 if (endpoint_servers == NULL) {
2752 DBG_ERR("No endpoint servers configured\n");
2753 return NT_STATUS_INTERNAL_ERROR;
2756 for (i=0;endpoint_servers[i];i++) {
2757 status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]);
2758 if (!NT_STATUS_IS_OK(status)) {
2759 DBG_ERR("failed to init endpoint server = '%s': %s\n",
2760 endpoint_servers[i], nt_errstr(status));
2761 return status;
2765 return NT_STATUS_OK;
2768 /* the list of currently registered DCERPC endpoint servers.
2770 static struct ep_server {
2771 struct dcesrv_endpoint_server *ep_server;
2772 } *ep_servers = NULL;
2773 static int num_ep_servers = 0;
2775 _PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers(
2776 struct dcesrv_context *dce_ctx)
2778 NTSTATUS status;
2779 int i;
2781 for (i = 0; i < num_ep_servers; i++) {
2782 status = dcesrv_init_ep_server(dce_ctx,
2783 ep_servers[i].ep_server->name);
2784 if (!NT_STATUS_IS_OK(status)) {
2785 return status;
2789 return NT_STATUS_OK;
2792 _PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
2793 const char *ep_server_name)
2795 struct dcesrv_endpoint_server *ep_server = NULL;
2796 NTSTATUS status;
2798 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2799 dcesrv_ep_server_byname(ep_server_name));
2800 if (ep_server == NULL) {
2801 DBG_ERR("Failed to find endpoint server '%s'\n",
2802 ep_server_name);
2803 return NT_STATUS_INTERNAL_ERROR;
2806 if (ep_server->initialized) {
2807 return NT_STATUS_OK;
2810 status = ep_server->init_server(dce_ctx, ep_server);
2811 if (!NT_STATUS_IS_OK(status)) {
2812 DBG_ERR("Failed to init endpoint server '%s': %s\n",
2813 ep_server_name, nt_errstr(status));
2814 return status;
2817 ep_server->initialized = true;
2819 return NT_STATUS_OK;
2822 _PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers(
2823 struct dcesrv_context *dce_ctx)
2825 NTSTATUS status;
2826 int i;
2828 for (i = 0; i < num_ep_servers; i++) {
2829 status = dcesrv_shutdown_ep_server(dce_ctx,
2830 ep_servers[i].ep_server->name);
2831 if (!NT_STATUS_IS_OK(status)) {
2832 return status;
2836 return NT_STATUS_OK;
2839 _PUBLIC_ NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
2840 const char *ep_server_name)
2842 struct dcesrv_endpoint_server *ep_server = NULL;
2843 NTSTATUS status;
2845 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2846 dcesrv_ep_server_byname(ep_server_name));
2847 if (ep_server == NULL) {
2848 DBG_ERR("Failed to find endpoint server '%s'\n",
2849 ep_server_name);
2850 return NT_STATUS_INTERNAL_ERROR;
2853 if (!ep_server->initialized) {
2854 return NT_STATUS_OK;
2857 DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2858 ep_server_name);
2860 status = ep_server->shutdown_server(dce_ctx, ep_server);
2861 if (!NT_STATUS_IS_OK(status)) {
2862 DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2863 ep_server_name, nt_errstr(status));
2864 return status;
2867 ep_server->initialized = false;
2869 return NT_STATUS_OK;
2873 register a DCERPC endpoint server.
2875 The 'name' can be later used by other backends to find the operations
2876 structure for this backend.
2879 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2882 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2883 /* its already registered! */
2884 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2885 ep_server->name));
2886 return NT_STATUS_OBJECT_NAME_COLLISION;
2889 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2890 if (!ep_servers) {
2891 smb_panic("out of memory in dcerpc_register");
2894 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2895 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2897 num_ep_servers++;
2899 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2900 ep_server->name));
2902 return NT_STATUS_OK;
2906 return the operations structure for a named backend of the specified type
2908 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2910 int i;
2912 for (i=0;i<num_ep_servers;i++) {
2913 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2914 return ep_servers[i].ep_server;
2918 return NULL;
2922 return the DCERPC module version, and the size of some critical types
2923 This can be used by endpoint server modules to either detect compilation errors, or provide
2924 multiple implementations for different smbd compilation options in one module
2926 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2928 static const struct dcesrv_critical_sizes critical_sizes = {
2929 DCERPC_MODULE_VERSION,
2930 sizeof(struct dcesrv_context),
2931 sizeof(struct dcesrv_endpoint),
2932 sizeof(struct dcesrv_endpoint_server),
2933 sizeof(struct dcesrv_interface),
2934 sizeof(struct dcesrv_if_list),
2935 sizeof(struct dcesrv_connection),
2936 sizeof(struct dcesrv_call_state),
2937 sizeof(struct dcesrv_auth),
2938 sizeof(struct dcesrv_handle)
2941 return &critical_sizes;
2944 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2946 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2947 struct dcesrv_call_state *c = NULL, *n = NULL;
2948 struct dcesrv_auth *a = NULL;
2950 dce_conn->wait_send = NULL;
2951 dce_conn->wait_recv = NULL;
2952 dce_conn->wait_private = NULL;
2954 dce_conn->allow_bind = false;
2955 dce_conn->allow_alter = false;
2957 dce_conn->default_auth_state->auth_invalid = true;
2959 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2960 a->auth_invalid = true;
2963 no_pending:
2964 if (dce_conn->pending_call_list == NULL) {
2965 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2967 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2968 dce_conn->transport.terminate_connection(dce_conn,
2969 full_reason ? full_reason : reason);
2970 return;
2973 if (dce_conn->terminate != NULL) {
2974 return;
2977 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2978 reason));
2979 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2980 if (dce_conn->terminate == NULL) {
2981 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2983 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2985 for (c = dce_conn->pending_call_list; c != NULL; c = n) {
2986 n = c->next;
2988 c->got_disconnect = true;
2989 if (c->subreq != NULL) {
2990 tevent_req_cancel(c->subreq);
2994 if (dce_conn->pending_call_list == NULL) {
2996 * tevent_req_cancel() was able to made progress
2997 * and we don't have pending calls anymore.
2999 goto no_pending;
3003 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
3005 struct dcesrv_connection *cur, *next;
3007 next = dce_ctx->broken_connections;
3008 while (next != NULL) {
3009 cur = next;
3010 next = cur->next;
3012 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
3013 struct dcesrv_connection_context *context_cur, *context_next;
3015 context_next = cur->contexts;
3016 while (context_next != NULL) {
3017 context_cur = context_next;
3018 context_next = context_cur->next;
3020 dcesrv_connection_context_destructor(context_cur);
3024 dcesrv_terminate_connection(cur, cur->terminate);
3028 struct dcesrv_sock_reply_state {
3029 struct dcesrv_connection *dce_conn;
3030 struct dcesrv_call_state *call;
3031 struct iovec iov;
3034 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
3035 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
3037 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
3039 struct dcesrv_call_state *call;
3041 call = dce_conn->call_list;
3042 if (!call || !call->replies) {
3043 return;
3046 while (call->replies) {
3047 struct data_blob_list_item *rep = call->replies;
3048 struct dcesrv_sock_reply_state *substate;
3049 struct tevent_req *subreq;
3051 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
3052 if (!substate) {
3053 dcesrv_terminate_connection(dce_conn, "no memory");
3054 return;
3057 substate->dce_conn = dce_conn;
3058 substate->call = NULL;
3060 DLIST_REMOVE(call->replies, rep);
3062 if (call->replies == NULL && call->terminate_reason == NULL) {
3063 substate->call = call;
3066 substate->iov.iov_base = (void *) rep->blob.data;
3067 substate->iov.iov_len = rep->blob.length;
3069 subreq = tstream_writev_queue_send(substate,
3070 dce_conn->event_ctx,
3071 dce_conn->stream,
3072 dce_conn->send_queue,
3073 &substate->iov, 1);
3074 if (!subreq) {
3075 dcesrv_terminate_connection(dce_conn, "no memory");
3076 return;
3078 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
3079 substate);
3082 if (call->terminate_reason != NULL) {
3083 struct tevent_req *subreq;
3085 subreq = tevent_queue_wait_send(call,
3086 dce_conn->event_ctx,
3087 dce_conn->send_queue);
3088 if (!subreq) {
3089 dcesrv_terminate_connection(dce_conn, __location__);
3090 return;
3092 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
3093 call);
3096 DLIST_REMOVE(call->conn->call_list, call);
3097 call->list = DCESRV_LIST_NONE;
3100 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
3102 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
3103 struct dcesrv_sock_reply_state);
3104 int ret;
3105 int sys_errno;
3106 NTSTATUS status;
3107 struct dcesrv_call_state *call = substate->call;
3109 ret = tstream_writev_queue_recv(subreq, &sys_errno);
3110 TALLOC_FREE(subreq);
3111 if (ret == -1) {
3112 status = map_nt_error_from_unix_common(sys_errno);
3113 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
3114 return;
3117 talloc_free(substate);
3118 if (call) {
3119 talloc_free(call);
3123 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
3125 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
3127 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
3128 struct dcesrv_call_state);
3129 bool ok;
3130 struct timeval tv;
3132 /* make sure we stop send queue before removing subreq */
3133 tevent_queue_stop(call->conn->send_queue);
3135 ok = tevent_queue_wait_recv(subreq);
3136 TALLOC_FREE(subreq);
3137 if (!ok) {
3138 dcesrv_terminate_connection(call->conn, __location__);
3139 return;
3142 /* disconnect after 200 usecs */
3143 tv = timeval_current_ofs_usec(200);
3144 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
3145 if (subreq == NULL) {
3146 dcesrv_terminate_connection(call->conn, __location__);
3147 return;
3149 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
3150 call);
3153 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
3155 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
3156 struct dcesrv_call_state);
3157 bool ok;
3159 ok = tevent_wakeup_recv(subreq);
3160 TALLOC_FREE(subreq);
3161 if (!ok) {
3162 dcesrv_terminate_connection(call->conn, __location__);
3163 return;
3166 dcesrv_terminate_connection(call->conn, call->terminate_reason);
3169 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
3171 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
3173 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3174 struct dcesrv_connection);
3175 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3176 struct ncacn_packet *pkt;
3177 DATA_BLOB buffer;
3178 NTSTATUS status;
3180 if (dce_conn->terminate) {
3182 * if the current connection is broken
3183 * we need to clean it up before any other connection
3185 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3186 dcesrv_cleanup_broken_connections(dce_ctx);
3187 return;
3190 dcesrv_cleanup_broken_connections(dce_ctx);
3192 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
3193 &pkt, &buffer);
3194 TALLOC_FREE(subreq);
3195 if (!NT_STATUS_IS_OK(status)) {
3196 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3197 return;
3200 dcesrv_loop_next_packet(dce_conn, pkt, buffer);
3204 * @brief Start the dcesrv loop, inducing the bind as a blob
3206 * Like dcesrv_connection_loop_start() but used from connections
3207 * where the caller has already read the dcerpc bind packet from
3208 * the socket and is available as a DATA_BLOB.
3210 * @param[in] dce_conn The connection to start
3211 * @param[in] pkt The parsed bind packet
3212 * @param[in] buffer The full binary bind including auth data
3214 void dcesrv_loop_next_packet(
3215 struct dcesrv_connection *dce_conn,
3216 struct ncacn_packet *pkt,
3217 DATA_BLOB buffer)
3219 struct tevent_req *subreq = NULL;
3220 NTSTATUS status;
3222 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
3223 if (!NT_STATUS_IS_OK(status)) {
3224 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3225 return;
3229 * This is used to block the connection during
3230 * pending authentication.
3232 if (dce_conn->wait_send != NULL) {
3233 subreq = dce_conn->wait_send(dce_conn,
3234 dce_conn->event_ctx,
3235 dce_conn->wait_private);
3236 if (!subreq) {
3237 status = NT_STATUS_NO_MEMORY;
3238 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3239 return;
3241 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
3242 return;
3245 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
3246 dce_conn->event_ctx,
3247 dce_conn->stream);
3248 if (!subreq) {
3249 status = NT_STATUS_NO_MEMORY;
3250 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3251 return;
3253 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
3256 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
3258 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3259 struct dcesrv_connection);
3260 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3261 NTSTATUS status;
3263 if (dce_conn->terminate) {
3265 * if the current connection is broken
3266 * we need to clean it up before any other connection
3268 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3269 dcesrv_cleanup_broken_connections(dce_ctx);
3270 return;
3273 dcesrv_cleanup_broken_connections(dce_ctx);
3275 status = dce_conn->wait_recv(subreq);
3276 dce_conn->wait_send = NULL;
3277 dce_conn->wait_recv = NULL;
3278 dce_conn->wait_private = NULL;
3279 TALLOC_FREE(subreq);
3280 if (!NT_STATUS_IS_OK(status)) {
3281 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3282 return;
3285 status = dcesrv_connection_loop_start(dce_conn);
3286 if (!NT_STATUS_IS_OK(status)) {
3287 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3288 return;
3293 * retrieve credentials from a dce_call
3295 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3297 struct dcesrv_auth *auth = dce_call->auth_state;
3298 SMB_ASSERT(auth->auth_finished);
3299 return auth->session_info->credentials;
3303 * returns true if this is an authenticated call
3305 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3307 struct dcesrv_auth *auth = dce_call->auth_state;
3308 enum security_user_level level;
3309 SMB_ASSERT(auth->auth_finished);
3310 level = security_session_user_level(auth->session_info, NULL);
3311 return level >= SECURITY_USER;
3315 * retrieve account_name for a dce_call
3317 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3319 struct dcesrv_auth *auth = dce_call->auth_state;
3320 SMB_ASSERT(auth->auth_finished);
3321 return auth->session_info->info->account_name;
3325 * retrieve session_info from a dce_call
3327 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3329 struct dcesrv_auth *auth = dce_call->auth_state;
3330 SMB_ASSERT(auth->auth_finished);
3331 return auth->session_info;
3335 * retrieve auth type/level from a dce_call
3337 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3338 enum dcerpc_AuthType *auth_type,
3339 enum dcerpc_AuthLevel *auth_level)
3341 struct dcesrv_auth *auth = dce_call->auth_state;
3343 SMB_ASSERT(auth->auth_finished);
3345 if (auth_type != NULL) {
3346 *auth_type = auth->auth_type;
3348 if (auth_level != NULL) {
3349 *auth_level = auth->auth_level;
3353 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
3355 struct tevent_req *subreq;
3357 subreq = dcerpc_read_ncacn_packet_send(conn,
3358 conn->event_ctx,
3359 conn->stream);
3360 if (subreq == NULL) {
3361 return NT_STATUS_NO_MEMORY;
3363 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
3365 return NT_STATUS_OK;
3368 _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
3370 NTSTATUS status;
3371 struct ndr_pull *pull = NULL;
3372 struct ndr_push *push = NULL;
3373 struct data_blob_list_item *rep = NULL;
3375 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier,
3376 call);
3377 if (pull == NULL) {
3378 return NT_STATUS_NO_MEMORY;
3381 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
3383 call->ndr_pull = pull;
3385 /* unravel the NDR for the packet */
3386 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
3387 if (!NT_STATUS_IS_OK(status)) {
3388 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3389 call->context->iface->name,
3390 call->pkt.u.request.opnum,
3391 dcerpc_errstr(call, call->fault_code));
3392 return dcerpc_fault_to_nt_status(call->fault_code);
3395 status = call->context->iface->local(call, call, call->r);
3396 if (!NT_STATUS_IS_OK(status)) {
3397 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3398 call->context->iface->name,
3399 call->pkt.u.request.opnum,
3400 dcerpc_errstr(call, call->fault_code));
3401 return dcerpc_fault_to_nt_status(call->fault_code);
3404 /* This can never go async for now! */
3405 SMB_ASSERT(!(call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC));
3407 /* call the reply function */
3408 status = call->context->iface->reply(call, call, call->r);
3409 if (!NT_STATUS_IS_OK(status)) {
3410 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3411 call->context->iface->name,
3412 call->pkt.u.request.opnum,
3413 dcerpc_errstr(call, call->fault_code));
3414 return dcerpc_fault_to_nt_status(call->fault_code);
3417 push = ndr_push_init_ctx(call);
3418 if (push == NULL) {
3419 return NT_STATUS_NO_MEMORY;
3422 push->ptr_count = call->ndr_pull->ptr_count;
3424 status = call->context->iface->ndr_push(call, call, push, call->r);
3425 if (!NT_STATUS_IS_OK(status)) {
3426 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3427 call->context->iface->name,
3428 call->pkt.u.request.opnum,
3429 dcerpc_errstr(call, call->fault_code));
3430 return dcerpc_fault_to_nt_status(call->fault_code);
3433 rep = talloc_zero(call, struct data_blob_list_item);
3434 if (rep == NULL) {
3435 return NT_STATUS_NO_MEMORY;
3438 rep->blob = ndr_push_blob(push);
3439 DLIST_ADD_END(call->replies, rep);
3441 return NT_STATUS_OK;