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
,
1177 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED
);
1180 ack_ctx_list
= talloc_zero_array(call
, struct dcerpc_ack_ctx
,
1181 call
->pkt
.u
.bind
.num_contexts
);
1182 if (ack_ctx_list
== NULL
) {
1183 return dcesrv_bind_nak(call
, 0);
1187 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1188 * dcesrv_check_or_create_context()) and do some protocol validation
1189 * and set sane defaults.
1191 for (i
= 0; i
< call
->pkt
.u
.bind
.num_contexts
; i
++) {
1192 const struct dcerpc_ctx_list
*c
= &call
->pkt
.u
.bind
.ctx_list
[i
];
1193 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1194 bool is_feature
= false;
1195 uint64_t features
= 0;
1197 if (c
->num_transfer_syntaxes
== 0) {
1198 return dcesrv_bind_nak(call
, 0);
1201 a
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1202 a
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1205 * It's only treated as bind time feature request, if the first
1206 * transfer_syntax matches, all others are ignored.
1208 is_feature
= dcerpc_extract_bind_time_features(c
->transfer_syntaxes
[0],
1214 if (ack_features
!= NULL
) {
1216 * Only one bind time feature context is allowed.
1218 return dcesrv_bind_nak(call
, 0);
1222 a
->result
= DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
;
1223 a
->reason
.negotiate
= 0;
1224 if (features
& DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
) {
1225 if (conn
->max_auth_states
!= 0) {
1226 a
->reason
.negotiate
|=
1227 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
;
1230 if (features
& DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
) {
1231 a
->reason
.negotiate
|=
1232 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
;
1235 conn
->assoc_group
->bind_time_features
= a
->reason
.negotiate
;
1239 * Try to negotiate one new presentation context.
1241 * Deep in here we locate the iface (by uuid) that the client
1242 * requested, from the list of interfaces on the
1243 * call->conn->endpoint, and call iface->bind() on that iface.
1245 * call->conn was set up at the accept() of the socket, and
1246 * call->conn->endpoint has a list of interfaces restricted to
1247 * this port or pipe.
1249 status
= dcesrv_negotiate_contexts(call
, &call
->pkt
.u
.bind
, ack_ctx_list
);
1250 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1251 return dcesrv_bind_nak(call
, 0);
1253 if (!NT_STATUS_IS_OK(status
)) {
1258 * At this point we still don't know which interface (eg
1259 * netlogon, lsa, drsuapi) the caller requested in this bind!
1260 * The most recently added context is available as the first
1261 * element in the linked list at call->conn->contexts, that is
1262 * call->conn->contexts->iface, but they may not have
1263 * requested one at all!
1266 if ((call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_CONC_MPX
) &&
1267 (call
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
1268 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1269 extra_flags
|= DCERPC_PFC_FLAG_CONC_MPX
;
1272 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
1273 conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
;
1277 * After finding the interface and setting up the NDR
1278 * transport negotiation etc, handle any authentication that
1279 * is being requested.
1281 if (!dcesrv_auth_bind(call
)) {
1283 if (auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
) {
1285 * With DCERPC_AUTH_LEVEL_NONE, we get the
1286 * reject_reason in auth->auth_context_id.
1288 return dcesrv_bind_nak(call
, auth
->auth_context_id
);
1292 * This must a be a temporary failure e.g. talloc or invalid
1293 * configuration, e.g. no machine account.
1295 return dcesrv_bind_nak(call
,
1296 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION
);
1299 /* setup a bind_ack */
1300 dcesrv_init_hdr(pkt
, lpcfg_rpc_big_endian(dce_ctx
->lp_ctx
));
1301 pkt
->auth_length
= 0;
1302 pkt
->call_id
= call
->pkt
.call_id
;
1303 pkt
->ptype
= DCERPC_PKT_BIND_ACK
;
1304 pkt
->pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
| extra_flags
;
1305 pkt
->u
.bind_ack
.max_xmit_frag
= conn
->max_xmit_frag
;
1306 pkt
->u
.bind_ack
.max_recv_frag
= conn
->max_recv_frag
;
1307 pkt
->u
.bind_ack
.assoc_group_id
= conn
->assoc_group
->id
;
1309 ep_2nd_description
= conn
->endpoint
->ep_2nd_description
;
1310 if (ep_2nd_description
== NULL
) {
1311 ep_2nd_description
= conn
->endpoint
->ep_description
;
1314 endpoint
= dcerpc_binding_get_string_option(
1317 if (endpoint
== NULL
) {
1321 pkt
->u
.bind_ack
.secondary_address
= endpoint
;
1322 pkt
->u
.bind_ack
.num_results
= call
->pkt
.u
.bind
.num_contexts
;
1323 pkt
->u
.bind_ack
.ctx_list
= ack_ctx_list
;
1324 pkt
->u
.bind_ack
.auth_info
= data_blob_null
;
1326 status
= dcesrv_auth_prepare_bind_ack(call
, pkt
);
1327 if (!NT_STATUS_IS_OK(status
)) {
1328 return dcesrv_bind_nak(call
, 0);
1331 if (auth
->auth_finished
) {
1332 return dcesrv_auth_reply(call
);
1335 cb
->auth
.become_root();
1336 subreq
= gensec_update_send(call
, call
->event_ctx
,
1337 auth
->gensec_security
,
1338 call
->in_auth_info
.credentials
);
1339 cb
->auth
.unbecome_root();
1340 if (subreq
== NULL
) {
1341 return NT_STATUS_NO_MEMORY
;
1343 tevent_req_set_callback(subreq
, dcesrv_bind_done
, call
);
1345 return dcesrv_conn_auth_wait_setup(conn
);
1348 static void dcesrv_bind_done(struct tevent_req
*subreq
)
1350 struct dcesrv_call_state
*call
=
1351 tevent_req_callback_data(subreq
,
1352 struct dcesrv_call_state
);
1353 struct dcesrv_connection
*conn
= call
->conn
;
1354 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1357 cb
->auth
.become_root();
1358 status
= gensec_update_recv(subreq
, call
,
1359 &call
->out_auth_info
->credentials
);
1360 cb
->auth
.unbecome_root();
1361 TALLOC_FREE(subreq
);
1363 status
= dcesrv_auth_complete(call
, status
);
1364 if (!NT_STATUS_IS_OK(status
)) {
1365 status
= dcesrv_bind_nak(call
, DCERPC_BIND_NAK_REASON_INVALID_CHECKSUM
);
1366 dcesrv_conn_auth_wait_finished(conn
, status
);
1370 status
= dcesrv_auth_reply(call
);
1371 dcesrv_conn_auth_wait_finished(conn
, status
);
1375 static NTSTATUS
dcesrv_auth_reply(struct dcesrv_call_state
*call
)
1377 struct ncacn_packet
*pkt
= &call
->ack_pkt
;
1378 struct data_blob_list_item
*rep
= NULL
;
1381 rep
= talloc_zero(call
, struct data_blob_list_item
);
1383 return NT_STATUS_NO_MEMORY
;
1386 status
= dcerpc_ncacn_push_auth(&rep
->blob
,
1389 call
->out_auth_info
);
1390 if (!NT_STATUS_IS_OK(status
)) {
1394 dcerpc_set_frag_length(&rep
->blob
, rep
->blob
.length
);
1396 DLIST_ADD_END(call
->replies
, rep
);
1397 dcesrv_call_set_list(call
, DCESRV_LIST_CALL_LIST
);
1399 if (call
->conn
->call_list
&& call
->conn
->call_list
->replies
) {
1400 if (call
->conn
->transport
.report_output_data
) {
1401 call
->conn
->transport
.report_output_data(call
->conn
);
1405 return NT_STATUS_OK
;
1409 static void dcesrv_auth3_done(struct tevent_req
*subreq
);
1412 handle a auth3 request
1414 static NTSTATUS
dcesrv_auth3(struct dcesrv_call_state
*call
)
1416 struct dcesrv_connection
*conn
= call
->conn
;
1417 struct dcesrv_auth
*auth
= call
->auth_state
;
1418 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1419 struct tevent_req
*subreq
= NULL
;
1422 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
1424 call
->pkt
.u
.auth3
.auth_info
.length
,
1425 0, /* required flags */
1426 DCERPC_PFC_FLAG_FIRST
|
1427 DCERPC_PFC_FLAG_LAST
|
1428 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
1429 0x08 | /* this is not defined, but should be ignored */
1430 DCERPC_PFC_FLAG_CONC_MPX
|
1431 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1432 DCERPC_PFC_FLAG_MAYBE
|
1433 DCERPC_PFC_FLAG_OBJECT_UUID
);
1434 if (!NT_STATUS_IS_OK(status
)) {
1435 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1438 /* handle the auth3 in the auth code */
1439 if (!dcesrv_auth_prepare_auth3(call
)) {
1441 * we don't send a reply to a auth3 request,
1442 * except by a fault.
1444 * In anycase we mark the connection as
1447 auth
->auth_invalid
= true;
1448 if (call
->fault_code
!= 0) {
1449 return dcesrv_fault_disconnect(call
, call
->fault_code
);
1452 return NT_STATUS_OK
;
1455 cb
->auth
.become_root();
1456 subreq
= gensec_update_send(call
, call
->event_ctx
,
1457 auth
->gensec_security
,
1458 call
->in_auth_info
.credentials
);
1459 cb
->auth
.unbecome_root();
1460 if (subreq
== NULL
) {
1461 return NT_STATUS_NO_MEMORY
;
1463 tevent_req_set_callback(subreq
, dcesrv_auth3_done
, call
);
1465 return dcesrv_conn_auth_wait_setup(conn
);
1468 static void dcesrv_auth3_done(struct tevent_req
*subreq
)
1470 struct dcesrv_call_state
*call
=
1471 tevent_req_callback_data(subreq
,
1472 struct dcesrv_call_state
);
1473 struct dcesrv_connection
*conn
= call
->conn
;
1474 struct dcesrv_auth
*auth
= call
->auth_state
;
1475 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1478 cb
->auth
.become_root();
1479 status
= gensec_update_recv(subreq
, call
,
1480 &call
->out_auth_info
->credentials
);
1481 cb
->auth
.unbecome_root();
1482 TALLOC_FREE(subreq
);
1484 status
= dcesrv_auth_complete(call
, status
);
1485 if (!NT_STATUS_IS_OK(status
)) {
1487 * we don't send a reply to a auth3 request,
1488 * except by a fault.
1490 * In anycase we mark the connection as
1493 auth
->auth_invalid
= true;
1494 if (call
->fault_code
!= 0) {
1495 status
= dcesrv_fault_disconnect(call
, call
->fault_code
);
1496 dcesrv_conn_auth_wait_finished(conn
, status
);
1500 dcesrv_conn_auth_wait_finished(conn
, NT_STATUS_OK
);
1505 * we don't send a reply to a auth3 request.
1508 dcesrv_conn_auth_wait_finished(conn
, NT_STATUS_OK
);
1513 static NTSTATUS
dcesrv_check_or_create_context(struct dcesrv_call_state
*call
,
1514 const struct dcerpc_bind
*b
,
1515 const struct dcerpc_ctx_list
*ctx
,
1516 struct dcerpc_ack_ctx
*ack
,
1518 const struct ndr_syntax_id
*supported_transfer
)
1520 struct dcesrv_connection_context
*context
;
1521 const struct dcesrv_interface
*iface
;
1523 const struct ndr_syntax_id
*selected_transfer
= NULL
;
1528 return NT_STATUS_INTERNAL_ERROR
;
1531 return NT_STATUS_INTERNAL_ERROR
;
1533 if (ctx
->num_transfer_syntaxes
< 1) {
1534 return NT_STATUS_INTERNAL_ERROR
;
1537 return NT_STATUS_INTERNAL_ERROR
;
1539 if (supported_transfer
== NULL
) {
1540 return NT_STATUS_INTERNAL_ERROR
;
1543 switch (ack
->result
) {
1544 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE
:
1545 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
:
1547 * We is already completed.
1549 return NT_STATUS_OK
;
1554 ack
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1555 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1557 iface
= find_interface_by_syntax_id(
1558 call
->conn
->endpoint
, &ctx
->abstract_syntax
);
1559 if (iface
== NULL
) {
1560 struct ndr_syntax_id_buf buf
;
1561 DBG_NOTICE("Request for unknown dcerpc interface %s\n",
1562 ndr_syntax_id_buf_string(
1563 &ctx
->abstract_syntax
, &buf
));
1565 * We report this only via ack->result
1567 return NT_STATUS_OK
;
1570 ack
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1571 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED
;
1573 if (validate_only
) {
1575 * We report this only via ack->result
1577 return NT_STATUS_OK
;
1580 for (i
= 0; i
< ctx
->num_transfer_syntaxes
; i
++) {
1582 * we only do NDR encoded dcerpc for now.
1584 ok
= ndr_syntax_id_equal(&ctx
->transfer_syntaxes
[i
],
1585 supported_transfer
);
1587 selected_transfer
= supported_transfer
;
1592 context
= dcesrv_find_context(call
->conn
, ctx
->context_id
);
1593 if (context
!= NULL
) {
1594 ok
= ndr_syntax_id_equal(&context
->iface
->syntax_id
,
1595 &ctx
->abstract_syntax
);
1597 return NT_STATUS_RPC_PROTOCOL_ERROR
;
1600 if (selected_transfer
!= NULL
) {
1601 ok
= ndr_syntax_id_equal(&context
->transfer_syntax
,
1604 return NT_STATUS_RPC_PROTOCOL_ERROR
;
1607 ack
->result
= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
;
1608 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_NOT_SPECIFIED
;
1609 ack
->syntax
= context
->transfer_syntax
;
1613 * We report this only via ack->result
1615 return NT_STATUS_OK
;
1618 if (selected_transfer
== NULL
) {
1620 * We report this only via ack->result
1622 return NT_STATUS_OK
;
1625 ack
->result
= DCERPC_BIND_ACK_RESULT_USER_REJECTION
;
1626 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED
;
1628 /* add this context to the list of available context_ids */
1629 context
= talloc_zero(call
->conn
, struct dcesrv_connection_context
);
1630 if (context
== NULL
) {
1631 return NT_STATUS_NO_MEMORY
;
1633 context
->conn
= call
->conn
;
1634 context
->context_id
= ctx
->context_id
;
1635 context
->iface
= iface
;
1636 context
->transfer_syntax
= *selected_transfer
;
1637 context
->ndr64
= ndr_syntax_id_equal(&context
->transfer_syntax
,
1638 &ndr_transfer_syntax_ndr64
);
1639 DLIST_ADD(call
->conn
->contexts
, context
);
1640 call
->context
= context
;
1641 talloc_set_destructor(context
, dcesrv_connection_context_destructor
);
1643 dcesrv_prepare_context_auth(call
);
1646 * Multiplex is supported by default
1648 call
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1650 status
= iface
->bind(context
, iface
);
1651 call
->context
= NULL
;
1652 if (!NT_STATUS_IS_OK(status
)) {
1653 /* we don't want to trigger the iface->unbind() hook */
1654 context
->iface
= NULL
;
1655 talloc_free(context
);
1657 * We report this only via ack->result
1659 return NT_STATUS_OK
;
1662 ack
->result
= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
;
1663 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_NOT_SPECIFIED
;
1664 ack
->syntax
= context
->transfer_syntax
;
1665 return NT_STATUS_OK
;
1668 static NTSTATUS
dcesrv_negotiate_contexts(struct dcesrv_call_state
*call
,
1669 const struct dcerpc_bind
*b
,
1670 struct dcerpc_ack_ctx
*ack_ctx_list
)
1674 bool validate_only
= false;
1675 bool preferred_ndr32
;
1678 * Try to negotiate one new presentation context,
1679 * using our preferred transfer syntax.
1681 for (i
= 0; i
< b
->num_contexts
; i
++) {
1682 const struct dcerpc_ctx_list
*c
= &b
->ctx_list
[i
];
1683 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1685 status
= dcesrv_check_or_create_context(call
, b
, c
, a
,
1687 call
->conn
->preferred_transfer
);
1688 if (!NT_STATUS_IS_OK(status
)) {
1692 if (a
->result
== DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1694 * We managed to negotiate one context.
1698 validate_only
= true;
1702 preferred_ndr32
= ndr_syntax_id_equal(&ndr_transfer_syntax_ndr
,
1703 call
->conn
->preferred_transfer
);
1704 if (preferred_ndr32
) {
1708 return NT_STATUS_OK
;
1712 * Try to negotiate one new presentation context,
1713 * using NDR 32 as fallback.
1715 for (i
= 0; i
< b
->num_contexts
; i
++) {
1716 const struct dcerpc_ctx_list
*c
= &b
->ctx_list
[i
];
1717 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1719 status
= dcesrv_check_or_create_context(call
, b
, c
, a
,
1721 &ndr_transfer_syntax_ndr
);
1722 if (!NT_STATUS_IS_OK(status
)) {
1726 if (a
->result
== DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1728 * We managed to negotiate one context.
1732 validate_only
= true;
1736 return NT_STATUS_OK
;
1739 static void dcesrv_alter_done(struct tevent_req
*subreq
);
1742 handle a alter context request
1744 static NTSTATUS
dcesrv_alter(struct dcesrv_call_state
*call
)
1746 struct dcesrv_connection
*conn
= call
->conn
;
1748 bool auth_ok
= false;
1749 struct ncacn_packet
*pkt
= &call
->ack_pkt
;
1750 uint32_t extra_flags
= 0;
1751 struct dcesrv_auth
*auth
= call
->auth_state
;
1752 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1753 struct dcerpc_ack_ctx
*ack_ctx_list
= NULL
;
1754 struct tevent_req
*subreq
= NULL
;
1757 if (!call
->conn
->allow_alter
) {
1758 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1761 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
1763 call
->pkt
.u
.alter
.auth_info
.length
,
1764 0, /* required flags */
1765 DCERPC_PFC_FLAG_FIRST
|
1766 DCERPC_PFC_FLAG_LAST
|
1767 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
1768 0x08 | /* this is not defined, but should be ignored */
1769 DCERPC_PFC_FLAG_CONC_MPX
|
1770 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1771 DCERPC_PFC_FLAG_MAYBE
|
1772 DCERPC_PFC_FLAG_OBJECT_UUID
);
1773 if (!NT_STATUS_IS_OK(status
)) {
1774 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1778 * Note that BIND and ALTER allow frag_len up to UINT16_MAX,
1779 * so we don't check again frag_len against
1780 * call->conn->transport_max_recv_frag
1783 auth_ok
= dcesrv_auth_alter(call
);
1785 if (call
->fault_code
!= 0) {
1786 return dcesrv_fault_disconnect(call
, call
->fault_code
);
1790 if (call
->pkt
.u
.alter
.num_contexts
< 1) {
1791 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1794 ack_ctx_list
= talloc_zero_array(call
, struct dcerpc_ack_ctx
,
1795 call
->pkt
.u
.alter
.num_contexts
);
1796 if (ack_ctx_list
== NULL
) {
1797 return NT_STATUS_NO_MEMORY
;
1801 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1802 * dcesrv_check_or_create_context()) and do some protocol validation
1803 * and set sane defaults.
1805 for (i
= 0; i
< call
->pkt
.u
.alter
.num_contexts
; i
++) {
1806 const struct dcerpc_ctx_list
*c
= &call
->pkt
.u
.alter
.ctx_list
[i
];
1807 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1809 if (c
->num_transfer_syntaxes
== 0) {
1810 return dcesrv_fault_disconnect(call
,
1811 DCERPC_NCA_S_PROTO_ERROR
);
1814 a
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1815 a
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1819 * Try to negotiate one new presentation context.
1821 status
= dcesrv_negotiate_contexts(call
, &call
->pkt
.u
.alter
, ack_ctx_list
);
1822 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1823 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1825 if (!NT_STATUS_IS_OK(status
)) {
1829 if ((call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_CONC_MPX
) &&
1830 (call
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
1831 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1832 extra_flags
|= DCERPC_PFC_FLAG_CONC_MPX
;
1835 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
1836 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
;
1839 /* handle any authentication that is being requested */
1841 if (call
->in_auth_info
.auth_type
!= auth
->auth_type
) {
1842 return dcesrv_fault_disconnect(call
,
1843 DCERPC_FAULT_SEC_PKG_ERROR
);
1845 return dcesrv_fault_disconnect(call
, DCERPC_FAULT_ACCESS_DENIED
);
1848 dcesrv_init_hdr(pkt
, lpcfg_rpc_big_endian(call
->conn
->dce_ctx
->lp_ctx
));
1849 pkt
->auth_length
= 0;
1850 pkt
->call_id
= call
->pkt
.call_id
;
1851 pkt
->ptype
= DCERPC_PKT_ALTER_RESP
;
1852 pkt
->pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
| extra_flags
;
1853 pkt
->u
.alter_resp
.max_xmit_frag
= call
->conn
->max_xmit_frag
;
1854 pkt
->u
.alter_resp
.max_recv_frag
= call
->conn
->max_recv_frag
;
1855 pkt
->u
.alter_resp
.assoc_group_id
= call
->conn
->assoc_group
->id
;
1856 pkt
->u
.alter_resp
.secondary_address
= "";
1857 pkt
->u
.alter_resp
.num_results
= call
->pkt
.u
.alter
.num_contexts
;
1858 pkt
->u
.alter_resp
.ctx_list
= ack_ctx_list
;
1859 pkt
->u
.alter_resp
.auth_info
= data_blob_null
;
1861 status
= dcesrv_auth_prepare_alter_ack(call
, pkt
);
1862 if (!NT_STATUS_IS_OK(status
)) {
1863 return dcesrv_fault_disconnect(call
, DCERPC_FAULT_SEC_PKG_ERROR
);
1866 if (auth
->auth_finished
) {
1867 return dcesrv_auth_reply(call
);
1870 cb
->auth
.become_root();
1871 subreq
= gensec_update_send(call
, call
->event_ctx
,
1872 auth
->gensec_security
,
1873 call
->in_auth_info
.credentials
);
1874 cb
->auth
.unbecome_root();
1875 if (subreq
== NULL
) {
1876 return NT_STATUS_NO_MEMORY
;
1878 tevent_req_set_callback(subreq
, dcesrv_alter_done
, call
);
1880 return dcesrv_conn_auth_wait_setup(conn
);
1883 static void dcesrv_alter_done(struct tevent_req
*subreq
)
1885 struct dcesrv_call_state
*call
=
1886 tevent_req_callback_data(subreq
,
1887 struct dcesrv_call_state
);
1888 struct dcesrv_connection
*conn
= call
->conn
;
1889 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1892 cb
->auth
.become_root();
1893 status
= gensec_update_recv(subreq
, call
,
1894 &call
->out_auth_info
->credentials
);
1895 cb
->auth
.unbecome_root();
1896 TALLOC_FREE(subreq
);
1898 status
= dcesrv_auth_complete(call
, status
);
1899 if (!NT_STATUS_IS_OK(status
)) {
1901 * NT_STATUS_ACCESS_DENIED from gensec means
1902 * a signing check or decryption failure,
1903 * which should result in DCERPC_FAULT_SEC_PKG_ERROR.
1905 * Any other status, e.g. NT_STATUS_LOGON_FAILURE or
1906 * NT_STATUS_INVALID_PARAMETER should result in
1907 * DCERPC_FAULT_ACCESS_DENIED.
1909 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
1910 status
= dcesrv_fault_disconnect(call
, DCERPC_FAULT_SEC_PKG_ERROR
);
1912 status
= dcesrv_fault_disconnect(call
, DCERPC_FAULT_ACCESS_DENIED
);
1914 dcesrv_conn_auth_wait_finished(conn
, status
);
1918 status
= dcesrv_auth_reply(call
);
1919 dcesrv_conn_auth_wait_finished(conn
, status
);
1924 possibly save the call for inspection with ndrdump
1926 static void dcesrv_save_call(struct dcesrv_call_state
*call
, const char *why
)
1929 dcerpc_log_packet(call
->conn
->packet_log_dir
,
1930 call
->context
->iface
->name
,
1931 call
->pkt
.u
.request
.opnum
,
1933 &call
->pkt
.u
.request
.stub_and_verifier
,
1940 Save the call for use as a seed for fuzzing.
1942 This is only enabled in a developer build, and only has effect if the
1943 "dcesrv fuzz directory" param is set.
1945 void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob
,
1946 struct dcesrv_call_state
*call
,
1947 ndr_flags_type flags
)
1949 const char *dump_dir
= lpcfg_parm_string(call
->conn
->dce_ctx
->lp_ctx
,
1951 "dcesrv", "fuzz directory");
1953 dcerpc_save_ndr_fuzz_seed(call
,
1956 call
->context
->iface
->name
,
1958 call
->pkt
.u
.request
.opnum
,
1959 call
->ndr_pull
->flags
& LIBNDR_FLAG_NDR64
);
1961 #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1964 static NTSTATUS
dcesrv_check_verification_trailer(struct dcesrv_call_state
*call
)
1966 TALLOC_CTX
*frame
= talloc_stackframe();
1967 const uint32_t bitmask1
= call
->conn
->client_hdr_signing
?
1968 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
: 0;
1969 const struct dcerpc_sec_vt_pcontext pcontext
= {
1970 .abstract_syntax
= call
->context
->iface
->syntax_id
,
1971 .transfer_syntax
= call
->context
->transfer_syntax
,
1973 const struct dcerpc_sec_vt_header2 header2
=
1974 dcerpc_sec_vt_header2_from_ncacn_packet(&call
->pkt
);
1975 enum ndr_err_code ndr_err
;
1976 struct dcerpc_sec_verification_trailer
*vt
= NULL
;
1977 NTSTATUS status
= NT_STATUS_OK
;
1980 SMB_ASSERT(call
->pkt
.ptype
== DCERPC_PKT_REQUEST
);
1982 ndr_err
= ndr_pop_dcerpc_sec_verification_trailer(call
->ndr_pull
,
1984 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1985 status
= ndr_map_error2ntstatus(ndr_err
);
1989 ok
= dcerpc_sec_verification_trailer_check(vt
, &bitmask1
,
1990 &pcontext
, &header2
);
1992 status
= NT_STATUS_ACCESS_DENIED
;
2001 handle a dcerpc request packet
2003 static NTSTATUS
dcesrv_request(struct dcesrv_call_state
*call
)
2005 const struct dcesrv_endpoint
*endpoint
= call
->conn
->endpoint
;
2006 struct dcesrv_auth
*auth
= call
->auth_state
;
2007 enum dcerpc_transport_t transport
=
2008 dcerpc_binding_get_transport(endpoint
->ep_description
);
2009 struct ndr_pull
*pull
;
2010 bool turn_winbind_on
= false;
2013 if (auth
->auth_invalid
) {
2014 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
2017 if (!auth
->auth_finished
) {
2018 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
2021 /* if authenticated, and the mech we use can't do async replies, don't use them... */
2022 if (auth
->gensec_security
!= NULL
&&
2023 !gensec_have_feature(auth
->gensec_security
, GENSEC_FEATURE_ASYNC_REPLIES
)) {
2024 call
->state_flags
&= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC
;
2027 if (call
->context
== NULL
) {
2028 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
2029 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2032 switch (auth
->auth_level
) {
2033 case DCERPC_AUTH_LEVEL_NONE
:
2034 case DCERPC_AUTH_LEVEL_PACKET
:
2035 case DCERPC_AUTH_LEVEL_INTEGRITY
:
2036 case DCERPC_AUTH_LEVEL_PRIVACY
:
2039 if (!call
->context
->allow_connect
) {
2042 addr
= tsocket_address_string(call
->conn
->remote_address
,
2045 DEBUG(2, ("%s: restrict auth_level_connect access "
2046 "to [%s] with auth[type=0x%x,level=0x%x] "
2047 "on [%s] from [%s]\n",
2048 __func__
, call
->context
->iface
->name
,
2051 derpc_transport_string_by_transport(transport
),
2053 if (!call
->conn
->got_explicit_auth_level_non_connect
) {
2055 * If there was is no auth context with
2056 * a level higher than DCERPC_AUTH_LEVEL_CONNECT,
2057 * the connection should be disconnected
2058 * after sending the fault.
2060 return dcesrv_fault_disconnect0(call
,
2061 DCERPC_FAULT_ACCESS_DENIED
);
2063 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
2068 if (auth
->auth_level
< call
->context
->min_auth_level
) {
2071 addr
= tsocket_address_string(call
->conn
->remote_address
, call
);
2073 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
2074 "to [%s] with auth[type=0x%x,level=0x%x] "
2075 "on [%s] from [%s]\n",
2077 call
->context
->min_auth_level
,
2078 call
->context
->iface
->name
,
2081 derpc_transport_string_by_transport(transport
),
2083 if (!call
->conn
->got_explicit_auth_level_non_connect
) {
2085 * If there was is no auth context with
2086 * a level higher than DCERPC_AUTH_LEVEL_CONNECT,
2087 * the connection should be disconnected
2088 * after sending the fault.
2090 return dcesrv_fault_disconnect0(call
,
2091 DCERPC_FAULT_ACCESS_DENIED
);
2093 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
2096 pull
= ndr_pull_init_blob(&call
->pkt
.u
.request
.stub_and_verifier
, call
);
2097 NT_STATUS_HAVE_NO_MEMORY(pull
);
2099 pull
->flags
|= LIBNDR_FLAG_REF_ALLOC
;
2101 call
->ndr_pull
= pull
;
2103 if (!(call
->pkt
.drep
[0] & DCERPC_DREP_LE
)) {
2104 pull
->flags
|= LIBNDR_FLAG_BIGENDIAN
;
2107 status
= dcesrv_check_verification_trailer(call
);
2108 if (!NT_STATUS_IS_OK(status
)) {
2109 uint32_t faultcode
= DCERPC_FAULT_OTHER
;
2110 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2111 faultcode
= DCERPC_FAULT_ACCESS_DENIED
;
2113 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
2114 nt_errstr(status
)));
2115 return dcesrv_fault(call
, faultcode
);
2118 if (call
->context
->ndr64
) {
2119 call
->ndr_pull
->flags
|= LIBNDR_FLAG_NDR64
;
2122 /* unravel the NDR for the packet */
2123 status
= call
->context
->iface
->ndr_pull(call
, call
, pull
, &call
->r
);
2124 if (!NT_STATUS_IS_OK(status
)) {
2125 uint8_t extra_flags
= 0;
2126 if (call
->fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
2127 /* we got an unknown call */
2128 DEBUG(3,(__location__
": Unknown RPC call %"PRIu16
" on %s\n",
2129 call
->pkt
.u
.request
.opnum
,
2130 call
->context
->iface
->name
));
2131 dcesrv_save_call(call
, "unknown");
2132 extra_flags
|= DCERPC_PFC_FLAG_DID_NOT_EXECUTE
;
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: %"PRIu32
" extra bytes in incoming RPC request\n",
2147 pull
->data_size
- pull
->offset
));
2150 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_WINBIND_OFF
) {
2151 bool winbind_active
= !winbind_env_set();
2152 if (winbind_active
) {
2153 DBG_DEBUG("turning winbind off\n");
2154 (void)winbind_off();
2155 turn_winbind_on
= true;
2159 /* call the dispatch function */
2160 status
= call
->context
->iface
->dispatch(call
, call
, call
->r
);
2162 if (turn_winbind_on
) {
2163 DBG_DEBUG("turning winbind on\n");
2167 if (!NT_STATUS_IS_OK(status
)) {
2168 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
2169 call
->context
->iface
->name
,
2170 call
->pkt
.u
.request
.opnum
,
2171 dcerpc_errstr(pull
, call
->fault_code
)));
2172 return dcesrv_fault(call
, call
->fault_code
);
2175 /* add the call to the pending list */
2176 dcesrv_call_set_list(call
, DCESRV_LIST_PENDING_CALL_LIST
);
2178 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
) {
2179 return NT_STATUS_OK
;
2182 return dcesrv_reply(call
);
2187 remove the call from the right list when freed
2189 static int dcesrv_call_dequeue(struct dcesrv_call_state
*call
)
2191 dcesrv_call_set_list(call
, DCESRV_LIST_NONE
);
2195 _PUBLIC_
const struct tsocket_address
*dcesrv_connection_get_local_address(struct dcesrv_connection
*conn
)
2197 return conn
->local_address
;
2200 _PUBLIC_
const struct tsocket_address
*dcesrv_connection_get_remote_address(struct dcesrv_connection
*conn
)
2202 return conn
->remote_address
;
2206 process some input to a dcerpc endpoint server.
2208 static NTSTATUS
dcesrv_process_ncacn_packet(struct dcesrv_connection
*dce_conn
,
2209 struct ncacn_packet
*pkt
,
2213 struct dcesrv_call_state
*call
;
2214 struct dcesrv_call_state
*existing
= NULL
;
2215 size_t num_auth_ctx
= 0;
2216 enum dcerpc_AuthType auth_type
= 0;
2217 enum dcerpc_AuthLevel auth_level
= 0;
2218 uint32_t auth_context_id
= 0;
2219 bool auth_invalid
= false;
2221 call
= talloc_zero(dce_conn
, struct dcesrv_call_state
);
2223 data_blob_free(&blob
);
2225 return NT_STATUS_NO_MEMORY
;
2227 call
->conn
= dce_conn
;
2228 call
->event_ctx
= dce_conn
->event_ctx
;
2229 call
->state_flags
= call
->conn
->state_flags
;
2230 call
->time
= timeval_current();
2231 call
->list
= DCESRV_LIST_NONE
;
2233 talloc_steal(call
, pkt
);
2234 talloc_steal(call
, blob
.data
);
2237 if (dce_conn
->max_auth_states
== 0) {
2238 call
->auth_state
= dce_conn
->default_auth_state
;
2239 } else if (call
->pkt
.auth_length
== 0) {
2240 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
&&
2241 dce_conn
->default_auth_level_connect
!= NULL
)
2243 call
->auth_state
= dce_conn
->default_auth_level_connect
;
2245 call
->auth_state
= dce_conn
->default_auth_state
;
2249 if (call
->auth_state
== NULL
) {
2250 struct dcesrv_auth
*a
= NULL
;
2251 bool check_type_level
= true;
2253 auth_type
= dcerpc_get_auth_type(&blob
);
2254 auth_level
= dcerpc_get_auth_level(&blob
);
2255 auth_context_id
= dcerpc_get_auth_context_id(&blob
);
2257 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2258 if (!(call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_FIRST
)) {
2259 check_type_level
= false;
2261 dce_conn
->default_auth_level_connect
= NULL
;
2262 if (auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
2263 dce_conn
->got_explicit_auth_level_connect
= true;
2264 } else if (auth_level
>= DCERPC_AUTH_LEVEL_PACKET
) {
2265 dce_conn
->got_explicit_auth_level_non_connect
= true;
2269 for (a
= dce_conn
->auth_states
; a
!= NULL
; a
= a
->next
) {
2272 if (a
->auth_context_id
!= auth_context_id
) {
2276 if (a
->auth_type
!= auth_type
) {
2277 auth_invalid
= true;
2279 if (a
->auth_level
!= auth_level
) {
2280 auth_invalid
= true;
2283 if (check_type_level
&& auth_invalid
) {
2284 a
->auth_invalid
= true;
2287 DLIST_PROMOTE(dce_conn
->auth_states
, a
);
2288 call
->auth_state
= a
;
2293 if (call
->auth_state
== NULL
) {
2294 struct dcesrv_auth
*a
= NULL
;
2296 if (num_auth_ctx
>= dce_conn
->max_auth_states
) {
2297 return dcesrv_fault_disconnect(call
,
2298 DCERPC_NCA_S_PROTO_ERROR
);
2301 a
= dcesrv_auth_create(dce_conn
);
2304 return NT_STATUS_NO_MEMORY
;
2306 DLIST_ADD(dce_conn
->auth_states
, a
);
2307 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2309 * This can never be valid.
2311 auth_invalid
= true;
2312 a
->auth_invalid
= true;
2314 call
->auth_state
= a
;
2317 talloc_set_destructor(call
, dcesrv_call_dequeue
);
2319 if (call
->conn
->allow_bind
) {
2321 * Only one bind is possible per connection
2323 call
->conn
->allow_bind
= false;
2324 return dcesrv_bind(call
);
2327 /* we have to check the signing here, before combining the
2329 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2330 dcesrv_default_auth_state_prepare_request(call
);
2332 if (call
->auth_state
->auth_started
&&
2333 !call
->auth_state
->auth_invalid
&&
2334 !call
->auth_state
->auth_finished
) {
2336 * We have this check here instead of
2337 * relying on the check in dcesrv_auth_pkt_pull()
2338 * because the fault should have context_id=0
2340 return dcesrv_fault_disconnect(call
,
2341 DCERPC_NCA_S_PROTO_ERROR
);
2344 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
2346 call
->pkt
.u
.request
.stub_and_verifier
.length
,
2347 0, /* required_flags */
2348 DCERPC_PFC_FLAG_FIRST
|
2349 DCERPC_PFC_FLAG_LAST
|
2350 DCERPC_PFC_FLAG_PENDING_CANCEL
|
2351 0x08 | /* this is not defined, but should be ignored */
2352 DCERPC_PFC_FLAG_CONC_MPX
|
2353 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
2354 DCERPC_PFC_FLAG_MAYBE
|
2355 DCERPC_PFC_FLAG_OBJECT_UUID
);
2356 if (!NT_STATUS_IS_OK(status
)) {
2357 return dcesrv_fault_disconnect(call
,
2358 DCERPC_NCA_S_PROTO_ERROR
);
2361 if (call
->pkt
.frag_length
> call
->conn
->transport_max_recv_frag
) {
2363 * We don't use dcesrv_fault_disconnect()
2364 * here, because we don't want to set
2365 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2367 * Note that we don't check against the negotiated
2368 * max_recv_frag, but a hard coded value from
2371 return dcesrv_fault_disconnect0(call
, DCERPC_NCA_S_PROTO_ERROR
);
2374 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_FIRST
) {
2375 if (dce_conn
->pending_call_list
!= NULL
) {
2377 * concurrent requests are only allowed
2378 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2380 if (!(dce_conn
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
2381 return dcesrv_fault_disconnect0(call
,
2382 DCERPC_NCA_S_PROTO_ERROR
);
2385 /* only one request is possible in the fragmented list */
2386 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
2387 call
->fault_code
= DCERPC_NCA_S_PROTO_ERROR
;
2389 existing
= dcesrv_find_fragmented_call(dce_conn
,
2391 if (existing
!= NULL
&& call
->auth_state
!= existing
->auth_state
) {
2392 call
->context
= dcesrv_find_context(call
->conn
,
2393 call
->pkt
.u
.request
.context_id
);
2395 if (call
->pkt
.auth_length
!= 0 && existing
->context
== call
->context
) {
2396 call
->fault_code
= DCERPC_FAULT_SEC_PKG_ERROR
;
2399 if (!(dce_conn
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
2401 * Without DCERPC_PFC_FLAG_CONC_MPX
2402 * we need to return the FAULT on the
2403 * already existing call.
2405 * This is important to get the
2406 * call_id and context_id right.
2408 dce_conn
->incoming_fragmented_call_list
->fault_code
= call
->fault_code
;
2410 call
= dce_conn
->incoming_fragmented_call_list
;
2412 if (existing
!= NULL
) {
2413 call
->context
= existing
->context
;
2415 return dcesrv_fault_disconnect0(call
, call
->fault_code
);
2417 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_PENDING_CANCEL
) {
2418 return dcesrv_fault_disconnect(call
,
2419 DCERPC_FAULT_NO_CALL_ACTIVE
);
2421 call
->context
= dcesrv_find_context(call
->conn
,
2422 call
->pkt
.u
.request
.context_id
);
2423 if (call
->context
== NULL
) {
2424 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
2425 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2430 existing
= dcesrv_find_fragmented_call(dce_conn
,
2432 if (existing
== NULL
) {
2433 if (!(dce_conn
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
2435 * Without DCERPC_PFC_FLAG_CONC_MPX
2436 * we need to return the FAULT on the
2437 * already existing call.
2439 * This is important to get the
2440 * call_id and context_id right.
2442 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
2444 call
= dce_conn
->incoming_fragmented_call_list
;
2446 return dcesrv_fault_disconnect0(call
,
2447 DCERPC_NCA_S_PROTO_ERROR
);
2449 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
2450 return dcesrv_fault_disconnect0(call
, DCERPC_NCA_S_PROTO_ERROR
);
2452 call
->context
= dcesrv_find_context(call
->conn
,
2453 call
->pkt
.u
.request
.context_id
);
2454 if (call
->context
== NULL
) {
2455 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
2456 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2459 return dcesrv_fault_disconnect0(call
,
2460 DCERPC_FAULT_ACCESS_DENIED
);
2462 return dcesrv_fault_disconnect0(call
,
2463 DCERPC_NCA_S_PROTO_ERROR
);
2466 if (call
->pkt
.ptype
!= existing
->pkt
.ptype
) {
2467 /* trying to play silly buggers are we? */
2468 return dcesrv_fault_disconnect(existing
,
2469 DCERPC_NCA_S_PROTO_ERROR
);
2471 cmp
= memcmp(call
->pkt
.drep
, existing
->pkt
.drep
,
2474 return dcesrv_fault_disconnect(existing
,
2475 DCERPC_NCA_S_PROTO_ERROR
);
2477 call
->auth_state
= existing
->auth_state
;
2478 call
->context
= existing
->context
;
2482 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2484 uint8_t payload_offset
= DCERPC_REQUEST_LENGTH
;
2486 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_OBJECT_UUID
) {
2487 payload_offset
+= 16;
2490 ok
= dcesrv_auth_pkt_pull(call
, &blob
,
2491 0, /* required_flags */
2492 DCERPC_PFC_FLAG_FIRST
|
2493 DCERPC_PFC_FLAG_LAST
|
2494 DCERPC_PFC_FLAG_PENDING_CANCEL
|
2495 0x08 | /* this is not defined, but should be ignored */
2496 DCERPC_PFC_FLAG_CONC_MPX
|
2497 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
2498 DCERPC_PFC_FLAG_MAYBE
|
2499 DCERPC_PFC_FLAG_OBJECT_UUID
,
2501 &call
->pkt
.u
.request
.stub_and_verifier
);
2504 * We don't use dcesrv_fault_disconnect()
2505 * here, because we don't want to set
2506 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2508 if (call
->fault_code
== 0) {
2509 call
->fault_code
= DCERPC_FAULT_ACCESS_DENIED
;
2511 return dcesrv_fault_disconnect0(call
, call
->fault_code
);
2515 /* see if this is a continued packet */
2516 if (existing
!= NULL
) {
2517 struct dcerpc_request
*er
= &existing
->pkt
.u
.request
;
2518 const struct dcerpc_request
*nr
= &call
->pkt
.u
.request
;
2524 * Up to 4 MByte are allowed by all fragments
2526 available
= dce_conn
->max_total_request_size
;
2527 if (er
->stub_and_verifier
.length
> available
) {
2528 return dcesrv_fault_disconnect0(existing
,
2529 DCERPC_FAULT_ACCESS_DENIED
);
2531 available
-= er
->stub_and_verifier
.length
;
2532 if (nr
->alloc_hint
> available
) {
2533 return dcesrv_fault_disconnect0(existing
,
2534 DCERPC_FAULT_ACCESS_DENIED
);
2536 if (nr
->stub_and_verifier
.length
> available
) {
2537 return dcesrv_fault_disconnect0(existing
,
2538 DCERPC_FAULT_ACCESS_DENIED
);
2540 alloc_hint
= er
->stub_and_verifier
.length
+ nr
->alloc_hint
;
2541 /* allocate at least 1 byte */
2542 alloc_hint
= MAX(alloc_hint
, 1);
2543 alloc_size
= er
->stub_and_verifier
.length
+
2544 nr
->stub_and_verifier
.length
;
2545 alloc_size
= MAX(alloc_size
, alloc_hint
);
2547 er
->stub_and_verifier
.data
=
2548 talloc_realloc(existing
,
2549 er
->stub_and_verifier
.data
,
2550 uint8_t, alloc_size
);
2551 if (er
->stub_and_verifier
.data
== NULL
) {
2553 return dcesrv_fault_with_flags(existing
,
2554 DCERPC_FAULT_OUT_OF_RESOURCES
,
2555 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2557 memcpy(er
->stub_and_verifier
.data
+
2558 er
->stub_and_verifier
.length
,
2559 nr
->stub_and_verifier
.data
,
2560 nr
->stub_and_verifier
.length
);
2561 er
->stub_and_verifier
.length
+= nr
->stub_and_verifier
.length
;
2563 existing
->pkt
.pfc_flags
|= (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_LAST
);
2569 /* this may not be the last pdu in the chain - if its isn't then
2570 just put it on the incoming_fragmented_call_list and wait for the rest */
2571 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
&&
2572 !(call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
2574 * Up to 4 MByte are allowed by all fragments
2576 if (call
->pkt
.u
.request
.alloc_hint
> dce_conn
->max_total_request_size
) {
2577 return dcesrv_fault_disconnect0(call
,
2578 DCERPC_FAULT_ACCESS_DENIED
);
2580 dcesrv_call_set_list(call
, DCESRV_LIST_FRAGMENTED_CALL_LIST
);
2581 return NT_STATUS_OK
;
2584 /* This removes any fragments we may have had stashed away */
2585 dcesrv_call_set_list(call
, DCESRV_LIST_NONE
);
2587 switch (call
->pkt
.ptype
) {
2588 case DCERPC_PKT_BIND
:
2589 status
= dcesrv_bind_nak(call
,
2590 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED
);
2592 case DCERPC_PKT_AUTH3
:
2593 status
= dcesrv_auth3(call
);
2595 case DCERPC_PKT_ALTER
:
2596 status
= dcesrv_alter(call
);
2598 case DCERPC_PKT_REQUEST
:
2599 status
= dcesrv_request(call
);
2601 case DCERPC_PKT_CO_CANCEL
:
2602 existing
= dcesrv_find_fragmented_call(dce_conn
,
2604 if (existing
!= NULL
) {
2606 * If the call is still waiting for
2607 * more fragments, it's not pending yet,
2608 * for now we just remember we got CO_CANCEL,
2609 * but ignore it otherwise.
2611 * This matches what windows is doing...
2613 existing
->got_co_cancel
= true;
2614 SMB_ASSERT(existing
->subreq
== NULL
);
2617 existing
= dcesrv_find_pending_call(dce_conn
,
2619 if (existing
!= NULL
) {
2621 * Give the backend a chance to react
2622 * on CO_CANCEL, but note it's ignored
2625 existing
->got_co_cancel
= true;
2626 if (existing
->subreq
!= NULL
) {
2627 tevent_req_cancel(existing
->subreq
);
2631 status
= NT_STATUS_OK
;
2634 case DCERPC_PKT_ORPHANED
:
2635 existing
= dcesrv_find_fragmented_call(dce_conn
,
2637 if (existing
!= NULL
) {
2639 * If the call is still waiting for
2640 * more fragments, it's not pending yet,
2641 * for now we just remember we got ORPHANED,
2642 * but ignore it otherwise.
2644 * This matches what windows is doing...
2646 existing
->got_orphaned
= true;
2647 SMB_ASSERT(existing
->subreq
== NULL
);
2650 existing
= dcesrv_find_pending_call(dce_conn
,
2652 if (existing
!= NULL
) {
2654 * Give the backend a chance to react
2655 * on ORPHANED, but note it's ignored
2658 existing
->got_orphaned
= true;
2659 if (existing
->subreq
!= NULL
) {
2660 tevent_req_cancel(existing
->subreq
);
2664 status
= NT_STATUS_OK
;
2667 case DCERPC_PKT_BIND_ACK
:
2668 case DCERPC_PKT_BIND_NAK
:
2669 case DCERPC_PKT_ALTER_RESP
:
2670 case DCERPC_PKT_RESPONSE
:
2671 case DCERPC_PKT_FAULT
:
2672 case DCERPC_PKT_SHUTDOWN
:
2674 status
= dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
2678 /* if we are going to be sending a reply then add
2679 it to the list of pending calls. We add it to the end to keep the call
2680 list in the order we will answer */
2681 if (!NT_STATUS_IS_OK(status
)) {
2688 _PUBLIC_ NTSTATUS
dcesrv_init_context(TALLOC_CTX
*mem_ctx
,
2689 struct loadparm_context
*lp_ctx
,
2690 struct dcesrv_context_callbacks
*cb
,
2691 struct dcesrv_context
**_dce_ctx
)
2693 struct dcesrv_context
*dce_ctx
;
2696 return NT_STATUS_INVALID_PARAMETER
;
2699 dce_ctx
= talloc_zero(mem_ctx
, struct dcesrv_context
);
2700 NT_STATUS_HAVE_NO_MEMORY(dce_ctx
);
2702 if (uid_wrapper_enabled()) {
2703 setenv("UID_WRAPPER_MYUID", "1", 1);
2705 dce_ctx
->initial_euid
= geteuid();
2706 if (uid_wrapper_enabled()) {
2707 unsetenv("UID_WRAPPER_MYUID");
2710 dce_ctx
->endpoint_list
= NULL
;
2711 dce_ctx
->lp_ctx
= lp_ctx
;
2712 dce_ctx
->assoc_groups_idr
= idr_init(dce_ctx
);
2713 if (dce_ctx
->assoc_groups_idr
== NULL
) {
2714 TALLOC_FREE(dce_ctx
);
2715 return NT_STATUS_NO_MEMORY
;
2717 dce_ctx
->broken_connections
= NULL
;
2718 dce_ctx
->callbacks
= cb
;
2721 * For now we only support NDR32.
2723 dce_ctx
->preferred_transfer
= &ndr_transfer_syntax_ndr
;
2725 *_dce_ctx
= dce_ctx
;
2726 return NT_STATUS_OK
;
2730 * @brief Set callback functions on an existing dcesrv_context
2732 * This allows to reset callbacks initially set via
2733 * dcesrv_init_context()
2735 * @param[in] dce_ctx The context to set the callbacks on
2736 * @param[in] cb The callbacks to set on dce_ctx
2738 _PUBLIC_
void dcesrv_context_set_callbacks(
2739 struct dcesrv_context
*dce_ctx
,
2740 struct dcesrv_context_callbacks
*cb
)
2742 dce_ctx
->callbacks
= cb
;
2745 _PUBLIC_ NTSTATUS
dcesrv_init_ep_servers(struct dcesrv_context
*dce_ctx
,
2746 const char **endpoint_servers
)
2751 if (endpoint_servers
== NULL
) {
2752 DBG_ERR("No endpoint servers configured\n");
2753 return NT_STATUS_INTERNAL_ERROR
;
2756 for (i
=0;endpoint_servers
[i
];i
++) {
2757 status
= dcesrv_init_ep_server(dce_ctx
, endpoint_servers
[i
]);
2758 if (!NT_STATUS_IS_OK(status
)) {
2759 DBG_ERR("failed to init endpoint server = '%s': %s\n",
2760 endpoint_servers
[i
], nt_errstr(status
));
2765 return NT_STATUS_OK
;
2768 /* the list of currently registered DCERPC endpoint servers.
2770 static struct ep_server
{
2771 struct dcesrv_endpoint_server
*ep_server
;
2772 } *ep_servers
= NULL
;
2773 static int num_ep_servers
= 0;
2775 _PUBLIC_ NTSTATUS
dcesrv_init_registered_ep_servers(
2776 struct dcesrv_context
*dce_ctx
)
2781 for (i
= 0; i
< num_ep_servers
; i
++) {
2782 status
= dcesrv_init_ep_server(dce_ctx
,
2783 ep_servers
[i
].ep_server
->name
);
2784 if (!NT_STATUS_IS_OK(status
)) {
2789 return NT_STATUS_OK
;
2792 _PUBLIC_ NTSTATUS
dcesrv_init_ep_server(struct dcesrv_context
*dce_ctx
,
2793 const char *ep_server_name
)
2795 struct dcesrv_endpoint_server
*ep_server
= NULL
;
2798 ep_server
= discard_const_p(struct dcesrv_endpoint_server
,
2799 dcesrv_ep_server_byname(ep_server_name
));
2800 if (ep_server
== NULL
) {
2801 DBG_ERR("Failed to find endpoint server '%s'\n",
2803 return NT_STATUS_INTERNAL_ERROR
;
2806 if (ep_server
->initialized
) {
2807 return NT_STATUS_OK
;
2810 status
= ep_server
->init_server(dce_ctx
, ep_server
);
2811 if (!NT_STATUS_IS_OK(status
)) {
2812 DBG_ERR("Failed to init endpoint server '%s': %s\n",
2813 ep_server_name
, nt_errstr(status
));
2817 ep_server
->initialized
= true;
2819 return NT_STATUS_OK
;
2822 _PUBLIC_ NTSTATUS
dcesrv_shutdown_registered_ep_servers(
2823 struct dcesrv_context
*dce_ctx
)
2828 for (i
= 0; i
< num_ep_servers
; i
++) {
2829 status
= dcesrv_shutdown_ep_server(dce_ctx
,
2830 ep_servers
[i
].ep_server
->name
);
2831 if (!NT_STATUS_IS_OK(status
)) {
2836 return NT_STATUS_OK
;
2839 _PUBLIC_ NTSTATUS
dcesrv_shutdown_ep_server(struct dcesrv_context
*dce_ctx
,
2840 const char *ep_server_name
)
2842 struct dcesrv_endpoint_server
*ep_server
= NULL
;
2845 ep_server
= discard_const_p(struct dcesrv_endpoint_server
,
2846 dcesrv_ep_server_byname(ep_server_name
));
2847 if (ep_server
== NULL
) {
2848 DBG_ERR("Failed to find endpoint server '%s'\n",
2850 return NT_STATUS_INTERNAL_ERROR
;
2853 if (!ep_server
->initialized
) {
2854 return NT_STATUS_OK
;
2857 DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2860 status
= ep_server
->shutdown_server(dce_ctx
, ep_server
);
2861 if (!NT_STATUS_IS_OK(status
)) {
2862 DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2863 ep_server_name
, nt_errstr(status
));
2867 ep_server
->initialized
= false;
2869 return NT_STATUS_OK
;
2873 register a DCERPC endpoint server.
2875 The 'name' can be later used by other backends to find the operations
2876 structure for this backend.
2879 _PUBLIC_ NTSTATUS
dcerpc_register_ep_server(const struct dcesrv_endpoint_server
*ep_server
)
2882 if (dcesrv_ep_server_byname(ep_server
->name
) != NULL
) {
2883 /* its already registered! */
2884 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2886 return NT_STATUS_OBJECT_NAME_COLLISION
;
2889 ep_servers
= realloc_p(ep_servers
, struct ep_server
, num_ep_servers
+1);
2891 smb_panic("out of memory in dcerpc_register");
2894 ep_servers
[num_ep_servers
].ep_server
= smb_xmemdup(ep_server
, sizeof(*ep_server
));
2895 ep_servers
[num_ep_servers
].ep_server
->name
= smb_xstrdup(ep_server
->name
);
2899 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2902 return NT_STATUS_OK
;
2906 return the operations structure for a named backend of the specified type
2908 _PUBLIC_
const struct dcesrv_endpoint_server
*dcesrv_ep_server_byname(const char *name
)
2912 for (i
=0;i
<num_ep_servers
;i
++) {
2913 if (strcmp(ep_servers
[i
].ep_server
->name
, name
) == 0) {
2914 return ep_servers
[i
].ep_server
;
2922 return the DCERPC module version, and the size of some critical types
2923 This can be used by endpoint server modules to either detect compilation errors, or provide
2924 multiple implementations for different smbd compilation options in one module
2926 const struct dcesrv_critical_sizes
*dcerpc_module_version(void)
2928 static const struct dcesrv_critical_sizes critical_sizes
= {
2929 DCERPC_MODULE_VERSION
,
2930 sizeof(struct dcesrv_context
),
2931 sizeof(struct dcesrv_endpoint
),
2932 sizeof(struct dcesrv_endpoint_server
),
2933 sizeof(struct dcesrv_interface
),
2934 sizeof(struct dcesrv_if_list
),
2935 sizeof(struct dcesrv_connection
),
2936 sizeof(struct dcesrv_call_state
),
2937 sizeof(struct dcesrv_auth
),
2938 sizeof(struct dcesrv_handle
)
2941 return &critical_sizes
;
2944 _PUBLIC_
void dcesrv_terminate_connection(struct dcesrv_connection
*dce_conn
, const char *reason
)
2946 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
2947 struct dcesrv_call_state
*c
= NULL
, *n
= NULL
;
2948 struct dcesrv_auth
*a
= NULL
;
2950 dce_conn
->wait_send
= NULL
;
2951 dce_conn
->wait_recv
= NULL
;
2952 dce_conn
->wait_private
= NULL
;
2954 dce_conn
->allow_bind
= false;
2955 dce_conn
->allow_alter
= false;
2957 dce_conn
->default_auth_state
->auth_invalid
= true;
2959 for (a
= dce_conn
->auth_states
; a
!= NULL
; a
= a
->next
) {
2960 a
->auth_invalid
= true;
2964 if (dce_conn
->pending_call_list
== NULL
) {
2965 char *full_reason
= talloc_asprintf(dce_conn
, "dcesrv: %s", reason
);
2967 DLIST_REMOVE(dce_ctx
->broken_connections
, dce_conn
);
2968 dce_conn
->transport
.terminate_connection(dce_conn
,
2969 full_reason
? full_reason
: reason
);
2973 if (dce_conn
->terminate
!= NULL
) {
2977 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2979 dce_conn
->terminate
= talloc_strdup(dce_conn
, reason
);
2980 if (dce_conn
->terminate
== NULL
) {
2981 dce_conn
->terminate
= "dcesrv: deferred terminating connection - no memory";
2983 DLIST_ADD_END(dce_ctx
->broken_connections
, dce_conn
);
2985 for (c
= dce_conn
->pending_call_list
; c
!= NULL
; c
= n
) {
2988 c
->got_disconnect
= true;
2989 if (c
->subreq
!= NULL
) {
2990 tevent_req_cancel(c
->subreq
);
2994 if (dce_conn
->pending_call_list
== NULL
) {
2996 * tevent_req_cancel() was able to made progress
2997 * and we don't have pending calls anymore.
3003 _PUBLIC_
void dcesrv_cleanup_broken_connections(struct dcesrv_context
*dce_ctx
)
3005 struct dcesrv_connection
*cur
, *next
;
3007 next
= dce_ctx
->broken_connections
;
3008 while (next
!= NULL
) {
3012 if (cur
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
3013 struct dcesrv_connection_context
*context_cur
, *context_next
;
3015 context_next
= cur
->contexts
;
3016 while (context_next
!= NULL
) {
3017 context_cur
= context_next
;
3018 context_next
= context_cur
->next
;
3020 dcesrv_connection_context_destructor(context_cur
);
3024 dcesrv_terminate_connection(cur
, cur
->terminate
);
3028 struct dcesrv_sock_reply_state
{
3029 struct dcesrv_connection
*dce_conn
;
3030 struct dcesrv_call_state
*call
;
3034 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
);
3035 static void dcesrv_call_terminate_step1(struct tevent_req
*subreq
);
3037 _PUBLIC_
void dcesrv_sock_report_output_data(struct dcesrv_connection
*dce_conn
)
3039 struct dcesrv_call_state
*call
;
3041 call
= dce_conn
->call_list
;
3042 if (!call
|| !call
->replies
) {
3046 while (call
->replies
) {
3047 struct data_blob_list_item
*rep
= call
->replies
;
3048 struct dcesrv_sock_reply_state
*substate
;
3049 struct tevent_req
*subreq
;
3051 substate
= talloc_zero(call
, struct dcesrv_sock_reply_state
);
3053 dcesrv_terminate_connection(dce_conn
, "no memory");
3057 substate
->dce_conn
= dce_conn
;
3058 substate
->call
= NULL
;
3060 DLIST_REMOVE(call
->replies
, rep
);
3062 if (call
->replies
== NULL
&& call
->terminate_reason
== NULL
) {
3063 substate
->call
= call
;
3066 substate
->iov
.iov_base
= (void *) rep
->blob
.data
;
3067 substate
->iov
.iov_len
= rep
->blob
.length
;
3069 subreq
= tstream_writev_queue_send(substate
,
3070 dce_conn
->event_ctx
,
3072 dce_conn
->send_queue
,
3075 dcesrv_terminate_connection(dce_conn
, "no memory");
3078 tevent_req_set_callback(subreq
, dcesrv_sock_reply_done
,
3082 if (call
->terminate_reason
!= NULL
) {
3083 struct tevent_req
*subreq
;
3085 subreq
= tevent_queue_wait_send(call
,
3086 dce_conn
->event_ctx
,
3087 dce_conn
->send_queue
);
3089 dcesrv_terminate_connection(dce_conn
, __location__
);
3092 tevent_req_set_callback(subreq
, dcesrv_call_terminate_step1
,
3096 DLIST_REMOVE(call
->conn
->call_list
, call
);
3097 call
->list
= DCESRV_LIST_NONE
;
3100 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
)
3102 struct dcesrv_sock_reply_state
*substate
= tevent_req_callback_data(subreq
,
3103 struct dcesrv_sock_reply_state
);
3107 struct dcesrv_call_state
*call
= substate
->call
;
3109 ret
= tstream_writev_queue_recv(subreq
, &sys_errno
);
3110 TALLOC_FREE(subreq
);
3112 status
= map_nt_error_from_unix_common(sys_errno
);
3113 dcesrv_terminate_connection(substate
->dce_conn
, nt_errstr(status
));
3117 talloc_free(substate
);
3123 static void dcesrv_call_terminate_step2(struct tevent_req
*subreq
);
3125 static void dcesrv_call_terminate_step1(struct tevent_req
*subreq
)
3127 struct dcesrv_call_state
*call
= tevent_req_callback_data(subreq
,
3128 struct dcesrv_call_state
);
3132 /* make sure we stop send queue before removing subreq */
3133 tevent_queue_stop(call
->conn
->send_queue
);
3135 ok
= tevent_queue_wait_recv(subreq
);
3136 TALLOC_FREE(subreq
);
3138 dcesrv_terminate_connection(call
->conn
, __location__
);
3142 /* disconnect after 200 usecs */
3143 tv
= timeval_current_ofs_usec(200);
3144 subreq
= tevent_wakeup_send(call
, call
->conn
->event_ctx
, tv
);
3145 if (subreq
== NULL
) {
3146 dcesrv_terminate_connection(call
->conn
, __location__
);
3149 tevent_req_set_callback(subreq
, dcesrv_call_terminate_step2
,
3153 static void dcesrv_call_terminate_step2(struct tevent_req
*subreq
)
3155 struct dcesrv_call_state
*call
= tevent_req_callback_data(subreq
,
3156 struct dcesrv_call_state
);
3159 ok
= tevent_wakeup_recv(subreq
);
3160 TALLOC_FREE(subreq
);
3162 dcesrv_terminate_connection(call
->conn
, __location__
);
3166 dcesrv_terminate_connection(call
->conn
, call
->terminate_reason
);
3169 static void dcesrv_conn_wait_done(struct tevent_req
*subreq
);
3171 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
)
3173 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
3174 struct dcesrv_connection
);
3175 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
3176 struct ncacn_packet
*pkt
;
3180 if (dce_conn
->terminate
) {
3182 * if the current connection is broken
3183 * we need to clean it up before any other connection
3185 dcesrv_terminate_connection(dce_conn
, dce_conn
->terminate
);
3186 dcesrv_cleanup_broken_connections(dce_ctx
);
3190 dcesrv_cleanup_broken_connections(dce_ctx
);
3192 status
= dcerpc_read_ncacn_packet_recv(subreq
, dce_conn
,
3194 TALLOC_FREE(subreq
);
3195 if (!NT_STATUS_IS_OK(status
)) {
3196 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
3200 dcesrv_loop_next_packet(dce_conn
, pkt
, buffer
);
3204 * @brief Start the dcesrv loop, inducing the bind as a blob
3206 * Like dcesrv_connection_loop_start() but used from connections
3207 * where the caller has already read the dcerpc bind packet from
3208 * the socket and is available as a DATA_BLOB.
3210 * @param[in] dce_conn The connection to start
3211 * @param[in] pkt The parsed bind packet
3212 * @param[in] buffer The full binary bind including auth data
3214 void dcesrv_loop_next_packet(
3215 struct dcesrv_connection
*dce_conn
,
3216 struct ncacn_packet
*pkt
,
3219 struct tevent_req
*subreq
= NULL
;
3222 status
= dcesrv_process_ncacn_packet(dce_conn
, pkt
, buffer
);
3223 if (!NT_STATUS_IS_OK(status
)) {
3224 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
3229 * This is used to block the connection during
3230 * pending authentication.
3232 if (dce_conn
->wait_send
!= NULL
) {
3233 subreq
= dce_conn
->wait_send(dce_conn
,
3234 dce_conn
->event_ctx
,
3235 dce_conn
->wait_private
);
3237 status
= NT_STATUS_NO_MEMORY
;
3238 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
3241 tevent_req_set_callback(subreq
, dcesrv_conn_wait_done
, dce_conn
);
3245 subreq
= dcerpc_read_ncacn_packet_send(dce_conn
,
3246 dce_conn
->event_ctx
,
3249 status
= NT_STATUS_NO_MEMORY
;
3250 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
3253 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dce_conn
);
3256 static void dcesrv_conn_wait_done(struct tevent_req
*subreq
)
3258 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
3259 struct dcesrv_connection
);
3260 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
3263 if (dce_conn
->terminate
) {
3265 * if the current connection is broken
3266 * we need to clean it up before any other connection
3268 dcesrv_terminate_connection(dce_conn
, dce_conn
->terminate
);
3269 dcesrv_cleanup_broken_connections(dce_ctx
);
3273 dcesrv_cleanup_broken_connections(dce_ctx
);
3275 status
= dce_conn
->wait_recv(subreq
);
3276 dce_conn
->wait_send
= NULL
;
3277 dce_conn
->wait_recv
= NULL
;
3278 dce_conn
->wait_private
= NULL
;
3279 TALLOC_FREE(subreq
);
3280 if (!NT_STATUS_IS_OK(status
)) {
3281 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
3285 status
= dcesrv_connection_loop_start(dce_conn
);
3286 if (!NT_STATUS_IS_OK(status
)) {
3287 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
3293 * retrieve credentials from a dce_call
3295 _PUBLIC_
struct cli_credentials
*dcesrv_call_credentials(struct dcesrv_call_state
*dce_call
)
3297 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3298 SMB_ASSERT(auth
->auth_finished
);
3299 return auth
->session_info
->credentials
;
3303 * returns true if this is an authenticated call
3305 _PUBLIC_
bool dcesrv_call_authenticated(struct dcesrv_call_state
*dce_call
)
3307 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3308 enum security_user_level level
;
3309 SMB_ASSERT(auth
->auth_finished
);
3310 level
= security_session_user_level(auth
->session_info
, NULL
);
3311 return level
>= SECURITY_USER
;
3315 * retrieve account_name for a dce_call
3317 _PUBLIC_
const char *dcesrv_call_account_name(struct dcesrv_call_state
*dce_call
)
3319 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3320 SMB_ASSERT(auth
->auth_finished
);
3321 return auth
->session_info
->info
->account_name
;
3325 * retrieve session_info from a dce_call
3327 _PUBLIC_
struct auth_session_info
*dcesrv_call_session_info(struct dcesrv_call_state
*dce_call
)
3329 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3330 SMB_ASSERT(auth
->auth_finished
);
3331 return auth
->session_info
;
3335 * retrieve auth type/level from a dce_call
3337 _PUBLIC_
void dcesrv_call_auth_info(struct dcesrv_call_state
*dce_call
,
3338 enum dcerpc_AuthType
*auth_type
,
3339 enum dcerpc_AuthLevel
*auth_level
)
3341 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3343 SMB_ASSERT(auth
->auth_finished
);
3345 if (auth_type
!= NULL
) {
3346 *auth_type
= auth
->auth_type
;
3348 if (auth_level
!= NULL
) {
3349 *auth_level
= auth
->auth_level
;
3353 _PUBLIC_ NTSTATUS
dcesrv_connection_loop_start(struct dcesrv_connection
*conn
)
3355 struct tevent_req
*subreq
;
3357 subreq
= dcerpc_read_ncacn_packet_send(conn
,
3360 if (subreq
== NULL
) {
3361 return NT_STATUS_NO_MEMORY
;
3363 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, conn
);
3365 return NT_STATUS_OK
;
3368 _PUBLIC_ NTSTATUS
dcesrv_call_dispatch_local(struct dcesrv_call_state
*call
)
3371 struct ndr_pull
*pull
= NULL
;
3372 struct ndr_push
*push
= NULL
;
3373 struct data_blob_list_item
*rep
= NULL
;
3375 pull
= ndr_pull_init_blob(&call
->pkt
.u
.request
.stub_and_verifier
,
3378 return NT_STATUS_NO_MEMORY
;
3381 pull
->flags
|= LIBNDR_FLAG_REF_ALLOC
;
3383 call
->ndr_pull
= pull
;
3385 /* unravel the NDR for the packet */
3386 status
= call
->context
->iface
->ndr_pull(call
, call
, pull
, &call
->r
);
3387 if (!NT_STATUS_IS_OK(status
)) {
3388 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3389 call
->context
->iface
->name
,
3390 call
->pkt
.u
.request
.opnum
,
3391 dcerpc_errstr(call
, call
->fault_code
));
3392 return dcerpc_fault_to_nt_status(call
->fault_code
);
3395 status
= call
->context
->iface
->local(call
, call
, call
->r
);
3396 if (!NT_STATUS_IS_OK(status
)) {
3397 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3398 call
->context
->iface
->name
,
3399 call
->pkt
.u
.request
.opnum
,
3400 dcerpc_errstr(call
, call
->fault_code
));
3401 return dcerpc_fault_to_nt_status(call
->fault_code
);
3404 /* This can never go async for now! */
3405 SMB_ASSERT(!(call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
));
3407 /* call the reply function */
3408 status
= call
->context
->iface
->reply(call
, call
, call
->r
);
3409 if (!NT_STATUS_IS_OK(status
)) {
3410 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3411 call
->context
->iface
->name
,
3412 call
->pkt
.u
.request
.opnum
,
3413 dcerpc_errstr(call
, call
->fault_code
));
3414 return dcerpc_fault_to_nt_status(call
->fault_code
);
3417 push
= ndr_push_init_ctx(call
);
3419 return NT_STATUS_NO_MEMORY
;
3422 push
->ptr_count
= call
->ndr_pull
->ptr_count
;
3424 status
= call
->context
->iface
->ndr_push(call
, call
, push
, call
->r
);
3425 if (!NT_STATUS_IS_OK(status
)) {
3426 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3427 call
->context
->iface
->name
,
3428 call
->pkt
.u
.request
.opnum
,
3429 dcerpc_errstr(call
, call
->fault_code
));
3430 return dcerpc_fault_to_nt_status(call
->fault_code
);
3433 rep
= talloc_zero(call
, struct data_blob_list_item
);
3435 return NT_STATUS_NO_MEMORY
;
3438 rep
->blob
= ndr_push_blob(push
);
3439 DLIST_ADD_END(call
->replies
, rep
);
3441 return NT_STATUS_OK
;