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