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"
41 * @brief DCERPC server
45 #define DBGC_CLASS DBGC_RPC_SRV
49 static NTSTATUS
dcesrv_negotiate_contexts(struct dcesrv_call_state
*call
,
50 const struct dcerpc_bind
*b
,
51 struct dcerpc_ack_ctx
*ack_ctx_list
);
54 see if two endpoints match
56 static bool endpoints_match(const struct dcerpc_binding
*ep1
,
57 const struct dcerpc_binding
*ep2
)
59 enum dcerpc_transport_t t1
;
60 enum dcerpc_transport_t t2
;
64 t1
= dcerpc_binding_get_transport(ep1
);
65 t2
= dcerpc_binding_get_transport(ep2
);
67 e1
= dcerpc_binding_get_string_option(ep1
, "endpoint");
68 e2
= dcerpc_binding_get_string_option(ep2
, "endpoint");
78 if (strcasecmp(e1
, e2
) != 0) {
86 find an endpoint in the dcesrv_context
88 _PUBLIC_ NTSTATUS
dcesrv_find_endpoint(struct dcesrv_context
*dce_ctx
,
89 const struct dcerpc_binding
*ep_description
,
90 struct dcesrv_endpoint
**_out
)
92 struct dcesrv_endpoint
*ep
= NULL
;
93 for (ep
=dce_ctx
->endpoint_list
; ep
; ep
=ep
->next
) {
94 if (endpoints_match(ep
->ep_description
, ep_description
)) {
99 return NT_STATUS_NOT_FOUND
;
103 find a registered context_id from a bind or alter_context
105 static struct dcesrv_connection_context
*dcesrv_find_context(struct dcesrv_connection
*conn
,
108 struct dcesrv_connection_context
*c
;
109 for (c
=conn
->contexts
;c
;c
=c
->next
) {
110 if (c
->context_id
== context_id
) return c
;
116 find the interface operations on any endpoint with this binding
118 static const struct dcesrv_interface
*find_interface_by_binding(struct dcesrv_context
*dce_ctx
,
119 struct dcerpc_binding
*binding
,
120 const struct dcesrv_interface
*iface
)
122 struct dcesrv_endpoint
*ep
;
123 for (ep
=dce_ctx
->endpoint_list
; ep
; ep
=ep
->next
) {
124 if (endpoints_match(ep
->ep_description
, binding
)) {
125 const struct dcesrv_interface
*ret
= NULL
;
127 ret
= find_interface_by_syntax_id(
128 ep
, &iface
->syntax_id
);
138 find the interface operations on an endpoint by uuid
140 _PUBLIC_
const struct dcesrv_interface
*find_interface_by_syntax_id(
141 const struct dcesrv_endpoint
*endpoint
,
142 const struct ndr_syntax_id
*interface
)
144 struct dcesrv_if_list
*ifl
;
145 for (ifl
=endpoint
->interface_list
; ifl
; ifl
=ifl
->next
) {
146 if (ndr_syntax_id_equal(&ifl
->iface
->syntax_id
, interface
)) {
154 find the earlier parts of a fragmented call awaiting reassembly
156 static struct dcesrv_call_state
*dcesrv_find_fragmented_call(struct dcesrv_connection
*dce_conn
, uint32_t call_id
)
158 struct dcesrv_call_state
*c
;
159 for (c
=dce_conn
->incoming_fragmented_call_list
;c
;c
=c
->next
) {
160 if (c
->pkt
.call_id
== call_id
) {
168 register an interface on an endpoint
170 An endpoint is one unix domain socket (for ncalrpc), one TCP port
171 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
173 Each endpoint can have many interfaces such as netlogon, lsa or
174 samr. Some have essentially the full set.
176 This is driven from the set of interfaces listed in each IDL file
177 via the PIDL generated *__op_init_server() functions.
179 _PUBLIC_ NTSTATUS
dcesrv_interface_register(struct dcesrv_context
*dce_ctx
,
181 const char *ncacn_np_secondary_endpoint
,
182 const struct dcesrv_interface
*iface
,
183 const struct security_descriptor
*sd
)
185 struct dcerpc_binding
*binding
= NULL
;
186 struct dcerpc_binding
*binding2
= NULL
;
189 ret
= dcerpc_parse_binding(dce_ctx
, ep_name
, &binding
);
190 if (NT_STATUS_IS_ERR(ret
)) {
191 DBG_ERR("Trouble parsing binding string '%s'\n", ep_name
);
195 if (ncacn_np_secondary_endpoint
!= NULL
) {
196 ret
= dcerpc_parse_binding(dce_ctx
,
197 ncacn_np_secondary_endpoint
,
199 if (NT_STATUS_IS_ERR(ret
)) {
200 DBG_ERR("Trouble parsing 2nd binding string '%s'\n",
201 ncacn_np_secondary_endpoint
);
206 ret
= dcesrv_interface_register_b(dce_ctx
,
212 TALLOC_FREE(binding
);
213 TALLOC_FREE(binding2
);
217 _PUBLIC_ NTSTATUS
dcesrv_interface_register_b(struct dcesrv_context
*dce_ctx
,
218 struct dcerpc_binding
*binding
,
219 struct dcerpc_binding
*binding2
,
220 const struct dcesrv_interface
*iface
,
221 const struct security_descriptor
*sd
)
223 struct dcesrv_endpoint
*ep
;
224 struct dcesrv_if_list
*ifl
;
227 enum dcerpc_transport_t transport
;
228 char *ep_string
= NULL
;
229 bool use_single_process
= true;
230 const char *ep_process_string
;
233 * If we are not using handles, there is no need for force
234 * this service into using a single process.
236 * However, due to the way we listen for RPC packets, we can
237 * only do this if we have a single service per pipe or TCP
238 * port, so we still force a single combined process for
241 if (iface
->flags
& DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED
) {
242 use_single_process
= false;
245 transport
= dcerpc_binding_get_transport(binding
);
246 if (transport
== NCACN_IP_TCP
) {
250 * First check if there is already a port specified, eg
251 * for epmapper on ncacn_ip_tcp:[135]
254 = dcerpc_binding_get_string_option(binding
,
256 if (endpoint
== NULL
) {
257 port
= lpcfg_parm_int(dce_ctx
->lp_ctx
, NULL
,
258 "rpc server port", iface
->name
, 0);
261 * For RPC services that are not set to use a single
262 * process, we do not default to using the 'rpc server
263 * port' because that would cause a double-bind on
266 if (port
== 0 && !use_single_process
) {
267 port
= lpcfg_rpc_server_port(dce_ctx
->lp_ctx
);
271 snprintf(port_str
, sizeof(port_str
), "%u", port
);
272 status
= dcerpc_binding_set_string_option(binding
,
275 if (!NT_STATUS_IS_OK(status
)) {
282 if (transport
== NCACN_NP
&& binding2
!= NULL
) {
283 enum dcerpc_transport_t transport2
;
285 transport2
= dcerpc_binding_get_transport(binding2
);
286 SMB_ASSERT(transport2
== transport
);
289 /* see if the interface is already registered on the endpoint */
290 if (find_interface_by_binding(dce_ctx
, binding
, iface
)!=NULL
) {
291 char *binding_string
= dcerpc_binding_string(dce_ctx
, binding
);
292 DBG_ERR("Interface '%s' already registered on endpoint '%s'\n",
293 iface
->name
, binding_string
);
294 TALLOC_FREE(binding_string
);
295 return NT_STATUS_OBJECT_NAME_COLLISION
;
298 /* check if this endpoint exists
300 status
= dcesrv_find_endpoint(dce_ctx
, binding
, &ep
);
301 if (NT_STATUS_IS_OK(status
)) {
303 * We want a new port on ncacn_ip_tcp for NETLOGON, so
304 * it can be multi-process. Other processes can also
305 * listen on distinct ports, if they have one forced
306 * in the code above with eg 'rpc server port:drsuapi = 1027'
308 * If we have mulitiple endpoints on port 0, they each
309 * get an epemeral port (currently by walking up from
312 * Because one endpoint can only have one process
313 * model, we add a new IP_TCP endpoint for each model.
315 * This works in conjunction with the forced overwrite
316 * of ep->use_single_process below.
318 if (ep
->use_single_process
!= use_single_process
319 && transport
== NCACN_IP_TCP
) {
324 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
) || add_ep
) {
325 ep
= talloc_zero(dce_ctx
, struct dcesrv_endpoint
);
327 return NT_STATUS_NO_MEMORY
;
329 ep
->ep_description
= dcerpc_binding_dup(ep
, binding
);
330 if (transport
== NCACN_NP
&& binding2
!= NULL
) {
331 ep
->ep_2nd_description
=
332 dcerpc_binding_dup(ep
, binding2
);
336 /* add mgmt interface */
337 ifl
= talloc_zero(ep
, struct dcesrv_if_list
);
340 return NT_STATUS_NO_MEMORY
;
343 ifl
->iface
= talloc_memdup(ifl
,
344 dcesrv_get_mgmt_interface(),
345 sizeof(struct dcesrv_interface
));
346 if (ifl
->iface
== NULL
) {
348 return NT_STATUS_NO_MEMORY
;
351 DLIST_ADD(ep
->interface_list
, ifl
);
352 } else if (!NT_STATUS_IS_OK(status
)) {
353 DBG_NOTICE("Failed to find endpoint: %s\n", nt_errstr(status
));
358 * By default don't force into a single process, but if any
359 * interface on this endpoint on this service uses handles
360 * (most do), then we must force into single process mode
362 * By overwriting this each time a new interface is added to
363 * this endpoint, we end up with the most restrictive setting.
365 if (use_single_process
) {
366 ep
->use_single_process
= true;
369 /* talloc a new interface list element */
370 ifl
= talloc_zero(ep
, struct dcesrv_if_list
);
372 return NT_STATUS_NO_MEMORY
;
375 /* copy the given interface struct to the one on the endpoints interface list */
376 ifl
->iface
= talloc_memdup(ifl
,
378 sizeof(struct dcesrv_interface
));
379 if (ifl
->iface
== NULL
) {
381 return NT_STATUS_NO_MEMORY
;
384 /* if we have a security descriptor given,
385 * we should see if we can set it up on the endpoint
388 /* if there's currently no security descriptor given on the endpoint
391 if (ep
->sd
== NULL
) {
392 ep
->sd
= security_descriptor_copy(ep
, sd
);
395 /* if now there's no security descriptor given on the endpoint
396 * something goes wrong, either we failed to copy the security descriptor
397 * or there was already one on the endpoint
399 if (ep
->sd
!= NULL
) {
400 char *binding_string
=
401 dcerpc_binding_string(dce_ctx
, binding
);
402 DBG_ERR("Interface '%s' failed to setup a security "
403 "descriptor on endpoint '%s'\n",
404 iface
->name
, binding_string
);
405 TALLOC_FREE(binding_string
);
406 if (add_ep
) free(ep
);
408 return NT_STATUS_OBJECT_NAME_COLLISION
;
412 /* finally add the interface on the endpoint */
413 DLIST_ADD(ep
->interface_list
, ifl
);
415 /* if it's a new endpoint add it to the dcesrv_context */
417 DLIST_ADD(dce_ctx
->endpoint_list
, ep
);
420 /* Re-get the string as we may have set a port */
421 ep_string
= dcerpc_binding_string(dce_ctx
, ep
->ep_description
);
423 if (use_single_process
) {
424 ep_process_string
= "single process required";
426 ep_process_string
= "multi process compatible";
429 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
430 iface
->name
, ep_string
, ep_process_string
);
431 TALLOC_FREE(ep_string
);
436 static NTSTATUS
dcesrv_session_info_session_key(struct dcesrv_auth
*auth
,
437 DATA_BLOB
*session_key
)
439 if (auth
->session_info
== NULL
) {
440 return NT_STATUS_NO_USER_SESSION_KEY
;
443 if (auth
->session_info
->session_key
.length
== 0) {
444 return NT_STATUS_NO_USER_SESSION_KEY
;
447 *session_key
= auth
->session_info
->session_key
;
451 static NTSTATUS
dcesrv_remote_session_key(struct dcesrv_auth
*auth
,
452 DATA_BLOB
*session_key
)
454 if (auth
->auth_type
!= DCERPC_AUTH_TYPE_NONE
) {
455 return NT_STATUS_NO_USER_SESSION_KEY
;
458 return dcesrv_session_info_session_key(auth
, session_key
);
461 static NTSTATUS
dcesrv_local_fixed_session_key(struct dcesrv_auth
*auth
,
462 DATA_BLOB
*session_key
)
464 return dcerpc_generic_session_key(session_key
);
468 * Fetch the authentication session key if available.
470 * This is the key generated by a gensec authentication.
473 _PUBLIC_ NTSTATUS
dcesrv_auth_session_key(struct dcesrv_call_state
*call
,
474 DATA_BLOB
*session_key
)
476 struct dcesrv_auth
*auth
= call
->auth_state
;
477 SMB_ASSERT(auth
->auth_finished
);
478 return dcesrv_session_info_session_key(auth
, session_key
);
482 * Fetch the transport session key if available.
483 * Typically this is the SMB session key
484 * or a fixed key for local transports.
486 * The key is always truncated to 16 bytes.
488 _PUBLIC_ NTSTATUS
dcesrv_transport_session_key(struct dcesrv_call_state
*call
,
489 DATA_BLOB
*session_key
)
491 struct dcesrv_auth
*auth
= call
->auth_state
;
494 SMB_ASSERT(auth
->auth_finished
);
496 if (auth
->session_key_fn
== NULL
) {
497 return NT_STATUS_NO_USER_SESSION_KEY
;
500 status
= auth
->session_key_fn(auth
, session_key
);
501 if (!NT_STATUS_IS_OK(status
)) {
505 session_key
->length
= MIN(session_key
->length
, 16);
510 static struct dcesrv_auth
*dcesrv_auth_create(struct dcesrv_connection
*conn
)
512 const struct dcesrv_endpoint
*ep
= conn
->endpoint
;
513 enum dcerpc_transport_t transport
=
514 dcerpc_binding_get_transport(ep
->ep_description
);
515 struct dcesrv_auth
*auth
= NULL
;
517 auth
= talloc_zero(conn
, struct dcesrv_auth
);
524 auth
->session_key_fn
= dcesrv_remote_session_key
;
527 case NCACN_UNIX_STREAM
:
528 auth
->session_key_fn
= dcesrv_local_fixed_session_key
;
532 * All other's get a NULL pointer, which
533 * results in NT_STATUS_NO_USER_SESSION_KEY
542 connect to a dcerpc endpoint
544 _PUBLIC_ NTSTATUS
dcesrv_endpoint_connect(struct dcesrv_context
*dce_ctx
,
546 const struct dcesrv_endpoint
*ep
,
547 struct auth_session_info
*session_info
,
548 struct tevent_context
*event_ctx
,
549 uint32_t state_flags
,
550 struct dcesrv_connection
**_p
)
552 struct dcesrv_auth
*auth
= NULL
;
553 struct dcesrv_connection
*p
= NULL
;
556 return NT_STATUS_ACCESS_DENIED
;
559 p
= talloc_zero(mem_ctx
, struct dcesrv_connection
);
564 p
->dce_ctx
= dce_ctx
;
566 p
->packet_log_dir
= lpcfg_parm_string(dce_ctx
->lp_ctx
,
570 p
->event_ctx
= event_ctx
;
571 p
->state_flags
= state_flags
;
572 p
->allow_bind
= true;
573 p
->max_recv_frag
= 5840;
574 p
->max_xmit_frag
= 5840;
575 p
->max_total_request_size
= DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE
;
577 p
->support_hdr_signing
= lpcfg_parm_bool(dce_ctx
->lp_ctx
,
582 p
->max_auth_states
= lpcfg_parm_ulong(dce_ctx
->lp_ctx
,
588 auth
= dcesrv_auth_create(p
);
593 auth
->session_info
= talloc_reference(auth
, session_info
);
594 if (auth
->session_info
== NULL
) {
598 p
->default_auth_state
= auth
;
601 * For now we only support NDR32.
603 p
->preferred_transfer
= &ndr_transfer_syntax_ndr
;
609 return NT_STATUS_NO_MEMORY
;
613 move a call from an existing linked list to the specified list. This
614 prevents bugs where we forget to remove the call from a previous
617 static void dcesrv_call_set_list(struct dcesrv_call_state
*call
,
618 enum dcesrv_call_list list
)
620 switch (call
->list
) {
621 case DCESRV_LIST_NONE
:
623 case DCESRV_LIST_CALL_LIST
:
624 DLIST_REMOVE(call
->conn
->call_list
, call
);
626 case DCESRV_LIST_FRAGMENTED_CALL_LIST
:
627 DLIST_REMOVE(call
->conn
->incoming_fragmented_call_list
, call
);
629 case DCESRV_LIST_PENDING_CALL_LIST
:
630 DLIST_REMOVE(call
->conn
->pending_call_list
, call
);
635 case DCESRV_LIST_NONE
:
637 case DCESRV_LIST_CALL_LIST
:
638 DLIST_ADD_END(call
->conn
->call_list
, call
);
640 case DCESRV_LIST_FRAGMENTED_CALL_LIST
:
641 DLIST_ADD_END(call
->conn
->incoming_fragmented_call_list
, call
);
643 case DCESRV_LIST_PENDING_CALL_LIST
:
644 DLIST_ADD_END(call
->conn
->pending_call_list
, call
);
649 static void dcesrv_call_disconnect_after(struct dcesrv_call_state
*call
,
652 struct dcesrv_auth
*a
= NULL
;
654 if (call
->conn
->terminate
!= NULL
) {
658 call
->conn
->allow_bind
= false;
659 call
->conn
->allow_alter
= false;
661 call
->conn
->default_auth_state
->auth_invalid
= true;
663 for (a
= call
->conn
->auth_states
; a
!= NULL
; a
= a
->next
) {
664 a
->auth_invalid
= true;
667 call
->terminate_reason
= talloc_strdup(call
, reason
);
668 if (call
->terminate_reason
== NULL
) {
669 call
->terminate_reason
= __location__
;
674 return a dcerpc bind_nak
676 static NTSTATUS
dcesrv_bind_nak(struct dcesrv_call_state
*call
, uint32_t reason
)
678 struct ncacn_packet pkt
;
679 struct dcerpc_bind_nak_version version
;
680 struct data_blob_list_item
*rep
;
682 static const uint8_t _pad
[3] = { 0, };
685 * We add the call to the pending_call_list
686 * in order to defer the termination.
688 dcesrv_call_disconnect_after(call
, "dcesrv_bind_nak");
690 /* setup a bind_nak */
691 dcesrv_init_hdr(&pkt
, lpcfg_rpc_big_endian(call
->conn
->dce_ctx
->lp_ctx
));
693 pkt
.call_id
= call
->pkt
.call_id
;
694 pkt
.ptype
= DCERPC_PKT_BIND_NAK
;
695 pkt
.pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
696 pkt
.u
.bind_nak
.reject_reason
= reason
;
697 version
.rpc_vers
= 5;
698 version
.rpc_vers_minor
= 0;
699 pkt
.u
.bind_nak
.num_versions
= 1;
700 pkt
.u
.bind_nak
.versions
= &version
;
701 pkt
.u
.bind_nak
._pad
= data_blob_const(_pad
, sizeof(_pad
));
703 rep
= talloc_zero(call
, struct data_blob_list_item
);
705 return NT_STATUS_NO_MEMORY
;
708 status
= dcerpc_ncacn_push_auth(&rep
->blob
, call
, &pkt
, NULL
);
709 if (!NT_STATUS_IS_OK(status
)) {
713 dcerpc_set_frag_length(&rep
->blob
, rep
->blob
.length
);
715 DLIST_ADD_END(call
->replies
, rep
);
716 dcesrv_call_set_list(call
, DCESRV_LIST_CALL_LIST
);
718 if (call
->conn
->call_list
&& call
->conn
->call_list
->replies
) {
719 if (call
->conn
->transport
.report_output_data
) {
720 call
->conn
->transport
.report_output_data(call
->conn
);
727 static NTSTATUS
_dcesrv_fault_disconnect_flags(struct dcesrv_call_state
*call
,
731 const char *location
)
733 const char *reason
= NULL
;
735 reason
= talloc_asprintf(call
, "%s:%s: fault=%u (%s) flags=0x%x",
738 dcerpc_errstr(call
, fault_code
),
740 if (reason
== NULL
) {
745 * We add the call to the pending_call_list
746 * in order to defer the termination.
749 dcesrv_call_disconnect_after(call
, reason
);
751 return dcesrv_fault_with_flags(call
, fault_code
, extra_flags
);
754 #define dcesrv_fault_disconnect(call, fault_code) \
755 _dcesrv_fault_disconnect_flags(call, fault_code, \
756 DCERPC_PFC_FLAG_DID_NOT_EXECUTE, \
757 __func__, __location__)
758 #define dcesrv_fault_disconnect0(call, fault_code) \
759 _dcesrv_fault_disconnect_flags(call, fault_code, 0, \
760 __func__, __location__)
762 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context
*c
)
764 DLIST_REMOVE(c
->conn
->contexts
, c
);
766 if (c
->iface
&& c
->iface
->unbind
) {
767 c
->iface
->unbind(c
, c
->iface
);
774 static void dcesrv_prepare_context_auth(struct dcesrv_call_state
*dce_call
)
776 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
777 const struct dcesrv_endpoint
*endpoint
= dce_call
->conn
->endpoint
;
778 enum dcerpc_transport_t transport
=
779 dcerpc_binding_get_transport(endpoint
->ep_description
);
780 struct dcesrv_connection_context
*context
= dce_call
->context
;
781 const struct dcesrv_interface
*iface
= context
->iface
;
783 context
->min_auth_level
= DCERPC_AUTH_LEVEL_NONE
;
785 if (transport
== NCALRPC
) {
786 context
->allow_connect
= true;
791 * allow overwrite per interface
792 * allow dcerpc auth level connect:<interface>
794 context
->allow_connect
= lpcfg_allow_dcerpc_auth_level_connect(lp_ctx
);
795 context
->allow_connect
= lpcfg_parm_bool(lp_ctx
, NULL
,
796 "allow dcerpc auth level connect",
798 context
->allow_connect
);
801 NTSTATUS
dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context
*context
,
802 const struct dcesrv_interface
*iface
)
805 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
806 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
808 context
->min_auth_level
= DCERPC_AUTH_LEVEL_PACKET
;
812 NTSTATUS
dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context
*context
,
813 const struct dcesrv_interface
*iface
)
815 context
->min_auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
819 _PUBLIC_ NTSTATUS
dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context
*context
,
820 const struct dcesrv_interface
*iface
)
822 struct loadparm_context
*lp_ctx
= context
->conn
->dce_ctx
->lp_ctx
;
823 const struct dcesrv_endpoint
*endpoint
= context
->conn
->endpoint
;
824 enum dcerpc_transport_t transport
=
825 dcerpc_binding_get_transport(endpoint
->ep_description
);
827 if (transport
== NCALRPC
) {
828 context
->allow_connect
= true;
833 * allow overwrite per interface
834 * allow dcerpc auth level connect:<interface>
836 context
->allow_connect
= false;
837 context
->allow_connect
= lpcfg_parm_bool(lp_ctx
, NULL
,
838 "allow dcerpc auth level connect",
840 context
->allow_connect
);
844 _PUBLIC_ NTSTATUS
dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context
*context
,
845 const struct dcesrv_interface
*iface
)
847 struct loadparm_context
*lp_ctx
= context
->conn
->dce_ctx
->lp_ctx
;
848 const struct dcesrv_endpoint
*endpoint
= context
->conn
->endpoint
;
849 enum dcerpc_transport_t transport
=
850 dcerpc_binding_get_transport(endpoint
->ep_description
);
852 if (transport
== NCALRPC
) {
853 context
->allow_connect
= true;
858 * allow overwrite per interface
859 * allow dcerpc auth level connect:<interface>
861 context
->allow_connect
= true;
862 context
->allow_connect
= lpcfg_parm_bool(lp_ctx
, NULL
,
863 "allow dcerpc auth level connect",
865 context
->allow_connect
);
869 struct dcesrv_conn_auth_wait_context
{
870 struct tevent_req
*req
;
875 struct dcesrv_conn_auth_wait_state
{
879 static struct tevent_req
*dcesrv_conn_auth_wait_send(TALLOC_CTX
*mem_ctx
,
880 struct tevent_context
*ev
,
883 struct dcesrv_conn_auth_wait_context
*auth_wait
=
884 talloc_get_type_abort(private_data
,
885 struct dcesrv_conn_auth_wait_context
);
886 struct tevent_req
*req
= NULL
;
887 struct dcesrv_conn_auth_wait_state
*state
= NULL
;
889 req
= tevent_req_create(mem_ctx
, &state
,
890 struct dcesrv_conn_auth_wait_state
);
894 auth_wait
->req
= req
;
896 tevent_req_defer_callback(req
, ev
);
898 if (!auth_wait
->done
) {
902 if (tevent_req_nterror(req
, auth_wait
->status
)) {
903 return tevent_req_post(req
, ev
);
906 tevent_req_done(req
);
907 return tevent_req_post(req
, ev
);
910 static NTSTATUS
dcesrv_conn_auth_wait_recv(struct tevent_req
*req
)
912 return tevent_req_simple_recv_ntstatus(req
);
915 static NTSTATUS
dcesrv_conn_auth_wait_setup(struct dcesrv_connection
*conn
)
917 struct dcesrv_conn_auth_wait_context
*auth_wait
= NULL
;
919 if (conn
->wait_send
!= NULL
) {
920 return NT_STATUS_INTERNAL_ERROR
;
923 auth_wait
= talloc_zero(conn
, struct dcesrv_conn_auth_wait_context
);
924 if (auth_wait
== NULL
) {
925 return NT_STATUS_NO_MEMORY
;
928 conn
->wait_private
= auth_wait
;
929 conn
->wait_send
= dcesrv_conn_auth_wait_send
;
930 conn
->wait_recv
= dcesrv_conn_auth_wait_recv
;
934 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection
*conn
,
937 struct dcesrv_conn_auth_wait_context
*auth_wait
=
938 talloc_get_type_abort(conn
->wait_private
,
939 struct dcesrv_conn_auth_wait_context
);
941 auth_wait
->done
= true;
942 auth_wait
->status
= status
;
944 if (auth_wait
->req
== NULL
) {
948 if (tevent_req_nterror(auth_wait
->req
, status
)) {
952 tevent_req_done(auth_wait
->req
);
955 static NTSTATUS
dcesrv_auth_reply(struct dcesrv_call_state
*call
);
957 static void dcesrv_bind_done(struct tevent_req
*subreq
);
960 handle a bind request
962 static NTSTATUS
dcesrv_bind(struct dcesrv_call_state
*call
)
964 struct dcesrv_connection
*conn
= call
->conn
;
965 struct dcesrv_context
*dce_ctx
= conn
->dce_ctx
;
966 struct ncacn_packet
*pkt
= &call
->ack_pkt
;
968 uint32_t extra_flags
= 0;
969 uint16_t max_req
= 0;
970 uint16_t max_rep
= 0;
971 struct dcerpc_binding
*ep_2nd_description
= NULL
;
972 const char *endpoint
= NULL
;
973 struct dcesrv_auth
*auth
= call
->auth_state
;
974 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
975 struct dcerpc_ack_ctx
*ack_ctx_list
= NULL
;
976 struct dcerpc_ack_ctx
*ack_features
= NULL
;
977 struct tevent_req
*subreq
= NULL
;
980 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
982 call
->pkt
.u
.bind
.auth_info
.length
,
983 0, /* required flags */
984 DCERPC_PFC_FLAG_FIRST
|
985 DCERPC_PFC_FLAG_LAST
|
986 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
987 0x08 | /* this is not defined, but should be ignored */
988 DCERPC_PFC_FLAG_CONC_MPX
|
989 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
990 DCERPC_PFC_FLAG_MAYBE
|
991 DCERPC_PFC_FLAG_OBJECT_UUID
);
992 if (!NT_STATUS_IS_OK(status
)) {
993 return dcesrv_bind_nak(call
,
994 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED
);
997 /* max_recv_frag and max_xmit_frag result always in the same value! */
998 max_req
= MIN(call
->pkt
.u
.bind
.max_xmit_frag
,
999 call
->pkt
.u
.bind
.max_recv_frag
);
1001 * The values are between 2048 and 5840 tested against Windows 2012R2
1002 * via ncacn_ip_tcp on port 135.
1004 max_req
= MAX(2048, max_req
);
1005 max_rep
= MIN(max_req
, conn
->max_recv_frag
);
1006 /* They are truncated to an 8 byte boundary. */
1009 /* max_recv_frag and max_xmit_frag result always in the same value! */
1010 conn
->max_recv_frag
= max_rep
;
1011 conn
->max_xmit_frag
= max_rep
;
1013 status
= dce_ctx
->callbacks
->assoc_group
.find(
1014 call
, dce_ctx
->callbacks
->assoc_group
.private_data
);
1015 if (!NT_STATUS_IS_OK(status
)) {
1016 DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
1017 call
->pkt
.u
.bind
.assoc_group_id
, nt_errstr(status
));
1018 return dcesrv_bind_nak(call
, 0);
1021 if (call
->pkt
.u
.bind
.num_contexts
< 1) {
1022 return dcesrv_bind_nak(call
, 0);
1025 ack_ctx_list
= talloc_zero_array(call
, struct dcerpc_ack_ctx
,
1026 call
->pkt
.u
.bind
.num_contexts
);
1027 if (ack_ctx_list
== NULL
) {
1028 return dcesrv_bind_nak(call
, 0);
1032 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1033 * dcesrv_check_or_create_context()) and do some protocol validation
1034 * and set sane defaults.
1036 for (i
= 0; i
< call
->pkt
.u
.bind
.num_contexts
; i
++) {
1037 const struct dcerpc_ctx_list
*c
= &call
->pkt
.u
.bind
.ctx_list
[i
];
1038 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1039 bool is_feature
= false;
1040 uint64_t features
= 0;
1042 if (c
->num_transfer_syntaxes
== 0) {
1043 return dcesrv_bind_nak(call
, 0);
1046 a
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1047 a
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1050 * It's only treated as bind time feature request, if the first
1051 * transfer_syntax matches, all others are ignored.
1053 is_feature
= dcerpc_extract_bind_time_features(c
->transfer_syntaxes
[0],
1059 if (ack_features
!= NULL
) {
1061 * Only one bind time feature context is allowed.
1063 return dcesrv_bind_nak(call
, 0);
1067 a
->result
= DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
;
1068 a
->reason
.negotiate
= 0;
1069 if (features
& DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
) {
1070 if (conn
->max_auth_states
!= 0) {
1071 a
->reason
.negotiate
|=
1072 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
;
1075 if (features
& DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
) {
1076 a
->reason
.negotiate
|=
1077 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
;
1080 conn
->assoc_group
->bind_time_features
= a
->reason
.negotiate
;
1084 * Try to negotiate one new presentation context.
1086 * Deep in here we locate the iface (by uuid) that the client
1087 * requested, from the list of interfaces on the
1088 * call->conn->endpoint, and call iface->bind() on that iface.
1090 * call->conn was set up at the accept() of the socket, and
1091 * call->conn->endpoint has a list of interfaces restricted to
1092 * this port or pipe.
1094 status
= dcesrv_negotiate_contexts(call
, &call
->pkt
.u
.bind
, ack_ctx_list
);
1095 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1096 return dcesrv_bind_nak(call
, 0);
1098 if (!NT_STATUS_IS_OK(status
)) {
1103 * At this point we still don't know which interface (eg
1104 * netlogon, lsa, drsuapi) the caller requested in this bind!
1105 * The most recently added context is available as the first
1106 * element in the linked list at call->conn->contexts, that is
1107 * call->conn->contexts->iface, but they may not have
1108 * requested one at all!
1111 if ((call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_CONC_MPX
) &&
1112 (call
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
1113 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1114 extra_flags
|= DCERPC_PFC_FLAG_CONC_MPX
;
1117 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
1118 conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
;
1122 * After finding the interface and setting up the NDR
1123 * transport negotiation etc, handle any authentication that
1124 * is being requested.
1126 if (!dcesrv_auth_bind(call
)) {
1128 if (auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
) {
1130 * With DCERPC_AUTH_LEVEL_NONE, we get the
1131 * reject_reason in auth->auth_context_id.
1133 return dcesrv_bind_nak(call
, auth
->auth_context_id
);
1137 * This must a be a temporary failure e.g. talloc or invalid
1138 * configuration, e.g. no machine account.
1140 return dcesrv_bind_nak(call
,
1141 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION
);
1144 /* setup a bind_ack */
1145 dcesrv_init_hdr(pkt
, lpcfg_rpc_big_endian(dce_ctx
->lp_ctx
));
1146 pkt
->auth_length
= 0;
1147 pkt
->call_id
= call
->pkt
.call_id
;
1148 pkt
->ptype
= DCERPC_PKT_BIND_ACK
;
1149 pkt
->pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
| extra_flags
;
1150 pkt
->u
.bind_ack
.max_xmit_frag
= conn
->max_xmit_frag
;
1151 pkt
->u
.bind_ack
.max_recv_frag
= conn
->max_recv_frag
;
1152 pkt
->u
.bind_ack
.assoc_group_id
= conn
->assoc_group
->id
;
1154 ep_2nd_description
= conn
->endpoint
->ep_2nd_description
;
1155 if (ep_2nd_description
== NULL
) {
1156 ep_2nd_description
= conn
->endpoint
->ep_description
;
1159 endpoint
= dcerpc_binding_get_string_option(
1162 if (endpoint
== NULL
) {
1166 pkt
->u
.bind_ack
.secondary_address
= endpoint
;
1167 pkt
->u
.bind_ack
.num_results
= call
->pkt
.u
.bind
.num_contexts
;
1168 pkt
->u
.bind_ack
.ctx_list
= ack_ctx_list
;
1169 pkt
->u
.bind_ack
.auth_info
= data_blob_null
;
1171 status
= dcesrv_auth_prepare_bind_ack(call
, pkt
);
1172 if (!NT_STATUS_IS_OK(status
)) {
1173 return dcesrv_bind_nak(call
, 0);
1176 if (auth
->auth_finished
) {
1177 return dcesrv_auth_reply(call
);
1180 cb
->auth
.become_root();
1181 subreq
= gensec_update_send(call
, call
->event_ctx
,
1182 auth
->gensec_security
,
1183 call
->in_auth_info
.credentials
);
1184 cb
->auth
.unbecome_root();
1185 if (subreq
== NULL
) {
1186 return NT_STATUS_NO_MEMORY
;
1188 tevent_req_set_callback(subreq
, dcesrv_bind_done
, call
);
1190 return dcesrv_conn_auth_wait_setup(conn
);
1193 static void dcesrv_bind_done(struct tevent_req
*subreq
)
1195 struct dcesrv_call_state
*call
=
1196 tevent_req_callback_data(subreq
,
1197 struct dcesrv_call_state
);
1198 struct dcesrv_connection
*conn
= call
->conn
;
1199 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1202 cb
->auth
.become_root();
1203 status
= gensec_update_recv(subreq
, call
,
1204 &call
->out_auth_info
->credentials
);
1205 cb
->auth
.unbecome_root();
1206 TALLOC_FREE(subreq
);
1208 status
= dcesrv_auth_complete(call
, status
);
1209 if (!NT_STATUS_IS_OK(status
)) {
1210 status
= dcesrv_bind_nak(call
, 0);
1211 dcesrv_conn_auth_wait_finished(conn
, status
);
1215 status
= dcesrv_auth_reply(call
);
1216 dcesrv_conn_auth_wait_finished(conn
, status
);
1220 static NTSTATUS
dcesrv_auth_reply(struct dcesrv_call_state
*call
)
1222 struct ncacn_packet
*pkt
= &call
->ack_pkt
;
1223 struct data_blob_list_item
*rep
= NULL
;
1226 rep
= talloc_zero(call
, struct data_blob_list_item
);
1228 return NT_STATUS_NO_MEMORY
;
1231 status
= dcerpc_ncacn_push_auth(&rep
->blob
,
1234 call
->out_auth_info
);
1235 if (!NT_STATUS_IS_OK(status
)) {
1239 dcerpc_set_frag_length(&rep
->blob
, rep
->blob
.length
);
1241 DLIST_ADD_END(call
->replies
, rep
);
1242 dcesrv_call_set_list(call
, DCESRV_LIST_CALL_LIST
);
1244 if (call
->conn
->call_list
&& call
->conn
->call_list
->replies
) {
1245 if (call
->conn
->transport
.report_output_data
) {
1246 call
->conn
->transport
.report_output_data(call
->conn
);
1250 return NT_STATUS_OK
;
1254 static void dcesrv_auth3_done(struct tevent_req
*subreq
);
1257 handle a auth3 request
1259 static NTSTATUS
dcesrv_auth3(struct dcesrv_call_state
*call
)
1261 struct dcesrv_connection
*conn
= call
->conn
;
1262 struct dcesrv_auth
*auth
= call
->auth_state
;
1263 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1264 struct tevent_req
*subreq
= NULL
;
1267 if (!auth
->auth_started
) {
1268 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1271 if (auth
->auth_finished
) {
1272 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1275 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
1277 call
->pkt
.u
.auth3
.auth_info
.length
,
1278 0, /* required flags */
1279 DCERPC_PFC_FLAG_FIRST
|
1280 DCERPC_PFC_FLAG_LAST
|
1281 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
1282 0x08 | /* this is not defined, but should be ignored */
1283 DCERPC_PFC_FLAG_CONC_MPX
|
1284 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1285 DCERPC_PFC_FLAG_MAYBE
|
1286 DCERPC_PFC_FLAG_OBJECT_UUID
);
1287 if (!NT_STATUS_IS_OK(status
)) {
1288 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1291 /* handle the auth3 in the auth code */
1292 if (!dcesrv_auth_prepare_auth3(call
)) {
1294 * we don't send a reply to a auth3 request,
1295 * except by a fault.
1297 * In anycase we mark the connection as
1300 auth
->auth_invalid
= true;
1301 if (call
->fault_code
!= 0) {
1302 return dcesrv_fault_disconnect(call
, call
->fault_code
);
1305 return NT_STATUS_OK
;
1308 cb
->auth
.become_root();
1309 subreq
= gensec_update_send(call
, call
->event_ctx
,
1310 auth
->gensec_security
,
1311 call
->in_auth_info
.credentials
);
1312 cb
->auth
.unbecome_root();
1313 if (subreq
== NULL
) {
1314 return NT_STATUS_NO_MEMORY
;
1316 tevent_req_set_callback(subreq
, dcesrv_auth3_done
, call
);
1318 return dcesrv_conn_auth_wait_setup(conn
);
1321 static void dcesrv_auth3_done(struct tevent_req
*subreq
)
1323 struct dcesrv_call_state
*call
=
1324 tevent_req_callback_data(subreq
,
1325 struct dcesrv_call_state
);
1326 struct dcesrv_connection
*conn
= call
->conn
;
1327 struct dcesrv_auth
*auth
= call
->auth_state
;
1328 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1331 cb
->auth
.become_root();
1332 status
= gensec_update_recv(subreq
, call
,
1333 &call
->out_auth_info
->credentials
);
1334 cb
->auth
.unbecome_root();
1335 TALLOC_FREE(subreq
);
1337 status
= dcesrv_auth_complete(call
, status
);
1338 if (!NT_STATUS_IS_OK(status
)) {
1340 * we don't send a reply to a auth3 request,
1341 * except by a fault.
1343 * In anycase we mark the connection as
1346 auth
->auth_invalid
= true;
1347 if (call
->fault_code
!= 0) {
1348 status
= dcesrv_fault_disconnect(call
, call
->fault_code
);
1349 dcesrv_conn_auth_wait_finished(conn
, status
);
1353 dcesrv_conn_auth_wait_finished(conn
, NT_STATUS_OK
);
1358 * we don't send a reply to a auth3 request.
1361 dcesrv_conn_auth_wait_finished(conn
, NT_STATUS_OK
);
1366 static NTSTATUS
dcesrv_check_or_create_context(struct dcesrv_call_state
*call
,
1367 const struct dcerpc_bind
*b
,
1368 const struct dcerpc_ctx_list
*ctx
,
1369 struct dcerpc_ack_ctx
*ack
,
1371 const struct ndr_syntax_id
*supported_transfer
)
1373 struct dcesrv_connection_context
*context
;
1374 const struct dcesrv_interface
*iface
;
1376 const struct ndr_syntax_id
*selected_transfer
= NULL
;
1381 return NT_STATUS_INTERNAL_ERROR
;
1384 return NT_STATUS_INTERNAL_ERROR
;
1386 if (ctx
->num_transfer_syntaxes
< 1) {
1387 return NT_STATUS_INTERNAL_ERROR
;
1390 return NT_STATUS_INTERNAL_ERROR
;
1392 if (supported_transfer
== NULL
) {
1393 return NT_STATUS_INTERNAL_ERROR
;
1396 switch (ack
->result
) {
1397 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE
:
1398 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
:
1400 * We is already completed.
1402 return NT_STATUS_OK
;
1407 ack
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1408 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1410 iface
= find_interface_by_syntax_id(
1411 call
->conn
->endpoint
, &ctx
->abstract_syntax
);
1412 if (iface
== NULL
) {
1413 struct ndr_syntax_id_buf buf
;
1414 DBG_NOTICE("Request for unknown dcerpc interface %s\n",
1415 ndr_syntax_id_buf_string(
1416 &ctx
->abstract_syntax
, &buf
));
1418 * We report this only via ack->result
1420 return NT_STATUS_OK
;
1423 ack
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1424 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED
;
1426 if (validate_only
) {
1428 * We report this only via ack->result
1430 return NT_STATUS_OK
;
1433 for (i
= 0; i
< ctx
->num_transfer_syntaxes
; i
++) {
1435 * we only do NDR encoded dcerpc for now.
1437 ok
= ndr_syntax_id_equal(&ctx
->transfer_syntaxes
[i
],
1438 supported_transfer
);
1440 selected_transfer
= supported_transfer
;
1445 context
= dcesrv_find_context(call
->conn
, ctx
->context_id
);
1446 if (context
!= NULL
) {
1447 ok
= ndr_syntax_id_equal(&context
->iface
->syntax_id
,
1448 &ctx
->abstract_syntax
);
1450 return NT_STATUS_RPC_PROTOCOL_ERROR
;
1453 if (selected_transfer
!= NULL
) {
1454 ok
= ndr_syntax_id_equal(&context
->transfer_syntax
,
1457 return NT_STATUS_RPC_PROTOCOL_ERROR
;
1460 ack
->result
= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
;
1461 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_NOT_SPECIFIED
;
1462 ack
->syntax
= context
->transfer_syntax
;
1466 * We report this only via ack->result
1468 return NT_STATUS_OK
;
1471 if (selected_transfer
== NULL
) {
1473 * We report this only via ack->result
1475 return NT_STATUS_OK
;
1478 ack
->result
= DCERPC_BIND_ACK_RESULT_USER_REJECTION
;
1479 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED
;
1481 /* add this context to the list of available context_ids */
1482 context
= talloc_zero(call
->conn
, struct dcesrv_connection_context
);
1483 if (context
== NULL
) {
1484 return NT_STATUS_NO_MEMORY
;
1486 context
->conn
= call
->conn
;
1487 context
->context_id
= ctx
->context_id
;
1488 context
->iface
= iface
;
1489 context
->transfer_syntax
= *selected_transfer
;
1490 DLIST_ADD(call
->conn
->contexts
, context
);
1491 call
->context
= context
;
1492 talloc_set_destructor(context
, dcesrv_connection_context_destructor
);
1494 dcesrv_prepare_context_auth(call
);
1497 * Multiplex is supported by default
1499 call
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1501 status
= iface
->bind(context
, iface
);
1502 call
->context
= NULL
;
1503 if (!NT_STATUS_IS_OK(status
)) {
1504 /* we don't want to trigger the iface->unbind() hook */
1505 context
->iface
= NULL
;
1506 talloc_free(context
);
1508 * We report this only via ack->result
1510 return NT_STATUS_OK
;
1513 ack
->result
= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
;
1514 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_NOT_SPECIFIED
;
1515 ack
->syntax
= context
->transfer_syntax
;
1516 return NT_STATUS_OK
;
1519 static NTSTATUS
dcesrv_negotiate_contexts(struct dcesrv_call_state
*call
,
1520 const struct dcerpc_bind
*b
,
1521 struct dcerpc_ack_ctx
*ack_ctx_list
)
1525 bool validate_only
= false;
1526 bool preferred_ndr32
;
1529 * Try to negotiate one new presentation context,
1530 * using our preferred transfer syntax.
1532 for (i
= 0; i
< b
->num_contexts
; i
++) {
1533 const struct dcerpc_ctx_list
*c
= &b
->ctx_list
[i
];
1534 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1536 status
= dcesrv_check_or_create_context(call
, b
, c
, a
,
1538 call
->conn
->preferred_transfer
);
1539 if (!NT_STATUS_IS_OK(status
)) {
1543 if (a
->result
== DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1545 * We managed to negotiate one context.
1549 validate_only
= true;
1553 preferred_ndr32
= ndr_syntax_id_equal(&ndr_transfer_syntax_ndr
,
1554 call
->conn
->preferred_transfer
);
1555 if (preferred_ndr32
) {
1559 return NT_STATUS_OK
;
1563 * Try to negotiate one new presentation context,
1564 * using NDR 32 as fallback.
1566 for (i
= 0; i
< b
->num_contexts
; i
++) {
1567 const struct dcerpc_ctx_list
*c
= &b
->ctx_list
[i
];
1568 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1570 status
= dcesrv_check_or_create_context(call
, b
, c
, a
,
1572 &ndr_transfer_syntax_ndr
);
1573 if (!NT_STATUS_IS_OK(status
)) {
1577 if (a
->result
== DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1579 * We managed to negotiate one context.
1583 validate_only
= true;
1587 return NT_STATUS_OK
;
1590 static void dcesrv_alter_done(struct tevent_req
*subreq
);
1593 handle a alter context request
1595 static NTSTATUS
dcesrv_alter(struct dcesrv_call_state
*call
)
1597 struct dcesrv_connection
*conn
= call
->conn
;
1599 bool auth_ok
= false;
1600 struct ncacn_packet
*pkt
= &call
->ack_pkt
;
1601 uint32_t extra_flags
= 0;
1602 struct dcesrv_auth
*auth
= call
->auth_state
;
1603 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1604 struct dcerpc_ack_ctx
*ack_ctx_list
= NULL
;
1605 struct tevent_req
*subreq
= NULL
;
1608 if (!call
->conn
->allow_alter
) {
1609 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1612 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
1614 call
->pkt
.u
.alter
.auth_info
.length
,
1615 0, /* required flags */
1616 DCERPC_PFC_FLAG_FIRST
|
1617 DCERPC_PFC_FLAG_LAST
|
1618 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
1619 0x08 | /* this is not defined, but should be ignored */
1620 DCERPC_PFC_FLAG_CONC_MPX
|
1621 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1622 DCERPC_PFC_FLAG_MAYBE
|
1623 DCERPC_PFC_FLAG_OBJECT_UUID
);
1624 if (!NT_STATUS_IS_OK(status
)) {
1625 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1628 auth_ok
= dcesrv_auth_alter(call
);
1630 if (call
->fault_code
!= 0) {
1631 return dcesrv_fault_disconnect(call
, call
->fault_code
);
1635 if (call
->pkt
.u
.alter
.num_contexts
< 1) {
1636 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1639 ack_ctx_list
= talloc_zero_array(call
, struct dcerpc_ack_ctx
,
1640 call
->pkt
.u
.alter
.num_contexts
);
1641 if (ack_ctx_list
== NULL
) {
1642 return NT_STATUS_NO_MEMORY
;
1646 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1647 * dcesrv_check_or_create_context()) and do some protocol validation
1648 * and set sane defaults.
1650 for (i
= 0; i
< call
->pkt
.u
.alter
.num_contexts
; i
++) {
1651 const struct dcerpc_ctx_list
*c
= &call
->pkt
.u
.alter
.ctx_list
[i
];
1652 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1654 if (c
->num_transfer_syntaxes
== 0) {
1655 return dcesrv_fault_disconnect(call
,
1656 DCERPC_NCA_S_PROTO_ERROR
);
1659 a
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1660 a
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1664 * Try to negotiate one new presentation context.
1666 status
= dcesrv_negotiate_contexts(call
, &call
->pkt
.u
.alter
, ack_ctx_list
);
1667 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1668 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1670 if (!NT_STATUS_IS_OK(status
)) {
1674 if ((call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_CONC_MPX
) &&
1675 (call
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
1676 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1677 extra_flags
|= DCERPC_PFC_FLAG_CONC_MPX
;
1680 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
1681 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
;
1684 /* handle any authentication that is being requested */
1686 if (call
->in_auth_info
.auth_type
!= auth
->auth_type
) {
1687 return dcesrv_fault_disconnect(call
,
1688 DCERPC_FAULT_SEC_PKG_ERROR
);
1690 return dcesrv_fault_disconnect(call
, DCERPC_FAULT_ACCESS_DENIED
);
1693 dcesrv_init_hdr(pkt
, lpcfg_rpc_big_endian(call
->conn
->dce_ctx
->lp_ctx
));
1694 pkt
->auth_length
= 0;
1695 pkt
->call_id
= call
->pkt
.call_id
;
1696 pkt
->ptype
= DCERPC_PKT_ALTER_RESP
;
1697 pkt
->pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
| extra_flags
;
1698 pkt
->u
.alter_resp
.max_xmit_frag
= call
->conn
->max_xmit_frag
;
1699 pkt
->u
.alter_resp
.max_recv_frag
= call
->conn
->max_recv_frag
;
1700 pkt
->u
.alter_resp
.assoc_group_id
= call
->conn
->assoc_group
->id
;
1701 pkt
->u
.alter_resp
.secondary_address
= "";
1702 pkt
->u
.alter_resp
.num_results
= call
->pkt
.u
.alter
.num_contexts
;
1703 pkt
->u
.alter_resp
.ctx_list
= ack_ctx_list
;
1704 pkt
->u
.alter_resp
.auth_info
= data_blob_null
;
1706 status
= dcesrv_auth_prepare_alter_ack(call
, pkt
);
1707 if (!NT_STATUS_IS_OK(status
)) {
1708 return dcesrv_fault_disconnect(call
, DCERPC_FAULT_SEC_PKG_ERROR
);
1711 if (auth
->auth_finished
) {
1712 return dcesrv_auth_reply(call
);
1715 cb
->auth
.become_root();
1716 subreq
= gensec_update_send(call
, call
->event_ctx
,
1717 auth
->gensec_security
,
1718 call
->in_auth_info
.credentials
);
1719 cb
->auth
.unbecome_root();
1720 if (subreq
== NULL
) {
1721 return NT_STATUS_NO_MEMORY
;
1723 tevent_req_set_callback(subreq
, dcesrv_alter_done
, call
);
1725 return dcesrv_conn_auth_wait_setup(conn
);
1728 static void dcesrv_alter_done(struct tevent_req
*subreq
)
1730 struct dcesrv_call_state
*call
=
1731 tevent_req_callback_data(subreq
,
1732 struct dcesrv_call_state
);
1733 struct dcesrv_connection
*conn
= call
->conn
;
1734 struct dcesrv_context_callbacks
*cb
= call
->conn
->dce_ctx
->callbacks
;
1737 cb
->auth
.become_root();
1738 status
= gensec_update_recv(subreq
, call
,
1739 &call
->out_auth_info
->credentials
);
1740 cb
->auth
.unbecome_root();
1741 TALLOC_FREE(subreq
);
1743 status
= dcesrv_auth_complete(call
, status
);
1744 if (!NT_STATUS_IS_OK(status
)) {
1745 status
= dcesrv_fault_disconnect(call
, DCERPC_FAULT_SEC_PKG_ERROR
);
1746 dcesrv_conn_auth_wait_finished(conn
, status
);
1750 status
= dcesrv_auth_reply(call
);
1751 dcesrv_conn_auth_wait_finished(conn
, status
);
1756 possibly save the call for inspection with ndrdump
1758 static void dcesrv_save_call(struct dcesrv_call_state
*call
, const char *why
)
1761 dcerpc_log_packet(call
->conn
->packet_log_dir
,
1762 call
->context
->iface
->name
,
1763 call
->pkt
.u
.request
.opnum
,
1765 &call
->pkt
.u
.request
.stub_and_verifier
,
1772 Save the call for use as a seed for fuzzing.
1774 This is only enabled in a developer build, and only has effect if the
1775 "dcesrv fuzz directory" param is set.
1777 void _dcesrv_save_ndr_fuzz_seed(DATA_BLOB call_blob
,
1778 struct dcesrv_call_state
*call
,
1781 const char *dump_dir
= lpcfg_parm_string(call
->conn
->dce_ctx
->lp_ctx
,
1783 "dcesrv", "fuzz directory");
1785 dcerpc_save_ndr_fuzz_seed(call
,
1788 call
->context
->iface
->name
,
1790 call
->pkt
.u
.request
.opnum
,
1791 call
->ndr_pull
->flags
& LIBNDR_FLAG_NDR64
);
1793 #endif /*if DEVELOPER, enveloping _dcesrv_save_ndr_fuzz_seed() */
1796 static NTSTATUS
dcesrv_check_verification_trailer(struct dcesrv_call_state
*call
)
1798 TALLOC_CTX
*frame
= talloc_stackframe();
1799 const uint32_t bitmask1
= call
->conn
->client_hdr_signing
?
1800 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
: 0;
1801 const struct dcerpc_sec_vt_pcontext pcontext
= {
1802 .abstract_syntax
= call
->context
->iface
->syntax_id
,
1803 .transfer_syntax
= call
->context
->transfer_syntax
,
1805 const struct dcerpc_sec_vt_header2 header2
=
1806 dcerpc_sec_vt_header2_from_ncacn_packet(&call
->pkt
);
1807 enum ndr_err_code ndr_err
;
1808 struct dcerpc_sec_verification_trailer
*vt
= NULL
;
1809 NTSTATUS status
= NT_STATUS_OK
;
1812 SMB_ASSERT(call
->pkt
.ptype
== DCERPC_PKT_REQUEST
);
1814 ndr_err
= ndr_pop_dcerpc_sec_verification_trailer(call
->ndr_pull
,
1816 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1817 status
= ndr_map_error2ntstatus(ndr_err
);
1821 ok
= dcerpc_sec_verification_trailer_check(vt
, &bitmask1
,
1822 &pcontext
, &header2
);
1824 status
= NT_STATUS_ACCESS_DENIED
;
1833 handle a dcerpc request packet
1835 static NTSTATUS
dcesrv_request(struct dcesrv_call_state
*call
)
1837 const struct dcesrv_endpoint
*endpoint
= call
->conn
->endpoint
;
1838 struct dcesrv_auth
*auth
= call
->auth_state
;
1839 enum dcerpc_transport_t transport
=
1840 dcerpc_binding_get_transport(endpoint
->ep_description
);
1841 struct ndr_pull
*pull
;
1844 if (auth
->auth_invalid
) {
1845 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1848 if (!auth
->auth_finished
) {
1849 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1852 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1853 if (auth
->gensec_security
!= NULL
&&
1854 !gensec_have_feature(auth
->gensec_security
, GENSEC_FEATURE_ASYNC_REPLIES
)) {
1855 call
->state_flags
&= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC
;
1858 if (call
->context
== NULL
) {
1859 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
1860 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
1863 switch (auth
->auth_level
) {
1864 case DCERPC_AUTH_LEVEL_NONE
:
1865 case DCERPC_AUTH_LEVEL_PACKET
:
1866 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1867 case DCERPC_AUTH_LEVEL_PRIVACY
:
1870 if (!call
->context
->allow_connect
) {
1873 addr
= tsocket_address_string(call
->conn
->remote_address
,
1876 DEBUG(2, ("%s: restrict auth_level_connect access "
1877 "to [%s] with auth[type=0x%x,level=0x%x] "
1878 "on [%s] from [%s]\n",
1879 __func__
, call
->context
->iface
->name
,
1882 derpc_transport_string_by_transport(transport
),
1884 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
1889 if (auth
->auth_level
< call
->context
->min_auth_level
) {
1892 addr
= tsocket_address_string(call
->conn
->remote_address
, call
);
1894 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1895 "to [%s] with auth[type=0x%x,level=0x%x] "
1896 "on [%s] from [%s]\n",
1898 call
->context
->min_auth_level
,
1899 call
->context
->iface
->name
,
1902 derpc_transport_string_by_transport(transport
),
1904 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
1907 pull
= ndr_pull_init_blob(&call
->pkt
.u
.request
.stub_and_verifier
, call
);
1908 NT_STATUS_HAVE_NO_MEMORY(pull
);
1910 pull
->flags
|= LIBNDR_FLAG_REF_ALLOC
;
1912 call
->ndr_pull
= pull
;
1914 if (!(call
->pkt
.drep
[0] & DCERPC_DREP_LE
)) {
1915 pull
->flags
|= LIBNDR_FLAG_BIGENDIAN
;
1918 status
= dcesrv_check_verification_trailer(call
);
1919 if (!NT_STATUS_IS_OK(status
)) {
1920 uint32_t faultcode
= DCERPC_FAULT_OTHER
;
1921 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
1922 faultcode
= DCERPC_FAULT_ACCESS_DENIED
;
1924 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1925 nt_errstr(status
)));
1926 return dcesrv_fault(call
, faultcode
);
1929 /* unravel the NDR for the packet */
1930 status
= call
->context
->iface
->ndr_pull(call
, call
, pull
, &call
->r
);
1931 if (!NT_STATUS_IS_OK(status
)) {
1932 uint8_t extra_flags
= 0;
1933 if (call
->fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
1934 /* we got an unknown call */
1935 DEBUG(3,(__location__
": Unknown RPC call %u on %s\n",
1936 call
->pkt
.u
.request
.opnum
,
1937 call
->context
->iface
->name
));
1938 dcesrv_save_call(call
, "unknown");
1939 extra_flags
|= DCERPC_PFC_FLAG_DID_NOT_EXECUTE
;
1941 dcesrv_save_call(call
, "pullfail");
1944 return dcesrv_fault_with_flags(call
, call
->fault_code
, extra_flags
);
1947 dcesrv_save_ndr_fuzz_seed(call
->pkt
.u
.request
.stub_and_verifier
,
1951 if (pull
->offset
!= pull
->data_size
) {
1952 dcesrv_save_call(call
, "extrabytes");
1953 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1954 pull
->data_size
- pull
->offset
));
1957 /* call the dispatch function */
1958 status
= call
->context
->iface
->dispatch(call
, call
, call
->r
);
1959 if (!NT_STATUS_IS_OK(status
)) {
1960 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1961 call
->context
->iface
->name
,
1962 call
->pkt
.u
.request
.opnum
,
1963 dcerpc_errstr(pull
, call
->fault_code
)));
1964 return dcesrv_fault(call
, call
->fault_code
);
1967 /* add the call to the pending list */
1968 dcesrv_call_set_list(call
, DCESRV_LIST_PENDING_CALL_LIST
);
1970 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
) {
1971 return NT_STATUS_OK
;
1974 return dcesrv_reply(call
);
1979 remove the call from the right list when freed
1981 static int dcesrv_call_dequeue(struct dcesrv_call_state
*call
)
1983 dcesrv_call_set_list(call
, DCESRV_LIST_NONE
);
1987 _PUBLIC_
const struct tsocket_address
*dcesrv_connection_get_local_address(struct dcesrv_connection
*conn
)
1989 return conn
->local_address
;
1992 _PUBLIC_
const struct tsocket_address
*dcesrv_connection_get_remote_address(struct dcesrv_connection
*conn
)
1994 return conn
->remote_address
;
1998 process some input to a dcerpc endpoint server.
2000 static NTSTATUS
dcesrv_process_ncacn_packet(struct dcesrv_connection
*dce_conn
,
2001 struct ncacn_packet
*pkt
,
2005 struct dcesrv_call_state
*call
;
2006 struct dcesrv_call_state
*existing
= NULL
;
2007 size_t num_auth_ctx
= 0;
2008 enum dcerpc_AuthType auth_type
= 0;
2009 enum dcerpc_AuthLevel auth_level
= 0;
2010 uint32_t auth_context_id
= 0;
2011 bool auth_invalid
= false;
2013 call
= talloc_zero(dce_conn
, struct dcesrv_call_state
);
2015 data_blob_free(&blob
);
2017 return NT_STATUS_NO_MEMORY
;
2019 call
->conn
= dce_conn
;
2020 call
->event_ctx
= dce_conn
->event_ctx
;
2021 call
->state_flags
= call
->conn
->state_flags
;
2022 call
->time
= timeval_current();
2023 call
->list
= DCESRV_LIST_NONE
;
2025 talloc_steal(call
, pkt
);
2026 talloc_steal(call
, blob
.data
);
2029 if (dce_conn
->max_auth_states
== 0) {
2030 call
->auth_state
= dce_conn
->default_auth_state
;
2031 } else if (call
->pkt
.auth_length
== 0) {
2032 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
&&
2033 dce_conn
->default_auth_level_connect
!= NULL
)
2035 call
->auth_state
= dce_conn
->default_auth_level_connect
;
2037 call
->auth_state
= dce_conn
->default_auth_state
;
2041 if (call
->auth_state
== NULL
) {
2042 struct dcesrv_auth
*a
= NULL
;
2043 bool check_type_level
= true;
2045 auth_type
= dcerpc_get_auth_type(&blob
);
2046 auth_level
= dcerpc_get_auth_level(&blob
);
2047 auth_context_id
= dcerpc_get_auth_context_id(&blob
);
2049 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2050 if (!(call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_FIRST
)) {
2051 check_type_level
= false;
2053 dce_conn
->default_auth_level_connect
= NULL
;
2054 if (auth_level
== DCERPC_AUTH_LEVEL_CONNECT
) {
2055 dce_conn
->got_explicit_auth_level_connect
= true;
2059 for (a
= dce_conn
->auth_states
; a
!= NULL
; a
= a
->next
) {
2062 if (a
->auth_context_id
!= auth_context_id
) {
2066 if (a
->auth_type
!= auth_type
) {
2067 auth_invalid
= true;
2069 if (a
->auth_level
!= auth_level
) {
2070 auth_invalid
= true;
2073 if (check_type_level
&& auth_invalid
) {
2074 a
->auth_invalid
= true;
2077 DLIST_PROMOTE(dce_conn
->auth_states
, a
);
2078 call
->auth_state
= a
;
2083 if (call
->auth_state
== NULL
) {
2084 struct dcesrv_auth
*a
= NULL
;
2086 if (num_auth_ctx
>= dce_conn
->max_auth_states
) {
2087 return dcesrv_fault_disconnect(call
,
2088 DCERPC_NCA_S_PROTO_ERROR
);
2091 a
= dcesrv_auth_create(dce_conn
);
2094 return NT_STATUS_NO_MEMORY
;
2096 DLIST_ADD(dce_conn
->auth_states
, a
);
2097 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2099 * This can never be valid.
2101 auth_invalid
= true;
2102 a
->auth_invalid
= true;
2104 call
->auth_state
= a
;
2107 talloc_set_destructor(call
, dcesrv_call_dequeue
);
2109 if (call
->conn
->allow_bind
) {
2111 * Only one bind is possible per connection
2113 call
->conn
->allow_bind
= false;
2114 return dcesrv_bind(call
);
2117 /* we have to check the signing here, before combining the
2119 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2120 dcesrv_default_auth_state_prepare_request(call
);
2122 if (call
->auth_state
->auth_started
&&
2123 !call
->auth_state
->auth_finished
) {
2124 return dcesrv_fault_disconnect(call
,
2125 DCERPC_NCA_S_PROTO_ERROR
);
2128 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
2130 call
->pkt
.u
.request
.stub_and_verifier
.length
,
2131 0, /* required_flags */
2132 DCERPC_PFC_FLAG_FIRST
|
2133 DCERPC_PFC_FLAG_LAST
|
2134 DCERPC_PFC_FLAG_PENDING_CANCEL
|
2135 0x08 | /* this is not defined, but should be ignored */
2136 DCERPC_PFC_FLAG_CONC_MPX
|
2137 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
2138 DCERPC_PFC_FLAG_MAYBE
|
2139 DCERPC_PFC_FLAG_OBJECT_UUID
);
2140 if (!NT_STATUS_IS_OK(status
)) {
2141 return dcesrv_fault_disconnect(call
,
2142 DCERPC_NCA_S_PROTO_ERROR
);
2145 if (call
->pkt
.frag_length
> DCERPC_FRAG_MAX_SIZE
) {
2147 * We don't use dcesrv_fault_disconnect()
2148 * here, because we don't want to set
2149 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2151 * Note that we don't check against the negotiated
2152 * max_recv_frag, but a hard coded value.
2154 return dcesrv_fault_disconnect0(call
, DCERPC_NCA_S_PROTO_ERROR
);
2157 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_FIRST
) {
2158 if (dce_conn
->pending_call_list
!= NULL
) {
2160 * concurrent requests are only allowed
2161 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2163 if (!(dce_conn
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
2164 return dcesrv_fault_disconnect0(call
,
2165 DCERPC_NCA_S_PROTO_ERROR
);
2168 /* only one request is possible in the fragmented list */
2169 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
2170 call
->fault_code
= DCERPC_NCA_S_PROTO_ERROR
;
2172 existing
= dcesrv_find_fragmented_call(dce_conn
,
2174 if (existing
!= NULL
&& call
->auth_state
!= existing
->auth_state
) {
2175 call
->context
= dcesrv_find_context(call
->conn
,
2176 call
->pkt
.u
.request
.context_id
);
2178 if (call
->pkt
.auth_length
!= 0 && existing
->context
== call
->context
) {
2179 call
->fault_code
= DCERPC_FAULT_SEC_PKG_ERROR
;
2182 if (!(dce_conn
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
2184 * Without DCERPC_PFC_FLAG_CONC_MPX
2185 * we need to return the FAULT on the
2186 * already existing call.
2188 * This is important to get the
2189 * call_id and context_id right.
2191 dce_conn
->incoming_fragmented_call_list
->fault_code
= call
->fault_code
;
2193 call
= dce_conn
->incoming_fragmented_call_list
;
2195 if (existing
!= NULL
) {
2196 call
->context
= existing
->context
;
2198 return dcesrv_fault_disconnect0(call
, call
->fault_code
);
2200 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_PENDING_CANCEL
) {
2201 return dcesrv_fault_disconnect(call
,
2202 DCERPC_FAULT_NO_CALL_ACTIVE
);
2204 call
->context
= dcesrv_find_context(call
->conn
,
2205 call
->pkt
.u
.request
.context_id
);
2206 if (call
->context
== NULL
) {
2207 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
2208 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2213 existing
= dcesrv_find_fragmented_call(dce_conn
,
2215 if (existing
== NULL
) {
2216 if (!(dce_conn
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
2218 * Without DCERPC_PFC_FLAG_CONC_MPX
2219 * we need to return the FAULT on the
2220 * already existing call.
2222 * This is important to get the
2223 * call_id and context_id right.
2225 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
2227 call
= dce_conn
->incoming_fragmented_call_list
;
2229 return dcesrv_fault_disconnect0(call
,
2230 DCERPC_NCA_S_PROTO_ERROR
);
2232 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
2233 return dcesrv_fault_disconnect0(call
, DCERPC_NCA_S_PROTO_ERROR
);
2235 call
->context
= dcesrv_find_context(call
->conn
,
2236 call
->pkt
.u
.request
.context_id
);
2237 if (call
->context
== NULL
) {
2238 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
2239 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2242 return dcesrv_fault_disconnect0(call
,
2243 DCERPC_FAULT_ACCESS_DENIED
);
2245 return dcesrv_fault_disconnect0(call
,
2246 DCERPC_NCA_S_PROTO_ERROR
);
2249 if (call
->pkt
.ptype
!= existing
->pkt
.ptype
) {
2250 /* trying to play silly buggers are we? */
2251 return dcesrv_fault_disconnect(existing
,
2252 DCERPC_NCA_S_PROTO_ERROR
);
2254 cmp
= memcmp(call
->pkt
.drep
, existing
->pkt
.drep
,
2257 return dcesrv_fault_disconnect(existing
,
2258 DCERPC_NCA_S_PROTO_ERROR
);
2260 call
->auth_state
= existing
->auth_state
;
2261 call
->context
= existing
->context
;
2265 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
2267 uint8_t payload_offset
= DCERPC_REQUEST_LENGTH
;
2269 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_OBJECT_UUID
) {
2270 payload_offset
+= 16;
2273 ok
= dcesrv_auth_pkt_pull(call
, &blob
,
2274 0, /* required_flags */
2275 DCERPC_PFC_FLAG_FIRST
|
2276 DCERPC_PFC_FLAG_LAST
|
2277 DCERPC_PFC_FLAG_PENDING_CANCEL
|
2278 0x08 | /* this is not defined, but should be ignored */
2279 DCERPC_PFC_FLAG_CONC_MPX
|
2280 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
2281 DCERPC_PFC_FLAG_MAYBE
|
2282 DCERPC_PFC_FLAG_OBJECT_UUID
,
2284 &call
->pkt
.u
.request
.stub_and_verifier
);
2287 * We don't use dcesrv_fault_disconnect()
2288 * here, because we don't want to set
2289 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2291 if (call
->fault_code
== 0) {
2292 call
->fault_code
= DCERPC_FAULT_ACCESS_DENIED
;
2294 return dcesrv_fault_disconnect0(call
, call
->fault_code
);
2298 /* see if this is a continued packet */
2299 if (existing
!= NULL
) {
2300 struct dcerpc_request
*er
= &existing
->pkt
.u
.request
;
2301 const struct dcerpc_request
*nr
= &call
->pkt
.u
.request
;
2307 * Up to 4 MByte are allowed by all fragments
2309 available
= dce_conn
->max_total_request_size
;
2310 if (er
->stub_and_verifier
.length
> available
) {
2311 return dcesrv_fault_disconnect0(existing
,
2312 DCERPC_FAULT_ACCESS_DENIED
);
2314 available
-= er
->stub_and_verifier
.length
;
2315 if (nr
->alloc_hint
> available
) {
2316 return dcesrv_fault_disconnect0(existing
,
2317 DCERPC_FAULT_ACCESS_DENIED
);
2319 if (nr
->stub_and_verifier
.length
> available
) {
2320 return dcesrv_fault_disconnect0(existing
,
2321 DCERPC_FAULT_ACCESS_DENIED
);
2323 alloc_hint
= er
->stub_and_verifier
.length
+ nr
->alloc_hint
;
2324 /* allocate at least 1 byte */
2325 alloc_hint
= MAX(alloc_hint
, 1);
2326 alloc_size
= er
->stub_and_verifier
.length
+
2327 nr
->stub_and_verifier
.length
;
2328 alloc_size
= MAX(alloc_size
, alloc_hint
);
2330 er
->stub_and_verifier
.data
=
2331 talloc_realloc(existing
,
2332 er
->stub_and_verifier
.data
,
2333 uint8_t, alloc_size
);
2334 if (er
->stub_and_verifier
.data
== NULL
) {
2336 return dcesrv_fault_with_flags(existing
,
2337 DCERPC_FAULT_OUT_OF_RESOURCES
,
2338 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
2340 memcpy(er
->stub_and_verifier
.data
+
2341 er
->stub_and_verifier
.length
,
2342 nr
->stub_and_verifier
.data
,
2343 nr
->stub_and_verifier
.length
);
2344 er
->stub_and_verifier
.length
+= nr
->stub_and_verifier
.length
;
2346 existing
->pkt
.pfc_flags
|= (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_LAST
);
2352 /* this may not be the last pdu in the chain - if its isn't then
2353 just put it on the incoming_fragmented_call_list and wait for the rest */
2354 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
&&
2355 !(call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
2357 * Up to 4 MByte are allowed by all fragments
2359 if (call
->pkt
.u
.request
.alloc_hint
> dce_conn
->max_total_request_size
) {
2360 return dcesrv_fault_disconnect0(call
,
2361 DCERPC_FAULT_ACCESS_DENIED
);
2363 dcesrv_call_set_list(call
, DCESRV_LIST_FRAGMENTED_CALL_LIST
);
2364 return NT_STATUS_OK
;
2367 /* This removes any fragments we may have had stashed away */
2368 dcesrv_call_set_list(call
, DCESRV_LIST_NONE
);
2370 switch (call
->pkt
.ptype
) {
2371 case DCERPC_PKT_BIND
:
2372 status
= dcesrv_bind_nak(call
,
2373 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED
);
2375 case DCERPC_PKT_AUTH3
:
2376 status
= dcesrv_auth3(call
);
2378 case DCERPC_PKT_ALTER
:
2379 status
= dcesrv_alter(call
);
2381 case DCERPC_PKT_REQUEST
:
2382 status
= dcesrv_request(call
);
2384 case DCERPC_PKT_CO_CANCEL
:
2385 case DCERPC_PKT_ORPHANED
:
2387 * Window just ignores CO_CANCEL and ORPHANED,
2390 status
= NT_STATUS_OK
;
2393 case DCERPC_PKT_BIND_ACK
:
2394 case DCERPC_PKT_BIND_NAK
:
2395 case DCERPC_PKT_ALTER_RESP
:
2396 case DCERPC_PKT_RESPONSE
:
2397 case DCERPC_PKT_FAULT
:
2398 case DCERPC_PKT_SHUTDOWN
:
2400 status
= dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
2404 /* if we are going to be sending a reply then add
2405 it to the list of pending calls. We add it to the end to keep the call
2406 list in the order we will answer */
2407 if (!NT_STATUS_IS_OK(status
)) {
2414 _PUBLIC_ NTSTATUS
dcesrv_init_context(TALLOC_CTX
*mem_ctx
,
2415 struct loadparm_context
*lp_ctx
,
2416 struct dcesrv_context_callbacks
*cb
,
2417 struct dcesrv_context
**_dce_ctx
)
2419 struct dcesrv_context
*dce_ctx
;
2422 return NT_STATUS_INVALID_PARAMETER
;
2425 dce_ctx
= talloc_zero(mem_ctx
, struct dcesrv_context
);
2426 NT_STATUS_HAVE_NO_MEMORY(dce_ctx
);
2428 if (uid_wrapper_enabled()) {
2429 setenv("UID_WRAPPER_MYUID", "1", 1);
2431 dce_ctx
->initial_euid
= geteuid();
2432 if (uid_wrapper_enabled()) {
2433 unsetenv("UID_WRAPPER_MYUID");
2436 dce_ctx
->endpoint_list
= NULL
;
2437 dce_ctx
->lp_ctx
= lp_ctx
;
2438 dce_ctx
->assoc_groups_idr
= idr_init(dce_ctx
);
2439 if (dce_ctx
->assoc_groups_idr
== NULL
) {
2440 TALLOC_FREE(dce_ctx
);
2441 return NT_STATUS_NO_MEMORY
;
2443 dce_ctx
->broken_connections
= NULL
;
2444 dce_ctx
->callbacks
= cb
;
2446 *_dce_ctx
= dce_ctx
;
2447 return NT_STATUS_OK
;
2451 * @brief Set callback functions on an existing dcesrv_context
2453 * This allows to reset callbacks initially set via
2454 * dcesrv_init_context()
2456 * @param[in] dce_ctx The context to set the callbacks on
2457 * @param[in] cb The callbacks to set on dce_ctx
2459 _PUBLIC_
void dcesrv_context_set_callbacks(
2460 struct dcesrv_context
*dce_ctx
,
2461 struct dcesrv_context_callbacks
*cb
)
2463 dce_ctx
->callbacks
= cb
;
2466 _PUBLIC_ NTSTATUS
dcesrv_init_ep_servers(struct dcesrv_context
*dce_ctx
,
2467 const char **endpoint_servers
)
2472 if (endpoint_servers
== NULL
) {
2473 DBG_ERR("No endpoint servers configured\n");
2474 return NT_STATUS_INTERNAL_ERROR
;
2477 for (i
=0;endpoint_servers
[i
];i
++) {
2478 status
= dcesrv_init_ep_server(dce_ctx
, endpoint_servers
[i
]);
2479 if (!NT_STATUS_IS_OK(status
)) {
2480 DBG_ERR("failed to init endpoint server = '%s': %s\n",
2481 endpoint_servers
[i
], nt_errstr(status
));
2486 return NT_STATUS_OK
;
2489 /* the list of currently registered DCERPC endpoint servers.
2491 static struct ep_server
{
2492 struct dcesrv_endpoint_server
*ep_server
;
2493 } *ep_servers
= NULL
;
2494 static int num_ep_servers
= 0;
2496 _PUBLIC_ NTSTATUS
dcesrv_init_registered_ep_servers(
2497 struct dcesrv_context
*dce_ctx
)
2502 for (i
= 0; i
< num_ep_servers
; i
++) {
2503 status
= dcesrv_init_ep_server(dce_ctx
,
2504 ep_servers
[i
].ep_server
->name
);
2505 if (!NT_STATUS_IS_OK(status
)) {
2510 return NT_STATUS_OK
;
2513 _PUBLIC_ NTSTATUS
dcesrv_init_ep_server(struct dcesrv_context
*dce_ctx
,
2514 const char *ep_server_name
)
2516 struct dcesrv_endpoint_server
*ep_server
= NULL
;
2519 ep_server
= discard_const_p(struct dcesrv_endpoint_server
,
2520 dcesrv_ep_server_byname(ep_server_name
));
2521 if (ep_server
== NULL
) {
2522 DBG_ERR("Failed to find endpoint server '%s'\n",
2524 return NT_STATUS_INTERNAL_ERROR
;
2527 if (ep_server
->initialized
) {
2528 return NT_STATUS_OK
;
2531 status
= ep_server
->init_server(dce_ctx
, ep_server
);
2532 if (!NT_STATUS_IS_OK(status
)) {
2533 DBG_ERR("Failed to init endpoint server '%s': %s\n",
2534 ep_server_name
, nt_errstr(status
));
2538 ep_server
->initialized
= true;
2540 return NT_STATUS_OK
;
2543 _PUBLIC_ NTSTATUS
dcesrv_shutdown_registered_ep_servers(
2544 struct dcesrv_context
*dce_ctx
)
2549 for (i
= 0; i
< num_ep_servers
; i
++) {
2550 status
= dcesrv_shutdown_ep_server(dce_ctx
,
2551 ep_servers
[i
].ep_server
->name
);
2552 if (!NT_STATUS_IS_OK(status
)) {
2557 return NT_STATUS_OK
;
2560 _PUBLIC_ NTSTATUS
dcesrv_shutdown_ep_server(struct dcesrv_context
*dce_ctx
,
2561 const char *ep_server_name
)
2563 struct dcesrv_endpoint_server
*ep_server
= NULL
;
2566 ep_server
= discard_const_p(struct dcesrv_endpoint_server
,
2567 dcesrv_ep_server_byname(ep_server_name
));
2568 if (ep_server
== NULL
) {
2569 DBG_ERR("Failed to find endpoint server '%s'\n",
2571 return NT_STATUS_INTERNAL_ERROR
;
2574 if (!ep_server
->initialized
) {
2575 return NT_STATUS_OK
;
2578 DBG_INFO("Shutting down DCE/RPC endpoint server '%s'\n",
2581 status
= ep_server
->shutdown_server(dce_ctx
, ep_server
);
2582 if (!NT_STATUS_IS_OK(status
)) {
2583 DBG_ERR("Failed to shutdown endpoint server '%s': %s\n",
2584 ep_server_name
, nt_errstr(status
));
2588 ep_server
->initialized
= false;
2590 return NT_STATUS_OK
;
2594 register a DCERPC endpoint server.
2596 The 'name' can be later used by other backends to find the operations
2597 structure for this backend.
2600 _PUBLIC_ NTSTATUS
dcerpc_register_ep_server(const struct dcesrv_endpoint_server
*ep_server
)
2603 if (dcesrv_ep_server_byname(ep_server
->name
) != NULL
) {
2604 /* its already registered! */
2605 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2607 return NT_STATUS_OBJECT_NAME_COLLISION
;
2610 ep_servers
= realloc_p(ep_servers
, struct ep_server
, num_ep_servers
+1);
2612 smb_panic("out of memory in dcerpc_register");
2615 ep_servers
[num_ep_servers
].ep_server
= smb_xmemdup(ep_server
, sizeof(*ep_server
));
2616 ep_servers
[num_ep_servers
].ep_server
->name
= smb_xstrdup(ep_server
->name
);
2620 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2623 return NT_STATUS_OK
;
2627 return the operations structure for a named backend of the specified type
2629 _PUBLIC_
const struct dcesrv_endpoint_server
*dcesrv_ep_server_byname(const char *name
)
2633 for (i
=0;i
<num_ep_servers
;i
++) {
2634 if (strcmp(ep_servers
[i
].ep_server
->name
, name
) == 0) {
2635 return ep_servers
[i
].ep_server
;
2643 return the DCERPC module version, and the size of some critical types
2644 This can be used by endpoint server modules to either detect compilation errors, or provide
2645 multiple implementations for different smbd compilation options in one module
2647 const struct dcesrv_critical_sizes
*dcerpc_module_version(void)
2649 static const struct dcesrv_critical_sizes critical_sizes
= {
2650 DCERPC_MODULE_VERSION
,
2651 sizeof(struct dcesrv_context
),
2652 sizeof(struct dcesrv_endpoint
),
2653 sizeof(struct dcesrv_endpoint_server
),
2654 sizeof(struct dcesrv_interface
),
2655 sizeof(struct dcesrv_if_list
),
2656 sizeof(struct dcesrv_connection
),
2657 sizeof(struct dcesrv_call_state
),
2658 sizeof(struct dcesrv_auth
),
2659 sizeof(struct dcesrv_handle
)
2662 return &critical_sizes
;
2665 _PUBLIC_
void dcesrv_terminate_connection(struct dcesrv_connection
*dce_conn
, const char *reason
)
2667 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
2668 struct dcesrv_auth
*a
= NULL
;
2670 dce_conn
->wait_send
= NULL
;
2671 dce_conn
->wait_recv
= NULL
;
2672 dce_conn
->wait_private
= NULL
;
2674 dce_conn
->allow_bind
= false;
2675 dce_conn
->allow_alter
= false;
2677 dce_conn
->default_auth_state
->auth_invalid
= true;
2679 for (a
= dce_conn
->auth_states
; a
!= NULL
; a
= a
->next
) {
2680 a
->auth_invalid
= true;
2683 if (dce_conn
->pending_call_list
== NULL
) {
2684 char *full_reason
= talloc_asprintf(dce_conn
, "dcesrv: %s", reason
);
2686 DLIST_REMOVE(dce_ctx
->broken_connections
, dce_conn
);
2687 dce_conn
->transport
.terminate_connection(dce_conn
,
2688 full_reason
? full_reason
: reason
);
2692 if (dce_conn
->terminate
!= NULL
) {
2696 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2698 dce_conn
->terminate
= talloc_strdup(dce_conn
, reason
);
2699 if (dce_conn
->terminate
== NULL
) {
2700 dce_conn
->terminate
= "dcesrv: deferred terminating connection - no memory";
2702 DLIST_ADD_END(dce_ctx
->broken_connections
, dce_conn
);
2705 _PUBLIC_
void dcesrv_cleanup_broken_connections(struct dcesrv_context
*dce_ctx
)
2707 struct dcesrv_connection
*cur
, *next
;
2709 next
= dce_ctx
->broken_connections
;
2710 while (next
!= NULL
) {
2714 if (cur
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
2715 struct dcesrv_connection_context
*context_cur
, *context_next
;
2717 context_next
= cur
->contexts
;
2718 while (context_next
!= NULL
) {
2719 context_cur
= context_next
;
2720 context_next
= context_cur
->next
;
2722 dcesrv_connection_context_destructor(context_cur
);
2726 dcesrv_terminate_connection(cur
, cur
->terminate
);
2730 struct dcesrv_sock_reply_state
{
2731 struct dcesrv_connection
*dce_conn
;
2732 struct dcesrv_call_state
*call
;
2736 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
);
2737 static void dcesrv_call_terminate_step1(struct tevent_req
*subreq
);
2739 _PUBLIC_
void dcesrv_sock_report_output_data(struct dcesrv_connection
*dce_conn
)
2741 struct dcesrv_call_state
*call
;
2743 call
= dce_conn
->call_list
;
2744 if (!call
|| !call
->replies
) {
2748 while (call
->replies
) {
2749 struct data_blob_list_item
*rep
= call
->replies
;
2750 struct dcesrv_sock_reply_state
*substate
;
2751 struct tevent_req
*subreq
;
2753 substate
= talloc_zero(call
, struct dcesrv_sock_reply_state
);
2755 dcesrv_terminate_connection(dce_conn
, "no memory");
2759 substate
->dce_conn
= dce_conn
;
2760 substate
->call
= NULL
;
2762 DLIST_REMOVE(call
->replies
, rep
);
2764 if (call
->replies
== NULL
&& call
->terminate_reason
== NULL
) {
2765 substate
->call
= call
;
2768 substate
->iov
.iov_base
= (void *) rep
->blob
.data
;
2769 substate
->iov
.iov_len
= rep
->blob
.length
;
2771 subreq
= tstream_writev_queue_send(substate
,
2772 dce_conn
->event_ctx
,
2774 dce_conn
->send_queue
,
2777 dcesrv_terminate_connection(dce_conn
, "no memory");
2780 tevent_req_set_callback(subreq
, dcesrv_sock_reply_done
,
2784 if (call
->terminate_reason
!= NULL
) {
2785 struct tevent_req
*subreq
;
2787 subreq
= tevent_queue_wait_send(call
,
2788 dce_conn
->event_ctx
,
2789 dce_conn
->send_queue
);
2791 dcesrv_terminate_connection(dce_conn
, __location__
);
2794 tevent_req_set_callback(subreq
, dcesrv_call_terminate_step1
,
2798 DLIST_REMOVE(call
->conn
->call_list
, call
);
2799 call
->list
= DCESRV_LIST_NONE
;
2802 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
)
2804 struct dcesrv_sock_reply_state
*substate
= tevent_req_callback_data(subreq
,
2805 struct dcesrv_sock_reply_state
);
2809 struct dcesrv_call_state
*call
= substate
->call
;
2811 ret
= tstream_writev_queue_recv(subreq
, &sys_errno
);
2812 TALLOC_FREE(subreq
);
2814 status
= map_nt_error_from_unix_common(sys_errno
);
2815 dcesrv_terminate_connection(substate
->dce_conn
, nt_errstr(status
));
2819 talloc_free(substate
);
2825 static void dcesrv_call_terminate_step2(struct tevent_req
*subreq
);
2827 static void dcesrv_call_terminate_step1(struct tevent_req
*subreq
)
2829 struct dcesrv_call_state
*call
= tevent_req_callback_data(subreq
,
2830 struct dcesrv_call_state
);
2834 /* make sure we stop send queue before removing subreq */
2835 tevent_queue_stop(call
->conn
->send_queue
);
2837 ok
= tevent_queue_wait_recv(subreq
);
2838 TALLOC_FREE(subreq
);
2840 dcesrv_terminate_connection(call
->conn
, __location__
);
2844 /* disconnect after 200 usecs */
2845 tv
= timeval_current_ofs_usec(200);
2846 subreq
= tevent_wakeup_send(call
, call
->conn
->event_ctx
, tv
);
2847 if (subreq
== NULL
) {
2848 dcesrv_terminate_connection(call
->conn
, __location__
);
2851 tevent_req_set_callback(subreq
, dcesrv_call_terminate_step2
,
2855 static void dcesrv_call_terminate_step2(struct tevent_req
*subreq
)
2857 struct dcesrv_call_state
*call
= tevent_req_callback_data(subreq
,
2858 struct dcesrv_call_state
);
2861 ok
= tevent_wakeup_recv(subreq
);
2862 TALLOC_FREE(subreq
);
2864 dcesrv_terminate_connection(call
->conn
, __location__
);
2868 dcesrv_terminate_connection(call
->conn
, call
->terminate_reason
);
2871 static void dcesrv_conn_wait_done(struct tevent_req
*subreq
);
2873 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
)
2875 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
2876 struct dcesrv_connection
);
2877 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
2878 struct ncacn_packet
*pkt
;
2882 if (dce_conn
->terminate
) {
2884 * if the current connection is broken
2885 * we need to clean it up before any other connection
2887 dcesrv_terminate_connection(dce_conn
, dce_conn
->terminate
);
2888 dcesrv_cleanup_broken_connections(dce_ctx
);
2892 dcesrv_cleanup_broken_connections(dce_ctx
);
2894 status
= dcerpc_read_ncacn_packet_recv(subreq
, dce_conn
,
2896 TALLOC_FREE(subreq
);
2897 if (!NT_STATUS_IS_OK(status
)) {
2898 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2902 dcesrv_loop_next_packet(dce_conn
, pkt
, buffer
);
2906 * @brief Start the dcesrv loop, inducing the bind as a blob
2908 * Like dcesrv_connection_loop_start() but used from connections
2909 * where the caller has already read the dcerpc bind packet from
2910 * the socket and is available as a DATA_BLOB.
2912 * @param[in] dce_conn The connection to start
2913 * @param[in] pkt The parsed bind packet
2914 * @param[in] buffer The full binary bind including auth data
2916 void dcesrv_loop_next_packet(
2917 struct dcesrv_connection
*dce_conn
,
2918 struct ncacn_packet
*pkt
,
2921 struct tevent_req
*subreq
= NULL
;
2924 status
= dcesrv_process_ncacn_packet(dce_conn
, pkt
, buffer
);
2925 if (!NT_STATUS_IS_OK(status
)) {
2926 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2931 * This is used to block the connection during
2932 * pending authentication.
2934 if (dce_conn
->wait_send
!= NULL
) {
2935 subreq
= dce_conn
->wait_send(dce_conn
,
2936 dce_conn
->event_ctx
,
2937 dce_conn
->wait_private
);
2939 status
= NT_STATUS_NO_MEMORY
;
2940 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2943 tevent_req_set_callback(subreq
, dcesrv_conn_wait_done
, dce_conn
);
2947 subreq
= dcerpc_read_ncacn_packet_send(dce_conn
,
2948 dce_conn
->event_ctx
,
2951 status
= NT_STATUS_NO_MEMORY
;
2952 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2955 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dce_conn
);
2958 static void dcesrv_conn_wait_done(struct tevent_req
*subreq
)
2960 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
2961 struct dcesrv_connection
);
2962 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
2965 if (dce_conn
->terminate
) {
2967 * if the current connection is broken
2968 * we need to clean it up before any other connection
2970 dcesrv_terminate_connection(dce_conn
, dce_conn
->terminate
);
2971 dcesrv_cleanup_broken_connections(dce_ctx
);
2975 dcesrv_cleanup_broken_connections(dce_ctx
);
2977 status
= dce_conn
->wait_recv(subreq
);
2978 dce_conn
->wait_send
= NULL
;
2979 dce_conn
->wait_recv
= NULL
;
2980 dce_conn
->wait_private
= NULL
;
2981 TALLOC_FREE(subreq
);
2982 if (!NT_STATUS_IS_OK(status
)) {
2983 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2987 status
= dcesrv_connection_loop_start(dce_conn
);
2988 if (!NT_STATUS_IS_OK(status
)) {
2989 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2995 * retrieve credentials from a dce_call
2997 _PUBLIC_
struct cli_credentials
*dcesrv_call_credentials(struct dcesrv_call_state
*dce_call
)
2999 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3000 SMB_ASSERT(auth
->auth_finished
);
3001 return auth
->session_info
->credentials
;
3005 * returns true if this is an authenticated call
3007 _PUBLIC_
bool dcesrv_call_authenticated(struct dcesrv_call_state
*dce_call
)
3009 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3010 enum security_user_level level
;
3011 SMB_ASSERT(auth
->auth_finished
);
3012 level
= security_session_user_level(auth
->session_info
, NULL
);
3013 return level
>= SECURITY_USER
;
3017 * retrieve account_name for a dce_call
3019 _PUBLIC_
const char *dcesrv_call_account_name(struct dcesrv_call_state
*dce_call
)
3021 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3022 SMB_ASSERT(auth
->auth_finished
);
3023 return auth
->session_info
->info
->account_name
;
3027 * retrieve session_info from a dce_call
3029 _PUBLIC_
struct auth_session_info
*dcesrv_call_session_info(struct dcesrv_call_state
*dce_call
)
3031 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3032 SMB_ASSERT(auth
->auth_finished
);
3033 return auth
->session_info
;
3037 * retrieve auth type/level from a dce_call
3039 _PUBLIC_
void dcesrv_call_auth_info(struct dcesrv_call_state
*dce_call
,
3040 enum dcerpc_AuthType
*auth_type
,
3041 enum dcerpc_AuthLevel
*auth_level
)
3043 struct dcesrv_auth
*auth
= dce_call
->auth_state
;
3045 SMB_ASSERT(auth
->auth_finished
);
3047 if (auth_type
!= NULL
) {
3048 *auth_type
= auth
->auth_type
;
3050 if (auth_level
!= NULL
) {
3051 *auth_level
= auth
->auth_level
;
3055 _PUBLIC_ NTSTATUS
dcesrv_connection_loop_start(struct dcesrv_connection
*conn
)
3057 struct tevent_req
*subreq
;
3059 subreq
= dcerpc_read_ncacn_packet_send(conn
,
3062 if (subreq
== NULL
) {
3063 return NT_STATUS_NO_MEMORY
;
3065 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, conn
);
3067 return NT_STATUS_OK
;
3070 _PUBLIC_ NTSTATUS
dcesrv_call_dispatch_local(struct dcesrv_call_state
*call
)
3073 struct ndr_pull
*pull
= NULL
;
3074 struct ndr_push
*push
= NULL
;
3075 struct data_blob_list_item
*rep
= NULL
;
3077 pull
= ndr_pull_init_blob(&call
->pkt
.u
.request
.stub_and_verifier
,
3080 return NT_STATUS_NO_MEMORY
;
3083 pull
->flags
|= LIBNDR_FLAG_REF_ALLOC
;
3085 call
->ndr_pull
= pull
;
3087 /* unravel the NDR for the packet */
3088 status
= call
->context
->iface
->ndr_pull(call
, call
, pull
, &call
->r
);
3089 if (!NT_STATUS_IS_OK(status
)) {
3090 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3091 call
->context
->iface
->name
,
3092 call
->pkt
.u
.request
.opnum
,
3093 dcerpc_errstr(call
, call
->fault_code
));
3094 return dcerpc_fault_to_nt_status(call
->fault_code
);
3097 status
= call
->context
->iface
->local(call
, call
, call
->r
);
3098 if (!NT_STATUS_IS_OK(status
)) {
3099 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3100 call
->context
->iface
->name
,
3101 call
->pkt
.u
.request
.opnum
,
3102 dcerpc_errstr(call
, call
->fault_code
));
3103 return dcerpc_fault_to_nt_status(call
->fault_code
);
3106 /* This can never go async for now! */
3107 SMB_ASSERT(!(call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
));
3109 /* call the reply function */
3110 status
= call
->context
->iface
->reply(call
, call
, call
->r
);
3111 if (!NT_STATUS_IS_OK(status
)) {
3112 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3113 call
->context
->iface
->name
,
3114 call
->pkt
.u
.request
.opnum
,
3115 dcerpc_errstr(call
, call
->fault_code
));
3116 return dcerpc_fault_to_nt_status(call
->fault_code
);
3119 push
= ndr_push_init_ctx(call
);
3121 return NT_STATUS_NO_MEMORY
;
3124 push
->ptr_count
= call
->ndr_pull
->ptr_count
;
3126 status
= call
->context
->iface
->ndr_push(call
, call
, push
, call
->r
);
3127 if (!NT_STATUS_IS_OK(status
)) {
3128 DBG_INFO("DCE/RPC fault in call %s:%02X - %s\n",
3129 call
->context
->iface
->name
,
3130 call
->pkt
.u
.request
.opnum
,
3131 dcerpc_errstr(call
, call
->fault_code
));
3132 return dcerpc_fault_to_nt_status(call
->fault_code
);
3135 rep
= talloc_zero(call
, struct data_blob_list_item
);
3137 return NT_STATUS_NO_MEMORY
;
3140 rep
->blob
= ndr_push_blob(push
);
3141 DLIST_ADD_END(call
->replies
, rep
);
3143 return NT_STATUS_OK
;