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/>.
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"
43 * @brief DCERPC server
47 #define DBGC_CLASS DBGC_RPC_SRV
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;
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");
80 if (strcasecmp(e1, e2) != 0) {
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)) {
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,
110 struct dcesrv_connection_context *c;
111 for (c=conn->contexts;c;c=c->next) {
112 if (c->context_id == context_id) return c;
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);
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)) {
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) {
170 find a pending request
172 static struct dcesrv_call_state *dcesrv_find_pending_call(
173 struct dcesrv_connection *dce_conn,
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) {
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);
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) {
214 return NT_STATUS_NO_MEMORY;
217 DLIST_ADD_END(dce_ctx->principal_list, p);
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;
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);
241 status = dcesrv_auth_type_principal_register(dce_ctx,
242 DCERPC_AUTH_TYPE_NTLMSSP,
244 if (!NT_STATUS_IS_OK(status)) {
247 status = dcesrv_auth_type_principal_register(dce_ctx,
248 DCERPC_AUTH_TYPE_SPNEGO,
250 if (!NT_STATUS_IS_OK(status)) {
254 if (realm == NULL || realm[0] == '\0') {
258 status = dcesrv_auth_type_principal_register(dce_ctx,
259 DCERPC_AUTH_TYPE_KRB5,
261 if (!NT_STATUS_IS_OK(status)) {
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;
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)) {
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,
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;
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);
321 if (ncacn_np_secondary_endpoint != NULL) {
322 ret = dcerpc_parse_binding(dce_ctx,
323 ncacn_np_secondary_endpoint,
325 if (NT_STATUS_IS_ERR(ret)) {
326 DBG_ERR("Trouble parsing 2nd binding string '%s'\n",
327 ncacn_np_secondary_endpoint);
332 ret = dcesrv_interface_register_b(dce_ctx,
338 TALLOC_FREE(binding);
339 TALLOC_FREE(binding2);
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;
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
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) {
376 * First check if there is already a port specified, eg
377 * for epmapper on ncacn_ip_tcp:[135]
380 = dcerpc_binding_get_string_option(binding,
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
392 if (port == 0 && !use_single_process) {
393 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
397 snprintf(port_str, sizeof(port_str), "%u", port);
398 status = dcerpc_binding_set_string_option(binding,
401 if (!NT_STATUS_IS_OK(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
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) {
450 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || add_ep) {
451 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
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);
462 /* add mgmt interface */
463 ifl = talloc_zero(ep, struct dcesrv_if_list);
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) {
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));
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);
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,
504 sizeof(struct dcesrv_interface));
505 if (ifl->iface == NULL) {
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
514 /* if there's currently no security descriptor given on the endpoint
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);
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 */
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";
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);
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;
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;
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)) {
631 session_key->length = MIN(session_key->length, 16);
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);
650 auth->session_key_fn = dcesrv_remote_session_key;
653 case NCACN_UNIX_STREAM:
654 auth->session_key_fn = dcesrv_local_fixed_session_key;
658 * All other's get a NULL pointer, which
659 * results in NT_STATUS_NO_USER_SESSION_KEY
668 connect to a dcerpc endpoint
670 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_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);
684 return NT_STATUS_ACCESS_DENIED;
687 p = talloc_zero(mem_ctx, struct dcesrv_connection);
692 p->dce_ctx = dce_ctx;
694 p->packet_log_dir = lpcfg_parm_string(dce_ctx->lp_ctx,
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;
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,
722 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
728 auth = dcesrv_auth_create(p);
733 auth->session_info = talloc_reference(auth, session_info);
734 if (auth->session_info == NULL) {
738 p->default_auth_state = auth;
740 p->preferred_transfer = dce_ctx->preferred_transfer;
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
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:
760 case DCESRV_LIST_CALL_LIST:
761 DLIST_REMOVE(call->conn->call_list, call);
763 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
764 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
766 case DCESRV_LIST_PENDING_CALL_LIST:
767 DLIST_REMOVE(call->conn->pending_call_list, call);
772 case DCESRV_LIST_NONE:
774 case DCESRV_LIST_CALL_LIST:
775 DLIST_ADD_END(call->conn->call_list, call);
777 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
778 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
780 case DCESRV_LIST_PENDING_CALL_LIST:
781 DLIST_ADD_END(call->conn->pending_call_list, call);
786 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
789 struct dcesrv_auth *a = NULL;
791 if (call->conn->terminate != NULL) {
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;
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));
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);
842 return NT_STATUS_NO_MEMORY;
845 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
846 if (!NT_STATUS_IS_OK(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);
864 static NTSTATUS _dcesrv_fault_disconnect_flags(struct dcesrv_call_state *call,
868 const char *location)
870 const char *reason = NULL;
872 reason = talloc_asprintf(call, "%s:%s: fault=%u (%s) flags=0x%x",
875 dcerpc_errstr(call, fault_code),
877 if (reason == NULL) {
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);
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;
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",
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;
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;
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;
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",
977 context->allow_connect);
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;
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",
1002 context->allow_connect);
1003 return NT_STATUS_OK;
1006 struct dcesrv_conn_auth_wait_context {
1007 struct tevent_req *req;
1012 struct dcesrv_conn_auth_wait_state {
1016 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
1017 struct tevent_context *ev,
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);
1031 auth_wait->req = req;
1033 tevent_req_defer_callback(req, ev);
1035 if (!auth_wait->done) {
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,
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) {
1085 if (tevent_req_nterror(auth_wait->req, status)) {
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;
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;
1117 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
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. */
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)) {
1163 raddr = tsocket_address_string(call->conn->remote_address, call);
1165 endpoint = dcerpc_binding_get_string_option(
1166 call->conn->endpoint->ep_description,
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, 0);
1179 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1180 call->pkt.u.bind.num_contexts);
1181 if (ack_ctx_list == NULL) {
1182 return dcesrv_bind_nak(call, 0);
1186 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1187 * dcesrv_check_or_create_context()) and do some protocol validation
1188 * and set sane defaults.
1190 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
1191 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
1192 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1193 bool is_feature = false;
1194 uint64_t features = 0;
1196 if (c->num_transfer_syntaxes == 0) {
1197 return dcesrv_bind_nak(call, 0);
1200 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1201 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1204 * It's only treated as bind time feature request, if the first
1205 * transfer_syntax matches, all others are ignored.
1207 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1213 if (ack_features != NULL) {
1215 * Only one bind time feature context is allowed.
1217 return dcesrv_bind_nak(call, 0);
1221 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1222 a->reason.negotiate = 0;
1223 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1224 if (conn->max_auth_states != 0) {
1225 a->reason.negotiate |=
1226 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1229 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1230 a->reason.negotiate |=
1231 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1234 conn->assoc_group->bind_time_features = a->reason.negotiate;
1238 * Try to negotiate one new presentation context.
1240 * Deep in here we locate the iface (by uuid) that the client
1241 * requested, from the list of interfaces on the
1242 * call->conn->endpoint, and call iface->bind() on that iface.
1244 * call->conn was set up at the accept() of the socket, and
1245 * call->conn->endpoint has a list of interfaces restricted to
1246 * this port or pipe.
1248 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1249 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1250 return dcesrv_bind_nak(call, 0);
1252 if (!NT_STATUS_IS_OK(status)) {
1257 * At this point we still don't know which interface (eg
1258 * netlogon, lsa, drsuapi) the caller requested in this bind!
1259 * The most recently added context is available as the first
1260 * element in the linked list at call->conn->contexts, that is
1261 * call->conn->contexts->iface, but they may not have
1262 * requested one at all!
1265 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1266 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1267 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1268 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1271 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1272 conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1276 * After finding the interface and setting up the NDR
1277 * transport negotiation etc, handle any authentication that
1278 * is being requested.
1280 if (!dcesrv_auth_bind(call)) {
1282 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1284 * With DCERPC_AUTH_LEVEL_NONE, we get the
1285 * reject_reason in auth->auth_context_id.
1287 return dcesrv_bind_nak(call, auth->auth_context_id);
1291 * This must a be a temporary failure e.g. talloc or invalid
1292 * configuration, e.g. no machine account.
1294 return dcesrv_bind_nak(call,
1295 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1298 /* setup a bind_ack */
1299 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(dce_ctx->lp_ctx));
1300 pkt->auth_length = 0;
1301 pkt->call_id = call->pkt.call_id;
1302 pkt->ptype = DCERPC_PKT_BIND_ACK;
1303 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1304 pkt->u.bind_ack.max_xmit_frag = conn->max_xmit_frag;
1305 pkt->u.bind_ack.max_recv_frag = conn->max_recv_frag;
1306 pkt->u.bind_ack.assoc_group_id = conn->assoc_group->id;
1308 ep_2nd_description = conn->endpoint->ep_2nd_description;
1309 if (ep_2nd_description == NULL) {
1310 ep_2nd_description = conn->endpoint->ep_description;
1313 endpoint = dcerpc_binding_get_string_option(
1316 if (endpoint == NULL) {
1320 pkt->u.bind_ack.secondary_address = endpoint;
1321 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1322 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1323 pkt->u.bind_ack.auth_info = data_blob_null;
1325 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 return dcesrv_bind_nak(call, 0);
1330 if (auth->auth_finished) {
1331 return dcesrv_auth_reply(call);
1334 cb->auth.become_root();
1335 subreq = gensec_update_send(call, call->event_ctx,
1336 auth->gensec_security,
1337 call->in_auth_info.credentials);
1338 cb->auth.unbecome_root();
1339 if (subreq == NULL) {
1340 return NT_STATUS_NO_MEMORY;
1342 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1344 return dcesrv_conn_auth_wait_setup(conn);
1347 static void dcesrv_bind_done(struct tevent_req *subreq)
1349 struct dcesrv_call_state *call =
1350 tevent_req_callback_data(subreq,
1351 struct dcesrv_call_state);
1352 struct dcesrv_connection *conn = call->conn;
1353 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1356 cb->auth.become_root();
1357 status = gensec_update_recv(subreq, call,
1358 &call->out_auth_info->credentials);
1359 cb->auth.unbecome_root();
1360 TALLOC_FREE(subreq);
1362 status = dcesrv_auth_complete(call, status);
1363 if (!NT_STATUS_IS_OK(status)) {
1364 status = dcesrv_bind_nak(call, DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM);
1365 dcesrv_conn_auth_wait_finished(conn, status);
1369 status = dcesrv_auth_reply(call);
1370 dcesrv_conn_auth_wait_finished(conn, status);
1374 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1376 struct ncacn_packet *pkt = &call->ack_pkt;
1377 struct data_blob_list_item *rep = NULL;
1380 rep = talloc_zero(call, struct data_blob_list_item);
1382 return NT_STATUS_NO_MEMORY;
1385 status = dcerpc_ncacn_push_auth(&rep->blob,
1388 call->out_auth_info);
1389 if (!NT_STATUS_IS_OK(status)) {
1393 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1395 DLIST_ADD_END(call->replies, rep);
1396 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1398 if (call->conn->call_list && call->conn->call_list->replies) {
1399 if (call->conn->transport.report_output_data) {
1400 call->conn->transport.report_output_data(call->conn);
1404 return NT_STATUS_OK;
1408 static void dcesrv_auth3_done(struct tevent_req *subreq);
1411 handle a auth3 request
1413 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1415 struct dcesrv_connection *conn = call->conn;
1416 struct dcesrv_auth *auth = call->auth_state;
1417 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1418 struct tevent_req *subreq = NULL;
1421 if (!auth->auth_started) {
1422 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1425 if (auth->auth_finished) {
1426 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1429 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1431 call->pkt.u.auth3.auth_info.length,
1432 0, /* required flags */
1433 DCERPC_PFC_FLAG_FIRST |
1434 DCERPC_PFC_FLAG_LAST |
1435 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1436 0x08 | /* this is not defined, but should be ignored */
1437 DCERPC_PFC_FLAG_CONC_MPX |
1438 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1439 DCERPC_PFC_FLAG_MAYBE |
1440 DCERPC_PFC_FLAG_OBJECT_UUID);
1441 if (!NT_STATUS_IS_OK(status)) {
1442 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1445 if (call->pkt.frag_length > call->conn->transport_max_recv_frag) {
1447 * Note that we don't check against the negotiated
1448 * max_recv_frag, but a hard coded value from
1451 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1454 /* handle the auth3 in the auth code */
1455 if (!dcesrv_auth_prepare_auth3(call)) {
1457 * we don't send a reply to a auth3 request,
1458 * except by a fault.
1460 * In anycase we mark the connection as
1463 auth->auth_invalid = true;
1464 if (call->fault_code != 0) {
1465 return dcesrv_fault_disconnect(call, call->fault_code);
1468 return NT_STATUS_OK;
1471 cb->auth.become_root();
1472 subreq = gensec_update_send(call, call->event_ctx,
1473 auth->gensec_security,
1474 call->in_auth_info.credentials);
1475 cb->auth.unbecome_root();
1476 if (subreq == NULL) {
1477 return NT_STATUS_NO_MEMORY;
1479 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1481 return dcesrv_conn_auth_wait_setup(conn);
1484 static void dcesrv_auth3_done(struct tevent_req *subreq)
1486 struct dcesrv_call_state *call =
1487 tevent_req_callback_data(subreq,
1488 struct dcesrv_call_state);
1489 struct dcesrv_connection *conn = call->conn;
1490 struct dcesrv_auth *auth = call->auth_state;
1491 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1494 cb->auth.become_root();
1495 status = gensec_update_recv(subreq, call,
1496 &call->out_auth_info->credentials);
1497 cb->auth.unbecome_root();
1498 TALLOC_FREE(subreq);
1500 status = dcesrv_auth_complete(call, status);
1501 if (!NT_STATUS_IS_OK(status)) {
1503 * we don't send a reply to a auth3 request,
1504 * except by a fault.
1506 * In anycase we mark the connection as
1509 auth->auth_invalid = true;
1510 if (call->fault_code != 0) {
1511 status = dcesrv_fault_disconnect(call, call->fault_code);
1512 dcesrv_conn_auth_wait_finished(conn, status);
1516 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1521 * we don't send a reply to a auth3 request.
1524 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1529 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1530 const struct dcerpc_bind *b,
1531 const struct dcerpc_ctx_list *ctx,
1532 struct dcerpc_ack_ctx *ack,
1534 const struct ndr_syntax_id *supported_transfer)
1536 struct dcesrv_connection_context *context;
1537 const struct dcesrv_interface *iface;
1539 const struct ndr_syntax_id *selected_transfer = NULL;
1544 return NT_STATUS_INTERNAL_ERROR;
1547 return NT_STATUS_INTERNAL_ERROR;
1549 if (ctx->num_transfer_syntaxes < 1) {
1550 return NT_STATUS_INTERNAL_ERROR;
1553 return NT_STATUS_INTERNAL_ERROR;
1555 if (supported_transfer == NULL) {
1556 return NT_STATUS_INTERNAL_ERROR;
1559 switch (ack->result) {
1560 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1561 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1563 * We is already completed.
1565 return NT_STATUS_OK;
1570 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1571 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1573 iface = find_interface_by_syntax_id(
1574 call->conn->endpoint, &ctx->abstract_syntax);
1575 if (iface == NULL) {
1576 struct ndr_syntax_id_buf buf;
1577 DBG_NOTICE("Request for unknown dcerpc interface %s\n",
1578 ndr_syntax_id_buf_string(
1579 &ctx->abstract_syntax, &buf));
1581 * We report this only via ack->result
1583 return NT_STATUS_OK;
1586 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1587 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1589 if (validate_only) {
1591 * We report this only via ack->result
1593 return NT_STATUS_OK;
1596 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1598 * we only do NDR encoded dcerpc for now.
1600 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1601 supported_transfer);
1603 selected_transfer = supported_transfer;
1608 context = dcesrv_find_context(call->conn, ctx->context_id);
1609 if (context != NULL) {
1610 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1611 &ctx->abstract_syntax);
1613 return NT_STATUS_RPC_PROTOCOL_ERROR;
1616 if (selected_transfer != NULL) {
1617 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1620 return NT_STATUS_RPC_PROTOCOL_ERROR;
1623 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1624 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1625 ack->syntax = context->transfer_syntax;
1629 * We report this only via ack->result
1631 return NT_STATUS_OK;
1634 if (selected_transfer == NULL) {
1636 * We report this only via ack->result
1638 return NT_STATUS_OK;
1641 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1642 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1644 /* add this context to the list of available context_ids */
1645 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1646 if (context == NULL) {
1647 return NT_STATUS_NO_MEMORY;
1649 context->conn = call->conn;
1650 context->context_id = ctx->context_id;
1651 context->iface = iface;
1652 context->transfer_syntax = *selected_transfer;
1653 context->ndr64 = ndr_syntax_id_equal(&context->transfer_syntax,
1654 &ndr_transfer_syntax_ndr64);
1655 DLIST_ADD(call->conn->contexts, context);
1656 call->context = context;
1657 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1659 dcesrv_prepare_context_auth(call);
1662 * Multiplex is supported by default
1664 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1666 status = iface->bind(context, iface);
1667 call->context = NULL;
1668 if (!NT_STATUS_IS_OK(status)) {
1669 /* we don't want to trigger the iface->unbind() hook */
1670 context->iface = NULL;
1671 talloc_free(context);
1673 * We report this only via ack->result
1675 return NT_STATUS_OK;
1678 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1679 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1680 ack->syntax = context->transfer_syntax;
1681 return NT_STATUS_OK;
1684 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1685 const struct dcerpc_bind *b,
1686 struct dcerpc_ack_ctx *ack_ctx_list)
1690 bool validate_only = false;
1691 bool preferred_ndr32;
1694 * Try to negotiate one new presentation context,
1695 * using our preferred transfer syntax.
1697 for (i = 0; i < b->num_contexts; i++) {
1698 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1699 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1701 status = dcesrv_check_or_create_context(call, b, c, a,
1703 call->conn->preferred_transfer);
1704 if (!NT_STATUS_IS_OK(status)) {
1708 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1710 * We managed to negotiate one context.
1714 validate_only = true;
1718 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1719 call->conn->preferred_transfer);
1720 if (preferred_ndr32) {
1724 return NT_STATUS_OK;
1728 * Try to negotiate one new presentation context,
1729 * using NDR 32 as fallback.
1731 for (i = 0; i < b->num_contexts; i++) {
1732 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1733 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1735 status = dcesrv_check_or_create_context(call, b, c, a,
1737 &ndr_transfer_syntax_ndr);
1738 if (!NT_STATUS_IS_OK(status)) {
1742 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1744 * We managed to negotiate one context.
1748 validate_only = true;
1752 return NT_STATUS_OK;
1755 static void dcesrv_alter_done(struct tevent_req *subreq);
1758 handle a alter context request
1760 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1762 struct dcesrv_connection *conn = call->conn;
1764 bool auth_ok = false;
1765 struct ncacn_packet *pkt = &call->ack_pkt;
1766 uint32_t extra_flags = 0;
1767 struct dcesrv_auth *auth = call->auth_state;
1768 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1769 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1770 struct tevent_req *subreq = NULL;
1773 if (!call->conn->allow_alter) {
1774 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1777 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1779 call->pkt.u.alter.auth_info.length,
1780 0, /* required flags */
1781 DCERPC_PFC_FLAG_FIRST |
1782 DCERPC_PFC_FLAG_LAST |
1783 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1784 0x08 | /* this is not defined, but should be ignored */
1785 DCERPC_PFC_FLAG_CONC_MPX |
1786 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1787 DCERPC_PFC_FLAG_MAYBE |
1788 DCERPC_PFC_FLAG_OBJECT_UUID);
1789 if (!NT_STATUS_IS_OK(status)) {
1790 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1794 * Note that BIND and ALTER allow frag_len up to UINT16_MAX,
1795 * so we don't check again frag_len against
1796 * call->conn->transport_max_recv_frag
1799 auth_ok = dcesrv_auth_alter(call);
1801 if (call->fault_code != 0) {
1802 return dcesrv_fault_disconnect(call, call->fault_code);
1806 if (call->pkt.u.alter.num_contexts < 1) {
1807 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1810 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1811 call->pkt.u.alter.num_contexts);
1812 if (ack_ctx_list == NULL) {
1813 return NT_STATUS_NO_MEMORY;
1817 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1818 * dcesrv_check_or_create_context()) and do some protocol validation
1819 * and set sane defaults.
1821 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1822 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1823 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1825 if (c->num_transfer_syntaxes == 0) {
1826 return dcesrv_fault_disconnect(call,
1827 DCERPC_NCA_S_PROTO_ERROR);
1830 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1831 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1835 * Try to negotiate one new presentation context.
1837 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1838 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1839 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1841 if (!NT_STATUS_IS_OK(status)) {
1845 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1846 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1847 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1848 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1851 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1852 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1855 /* handle any authentication that is being requested */
1857 if (call->in_auth_info.auth_type != auth->auth_type) {
1858 return dcesrv_fault_disconnect(call,
1859 DCERPC_FAULT_SEC_PKG_ERROR);
1861 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1864 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1865 pkt->auth_length = 0;
1866 pkt->call_id = call->pkt.call_id;
1867 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1868 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1869 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1870 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1871 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1872 pkt->u.alter_resp.secondary_address = "";
1873 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1874 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1875 pkt->u.alter_resp.auth_info = data_blob_null;
1877 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1878 if (!NT_STATUS_IS_OK(status)) {
1879 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1882 if (auth->auth_finished) {
1883 return dcesrv_auth_reply(call);
1886 cb->auth.become_root();
1887 subreq = gensec_update_send(call, call->event_ctx,
1888 auth->gensec_security,
1889 call->in_auth_info.credentials);
1890 cb->auth.unbecome_root();
1891 if (subreq == NULL) {
1892 return NT_STATUS_NO_MEMORY;
1894 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1896 return dcesrv_conn_auth_wait_setup(conn);
1899 static void dcesrv_alter_done(struct tevent_req *subreq)
1901 struct dcesrv_call_state *call =
1902 tevent_req_callback_data(subreq,
1903 struct dcesrv_call_state);
1904 struct dcesrv_connection *conn = call->conn;
1905 struct dcesrv_context_callbacks *cb = call->conn->dce_ctx->callbacks;
1908 cb->auth.become_root();
1909 status = gensec_update_recv(subreq, call,
1910 &call->out_auth_info->credentials);
1911 cb->auth.unbecome_root();
1912 TALLOC_FREE(subreq);
1914 status = dcesrv_auth_complete(call, status);
1915 if (!NT_STATUS_IS_OK(status)) {
1917 * NT_STATUS_ACCESS_DENIED from gensec means
1918 * a signing check or decryption failure,
1919 * which should result in DCERPC_FAULT_SEC_PKG_ERROR.
1921 * Any other status, e.g. NT_STATUS_LOGON_FAILURE or
1922 * NT_STATUS_INVALID_PARAMETER should result in
1923 * DCERPC_FAULT_ACCESS_DENIED.
1925 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1926 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1928 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1930 dcesrv_conn_auth_wait_finished(conn, status);
1934 status = dcesrv_auth_reply(call);
1935 dcesrv_conn_auth_wait_finished(conn, status);
1940 possibly save the call for inspection with ndrdump
1942 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1945 dcerpc_log_packet(call->conn->packet_log_dir,
1946 call->context->iface->name,
1947 call->pkt.u.request.opnum,
1949 &call->pkt.u.request.stub_and_verifier,
1956 Save the call for use as a seed for fuzzing.
1958 This is only enabled in a developer build, and only has effect if the
1959 "dcesrv fuzz directory" param is set.
1961 void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob,
1962 struct dcesrv_call_state *call,
1965 const char *dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx,
1967 "dcesrv", "fuzz directory");
1969 dcerpc_save_ndr_fuzz_seed(call,
1972 call->context->iface->name,
1974 call->pkt.u.request.opnum,
1975 call->ndr_pull->flags & LIBNDR_FLAG_NDR64);
1977 #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1980 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1982 TALLOC_CTX *frame = talloc_stackframe();
1983 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1984 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1985 const struct dcerpc_sec_vt_pcontext pcontext = {
1986 .abstract_syntax = call->context->iface->syntax_id,
1987 .transfer_syntax = call->context->transfer_syntax,
1989 const struct dcerpc_sec_vt_header2 header2 =
1990 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1991 enum ndr_err_code ndr_err;
1992 struct dcerpc_sec_verification_trailer *vt = NULL;
1993 NTSTATUS status = NT_STATUS_OK;
1996 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1998 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
2000 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2001 status = ndr_map_error2ntstatus(ndr_err);
2005 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
2006 &pcontext, &header2);
2008 status = NT_STATUS_ACCESS_DENIED;
2017 handle a dcerpc request packet
2019 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
2021 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
2022 struct dcesrv_auth *auth = call->auth_state;
2023 enum dcerpc_transport_t transport =
2024 dcerpc_binding_get_transport(endpoint->ep_description);
2025 struct ndr_pull *pull;
2026 bool turn_winbind_on = false;
2029 DBG_ERR("%s: HERE\n", __location__);
2030 if (auth->auth_invalid) {
2031 DBG_ERR("%s: HERE\n", __location__);
2032 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2035 if (!auth->auth_finished) {
2036 DBG_ERR("%s: HERE\n", __location__);
2037 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2040 /* if authenticated, and the mech we use can't do async replies, don't use them... */
2041 if (auth->gensec_security != NULL &&
2042 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
2043 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
2046 if (call->context == NULL) {
2047 DBG_ERR("%s: HERE\n", __location__);
2048 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2049 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2052 switch (auth->auth_level) {
2053 case DCERPC_AUTH_LEVEL_NONE:
2054 case DCERPC_AUTH_LEVEL_PACKET:
2055 case DCERPC_AUTH_LEVEL_INTEGRITY:
2056 case DCERPC_AUTH_LEVEL_PRIVACY:
2059 if (!call->context->allow_connect) {
2062 addr = tsocket_address_string(call->conn->remote_address,
2065 DEBUG(2, ("%s: restrict auth_level_connect access "
2066 "to [%s] with auth[type=0x%x,level=0x%x] "
2067 "on [%s] from [%s]\n",
2068 __func__, call->context->iface->name,
2071 derpc_transport_string_by_transport(transport),
2073 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2078 if (auth->auth_level < call->context->min_auth_level) {
2081 addr = tsocket_address_string(call->conn->remote_address, call);
2083 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
2084 "to [%s] with auth[type=0x%x,level=0x%x] "
2085 "on [%s] from [%s]\n",
2087 call->context->min_auth_level,
2088 call->context->iface->name,
2091 derpc_transport_string_by_transport(transport),
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 %u 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;
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,
2144 if (pull->offset != pull->data_size) {
2145 dcesrv_save_call(call, "extrabytes");
2146 DEBUG(3,("Warning: %d 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 DBG_ERR("%s: HERE\n", __location__);
2161 status = call->context->iface->dispatch(call, call, call->r);
2162 DBG_ERR("%s: HERE\n", __location__);
2164 if (turn_winbind_on) {
2165 DBG_DEBUG("turning winbind on\n");
2169 if (!NT_STATUS_IS_OK(status)) {
2170 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
2171 call->context->iface->name,
2172 call->pkt.u.request.opnum,
2173 dcerpc_errstr(pull, call->fault_code)));
2174 return dcesrv_fault(call, call->fault_code);
2177 /* add the call to the pending list */
2178 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
2180 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
2181 return NT_STATUS_OK;
2184 return dcesrv_reply(call);
2189 remove the call from the right list when freed
2191 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
2193 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2197 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
2199 return conn->local_address;
2202 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
2204 return conn->remote_address;
2208 process some input to a dcerpc endpoint server.
2210 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
2211 struct ncacn_packet *pkt,
2215 struct dcesrv_call_state *call;
2216 struct dcesrv_call_state *existing = NULL;
2217 size_t num_auth_ctx = 0;
2218 enum dcerpc_AuthType auth_type = 0;
2219 enum dcerpc_AuthLevel auth_level = 0;
2220 uint32_t auth_context_id = 0;
2221 bool auth_invalid = false;
2223 DBG_ERR("%s: HERE\n", __location__);
2224 call = talloc_zero(dce_conn, struct dcesrv_call_state);
2226 data_blob_free(&blob);
2228 return NT_STATUS_NO_MEMORY;
2230 call->conn = dce_conn;
2231 call->event_ctx = dce_conn->event_ctx;
2232 call->state_flags = call->conn->state_flags;
2233 call->time = timeval_current();
2234 call->list = DCESRV_LIST_NONE;
2236 talloc_steal(call, pkt);
2237 talloc_steal(call, blob.data);
2240 if (dce_conn->max_auth_states == 0) {
2241 call->auth_state = dce_conn->default_auth_state;
2242 } else if (call->pkt.auth_length == 0) {
2243 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2244 dce_conn->default_auth_level_connect != NULL)
2246 call->auth_state = dce_conn->default_auth_level_connect;
2248 call->auth_state = dce_conn->default_auth_state;
2252 if (call->auth_state == NULL) {
2253 struct dcesrv_auth *a = NULL;
2254 bool check_type_level = true;
2256 auth_type = dcerpc_get_auth_type(&blob);
2257 auth_level = dcerpc_get_auth_level(&blob);
2258 auth_context_id = dcerpc_get_auth_context_id(&blob);
2260 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2261 if (!(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) {
2262 check_type_level = false;
2264 dce_conn->default_auth_level_connect = NULL;
2265 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
2266 dce_conn->got_explicit_auth_level_connect = true;
2270 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2273 if (a->auth_context_id != auth_context_id) {
2277 if (a->auth_type != auth_type) {
2278 auth_invalid = true;
2280 if (a->auth_level != auth_level) {
2281 auth_invalid = true;
2284 if (check_type_level && auth_invalid) {
2285 a->auth_invalid = true;
2288 DLIST_PROMOTE(dce_conn->auth_states, a);
2289 call->auth_state = a;
2294 if (call->auth_state == NULL) {
2295 struct dcesrv_auth *a = NULL;
2297 if (num_auth_ctx >= dce_conn->max_auth_states) {
2298 return dcesrv_fault_disconnect(call,
2299 DCERPC_NCA_S_PROTO_ERROR);
2302 a = dcesrv_auth_create(dce_conn);
2305 return NT_STATUS_NO_MEMORY;
2307 DLIST_ADD(dce_conn->auth_states, a);
2308 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2310 * This can never be valid.
2312 auth_invalid = true;
2313 a->auth_invalid = true;
2315 call->auth_state = a;
2318 talloc_set_destructor(call, dcesrv_call_dequeue);
2320 if (call->conn->allow_bind) {
2322 * Only one bind is possible per connection
2324 call->conn->allow_bind = false;
2325 return dcesrv_bind(call);
2328 /* we have to check the signing here, before combining the
2330 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2331 dcesrv_default_auth_state_prepare_request(call);
2333 if (call->auth_state->auth_started &&
2334 !call->auth_state->auth_invalid &&
2335 !call->auth_state->auth_finished) {
2337 * We have this check here instead of
2338 * relying on the check in dcesrv_auth_pkt_pull()
2339 * because the fault should have context_id=0
2341 return dcesrv_fault_disconnect(call,
2342 DCERPC_NCA_S_PROTO_ERROR);
2345 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2347 call->pkt.u.request.stub_and_verifier.length,
2348 0, /* required_flags */
2349 DCERPC_PFC_FLAG_FIRST |
2350 DCERPC_PFC_FLAG_LAST |
2351 DCERPC_PFC_FLAG_PENDING_CANCEL |
2352 0x08 | /* this is not defined, but should be ignored */
2353 DCERPC_PFC_FLAG_CONC_MPX |
2354 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2355 DCERPC_PFC_FLAG_MAYBE |
2356 DCERPC_PFC_FLAG_OBJECT_UUID);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 return dcesrv_fault_disconnect(call,
2359 DCERPC_NCA_S_PROTO_ERROR);
2362 if (call->pkt.frag_length > call->conn->transport_max_recv_frag) {
2364 * We don't use dcesrv_fault_disconnect()
2365 * here, because we don't want to set
2366 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2368 * Note that we don't check against the negotiated
2369 * max_recv_frag, but a hard coded value from
2372 return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2375 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2376 if (dce_conn->pending_call_list != NULL) {
2378 * concurrent requests are only allowed
2379 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2381 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2382 return dcesrv_fault_disconnect0(call,
2383 DCERPC_NCA_S_PROTO_ERROR);
2386 /* only one request is possible in the fragmented list */
2387 if (dce_conn->incoming_fragmented_call_list != NULL) {
2388 call->fault_code = DCERPC_NCA_S_PROTO_ERROR;
2390 existing = dcesrv_find_fragmented_call(dce_conn,
2392 if (existing != NULL && call->auth_state != existing->auth_state) {
2393 call->context = dcesrv_find_context(call->conn,
2394 call->pkt.u.request.context_id);
2396 if (call->pkt.auth_length != 0 && existing->context == call->context) {
2397 call->fault_code = DCERPC_FAULT_SEC_PKG_ERROR;
2400 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2402 * Without DCERPC_PFC_FLAG_CONC_MPX
2403 * we need to return the FAULT on the
2404 * already existing call.
2406 * This is important to get the
2407 * call_id and context_id right.
2409 dce_conn->incoming_fragmented_call_list->fault_code = call->fault_code;
2411 call = dce_conn->incoming_fragmented_call_list;
2413 if (existing != NULL) {
2414 call->context = existing->context;
2416 return dcesrv_fault_disconnect0(call, call->fault_code);
2418 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2419 return dcesrv_fault_disconnect(call,
2420 DCERPC_FAULT_NO_CALL_ACTIVE);
2422 call->context = dcesrv_find_context(call->conn,
2423 call->pkt.u.request.context_id);
2424 if (call->context == NULL) {
2425 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2426 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2431 existing = dcesrv_find_fragmented_call(dce_conn,
2433 if (existing == NULL) {
2434 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2436 * Without DCERPC_PFC_FLAG_CONC_MPX
2437 * we need to return the FAULT on the
2438 * already existing call.
2440 * This is important to get the
2441 * call_id and context_id right.
2443 if (dce_conn->incoming_fragmented_call_list != NULL) {
2445 call = dce_conn->incoming_fragmented_call_list;
2447 return dcesrv_fault_disconnect0(call,
2448 DCERPC_NCA_S_PROTO_ERROR);
2450 if (dce_conn->incoming_fragmented_call_list != NULL) {
2451 return dcesrv_fault_disconnect0(call, DCERPC_NCA_S_PROTO_ERROR);
2453 call->context = dcesrv_find_context(call->conn,
2454 call->pkt.u.request.context_id);
2455 if (call->context == NULL) {
2456 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2457 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2460 return dcesrv_fault_disconnect0(call,
2461 DCERPC_FAULT_ACCESS_DENIED);
2463 return dcesrv_fault_disconnect0(call,
2464 DCERPC_NCA_S_PROTO_ERROR);
2467 if (call->pkt.ptype != existing->pkt.ptype) {
2468 /* trying to play silly buggers are we? */
2469 return dcesrv_fault_disconnect(existing,
2470 DCERPC_NCA_S_PROTO_ERROR);
2472 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2475 return dcesrv_fault_disconnect(existing,
2476 DCERPC_NCA_S_PROTO_ERROR);
2478 call->auth_state = existing->auth_state;
2479 call->context = existing->context;
2483 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2485 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2487 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2488 payload_offset += 16;
2491 ok = dcesrv_auth_pkt_pull(call, &blob,
2492 0, /* required_flags */
2493 DCERPC_PFC_FLAG_FIRST |
2494 DCERPC_PFC_FLAG_LAST |
2495 DCERPC_PFC_FLAG_PENDING_CANCEL |
2496 0x08 | /* this is not defined, but should be ignored */
2497 DCERPC_PFC_FLAG_CONC_MPX |
2498 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2499 DCERPC_PFC_FLAG_MAYBE |
2500 DCERPC_PFC_FLAG_OBJECT_UUID,
2502 &call->pkt.u.request.stub_and_verifier);
2505 * We don't use dcesrv_fault_disconnect()
2506 * here, because we don't want to set
2507 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2509 if (call->fault_code == 0) {
2510 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2512 return dcesrv_fault_disconnect0(call, call->fault_code);
2516 /* see if this is a continued packet */
2517 if (existing != NULL) {
2518 struct dcerpc_request *er = &existing->pkt.u.request;
2519 const struct dcerpc_request *nr = &call->pkt.u.request;
2525 * Up to 4 MByte are allowed by all fragments
2527 available = dce_conn->max_total_request_size;
2528 if (er->stub_and_verifier.length > available) {
2529 return dcesrv_fault_disconnect0(existing,
2530 DCERPC_FAULT_ACCESS_DENIED);
2532 available -= er->stub_and_verifier.length;
2533 if (nr->alloc_hint > available) {
2534 return dcesrv_fault_disconnect0(existing,
2535 DCERPC_FAULT_ACCESS_DENIED);
2537 if (nr->stub_and_verifier.length > available) {
2538 return dcesrv_fault_disconnect0(existing,
2539 DCERPC_FAULT_ACCESS_DENIED);
2541 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2542 /* allocate at least 1 byte */
2543 alloc_hint = MAX(alloc_hint, 1);
2544 alloc_size = er->stub_and_verifier.length +
2545 nr->stub_and_verifier.length;
2546 alloc_size = MAX(alloc_size, alloc_hint);
2548 er->stub_and_verifier.data =
2549 talloc_realloc(existing,
2550 er->stub_and_verifier.data,
2551 uint8_t, alloc_size);
2552 if (er->stub_and_verifier.data == NULL) {
2554 return dcesrv_fault_with_flags(existing,
2555 DCERPC_FAULT_OUT_OF_RESOURCES,
2556 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2558 memcpy(er->stub_and_verifier.data +
2559 er->stub_and_verifier.length,
2560 nr->stub_and_verifier.data,
2561 nr->stub_and_verifier.length);
2562 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2564 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2570 /* this may not be the last pdu in the chain - if its isn't then
2571 just put it on the incoming_fragmented_call_list and wait for the rest */
2572 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2573 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2575 * Up to 4 MByte are allowed by all fragments
2577 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2578 return dcesrv_fault_disconnect0(call,
2579 DCERPC_FAULT_ACCESS_DENIED);
2581 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2582 return NT_STATUS_OK;
2585 /* This removes any fragments we may have had stashed away */
2586 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2588 switch (call->pkt.ptype) {
2589 case DCERPC_PKT_BIND:
2590 status = dcesrv_bind_nak(call,
2591 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2593 case DCERPC_PKT_AUTH3:
2594 status = dcesrv_auth3(call);
2596 case DCERPC_PKT_ALTER:
2597 status = dcesrv_alter(call);
2599 case DCERPC_PKT_REQUEST:
2600 status = dcesrv_request(call);
2602 case DCERPC_PKT_CO_CANCEL:
2603 existing = dcesrv_find_fragmented_call(dce_conn,
2605 if (existing != NULL) {
2607 * If the call is still waiting for
2608 * more fragments, it's not pending yet,
2609 * for now we just remember we got CO_CANCEL,
2610 * but ignore it otherwise.
2612 * This matches what windows is doing...
2614 existing->got_co_cancel = true;
2615 SMB_ASSERT(existing->subreq == NULL);
2618 existing = dcesrv_find_pending_call(dce_conn,
2620 if (existing != NULL) {
2622 * Give the backend a chance to react
2623 * on CO_CANCEL, but note it's ignored
2626 existing->got_co_cancel = true;
2627 if (existing->subreq != NULL) {
2628 tevent_req_cancel(existing->subreq);
2632 status = NT_STATUS_OK;
2635 case DCERPC_PKT_ORPHANED:
2636 existing = dcesrv_find_fragmented_call(dce_conn,
2638 if (existing != NULL) {
2640 * If the call is still waiting for
2641 * more fragments, it's not pending yet,
2642 * for now we just remember we got ORPHANED,
2643 * but ignore it otherwise.
2645 * This matches what windows is doing...
2647 existing->got_orphaned = true;
2648 SMB_ASSERT(existing->subreq == NULL);
2651 existing = dcesrv_find_pending_call(dce_conn,
2653 if (existing != NULL) {
2655 * Give the backend a chance to react
2656 * on ORPHANED, but note it's ignored
2659 existing->got_orphaned = true;
2660 if (existing->subreq != NULL) {
2661 tevent_req_cancel(existing->subreq);
2665 status = NT_STATUS_OK;
2668 case DCERPC_PKT_BIND_ACK:
2669 case DCERPC_PKT_BIND_NAK:
2670 case DCERPC_PKT_ALTER_RESP:
2671 case DCERPC_PKT_RESPONSE:
2672 case DCERPC_PKT_FAULT:
2673 case DCERPC_PKT_SHUTDOWN:
2675 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2679 /* if we are going to be sending a reply then add
2680 it to the list of pending calls. We add it to the end to keep the call
2681 list in the order we will answer */
2682 if (!NT_STATUS_IS_OK(status)) {
2689 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2690 struct loadparm_context *lp_ctx,
2691 struct dcesrv_context_callbacks *cb,
2692 struct dcesrv_context **_dce_ctx)
2694 struct dcesrv_context *dce_ctx;
2697 return NT_STATUS_INVALID_PARAMETER;
2700 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2701 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2703 if (uid_wrapper_enabled()) {
2704 setenv("UID_WRAPPER_MYUID", "1", 1);
2706 dce_ctx->initial_euid = geteuid();
2707 if (uid_wrapper_enabled()) {
2708 unsetenv("UID_WRAPPER_MYUID");
2711 dce_ctx->endpoint_list = NULL;
2712 dce_ctx->lp_ctx = lp_ctx;
2713 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2714 if (dce_ctx->assoc_groups_idr == NULL) {
2715 TALLOC_FREE(dce_ctx);
2716 return NT_STATUS_NO_MEMORY;
2718 dce_ctx->broken_connections = NULL;
2719 dce_ctx->callbacks = cb;
2722 * For now we only support NDR32.
2724 dce_ctx->preferred_transfer = &ndr_transfer_syntax_ndr;
2726 *_dce_ctx = dce_ctx;
2727 return NT_STATUS_OK;
2731 * @brief Set callback functions on an existing dcesrv_context
2733 * This allows to reset callbacks initially set via
2734 * dcesrv_init_context()
2736 * @param[in] dce_ctx The context to set the callbacks on
2737 * @param[in] cb The callbacks to set on dce_ctx
2739 _PUBLIC_ void dcesrv_context_set_callbacks(
2740 struct dcesrv_context *dce_ctx,
2741 struct dcesrv_context_callbacks *cb)
2743 dce_ctx->callbacks = cb;
2746 _PUBLIC_ NTSTATUS dcesrv_init_ep_servers(struct dcesrv_context *dce_ctx,
2747 const char **endpoint_servers)
2752 if (endpoint_servers == NULL) {
2753 DBG_ERR("No endpoint servers configured\n");
2754 return NT_STATUS_INTERNAL_ERROR;
2757 for (i=0;endpoint_servers[i];i++) {
2758 status = dcesrv_init_ep_server(dce_ctx, endpoint_servers[i]);
2759 if (!NT_STATUS_IS_OK(status)) {
2760 DBG_ERR("failed to init endpoint server = '%s': %s\n",
2761 endpoint_servers[i], nt_errstr(status));
2766 return NT_STATUS_OK;
2769 /* the list of currently registered DCERPC endpoint servers.
2771 static struct ep_server {
2772 struct dcesrv_endpoint_server *ep_server;
2773 } *ep_servers = NULL;
2774 static int num_ep_servers = 0;
2776 _PUBLIC_ NTSTATUS dcesrv_init_registered_ep_servers(
2777 struct dcesrv_context *dce_ctx)
2782 for (i = 0; i < num_ep_servers; i++) {
2783 status = dcesrv_init_ep_server(dce_ctx,
2784 ep_servers[i].ep_server->name);
2785 if (!NT_STATUS_IS_OK(status)) {
2790 return NT_STATUS_OK;
2793 _PUBLIC_ NTSTATUS dcesrv_init_ep_server(struct dcesrv_context *dce_ctx,
2794 const char *ep_server_name)
2796 struct dcesrv_endpoint_server *ep_server = NULL;
2799 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2800 dcesrv_ep_server_byname(ep_server_name));
2801 if (ep_server == NULL) {
2802 DBG_ERR("Failed to find endpoint server '%s'\n",
2804 return NT_STATUS_INTERNAL_ERROR;
2807 if (ep_server->initialized) {
2808 return NT_STATUS_OK;
2811 status = ep_server->init_server(dce_ctx, ep_server);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 DBG_ERR("Failed to init endpoint server '%s': %s\n",
2814 ep_server_name, nt_errstr(status));
2818 ep_server->initialized = true;
2820 return NT_STATUS_OK;
2823 _PUBLIC_ NTSTATUS dcesrv_shutdown_registered_ep_servers(
2824 struct dcesrv_context *dce_ctx)
2829 for (i = 0; i < num_ep_servers; i++) {
2830 status = dcesrv_shutdown_ep_server(dce_ctx,
2831 ep_servers[i].ep_server->name);
2832 if (!NT_STATUS_IS_OK(status)) {
2837 return NT_STATUS_OK;
2840 _PUBLIC_ NTSTATUS dcesrv_shutdown_ep_server(struct dcesrv_context *dce_ctx,
2841 const char *ep_server_name)
2843 struct dcesrv_endpoint_server *ep_server = NULL;
2846 ep_server = discard_const_p(struct dcesrv_endpoint_server,
2847 dcesrv_ep_server_byname(ep_server_name));
2848 if (ep_server == NULL) {
2849 DBG_ERR("Failed to find endpoint server '%s'\n",
2851 return NT_STATUS_INTERNAL_ERROR;
2854 if (!ep_server->initialized) {
2855 return NT_STATUS_OK;
2858 DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2861 status = ep_server->shutdown_server(dce_ctx, ep_server);
2862 if (!NT_STATUS_IS_OK(status)) {
2863 DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2864 ep_server_name, nt_errstr(status));
2868 ep_server->initialized = false;
2870 return NT_STATUS_OK;
2874 register a DCERPC endpoint server.
2876 The 'name' can be later used by other backends to find the operations
2877 structure for this backend.
2880 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2883 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2884 /* its already registered! */
2885 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2887 return NT_STATUS_OBJECT_NAME_COLLISION;
2890 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2892 smb_panic("out of memory in dcerpc_register");
2895 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2896 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2900 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2903 return NT_STATUS_OK;
2907 return the operations structure for a named backend of the specified type
2909 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2913 for (i=0;i<num_ep_servers;i++) {
2914 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2915 return ep_servers[i].ep_server;
2923 return the DCERPC module version, and the size of some critical types
2924 This can be used by endpoint server modules to either detect compilation errors, or provide
2925 multiple implementations for different smbd compilation options in one module
2927 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2929 static const struct dcesrv_critical_sizes critical_sizes = {
2930 DCERPC_MODULE_VERSION,
2931 sizeof(struct dcesrv_context),
2932 sizeof(struct dcesrv_endpoint),
2933 sizeof(struct dcesrv_endpoint_server),
2934 sizeof(struct dcesrv_interface),
2935 sizeof(struct dcesrv_if_list),
2936 sizeof(struct dcesrv_connection),
2937 sizeof(struct dcesrv_call_state),
2938 sizeof(struct dcesrv_auth),
2939 sizeof(struct dcesrv_handle)
2942 return &critical_sizes;
2945 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2947 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2948 struct dcesrv_call_state *c = NULL, *n = NULL;
2949 struct dcesrv_auth *a = NULL;
2951 dce_conn->wait_send = NULL;
2952 dce_conn->wait_recv = NULL;
2953 dce_conn->wait_private = NULL;
2955 dce_conn->allow_bind = false;
2956 dce_conn->allow_alter = false;
2958 dce_conn->default_auth_state->auth_invalid = true;
2960 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2961 a->auth_invalid = true;
2965 if (dce_conn->pending_call_list == NULL) {
2966 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2968 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2969 dce_conn->transport.terminate_connection(dce_conn,
2970 full_reason ? full_reason : reason);
2974 if (dce_conn->terminate != NULL) {
2978 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2980 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2981 if (dce_conn->terminate == NULL) {
2982 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2984 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2986 for (c = dce_conn->pending_call_list; c != NULL; c = n) {
2989 c->got_disconnect = true;
2990 if (c->subreq != NULL) {
2991 tevent_req_cancel(c->subreq);
2995 if (dce_conn->pending_call_list == NULL) {
2997 * tevent_req_cancel() was able to made progress
2998 * and we don't have pending calls anymore.
3004 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
3006 struct dcesrv_connection *cur, *next;
3008 next = dce_ctx->broken_connections;
3009 while (next != NULL) {
3013 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
3014 struct dcesrv_connection_context *context_cur, *context_next;
3016 context_next = cur->contexts;
3017 while (context_next != NULL) {
3018 context_cur = context_next;
3019 context_next = context_cur->next;
3021 dcesrv_connection_context_destructor(context_cur);
3025 dcesrv_terminate_connection(cur, cur->terminate);
3029 struct dcesrv_sock_reply_state {
3030 struct dcesrv_connection *dce_conn;
3031 struct dcesrv_call_state *call;
3035 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
3036 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
3038 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
3040 struct dcesrv_call_state *call;
3042 call = dce_conn->call_list;
3043 if (!call || !call->replies) {
3047 while (call->replies) {
3048 struct data_blob_list_item *rep = call->replies;
3049 struct dcesrv_sock_reply_state *substate;
3050 struct tevent_req *subreq;
3052 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
3054 dcesrv_terminate_connection(dce_conn, "no memory");
3058 substate->dce_conn = dce_conn;
3059 substate->call = NULL;
3061 DLIST_REMOVE(call->replies, rep);
3063 if (call->replies == NULL && call->terminate_reason == NULL) {
3064 substate->call = call;
3067 substate->iov.iov_base = (void *) rep->blob.data;
3068 substate->iov.iov_len = rep->blob.length;
3070 subreq = tstream_writev_queue_send(substate,
3071 dce_conn->event_ctx,
3073 dce_conn->send_queue,
3076 dcesrv_terminate_connection(dce_conn, "no memory");
3079 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
3083 if (call->terminate_reason != NULL) {
3084 struct tevent_req *subreq;
3086 subreq = tevent_queue_wait_send(call,
3087 dce_conn->event_ctx,
3088 dce_conn->send_queue);
3090 dcesrv_terminate_connection(dce_conn, __location__);
3093 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
3097 DLIST_REMOVE(call->conn->call_list, call);
3098 call->list = DCESRV_LIST_NONE;
3101 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
3103 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
3104 struct dcesrv_sock_reply_state);
3108 struct dcesrv_call_state *call = substate->call;
3110 ret = tstream_writev_queue_recv(subreq, &sys_errno);
3111 TALLOC_FREE(subreq);
3113 status = map_nt_error_from_unix_common(sys_errno);
3114 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
3118 talloc_free(substate);
3124 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
3126 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
3128 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
3129 struct dcesrv_call_state);
3133 /* make sure we stop send queue before removing subreq */
3134 tevent_queue_stop(call->conn->send_queue);
3136 ok = tevent_queue_wait_recv(subreq);
3137 TALLOC_FREE(subreq);
3139 dcesrv_terminate_connection(call->conn, __location__);
3143 /* disconnect after 200 usecs */
3144 tv = timeval_current_ofs_usec(200);
3145 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
3146 if (subreq == NULL) {
3147 dcesrv_terminate_connection(call->conn, __location__);
3150 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
3154 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
3156 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
3157 struct dcesrv_call_state);
3160 ok = tevent_wakeup_recv(subreq);
3161 TALLOC_FREE(subreq);
3163 dcesrv_terminate_connection(call->conn, __location__);
3167 dcesrv_terminate_connection(call->conn, call->terminate_reason);
3170 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
3172 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
3174 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3175 struct dcesrv_connection);
3176 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3177 struct ncacn_packet *pkt;
3181 if (dce_conn->terminate) {
3183 * if the current connection is broken
3184 * we need to clean it up before any other connection
3186 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3187 dcesrv_cleanup_broken_connections(dce_ctx);
3191 dcesrv_cleanup_broken_connections(dce_ctx);
3193 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
3195 TALLOC_FREE(subreq);
3196 if (!NT_STATUS_IS_OK(status)) {
3197 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3201 dcesrv_loop_next_packet(dce_conn, pkt, buffer);
3205 * @brief Start the dcesrv loop, inducing the bind as a blob
3207 * Like dcesrv_connection_loop_start() but used from connections
3208 * where the caller has already read the dcerpc bind packet from
3209 * the socket and is available as a DATA_BLOB.
3211 * @param[in] dce_conn The connection to start
3212 * @param[in] pkt The parsed bind packet
3213 * @param[in] buffer The full binary bind including auth data
3215 void dcesrv_loop_next_packet(
3216 struct dcesrv_connection *dce_conn,
3217 struct ncacn_packet *pkt,
3220 struct tevent_req *subreq = NULL;
3223 DBG_ERR("%s: HERE\n", __location__);
3224 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
3225 DBG_ERR("%s: HERE\n", __location__);
3226 if (!NT_STATUS_IS_OK(status)) {
3227 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3232 * This is used to block the connection during
3233 * pending authentication.
3235 if (dce_conn->wait_send != NULL) {
3236 subreq = dce_conn->wait_send(dce_conn,
3237 dce_conn->event_ctx,
3238 dce_conn->wait_private);
3240 status = NT_STATUS_NO_MEMORY;
3241 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3244 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
3248 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
3249 dce_conn->event_ctx,
3252 status = NT_STATUS_NO_MEMORY;
3253 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3256 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
3259 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
3261 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
3262 struct dcesrv_connection);
3263 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
3266 if (dce_conn->terminate) {
3268 * if the current connection is broken
3269 * we need to clean it up before any other connection
3271 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
3272 dcesrv_cleanup_broken_connections(dce_ctx);
3276 dcesrv_cleanup_broken_connections(dce_ctx);
3278 status = dce_conn->wait_recv(subreq);
3279 dce_conn->wait_send = NULL;
3280 dce_conn->wait_recv = NULL;
3281 dce_conn->wait_private = NULL;
3282 TALLOC_FREE(subreq);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3288 status = dcesrv_connection_loop_start(dce_conn);
3289 if (!NT_STATUS_IS_OK(status)) {
3290 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
3296 * retrieve credentials from a dce_call
3298 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
3300 struct dcesrv_auth *auth = dce_call->auth_state;
3301 SMB_ASSERT(auth->auth_finished);
3302 return auth->session_info->credentials;
3306 * returns true if this is an authenticated call
3308 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
3310 struct dcesrv_auth *auth = dce_call->auth_state;
3311 enum security_user_level level;
3312 SMB_ASSERT(auth->auth_finished);
3313 level = security_session_user_level(auth->session_info, NULL);
3314 return level >= SECURITY_USER;
3318 * retrieve account_name for a dce_call
3320 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
3322 struct dcesrv_auth *auth = dce_call->auth_state;
3323 SMB_ASSERT(auth->auth_finished);
3324 return auth->session_info->info->account_name;
3328 * retrieve session_info from a dce_call
3330 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
3332 struct dcesrv_auth *auth = dce_call->auth_state;
3333 SMB_ASSERT(auth->auth_finished);
3334 return auth->session_info;
3338 * retrieve auth type/level from a dce_call
3340 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
3341 enum dcerpc_AuthType *auth_type,
3342 enum dcerpc_AuthLevel *auth_level)
3344 struct dcesrv_auth *auth = dce_call->auth_state;
3346 SMB_ASSERT(auth->auth_finished);
3348 if (auth_type != NULL) {
3349 *auth_type = auth->auth_type;
3351 if (auth_level != NULL) {
3352 *auth_level = auth->auth_level;
3356 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
3358 struct tevent_req *subreq;
3360 subreq = dcerpc_read_ncacn_packet_send(conn,
3363 if (subreq == NULL) {
3364 return NT_STATUS_NO_MEMORY;
3366 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
3368 return NT_STATUS_OK;
3371 _PUBLIC_ NTSTATUS dcesrv_call_dispatch_local(struct dcesrv_call_state *call)
3374 struct ndr_pull *pull = NULL;
3375 struct ndr_push *push = NULL;
3376 struct data_blob_list_item *rep = NULL;
3378 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier,
3381 return NT_STATUS_NO_MEMORY;
3384 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
3386 call->ndr_pull = pull;
3388 /* unravel the NDR for the packet */
3389 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3392 call->context->iface->name,
3393 call->pkt.u.request.opnum,
3394 dcerpc_errstr(call, call->fault_code));
3395 return dcerpc_fault_to_nt_status(call->fault_code);
3398 status = call->context->iface->local(call, call, call->r);
3399 if (!NT_STATUS_IS_OK(status)) {
3400 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3401 call->context->iface->name,
3402 call->pkt.u.request.opnum,
3403 dcerpc_errstr(call, call->fault_code));
3404 return dcerpc_fault_to_nt_status(call->fault_code);
3407 /* This can never go async for now! */
3408 SMB_ASSERT(!(call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC));
3410 /* call the reply function */
3411 status = call->context->iface->reply(call, call, call->r);
3412 if (!NT_STATUS_IS_OK(status)) {
3413 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3414 call->context->iface->name,
3415 call->pkt.u.request.opnum,
3416 dcerpc_errstr(call, call->fault_code));
3417 return dcerpc_fault_to_nt_status(call->fault_code);
3420 push = ndr_push_init_ctx(call);
3422 return NT_STATUS_NO_MEMORY;
3425 push->ptr_count = call->ndr_pull->ptr_count;
3427 status = call->context->iface->ndr_push(call, call, push, call->r);
3428 if (!NT_STATUS_IS_OK(status)) {
3429 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3430 call->context->iface->name,
3431 call->pkt.u.request.opnum,
3432 dcerpc_errstr(call, call->fault_code));
3433 return dcerpc_fault_to_nt_status(call->fault_code);
3436 rep = talloc_zero(call, struct data_blob_list_item);
3438 return NT_STATUS_NO_MEMORY;
3441 rep->blob = ndr_push_blob(push);
3442 DLIST_ADD_END(call->replies, rep);
3444 return NT_STATUS_OK;