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
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "auth/auth.h"
25 #include "auth/gensec/gensec.h"
26 #include "../lib/util/dlinklist.h"
27 #include "rpc_server/dcerpc_server.h"
28 #include "rpc_server/dcerpc_server_proto.h"
29 #include "rpc_server/common/proto.h"
30 #include "librpc/rpc/dcerpc_proto.h"
31 #include "system/filesys.h"
32 #include "libcli/security/security.h"
33 #include "param/param.h"
34 #include "../lib/tsocket/tsocket.h"
35 #include "../libcli/named_pipe_auth/npa_tstream.h"
36 #include "smbd/service_stream.h"
37 #include "../lib/tsocket/tsocket.h"
38 #include "lib/socket/socket.h"
39 #include "smbd/process_model.h"
40 #include "lib/messaging/irpc.h"
41 #include "librpc/rpc/rpc_common.h"
42 #include "lib/util/samba_modules.h"
43 #include "librpc/gen_ndr/ndr_dcerpc.h"
45 extern const struct dcesrv_interface dcesrv_mgmt_interface
;
47 static NTSTATUS
dcesrv_negotiate_contexts(struct dcesrv_call_state
*call
,
48 const struct dcerpc_bind
*b
,
49 struct dcerpc_ack_ctx
*ack_ctx_list
);
52 find an association group given a assoc_group_id
54 static struct dcesrv_assoc_group
*dcesrv_assoc_group_find(struct dcesrv_context
*dce_ctx
,
59 id_ptr
= idr_find(dce_ctx
->assoc_groups_idr
, id
);
63 return talloc_get_type_abort(id_ptr
, struct dcesrv_assoc_group
);
67 take a reference to an existing association group
69 static struct dcesrv_assoc_group
*dcesrv_assoc_group_reference(TALLOC_CTX
*mem_ctx
,
70 struct dcesrv_context
*dce_ctx
,
73 struct dcesrv_assoc_group
*assoc_group
;
75 assoc_group
= dcesrv_assoc_group_find(dce_ctx
, id
);
76 if (assoc_group
== NULL
) {
77 DEBUG(2,(__location__
": Failed to find assoc_group 0x%08x\n", id
));
80 return talloc_reference(mem_ctx
, assoc_group
);
83 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group
*assoc_group
)
86 ret
= idr_remove(assoc_group
->dce_ctx
->assoc_groups_idr
, assoc_group
->id
);
88 DEBUG(0,(__location__
": Failed to remove assoc_group 0x%08x\n",
95 allocate a new association group
97 static struct dcesrv_assoc_group
*dcesrv_assoc_group_new(TALLOC_CTX
*mem_ctx
,
98 struct dcesrv_context
*dce_ctx
)
100 struct dcesrv_assoc_group
*assoc_group
;
103 assoc_group
= talloc_zero(mem_ctx
, struct dcesrv_assoc_group
);
104 if (assoc_group
== NULL
) {
108 id
= idr_get_new_random(dce_ctx
->assoc_groups_idr
, assoc_group
, UINT16_MAX
);
110 talloc_free(assoc_group
);
111 DEBUG(0,(__location__
": Out of association groups!\n"));
115 assoc_group
->id
= id
;
116 assoc_group
->dce_ctx
= dce_ctx
;
118 talloc_set_destructor(assoc_group
, dcesrv_assoc_group_destructor
);
125 see if two endpoints match
127 static bool endpoints_match(const struct dcerpc_binding
*ep1
,
128 const struct dcerpc_binding
*ep2
)
130 enum dcerpc_transport_t t1
;
131 enum dcerpc_transport_t t2
;
135 t1
= dcerpc_binding_get_transport(ep1
);
136 t2
= dcerpc_binding_get_transport(ep2
);
138 e1
= dcerpc_binding_get_string_option(ep1
, "endpoint");
139 e2
= dcerpc_binding_get_string_option(ep2
, "endpoint");
149 if (strcasecmp(e1
, e2
) != 0) {
157 find an endpoint in the dcesrv_context
159 static struct dcesrv_endpoint
*find_endpoint(struct dcesrv_context
*dce_ctx
,
160 const struct dcerpc_binding
*ep_description
)
162 struct dcesrv_endpoint
*ep
;
163 for (ep
=dce_ctx
->endpoint_list
; ep
; ep
=ep
->next
) {
164 if (endpoints_match(ep
->ep_description
, ep_description
)) {
172 find a registered context_id from a bind or alter_context
174 static struct dcesrv_connection_context
*dcesrv_find_context(struct dcesrv_connection
*conn
,
177 struct dcesrv_connection_context
*c
;
178 for (c
=conn
->contexts
;c
;c
=c
->next
) {
179 if (c
->context_id
== context_id
) return c
;
185 see if a uuid and if_version match to an interface
187 static bool interface_match(const struct dcesrv_interface
*if1
,
188 const struct dcesrv_interface
*if2
)
190 return (if1
->syntax_id
.if_version
== if2
->syntax_id
.if_version
&&
191 GUID_equal(&if1
->syntax_id
.uuid
, &if2
->syntax_id
.uuid
));
195 find the interface operations on an endpoint
197 static const struct dcesrv_interface
*find_interface(const struct dcesrv_endpoint
*endpoint
,
198 const struct dcesrv_interface
*iface
)
200 struct dcesrv_if_list
*ifl
;
201 for (ifl
=endpoint
->interface_list
; ifl
; ifl
=ifl
->next
) {
202 if (interface_match(&(ifl
->iface
), iface
)) {
203 return &(ifl
->iface
);
210 see if a uuid and if_version match to an interface
212 static bool interface_match_by_uuid(const struct dcesrv_interface
*iface
,
213 const struct GUID
*uuid
, uint32_t if_version
)
215 return (iface
->syntax_id
.if_version
== if_version
&&
216 GUID_equal(&iface
->syntax_id
.uuid
, uuid
));
220 find the interface operations on an endpoint by uuid
222 static const struct dcesrv_interface
*find_interface_by_uuid(const struct dcesrv_endpoint
*endpoint
,
223 const struct GUID
*uuid
, uint32_t if_version
)
225 struct dcesrv_if_list
*ifl
;
226 for (ifl
=endpoint
->interface_list
; ifl
; ifl
=ifl
->next
) {
227 if (interface_match_by_uuid(&(ifl
->iface
), uuid
, if_version
)) {
228 return &(ifl
->iface
);
235 find the earlier parts of a fragmented call awaiting reassembily
237 static struct dcesrv_call_state
*dcesrv_find_fragmented_call(struct dcesrv_connection
*dce_conn
, uint16_t call_id
)
239 struct dcesrv_call_state
*c
;
240 for (c
=dce_conn
->incoming_fragmented_call_list
;c
;c
=c
->next
) {
241 if (c
->pkt
.call_id
== call_id
) {
249 register an interface on an endpoint
251 _PUBLIC_ NTSTATUS
dcesrv_interface_register(struct dcesrv_context
*dce_ctx
,
253 const struct dcesrv_interface
*iface
,
254 const struct security_descriptor
*sd
)
256 struct dcesrv_endpoint
*ep
;
257 struct dcesrv_if_list
*ifl
;
258 struct dcerpc_binding
*binding
;
262 status
= dcerpc_parse_binding(dce_ctx
, ep_name
, &binding
);
264 if (NT_STATUS_IS_ERR(status
)) {
265 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name
));
269 /* check if this endpoint exists
271 if ((ep
=find_endpoint(dce_ctx
, binding
))==NULL
) {
272 ep
= talloc_zero(dce_ctx
, struct dcesrv_endpoint
);
274 return NT_STATUS_NO_MEMORY
;
277 ep
->ep_description
= talloc_move(ep
, &binding
);
280 /* add mgmt interface */
281 ifl
= talloc_zero(ep
, struct dcesrv_if_list
);
283 return NT_STATUS_NO_MEMORY
;
286 memcpy(&(ifl
->iface
), &dcesrv_mgmt_interface
,
287 sizeof(struct dcesrv_interface
));
289 DLIST_ADD(ep
->interface_list
, ifl
);
292 /* see if the interface is already registered on te endpoint */
293 if (find_interface(ep
, iface
)!=NULL
) {
294 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
295 iface
->name
, ep_name
));
296 return NT_STATUS_OBJECT_NAME_COLLISION
;
299 /* talloc a new interface list element */
300 ifl
= talloc_zero(ep
, struct dcesrv_if_list
);
302 return NT_STATUS_NO_MEMORY
;
305 /* copy the given interface struct to the one on the endpoints interface list */
306 memcpy(&(ifl
->iface
),iface
, sizeof(struct dcesrv_interface
));
308 /* if we have a security descriptor given,
309 * we should see if we can set it up on the endpoint
312 /* if there's currently no security descriptor given on the endpoint
315 if (ep
->sd
== NULL
) {
316 ep
->sd
= security_descriptor_copy(ep
, sd
);
319 /* if now there's no security descriptor given on the endpoint
320 * something goes wrong, either we failed to copy the security descriptor
321 * or there was already one on the endpoint
323 if (ep
->sd
!= NULL
) {
324 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
325 " on endpoint '%s'\n",
326 iface
->name
, ep_name
));
327 if (add_ep
) free(ep
);
329 return NT_STATUS_OBJECT_NAME_COLLISION
;
333 /* finally add the interface on the endpoint */
334 DLIST_ADD(ep
->interface_list
, ifl
);
336 /* if it's a new endpoint add it to the dcesrv_context */
338 DLIST_ADD(dce_ctx
->endpoint_list
, ep
);
341 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
342 iface
->name
, ep_name
));
347 NTSTATUS
dcesrv_inherited_session_key(struct dcesrv_connection
*p
,
348 DATA_BLOB
*session_key
)
350 if (p
->auth_state
.session_info
->session_key
.length
) {
351 *session_key
= p
->auth_state
.session_info
->session_key
;
354 return NT_STATUS_NO_USER_SESSION_KEY
;
358 fetch the user session key - may be default (above) or the SMB session key
360 The key is always truncated to 16 bytes
362 _PUBLIC_ NTSTATUS
dcesrv_fetch_session_key(struct dcesrv_connection
*p
,
363 DATA_BLOB
*session_key
)
365 NTSTATUS status
= p
->auth_state
.session_key(p
, session_key
);
366 if (!NT_STATUS_IS_OK(status
)) {
370 session_key
->length
= MIN(session_key
->length
, 16);
376 connect to a dcerpc endpoint
378 _PUBLIC_ NTSTATUS
dcesrv_endpoint_connect(struct dcesrv_context
*dce_ctx
,
380 const struct dcesrv_endpoint
*ep
,
381 struct auth_session_info
*session_info
,
382 struct tevent_context
*event_ctx
,
383 struct imessaging_context
*msg_ctx
,
384 struct server_id server_id
,
385 uint32_t state_flags
,
386 struct dcesrv_connection
**_p
)
388 struct dcesrv_connection
*p
;
391 return NT_STATUS_ACCESS_DENIED
;
394 p
= talloc_zero(mem_ctx
, struct dcesrv_connection
);
395 NT_STATUS_HAVE_NO_MEMORY(p
);
397 if (!talloc_reference(p
, session_info
)) {
399 return NT_STATUS_NO_MEMORY
;
402 p
->dce_ctx
= dce_ctx
;
404 p
->packet_log_dir
= lpcfg_lock_directory(dce_ctx
->lp_ctx
);
405 p
->auth_state
.session_info
= session_info
;
406 p
->auth_state
.session_key
= dcesrv_generic_session_key
;
407 p
->event_ctx
= event_ctx
;
408 p
->msg_ctx
= msg_ctx
;
409 p
->server_id
= server_id
;
410 p
->state_flags
= state_flags
;
411 p
->allow_bind
= true;
412 p
->max_recv_frag
= 5840;
413 p
->max_xmit_frag
= 5840;
414 p
->max_total_request_size
= DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE
;
417 * For now we only support NDR32.
419 p
->preferred_transfer
= &ndr_transfer_syntax_ndr
;
426 move a call from an existing linked list to the specified list. This
427 prevents bugs where we forget to remove the call from a previous
430 static void dcesrv_call_set_list(struct dcesrv_call_state
*call
,
431 enum dcesrv_call_list list
)
433 switch (call
->list
) {
434 case DCESRV_LIST_NONE
:
436 case DCESRV_LIST_CALL_LIST
:
437 DLIST_REMOVE(call
->conn
->call_list
, call
);
439 case DCESRV_LIST_FRAGMENTED_CALL_LIST
:
440 DLIST_REMOVE(call
->conn
->incoming_fragmented_call_list
, call
);
442 case DCESRV_LIST_PENDING_CALL_LIST
:
443 DLIST_REMOVE(call
->conn
->pending_call_list
, call
);
448 case DCESRV_LIST_NONE
:
450 case DCESRV_LIST_CALL_LIST
:
451 DLIST_ADD_END(call
->conn
->call_list
, call
);
453 case DCESRV_LIST_FRAGMENTED_CALL_LIST
:
454 DLIST_ADD_END(call
->conn
->incoming_fragmented_call_list
, call
);
456 case DCESRV_LIST_PENDING_CALL_LIST
:
457 DLIST_ADD_END(call
->conn
->pending_call_list
, call
);
462 static void dcesrv_call_disconnect_after(struct dcesrv_call_state
*call
,
465 if (call
->conn
->terminate
!= NULL
) {
469 call
->conn
->allow_bind
= false;
470 call
->conn
->allow_alter
= false;
471 call
->conn
->allow_auth3
= false;
472 call
->conn
->allow_request
= false;
474 call
->terminate_reason
= talloc_strdup(call
, reason
);
475 if (call
->terminate_reason
== NULL
) {
476 call
->terminate_reason
= __location__
;
481 return a dcerpc bind_nak
483 static NTSTATUS
dcesrv_bind_nak(struct dcesrv_call_state
*call
, uint32_t reason
)
485 struct ncacn_packet pkt
;
486 struct dcerpc_bind_nak_version version
;
487 struct data_blob_list_item
*rep
;
489 static const uint8_t _pad
[3] = { 0, };
492 * We add the call to the pending_call_list
493 * in order to defer the termination.
495 dcesrv_call_disconnect_after(call
, "dcesrv_bind_nak");
497 /* setup a bind_nak */
498 dcesrv_init_hdr(&pkt
, lpcfg_rpc_big_endian(call
->conn
->dce_ctx
->lp_ctx
));
500 pkt
.call_id
= call
->pkt
.call_id
;
501 pkt
.ptype
= DCERPC_PKT_BIND_NAK
;
502 pkt
.pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
;
503 pkt
.u
.bind_nak
.reject_reason
= reason
;
504 version
.rpc_vers
= 5;
505 version
.rpc_vers_minor
= 0;
506 pkt
.u
.bind_nak
.num_versions
= 1;
507 pkt
.u
.bind_nak
.versions
= &version
;
508 pkt
.u
.bind_nak
._pad
= data_blob_const(_pad
, sizeof(_pad
));
510 rep
= talloc_zero(call
, struct data_blob_list_item
);
512 return NT_STATUS_NO_MEMORY
;
515 status
= ncacn_push_auth(&rep
->blob
, call
, &pkt
, NULL
);
516 if (!NT_STATUS_IS_OK(status
)) {
520 dcerpc_set_frag_length(&rep
->blob
, rep
->blob
.length
);
522 DLIST_ADD_END(call
->replies
, rep
);
523 dcesrv_call_set_list(call
, DCESRV_LIST_CALL_LIST
);
525 if (call
->conn
->call_list
&& call
->conn
->call_list
->replies
) {
526 if (call
->conn
->transport
.report_output_data
) {
527 call
->conn
->transport
.report_output_data(call
->conn
);
534 static NTSTATUS
dcesrv_fault_disconnect(struct dcesrv_call_state
*call
,
538 * We add the call to the pending_call_list
539 * in order to defer the termination.
541 dcesrv_call_disconnect_after(call
, "dcesrv_fault_disconnect");
543 return dcesrv_fault_with_flags(call
, fault_code
,
544 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
547 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context
*c
)
549 DLIST_REMOVE(c
->conn
->contexts
, c
);
551 if (c
->iface
&& c
->iface
->unbind
) {
552 c
->iface
->unbind(c
, c
->iface
);
559 static void dcesrv_prepare_context_auth(struct dcesrv_call_state
*dce_call
)
561 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
562 const struct dcesrv_endpoint
*endpoint
= dce_call
->conn
->endpoint
;
563 enum dcerpc_transport_t transport
=
564 dcerpc_binding_get_transport(endpoint
->ep_description
);
565 struct dcesrv_connection_context
*context
= dce_call
->context
;
566 const struct dcesrv_interface
*iface
= context
->iface
;
568 context
->min_auth_level
= DCERPC_AUTH_LEVEL_NONE
;
570 if (transport
== NCALRPC
) {
571 context
->allow_connect
= true;
576 * allow overwrite per interface
577 * allow dcerpc auth level connect:<interface>
579 context
->allow_connect
= lpcfg_allow_dcerpc_auth_level_connect(lp_ctx
);
580 context
->allow_connect
= lpcfg_parm_bool(lp_ctx
, NULL
,
581 "allow dcerpc auth level connect",
583 context
->allow_connect
);
586 NTSTATUS
dcesrv_interface_bind_require_integrity(struct dcesrv_call_state
*dce_call
,
587 const struct dcesrv_interface
*iface
)
589 if (dce_call
->context
== NULL
) {
590 return NT_STATUS_INTERNAL_ERROR
;
594 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
595 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
597 dce_call
->context
->min_auth_level
= DCERPC_AUTH_LEVEL_PACKET
;
601 NTSTATUS
dcesrv_interface_bind_require_privacy(struct dcesrv_call_state
*dce_call
,
602 const struct dcesrv_interface
*iface
)
604 if (dce_call
->context
== NULL
) {
605 return NT_STATUS_INTERNAL_ERROR
;
608 dce_call
->context
->min_auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
612 _PUBLIC_ NTSTATUS
dcesrv_interface_bind_reject_connect(struct dcesrv_call_state
*dce_call
,
613 const struct dcesrv_interface
*iface
)
615 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
616 const struct dcesrv_endpoint
*endpoint
= dce_call
->conn
->endpoint
;
617 enum dcerpc_transport_t transport
=
618 dcerpc_binding_get_transport(endpoint
->ep_description
);
619 struct dcesrv_connection_context
*context
= dce_call
->context
;
621 if (context
== NULL
) {
622 return NT_STATUS_INTERNAL_ERROR
;
625 if (transport
== NCALRPC
) {
626 context
->allow_connect
= true;
631 * allow overwrite per interface
632 * allow dcerpc auth level connect:<interface>
634 context
->allow_connect
= false;
635 context
->allow_connect
= lpcfg_parm_bool(lp_ctx
, NULL
,
636 "allow dcerpc auth level connect",
638 context
->allow_connect
);
642 _PUBLIC_ NTSTATUS
dcesrv_interface_bind_allow_connect(struct dcesrv_call_state
*dce_call
,
643 const struct dcesrv_interface
*iface
)
645 struct loadparm_context
*lp_ctx
= dce_call
->conn
->dce_ctx
->lp_ctx
;
646 const struct dcesrv_endpoint
*endpoint
= dce_call
->conn
->endpoint
;
647 enum dcerpc_transport_t transport
=
648 dcerpc_binding_get_transport(endpoint
->ep_description
);
649 struct dcesrv_connection_context
*context
= dce_call
->context
;
651 if (context
== NULL
) {
652 return NT_STATUS_INTERNAL_ERROR
;
655 if (transport
== NCALRPC
) {
656 context
->allow_connect
= true;
661 * allow overwrite per interface
662 * allow dcerpc auth level connect:<interface>
664 context
->allow_connect
= true;
665 context
->allow_connect
= lpcfg_parm_bool(lp_ctx
, NULL
,
666 "allow dcerpc auth level connect",
668 context
->allow_connect
);
673 handle a bind request
675 static NTSTATUS
dcesrv_bind(struct dcesrv_call_state
*call
)
677 struct ncacn_packet pkt
;
678 struct data_blob_list_item
*rep
;
680 uint32_t extra_flags
= 0;
681 uint16_t max_req
= 0;
682 uint16_t max_rep
= 0;
683 const char *ep_prefix
= "";
684 const char *endpoint
= NULL
;
685 struct dcerpc_ack_ctx
*ack_ctx_list
= NULL
;
686 struct dcerpc_ack_ctx
*ack_features
= NULL
;
689 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
691 call
->pkt
.u
.bind
.auth_info
.length
,
692 0, /* required flags */
693 DCERPC_PFC_FLAG_FIRST
|
694 DCERPC_PFC_FLAG_LAST
|
695 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
696 0x08 | /* this is not defined, but should be ignored */
697 DCERPC_PFC_FLAG_CONC_MPX
|
698 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
699 DCERPC_PFC_FLAG_MAYBE
|
700 DCERPC_PFC_FLAG_OBJECT_UUID
);
701 if (!NT_STATUS_IS_OK(status
)) {
702 return dcesrv_bind_nak(call
,
703 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED
);
706 /* max_recv_frag and max_xmit_frag result always in the same value! */
707 max_req
= MIN(call
->pkt
.u
.bind
.max_xmit_frag
,
708 call
->pkt
.u
.bind
.max_recv_frag
);
710 * The values are between 2048 and 5840 tested against Windows 2012R2
711 * via ncacn_ip_tcp on port 135.
713 max_req
= MAX(2048, max_req
);
714 max_rep
= MIN(max_req
, call
->conn
->max_recv_frag
);
715 /* They are truncated to an 8 byte boundary. */
718 /* max_recv_frag and max_xmit_frag result always in the same value! */
719 call
->conn
->max_recv_frag
= max_rep
;
720 call
->conn
->max_xmit_frag
= max_rep
;
723 if provided, check the assoc_group is valid
725 if (call
->pkt
.u
.bind
.assoc_group_id
!= 0) {
726 call
->conn
->assoc_group
= dcesrv_assoc_group_reference(call
->conn
,
728 call
->pkt
.u
.bind
.assoc_group_id
);
730 call
->conn
->assoc_group
= dcesrv_assoc_group_new(call
->conn
,
731 call
->conn
->dce_ctx
);
733 if (call
->conn
->assoc_group
== NULL
) {
734 return dcesrv_bind_nak(call
, 0);
737 if (call
->pkt
.u
.bind
.num_contexts
< 1) {
738 return dcesrv_bind_nak(call
, 0);
741 ack_ctx_list
= talloc_zero_array(call
, struct dcerpc_ack_ctx
,
742 call
->pkt
.u
.bind
.num_contexts
);
743 if (ack_ctx_list
== NULL
) {
744 return dcesrv_bind_nak(call
, 0);
748 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
749 * dcesrv_check_or_create_context()) and do some protocol validation
750 * and set sane defaults.
752 for (i
= 0; i
< call
->pkt
.u
.bind
.num_contexts
; i
++) {
753 const struct dcerpc_ctx_list
*c
= &call
->pkt
.u
.bind
.ctx_list
[i
];
754 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
755 bool is_feature
= false;
756 uint64_t features
= 0;
758 if (c
->num_transfer_syntaxes
== 0) {
759 return dcesrv_bind_nak(call
, 0);
762 a
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
763 a
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
766 * It's only treated as bind time feature request, if the first
767 * transfer_syntax matches, all others are ignored.
769 is_feature
= dcerpc_extract_bind_time_features(c
->transfer_syntaxes
[0],
775 if (ack_features
!= NULL
) {
777 * Only one bind time feature context is allowed.
779 return dcesrv_bind_nak(call
, 0);
783 a
->result
= DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
;
784 a
->reason
.negotiate
= 0;
785 if (features
& DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING
) {
786 /* not supported yet */
788 if (features
& DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN
) {
789 /* not supported yet */
792 call
->conn
->bind_time_features
= a
->reason
.negotiate
;
796 * Try to negotiate one new presentation context.
798 status
= dcesrv_negotiate_contexts(call
, &call
->pkt
.u
.bind
, ack_ctx_list
);
799 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
800 return dcesrv_bind_nak(call
, 0);
802 if (!NT_STATUS_IS_OK(status
)) {
806 if ((call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_CONC_MPX
) &&
807 (call
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
808 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
809 extra_flags
|= DCERPC_PFC_FLAG_CONC_MPX
;
812 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
813 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
;
816 /* handle any authentication that is being requested */
817 if (!dcesrv_auth_bind(call
)) {
818 struct dcesrv_auth
*auth
= &call
->conn
->auth_state
;
820 TALLOC_FREE(call
->context
);
822 if (auth
->auth_level
== DCERPC_AUTH_LEVEL_NONE
) {
824 * With DCERPC_AUTH_LEVEL_NONE, we get the
825 * reject_reason in auth->auth_context_id.
827 return dcesrv_bind_nak(call
, auth
->auth_context_id
);
831 * This must a be a temporary failure e.g. talloc or invalid
832 * configuration, e.g. no machine account.
834 return dcesrv_bind_nak(call
,
835 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION
);
838 /* setup a bind_ack */
839 dcesrv_init_hdr(&pkt
, lpcfg_rpc_big_endian(call
->conn
->dce_ctx
->lp_ctx
));
841 pkt
.call_id
= call
->pkt
.call_id
;
842 pkt
.ptype
= DCERPC_PKT_BIND_ACK
;
843 pkt
.pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
| extra_flags
;
844 pkt
.u
.bind_ack
.max_xmit_frag
= call
->conn
->max_xmit_frag
;
845 pkt
.u
.bind_ack
.max_recv_frag
= call
->conn
->max_recv_frag
;
846 pkt
.u
.bind_ack
.assoc_group_id
= call
->conn
->assoc_group
->id
;
848 endpoint
= dcerpc_binding_get_string_option(
849 call
->conn
->endpoint
->ep_description
,
851 if (endpoint
== NULL
) {
855 if (strncasecmp(endpoint
, "\\pipe\\", 6) == 0) {
857 * TODO: check if this is really needed
859 * Or if we should fix this in our idl files.
861 ep_prefix
= "\\PIPE\\";
865 pkt
.u
.bind_ack
.secondary_address
= talloc_asprintf(call
, "%s%s",
868 if (pkt
.u
.bind_ack
.secondary_address
== NULL
) {
869 TALLOC_FREE(call
->context
);
870 return NT_STATUS_NO_MEMORY
;
872 pkt
.u
.bind_ack
.num_results
= call
->pkt
.u
.bind
.num_contexts
;
873 pkt
.u
.bind_ack
.ctx_list
= ack_ctx_list
;
874 pkt
.u
.bind_ack
.auth_info
= data_blob_null
;
876 status
= dcesrv_auth_bind_ack(call
, &pkt
);
877 if (!NT_STATUS_IS_OK(status
)) {
878 TALLOC_FREE(call
->context
);
879 return dcesrv_bind_nak(call
, 0);
882 rep
= talloc_zero(call
, struct data_blob_list_item
);
884 TALLOC_FREE(call
->context
);
885 return NT_STATUS_NO_MEMORY
;
888 status
= ncacn_push_auth(&rep
->blob
, call
, &pkt
,
889 call
->out_auth_info
);
890 if (!NT_STATUS_IS_OK(status
)) {
891 TALLOC_FREE(call
->context
);
895 dcerpc_set_frag_length(&rep
->blob
, rep
->blob
.length
);
897 DLIST_ADD_END(call
->replies
, rep
);
898 dcesrv_call_set_list(call
, DCESRV_LIST_CALL_LIST
);
900 if (call
->conn
->call_list
&& call
->conn
->call_list
->replies
) {
901 if (call
->conn
->transport
.report_output_data
) {
902 call
->conn
->transport
.report_output_data(call
->conn
);
911 handle a auth3 request
913 static NTSTATUS
dcesrv_auth3(struct dcesrv_call_state
*call
)
917 if (!call
->conn
->allow_auth3
) {
918 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
921 if (call
->conn
->auth_state
.auth_finished
) {
922 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
925 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
927 call
->pkt
.u
.auth3
.auth_info
.length
,
928 0, /* required flags */
929 DCERPC_PFC_FLAG_FIRST
|
930 DCERPC_PFC_FLAG_LAST
|
931 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
932 0x08 | /* this is not defined, but should be ignored */
933 DCERPC_PFC_FLAG_CONC_MPX
|
934 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
935 DCERPC_PFC_FLAG_MAYBE
|
936 DCERPC_PFC_FLAG_OBJECT_UUID
);
937 if (!NT_STATUS_IS_OK(status
)) {
938 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
941 /* handle the auth3 in the auth code */
942 if (!dcesrv_auth_auth3(call
)) {
943 call
->conn
->auth_state
.auth_invalid
= true;
944 if (call
->fault_code
!= 0) {
945 return dcesrv_fault_disconnect(call
, call
->fault_code
);
951 /* we don't send a reply to a auth3 request, except by a
957 static NTSTATUS
dcesrv_check_or_create_context(struct dcesrv_call_state
*call
,
958 const struct dcerpc_bind
*b
,
959 const struct dcerpc_ctx_list
*ctx
,
960 struct dcerpc_ack_ctx
*ack
,
962 const struct ndr_syntax_id
*supported_transfer
)
965 struct dcesrv_connection_context
*context
;
966 const struct dcesrv_interface
*iface
;
969 const struct ndr_syntax_id
*selected_transfer
= NULL
;
974 return NT_STATUS_INTERNAL_ERROR
;
977 return NT_STATUS_INTERNAL_ERROR
;
979 if (ctx
->num_transfer_syntaxes
< 1) {
980 return NT_STATUS_INTERNAL_ERROR
;
983 return NT_STATUS_INTERNAL_ERROR
;
985 if (supported_transfer
== NULL
) {
986 return NT_STATUS_INTERNAL_ERROR
;
989 switch (ack
->result
) {
990 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE
:
991 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK
:
993 * We is already completed.
1000 ack
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1001 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1003 if_version
= ctx
->abstract_syntax
.if_version
;
1004 uuid
= ctx
->abstract_syntax
.uuid
;
1006 iface
= find_interface_by_uuid(call
->conn
->endpoint
, &uuid
, if_version
);
1007 if (iface
== NULL
) {
1008 char *uuid_str
= GUID_string(call
, &uuid
);
1009 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str
, if_version
));
1010 talloc_free(uuid_str
);
1012 * We report this only via ack->result
1014 return NT_STATUS_OK
;
1017 ack
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1018 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED
;
1020 if (validate_only
) {
1022 * We report this only via ack->result
1024 return NT_STATUS_OK
;
1027 for (i
= 0; i
< ctx
->num_transfer_syntaxes
; i
++) {
1029 * we only do NDR encoded dcerpc for now.
1031 ok
= ndr_syntax_id_equal(&ctx
->transfer_syntaxes
[i
],
1032 supported_transfer
);
1034 selected_transfer
= supported_transfer
;
1039 context
= dcesrv_find_context(call
->conn
, ctx
->context_id
);
1040 if (context
!= NULL
) {
1041 ok
= ndr_syntax_id_equal(&context
->iface
->syntax_id
,
1042 &ctx
->abstract_syntax
);
1044 return NT_STATUS_RPC_PROTOCOL_ERROR
;
1047 if (selected_transfer
!= NULL
) {
1048 ok
= ndr_syntax_id_equal(&context
->transfer_syntax
,
1051 return NT_STATUS_RPC_PROTOCOL_ERROR
;
1054 ack
->result
= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
;
1055 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_NOT_SPECIFIED
;
1056 ack
->syntax
= context
->transfer_syntax
;
1060 * We report this only via ack->result
1062 return NT_STATUS_OK
;
1065 if (selected_transfer
== NULL
) {
1067 * We report this only via ack->result
1069 return NT_STATUS_OK
;
1072 ack
->result
= DCERPC_BIND_ACK_RESULT_USER_REJECTION
;
1073 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED
;
1075 /* add this context to the list of available context_ids */
1076 context
= talloc_zero(call
->conn
, struct dcesrv_connection_context
);
1077 if (context
== NULL
) {
1078 return NT_STATUS_NO_MEMORY
;
1080 context
->conn
= call
->conn
;
1081 context
->context_id
= ctx
->context_id
;
1082 context
->iface
= iface
;
1083 context
->transfer_syntax
= *selected_transfer
;
1084 context
->private_data
= NULL
;
1085 DLIST_ADD(call
->conn
->contexts
, context
);
1086 call
->context
= context
;
1087 talloc_set_destructor(context
, dcesrv_connection_context_destructor
);
1089 dcesrv_prepare_context_auth(call
);
1091 status
= iface
->bind(call
, iface
, if_version
);
1092 call
->context
= NULL
;
1093 if (!NT_STATUS_IS_OK(status
)) {
1094 /* we don't want to trigger the iface->unbind() hook */
1095 context
->iface
= NULL
;
1096 talloc_free(context
);
1098 * We report this only via ack->result
1100 return NT_STATUS_OK
;
1103 ack
->result
= DCERPC_BIND_ACK_RESULT_ACCEPTANCE
;
1104 ack
->reason
.value
= DCERPC_BIND_ACK_REASON_NOT_SPECIFIED
;
1105 ack
->syntax
= context
->transfer_syntax
;
1106 return NT_STATUS_OK
;
1109 static NTSTATUS
dcesrv_negotiate_contexts(struct dcesrv_call_state
*call
,
1110 const struct dcerpc_bind
*b
,
1111 struct dcerpc_ack_ctx
*ack_ctx_list
)
1115 bool validate_only
= false;
1116 bool preferred_ndr32
;
1119 * Try to negotiate one new presentation context,
1120 * using our preferred transfer syntax.
1122 for (i
= 0; i
< b
->num_contexts
; i
++) {
1123 const struct dcerpc_ctx_list
*c
= &b
->ctx_list
[i
];
1124 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1126 status
= dcesrv_check_or_create_context(call
, b
, c
, a
,
1128 call
->conn
->preferred_transfer
);
1129 if (!NT_STATUS_IS_OK(status
)) {
1133 if (a
->result
== DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1135 * We managed to negotiate one context.
1139 validate_only
= true;
1143 preferred_ndr32
= ndr_syntax_id_equal(&ndr_transfer_syntax_ndr
,
1144 call
->conn
->preferred_transfer
);
1145 if (preferred_ndr32
) {
1149 return NT_STATUS_OK
;
1153 * Try to negotiate one new presentation context,
1154 * using NDR 32 as fallback.
1156 for (i
= 0; i
< b
->num_contexts
; i
++) {
1157 const struct dcerpc_ctx_list
*c
= &b
->ctx_list
[i
];
1158 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1160 status
= dcesrv_check_or_create_context(call
, b
, c
, a
,
1162 &ndr_transfer_syntax_ndr
);
1163 if (!NT_STATUS_IS_OK(status
)) {
1167 if (a
->result
== DCERPC_BIND_ACK_RESULT_ACCEPTANCE
) {
1169 * We managed to negotiate one context.
1173 validate_only
= true;
1177 return NT_STATUS_OK
;
1181 handle a alter context request
1183 static NTSTATUS
dcesrv_alter(struct dcesrv_call_state
*call
)
1186 bool auth_ok
= false;
1187 struct ncacn_packet pkt
;
1188 uint32_t extra_flags
= 0;
1189 struct data_blob_list_item
*rep
= NULL
;
1190 struct dcerpc_ack_ctx
*ack_ctx_list
= NULL
;
1193 if (!call
->conn
->allow_alter
) {
1194 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1197 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
1199 call
->pkt
.u
.alter
.auth_info
.length
,
1200 0, /* required flags */
1201 DCERPC_PFC_FLAG_FIRST
|
1202 DCERPC_PFC_FLAG_LAST
|
1203 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN
|
1204 0x08 | /* this is not defined, but should be ignored */
1205 DCERPC_PFC_FLAG_CONC_MPX
|
1206 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1207 DCERPC_PFC_FLAG_MAYBE
|
1208 DCERPC_PFC_FLAG_OBJECT_UUID
);
1209 if (!NT_STATUS_IS_OK(status
)) {
1210 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1213 auth_ok
= dcesrv_auth_alter(call
);
1215 if (call
->fault_code
!= 0) {
1216 return dcesrv_fault_disconnect(call
, call
->fault_code
);
1220 if (call
->pkt
.u
.alter
.num_contexts
< 1) {
1221 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1224 ack_ctx_list
= talloc_zero_array(call
, struct dcerpc_ack_ctx
,
1225 call
->pkt
.u
.alter
.num_contexts
);
1226 if (ack_ctx_list
== NULL
) {
1227 return NT_STATUS_NO_MEMORY
;
1231 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1232 * dcesrv_check_or_create_context()) and do some protocol validation
1233 * and set sane defaults.
1235 for (i
= 0; i
< call
->pkt
.u
.alter
.num_contexts
; i
++) {
1236 const struct dcerpc_ctx_list
*c
= &call
->pkt
.u
.alter
.ctx_list
[i
];
1237 struct dcerpc_ack_ctx
*a
= &ack_ctx_list
[i
];
1239 if (c
->num_transfer_syntaxes
== 0) {
1240 return dcesrv_fault_disconnect(call
,
1241 DCERPC_NCA_S_PROTO_ERROR
);
1244 a
->result
= DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION
;
1245 a
->reason
.value
= DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED
;
1249 * Try to negotiate one new presentation context.
1251 status
= dcesrv_negotiate_contexts(call
, &call
->pkt
.u
.alter
, ack_ctx_list
);
1252 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROTOCOL_ERROR
)) {
1253 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1255 if (!NT_STATUS_IS_OK(status
)) {
1259 if ((call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_CONC_MPX
) &&
1260 (call
->state_flags
& DCESRV_CALL_STATE_FLAG_MULTIPLEXED
)) {
1261 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_MULTIPLEXED
;
1262 extra_flags
|= DCERPC_PFC_FLAG_CONC_MPX
;
1265 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
1266 call
->conn
->state_flags
|= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
;
1269 /* handle any authentication that is being requested */
1271 if (call
->in_auth_info
.auth_type
!=
1272 call
->conn
->auth_state
.auth_type
)
1274 return dcesrv_fault_disconnect(call
,
1275 DCERPC_FAULT_SEC_PKG_ERROR
);
1277 return dcesrv_fault_disconnect(call
, DCERPC_FAULT_ACCESS_DENIED
);
1280 dcesrv_init_hdr(&pkt
, lpcfg_rpc_big_endian(call
->conn
->dce_ctx
->lp_ctx
));
1281 pkt
.auth_length
= 0;
1282 pkt
.call_id
= call
->pkt
.call_id
;
1283 pkt
.ptype
= DCERPC_PKT_ALTER_RESP
;
1284 pkt
.pfc_flags
= DCERPC_PFC_FLAG_FIRST
| DCERPC_PFC_FLAG_LAST
| extra_flags
;
1285 pkt
.u
.alter_resp
.max_xmit_frag
= call
->conn
->max_xmit_frag
;
1286 pkt
.u
.alter_resp
.max_recv_frag
= call
->conn
->max_recv_frag
;
1287 pkt
.u
.alter_resp
.assoc_group_id
= call
->conn
->assoc_group
->id
;
1288 pkt
.u
.alter_resp
.secondary_address
= "";
1289 pkt
.u
.alter_resp
.num_results
= call
->pkt
.u
.alter
.num_contexts
;
1290 pkt
.u
.alter_resp
.ctx_list
= ack_ctx_list
;
1291 pkt
.u
.alter_resp
.auth_info
= data_blob_null
;
1293 status
= dcesrv_auth_alter_ack(call
, &pkt
);
1294 if (!NT_STATUS_IS_OK(status
)) {
1295 return dcesrv_fault_disconnect(call
, DCERPC_FAULT_SEC_PKG_ERROR
);
1298 rep
= talloc_zero(call
, struct data_blob_list_item
);
1300 return NT_STATUS_NO_MEMORY
;
1303 status
= ncacn_push_auth(&rep
->blob
, call
, &pkt
, call
->out_auth_info
);
1304 if (!NT_STATUS_IS_OK(status
)) {
1308 dcerpc_set_frag_length(&rep
->blob
, rep
->blob
.length
);
1310 DLIST_ADD_END(call
->replies
, rep
);
1311 dcesrv_call_set_list(call
, DCESRV_LIST_CALL_LIST
);
1313 if (call
->conn
->call_list
&& call
->conn
->call_list
->replies
) {
1314 if (call
->conn
->transport
.report_output_data
) {
1315 call
->conn
->transport
.report_output_data(call
->conn
);
1319 return NT_STATUS_OK
;
1323 possibly save the call for inspection with ndrdump
1325 static void dcesrv_save_call(struct dcesrv_call_state
*call
, const char *why
)
1329 const char *dump_dir
;
1330 dump_dir
= lpcfg_parm_string(call
->conn
->dce_ctx
->lp_ctx
, NULL
, "dcesrv", "stubs directory");
1334 fname
= talloc_asprintf(call
, "%s/RPC-%s-%u-%s.dat",
1336 call
->context
->iface
->name
,
1337 call
->pkt
.u
.request
.opnum
,
1339 if (file_save(fname
, call
->pkt
.u
.request
.stub_and_verifier
.data
, call
->pkt
.u
.request
.stub_and_verifier
.length
)) {
1340 DEBUG(0,("RPC SAVED %s\n", fname
));
1346 static NTSTATUS
dcesrv_check_verification_trailer(struct dcesrv_call_state
*call
)
1348 TALLOC_CTX
*frame
= talloc_stackframe();
1349 const uint32_t bitmask1
= call
->conn
->auth_state
.client_hdr_signing
?
1350 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING
: 0;
1351 const struct dcerpc_sec_vt_pcontext pcontext
= {
1352 .abstract_syntax
= call
->context
->iface
->syntax_id
,
1353 .transfer_syntax
= call
->context
->transfer_syntax
,
1355 const struct dcerpc_sec_vt_header2 header2
=
1356 dcerpc_sec_vt_header2_from_ncacn_packet(&call
->pkt
);
1357 enum ndr_err_code ndr_err
;
1358 struct dcerpc_sec_verification_trailer
*vt
= NULL
;
1359 NTSTATUS status
= NT_STATUS_OK
;
1362 SMB_ASSERT(call
->pkt
.ptype
== DCERPC_PKT_REQUEST
);
1364 ndr_err
= ndr_pop_dcerpc_sec_verification_trailer(call
->ndr_pull
,
1366 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1367 status
= ndr_map_error2ntstatus(ndr_err
);
1371 ok
= dcerpc_sec_verification_trailer_check(vt
, &bitmask1
,
1372 &pcontext
, &header2
);
1374 status
= NT_STATUS_ACCESS_DENIED
;
1383 handle a dcerpc request packet
1385 static NTSTATUS
dcesrv_request(struct dcesrv_call_state
*call
)
1387 const struct dcesrv_endpoint
*endpoint
= call
->conn
->endpoint
;
1388 enum dcerpc_transport_t transport
=
1389 dcerpc_binding_get_transport(endpoint
->ep_description
);
1390 struct ndr_pull
*pull
;
1392 struct dcesrv_connection_context
*context
;
1394 if (!call
->conn
->allow_request
) {
1395 return dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1398 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1399 if (call
->conn
->auth_state
.gensec_security
&&
1400 !gensec_have_feature(call
->conn
->auth_state
.gensec_security
, GENSEC_FEATURE_ASYNC_REPLIES
)) {
1401 call
->state_flags
&= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC
;
1404 context
= dcesrv_find_context(call
->conn
, call
->pkt
.u
.request
.context_id
);
1405 if (context
== NULL
) {
1406 return dcesrv_fault_with_flags(call
, DCERPC_NCA_S_UNKNOWN_IF
,
1407 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
1410 switch (call
->conn
->auth_state
.auth_level
) {
1411 case DCERPC_AUTH_LEVEL_NONE
:
1412 case DCERPC_AUTH_LEVEL_PACKET
:
1413 case DCERPC_AUTH_LEVEL_INTEGRITY
:
1414 case DCERPC_AUTH_LEVEL_PRIVACY
:
1417 if (!context
->allow_connect
) {
1420 addr
= tsocket_address_string(call
->conn
->remote_address
,
1423 DEBUG(2, ("%s: restrict auth_level_connect access "
1424 "to [%s] with auth[type=0x%x,level=0x%x] "
1425 "on [%s] from [%s]\n",
1426 __func__
, context
->iface
->name
,
1427 call
->conn
->auth_state
.auth_type
,
1428 call
->conn
->auth_state
.auth_level
,
1429 derpc_transport_string_by_transport(transport
),
1431 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
1436 if (call
->conn
->auth_state
.auth_level
< context
->min_auth_level
) {
1439 addr
= tsocket_address_string(call
->conn
->remote_address
, call
);
1441 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1442 "to [%s] with auth[type=0x%x,level=0x%x] "
1443 "on [%s] from [%s]\n",
1445 context
->min_auth_level
,
1446 context
->iface
->name
,
1447 call
->conn
->auth_state
.auth_type
,
1448 call
->conn
->auth_state
.auth_level
,
1449 derpc_transport_string_by_transport(transport
),
1451 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
1454 pull
= ndr_pull_init_blob(&call
->pkt
.u
.request
.stub_and_verifier
, call
);
1455 NT_STATUS_HAVE_NO_MEMORY(pull
);
1457 pull
->flags
|= LIBNDR_FLAG_REF_ALLOC
;
1459 call
->context
= context
;
1460 call
->ndr_pull
= pull
;
1462 if (!(call
->pkt
.drep
[0] & DCERPC_DREP_LE
)) {
1463 pull
->flags
|= LIBNDR_FLAG_BIGENDIAN
;
1466 status
= dcesrv_check_verification_trailer(call
);
1467 if (!NT_STATUS_IS_OK(status
)) {
1468 uint32_t faultcode
= DCERPC_FAULT_OTHER
;
1469 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
1470 faultcode
= DCERPC_FAULT_ACCESS_DENIED
;
1472 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1473 nt_errstr(status
)));
1474 return dcesrv_fault(call
, faultcode
);
1477 /* unravel the NDR for the packet */
1478 status
= context
->iface
->ndr_pull(call
, call
, pull
, &call
->r
);
1479 if (!NT_STATUS_IS_OK(status
)) {
1480 uint8_t extra_flags
= 0;
1481 if (call
->fault_code
== DCERPC_FAULT_OP_RNG_ERROR
) {
1482 /* we got an unknown call */
1483 DEBUG(3,(__location__
": Unknown RPC call %u on %s\n",
1484 call
->pkt
.u
.request
.opnum
, context
->iface
->name
));
1485 dcesrv_save_call(call
, "unknown");
1486 extra_flags
|= DCERPC_PFC_FLAG_DID_NOT_EXECUTE
;
1488 dcesrv_save_call(call
, "pullfail");
1490 return dcesrv_fault_with_flags(call
, call
->fault_code
, extra_flags
);
1493 if (pull
->offset
!= pull
->data_size
) {
1494 dcesrv_save_call(call
, "extrabytes");
1495 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1496 pull
->data_size
- pull
->offset
));
1499 /* call the dispatch function */
1500 status
= context
->iface
->dispatch(call
, call
, call
->r
);
1501 if (!NT_STATUS_IS_OK(status
)) {
1502 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1503 context
->iface
->name
,
1504 call
->pkt
.u
.request
.opnum
,
1505 dcerpc_errstr(pull
, call
->fault_code
)));
1506 return dcesrv_fault(call
, call
->fault_code
);
1509 /* add the call to the pending list */
1510 dcesrv_call_set_list(call
, DCESRV_LIST_PENDING_CALL_LIST
);
1512 if (call
->state_flags
& DCESRV_CALL_STATE_FLAG_ASYNC
) {
1513 return NT_STATUS_OK
;
1516 return dcesrv_reply(call
);
1521 remove the call from the right list when freed
1523 static int dcesrv_call_dequeue(struct dcesrv_call_state
*call
)
1525 dcesrv_call_set_list(call
, DCESRV_LIST_NONE
);
1529 _PUBLIC_
const struct tsocket_address
*dcesrv_connection_get_local_address(struct dcesrv_connection
*conn
)
1531 return conn
->local_address
;
1534 _PUBLIC_
const struct tsocket_address
*dcesrv_connection_get_remote_address(struct dcesrv_connection
*conn
)
1536 return conn
->remote_address
;
1540 process some input to a dcerpc endpoint server.
1542 static NTSTATUS
dcesrv_process_ncacn_packet(struct dcesrv_connection
*dce_conn
,
1543 struct ncacn_packet
*pkt
,
1547 struct dcesrv_call_state
*call
;
1548 struct dcesrv_call_state
*existing
= NULL
;
1550 call
= talloc_zero(dce_conn
, struct dcesrv_call_state
);
1552 data_blob_free(&blob
);
1554 return NT_STATUS_NO_MEMORY
;
1556 call
->conn
= dce_conn
;
1557 call
->event_ctx
= dce_conn
->event_ctx
;
1558 call
->msg_ctx
= dce_conn
->msg_ctx
;
1559 call
->state_flags
= call
->conn
->state_flags
;
1560 call
->time
= timeval_current();
1561 call
->list
= DCESRV_LIST_NONE
;
1563 talloc_steal(call
, pkt
);
1564 talloc_steal(call
, blob
.data
);
1567 talloc_set_destructor(call
, dcesrv_call_dequeue
);
1569 if (call
->conn
->allow_bind
) {
1571 * Only one bind is possible per connection
1573 call
->conn
->allow_bind
= false;
1574 return dcesrv_bind(call
);
1577 /* we have to check the signing here, before combining the
1579 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
1580 if (!call
->conn
->allow_request
) {
1581 return dcesrv_fault_disconnect(call
,
1582 DCERPC_NCA_S_PROTO_ERROR
);
1585 status
= dcerpc_verify_ncacn_packet_header(&call
->pkt
,
1587 call
->pkt
.u
.request
.stub_and_verifier
.length
,
1588 0, /* required_flags */
1589 DCERPC_PFC_FLAG_FIRST
|
1590 DCERPC_PFC_FLAG_LAST
|
1591 DCERPC_PFC_FLAG_PENDING_CANCEL
|
1592 0x08 | /* this is not defined, but should be ignored */
1593 DCERPC_PFC_FLAG_CONC_MPX
|
1594 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1595 DCERPC_PFC_FLAG_MAYBE
|
1596 DCERPC_PFC_FLAG_OBJECT_UUID
);
1597 if (!NT_STATUS_IS_OK(status
)) {
1598 return dcesrv_fault_disconnect(call
,
1599 DCERPC_NCA_S_PROTO_ERROR
);
1602 if (call
->pkt
.frag_length
> DCERPC_FRAG_MAX_SIZE
) {
1604 * We don't use dcesrv_fault_disconnect()
1605 * here, because we don't want to set
1606 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1608 * Note that we don't check against the negotiated
1609 * max_recv_frag, but a hard coded value.
1611 dcesrv_call_disconnect_after(call
,
1612 "dcesrv_auth_request - frag_length too large");
1613 return dcesrv_fault(call
,
1614 DCERPC_NCA_S_PROTO_ERROR
);
1617 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_FIRST
) {
1618 /* only one request is possible in the fragmented list */
1619 if (dce_conn
->incoming_fragmented_call_list
!= NULL
) {
1621 call
= dce_conn
->incoming_fragmented_call_list
;
1622 dcesrv_call_disconnect_after(call
,
1623 "dcesrv_auth_request - "
1624 "existing fragmented call");
1625 return dcesrv_fault(call
,
1626 DCERPC_NCA_S_PROTO_ERROR
);
1628 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_PENDING_CANCEL
) {
1629 return dcesrv_fault_disconnect(call
,
1630 DCERPC_FAULT_NO_CALL_ACTIVE
);
1633 const struct dcerpc_request
*nr
= &call
->pkt
.u
.request
;
1634 const struct dcerpc_request
*er
= NULL
;
1637 existing
= dcesrv_find_fragmented_call(dce_conn
,
1639 if (existing
== NULL
) {
1640 dcesrv_call_disconnect_after(call
,
1641 "dcesrv_auth_request - "
1642 "no existing fragmented call");
1643 return dcesrv_fault(call
,
1644 DCERPC_NCA_S_PROTO_ERROR
);
1646 er
= &existing
->pkt
.u
.request
;
1648 if (call
->pkt
.ptype
!= existing
->pkt
.ptype
) {
1649 /* trying to play silly buggers are we? */
1650 return dcesrv_fault_disconnect(existing
,
1651 DCERPC_NCA_S_PROTO_ERROR
);
1653 cmp
= memcmp(call
->pkt
.drep
, existing
->pkt
.drep
,
1656 return dcesrv_fault_disconnect(existing
,
1657 DCERPC_NCA_S_PROTO_ERROR
);
1659 if (nr
->context_id
!= er
->context_id
) {
1660 return dcesrv_fault_disconnect(existing
,
1661 DCERPC_NCA_S_PROTO_ERROR
);
1663 if (nr
->opnum
!= er
->opnum
) {
1664 return dcesrv_fault_disconnect(existing
,
1665 DCERPC_NCA_S_PROTO_ERROR
);
1670 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
) {
1672 uint8_t payload_offset
= DCERPC_REQUEST_LENGTH
;
1674 if (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_OBJECT_UUID
) {
1675 payload_offset
+= 16;
1678 ok
= dcesrv_auth_pkt_pull(call
, &blob
,
1679 0, /* required_flags */
1680 DCERPC_PFC_FLAG_FIRST
|
1681 DCERPC_PFC_FLAG_LAST
|
1682 DCERPC_PFC_FLAG_PENDING_CANCEL
|
1683 0x08 | /* this is not defined, but should be ignored */
1684 DCERPC_PFC_FLAG_CONC_MPX
|
1685 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
|
1686 DCERPC_PFC_FLAG_MAYBE
|
1687 DCERPC_PFC_FLAG_OBJECT_UUID
,
1689 &call
->pkt
.u
.request
.stub_and_verifier
);
1692 * We don't use dcesrv_fault_disconnect()
1693 * here, because we don't want to set
1694 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1696 dcesrv_call_disconnect_after(call
,
1697 "dcesrv_auth_request - failed");
1698 if (call
->fault_code
== 0) {
1699 call
->fault_code
= DCERPC_FAULT_ACCESS_DENIED
;
1701 return dcesrv_fault(call
, call
->fault_code
);
1705 /* see if this is a continued packet */
1706 if (existing
!= NULL
) {
1707 struct dcerpc_request
*er
= &existing
->pkt
.u
.request
;
1708 const struct dcerpc_request
*nr
= &call
->pkt
.u
.request
;
1714 * Up to 4 MByte are allowed by all fragments
1716 available
= dce_conn
->max_total_request_size
;
1717 if (er
->stub_and_verifier
.length
> available
) {
1718 dcesrv_call_disconnect_after(existing
,
1719 "dcesrv_auth_request - existing payload too large");
1720 return dcesrv_fault(existing
, DCERPC_FAULT_ACCESS_DENIED
);
1722 available
-= er
->stub_and_verifier
.length
;
1723 if (nr
->alloc_hint
> available
) {
1724 dcesrv_call_disconnect_after(existing
,
1725 "dcesrv_auth_request - alloc hint too large");
1726 return dcesrv_fault(existing
, DCERPC_FAULT_ACCESS_DENIED
);
1728 if (nr
->stub_and_verifier
.length
> available
) {
1729 dcesrv_call_disconnect_after(existing
,
1730 "dcesrv_auth_request - new payload too large");
1731 return dcesrv_fault(existing
, DCERPC_FAULT_ACCESS_DENIED
);
1733 alloc_hint
= er
->stub_and_verifier
.length
+ nr
->alloc_hint
;
1734 /* allocate at least 1 byte */
1735 alloc_hint
= MAX(alloc_hint
, 1);
1736 alloc_size
= er
->stub_and_verifier
.length
+
1737 nr
->stub_and_verifier
.length
;
1738 alloc_size
= MAX(alloc_size
, alloc_hint
);
1740 er
->stub_and_verifier
.data
=
1741 talloc_realloc(existing
,
1742 er
->stub_and_verifier
.data
,
1743 uint8_t, alloc_size
);
1744 if (er
->stub_and_verifier
.data
== NULL
) {
1746 return dcesrv_fault_with_flags(existing
,
1747 DCERPC_FAULT_OUT_OF_RESOURCES
,
1748 DCERPC_PFC_FLAG_DID_NOT_EXECUTE
);
1750 memcpy(er
->stub_and_verifier
.data
+
1751 er
->stub_and_verifier
.length
,
1752 nr
->stub_and_verifier
.data
,
1753 nr
->stub_and_verifier
.length
);
1754 er
->stub_and_verifier
.length
+= nr
->stub_and_verifier
.length
;
1756 existing
->pkt
.pfc_flags
|= (call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_LAST
);
1762 /* this may not be the last pdu in the chain - if its isn't then
1763 just put it on the incoming_fragmented_call_list and wait for the rest */
1764 if (call
->pkt
.ptype
== DCERPC_PKT_REQUEST
&&
1765 !(call
->pkt
.pfc_flags
& DCERPC_PFC_FLAG_LAST
)) {
1767 * Up to 4 MByte are allowed by all fragments
1769 if (call
->pkt
.u
.request
.alloc_hint
> dce_conn
->max_total_request_size
) {
1770 dcesrv_call_disconnect_after(call
,
1771 "dcesrv_auth_request - initial alloc hint too large");
1772 return dcesrv_fault(call
, DCERPC_FAULT_ACCESS_DENIED
);
1774 dcesrv_call_set_list(call
, DCESRV_LIST_FRAGMENTED_CALL_LIST
);
1775 return NT_STATUS_OK
;
1778 /* This removes any fragments we may have had stashed away */
1779 dcesrv_call_set_list(call
, DCESRV_LIST_NONE
);
1781 switch (call
->pkt
.ptype
) {
1782 case DCERPC_PKT_BIND
:
1783 status
= dcesrv_bind_nak(call
,
1784 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED
);
1786 case DCERPC_PKT_AUTH3
:
1787 status
= dcesrv_auth3(call
);
1789 case DCERPC_PKT_ALTER
:
1790 status
= dcesrv_alter(call
);
1792 case DCERPC_PKT_REQUEST
:
1793 status
= dcesrv_request(call
);
1795 case DCERPC_PKT_BIND_ACK
:
1796 case DCERPC_PKT_BIND_NAK
:
1797 case DCERPC_PKT_ALTER_RESP
:
1798 case DCERPC_PKT_RESPONSE
:
1799 case DCERPC_PKT_FAULT
:
1800 case DCERPC_PKT_SHUTDOWN
:
1801 case DCERPC_PKT_CO_CANCEL
:
1802 case DCERPC_PKT_ORPHANED
:
1804 status
= dcesrv_fault_disconnect(call
, DCERPC_NCA_S_PROTO_ERROR
);
1808 /* if we are going to be sending a reply then add
1809 it to the list of pending calls. We add it to the end to keep the call
1810 list in the order we will answer */
1811 if (!NT_STATUS_IS_OK(status
)) {
1818 _PUBLIC_ NTSTATUS
dcesrv_init_context(TALLOC_CTX
*mem_ctx
,
1819 struct loadparm_context
*lp_ctx
,
1820 const char **endpoint_servers
, struct dcesrv_context
**_dce_ctx
)
1823 struct dcesrv_context
*dce_ctx
;
1826 if (!endpoint_servers
) {
1827 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1828 return NT_STATUS_INTERNAL_ERROR
;
1831 dce_ctx
= talloc_zero(mem_ctx
, struct dcesrv_context
);
1832 NT_STATUS_HAVE_NO_MEMORY(dce_ctx
);
1834 if (uid_wrapper_enabled()) {
1835 setenv("UID_WRAPPER_MYUID", "1", 1);
1837 dce_ctx
->initial_euid
= geteuid();
1838 if (uid_wrapper_enabled()) {
1839 unsetenv("UID_WRAPPER_MYUID");
1842 dce_ctx
->endpoint_list
= NULL
;
1843 dce_ctx
->lp_ctx
= lp_ctx
;
1844 dce_ctx
->assoc_groups_idr
= idr_init(dce_ctx
);
1845 NT_STATUS_HAVE_NO_MEMORY(dce_ctx
->assoc_groups_idr
);
1846 dce_ctx
->broken_connections
= NULL
;
1848 for (i
=0;endpoint_servers
[i
];i
++) {
1849 const struct dcesrv_endpoint_server
*ep_server
;
1851 ep_server
= dcesrv_ep_server_byname(endpoint_servers
[i
]);
1853 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers
[i
]));
1854 return NT_STATUS_INTERNAL_ERROR
;
1857 status
= ep_server
->init_server(dce_ctx
, ep_server
);
1858 if (!NT_STATUS_IS_OK(status
)) {
1859 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers
[i
],
1860 nt_errstr(status
)));
1865 *_dce_ctx
= dce_ctx
;
1866 return NT_STATUS_OK
;
1869 /* the list of currently registered DCERPC endpoint servers.
1871 static struct ep_server
{
1872 struct dcesrv_endpoint_server
*ep_server
;
1873 } *ep_servers
= NULL
;
1874 static int num_ep_servers
;
1877 register a DCERPC endpoint server.
1879 The 'name' can be later used by other backends to find the operations
1880 structure for this backend.
1882 The 'type' is used to specify whether this is for a disk, printer or IPC$ share
1884 _PUBLIC_ NTSTATUS
dcerpc_register_ep_server(const void *_ep_server
)
1886 const struct dcesrv_endpoint_server
*ep_server
= _ep_server
;
1888 if (dcesrv_ep_server_byname(ep_server
->name
) != NULL
) {
1889 /* its already registered! */
1890 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
1892 return NT_STATUS_OBJECT_NAME_COLLISION
;
1895 ep_servers
= realloc_p(ep_servers
, struct ep_server
, num_ep_servers
+1);
1897 smb_panic("out of memory in dcerpc_register");
1900 ep_servers
[num_ep_servers
].ep_server
= smb_xmemdup(ep_server
, sizeof(*ep_server
));
1901 ep_servers
[num_ep_servers
].ep_server
->name
= smb_xstrdup(ep_server
->name
);
1905 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
1908 return NT_STATUS_OK
;
1912 return the operations structure for a named backend of the specified type
1914 const struct dcesrv_endpoint_server
*dcesrv_ep_server_byname(const char *name
)
1918 for (i
=0;i
<num_ep_servers
;i
++) {
1919 if (strcmp(ep_servers
[i
].ep_server
->name
, name
) == 0) {
1920 return ep_servers
[i
].ep_server
;
1927 void dcerpc_server_init(struct loadparm_context
*lp_ctx
)
1929 static bool initialized
;
1930 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
1931 STATIC_dcerpc_server_MODULES_PROTO
;
1932 init_module_fn static_init
[] = { STATIC_dcerpc_server_MODULES
};
1933 init_module_fn
*shared_init
;
1940 shared_init
= load_samba_modules(NULL
, "dcerpc_server");
1942 run_init_functions(static_init
);
1943 run_init_functions(shared_init
);
1945 talloc_free(shared_init
);
1949 return the DCERPC module version, and the size of some critical types
1950 This can be used by endpoint server modules to either detect compilation errors, or provide
1951 multiple implementations for different smbd compilation options in one module
1953 const struct dcesrv_critical_sizes
*dcerpc_module_version(void)
1955 static const struct dcesrv_critical_sizes critical_sizes
= {
1956 DCERPC_MODULE_VERSION
,
1957 sizeof(struct dcesrv_context
),
1958 sizeof(struct dcesrv_endpoint
),
1959 sizeof(struct dcesrv_endpoint_server
),
1960 sizeof(struct dcesrv_interface
),
1961 sizeof(struct dcesrv_if_list
),
1962 sizeof(struct dcesrv_connection
),
1963 sizeof(struct dcesrv_call_state
),
1964 sizeof(struct dcesrv_auth
),
1965 sizeof(struct dcesrv_handle
)
1968 return &critical_sizes
;
1971 static void dcesrv_terminate_connection(struct dcesrv_connection
*dce_conn
, const char *reason
)
1973 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
1974 struct stream_connection
*srv_conn
;
1975 srv_conn
= talloc_get_type(dce_conn
->transport
.private_data
,
1976 struct stream_connection
);
1978 dce_conn
->allow_bind
= false;
1979 dce_conn
->allow_auth3
= false;
1980 dce_conn
->allow_alter
= false;
1981 dce_conn
->allow_request
= false;
1983 if (dce_conn
->pending_call_list
== NULL
) {
1984 char *full_reason
= talloc_asprintf(dce_conn
, "dcesrv: %s", reason
);
1986 DLIST_REMOVE(dce_ctx
->broken_connections
, dce_conn
);
1987 stream_terminate_connection(srv_conn
, full_reason
? full_reason
: reason
);
1991 if (dce_conn
->terminate
!= NULL
) {
1995 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
1997 dce_conn
->terminate
= talloc_strdup(dce_conn
, reason
);
1998 if (dce_conn
->terminate
== NULL
) {
1999 dce_conn
->terminate
= "dcesrv: defered terminating connection - no memory";
2001 DLIST_ADD_END(dce_ctx
->broken_connections
, dce_conn
);
2004 static void dcesrv_cleanup_broken_connections(struct dcesrv_context
*dce_ctx
)
2006 struct dcesrv_connection
*cur
, *next
;
2008 next
= dce_ctx
->broken_connections
;
2009 while (next
!= NULL
) {
2013 if (cur
->state_flags
& DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL
) {
2014 struct dcesrv_connection_context
*context_cur
, *context_next
;
2016 context_next
= cur
->contexts
;
2017 while (context_next
!= NULL
) {
2018 context_cur
= context_next
;
2019 context_next
= context_cur
->next
;
2021 dcesrv_connection_context_destructor(context_cur
);
2025 dcesrv_terminate_connection(cur
, cur
->terminate
);
2029 /* We need this include to be able to compile on some plateforms
2030 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2032 * It has to be that deep because otherwise we have a conflict on
2033 * const struct dcesrv_interface declaration.
2034 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2035 * which conflict with the bind used before.
2037 #include "system/network.h"
2039 struct dcesrv_sock_reply_state
{
2040 struct dcesrv_connection
*dce_conn
;
2041 struct dcesrv_call_state
*call
;
2045 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
);
2046 static void dcesrv_call_terminate_step1(struct tevent_req
*subreq
);
2048 static void dcesrv_sock_report_output_data(struct dcesrv_connection
*dce_conn
)
2050 struct dcesrv_call_state
*call
;
2052 call
= dce_conn
->call_list
;
2053 if (!call
|| !call
->replies
) {
2057 while (call
->replies
) {
2058 struct data_blob_list_item
*rep
= call
->replies
;
2059 struct dcesrv_sock_reply_state
*substate
;
2060 struct tevent_req
*subreq
;
2062 substate
= talloc_zero(call
, struct dcesrv_sock_reply_state
);
2064 dcesrv_terminate_connection(dce_conn
, "no memory");
2068 substate
->dce_conn
= dce_conn
;
2069 substate
->call
= NULL
;
2071 DLIST_REMOVE(call
->replies
, rep
);
2073 if (call
->replies
== NULL
&& call
->terminate_reason
== NULL
) {
2074 substate
->call
= call
;
2077 substate
->iov
.iov_base
= (void *) rep
->blob
.data
;
2078 substate
->iov
.iov_len
= rep
->blob
.length
;
2080 subreq
= tstream_writev_queue_send(substate
,
2081 dce_conn
->event_ctx
,
2083 dce_conn
->send_queue
,
2086 dcesrv_terminate_connection(dce_conn
, "no memory");
2089 tevent_req_set_callback(subreq
, dcesrv_sock_reply_done
,
2093 if (call
->terminate_reason
!= NULL
) {
2094 struct tevent_req
*subreq
;
2096 subreq
= tevent_queue_wait_send(call
,
2097 dce_conn
->event_ctx
,
2098 dce_conn
->send_queue
);
2100 dcesrv_terminate_connection(dce_conn
, __location__
);
2103 tevent_req_set_callback(subreq
, dcesrv_call_terminate_step1
,
2107 DLIST_REMOVE(call
->conn
->call_list
, call
);
2108 call
->list
= DCESRV_LIST_NONE
;
2111 static void dcesrv_sock_reply_done(struct tevent_req
*subreq
)
2113 struct dcesrv_sock_reply_state
*substate
= tevent_req_callback_data(subreq
,
2114 struct dcesrv_sock_reply_state
);
2118 struct dcesrv_call_state
*call
= substate
->call
;
2120 ret
= tstream_writev_queue_recv(subreq
, &sys_errno
);
2121 TALLOC_FREE(subreq
);
2123 status
= map_nt_error_from_unix_common(sys_errno
);
2124 dcesrv_terminate_connection(substate
->dce_conn
, nt_errstr(status
));
2128 talloc_free(substate
);
2134 static void dcesrv_call_terminate_step2(struct tevent_req
*subreq
);
2136 static void dcesrv_call_terminate_step1(struct tevent_req
*subreq
)
2138 struct dcesrv_call_state
*call
= tevent_req_callback_data(subreq
,
2139 struct dcesrv_call_state
);
2143 /* make sure we stop send queue before removing subreq */
2144 tevent_queue_stop(call
->conn
->send_queue
);
2146 ok
= tevent_queue_wait_recv(subreq
);
2147 TALLOC_FREE(subreq
);
2149 dcesrv_terminate_connection(call
->conn
, __location__
);
2153 /* disconnect after 200 usecs */
2154 tv
= timeval_current_ofs_usec(200);
2155 subreq
= tevent_wakeup_send(call
, call
->conn
->event_ctx
, tv
);
2156 if (subreq
== NULL
) {
2157 dcesrv_terminate_connection(call
->conn
, __location__
);
2160 tevent_req_set_callback(subreq
, dcesrv_call_terminate_step2
,
2164 static void dcesrv_call_terminate_step2(struct tevent_req
*subreq
)
2166 struct dcesrv_call_state
*call
= tevent_req_callback_data(subreq
,
2167 struct dcesrv_call_state
);
2170 ok
= tevent_wakeup_recv(subreq
);
2171 TALLOC_FREE(subreq
);
2173 dcesrv_terminate_connection(call
->conn
, __location__
);
2177 dcesrv_terminate_connection(call
->conn
, call
->terminate_reason
);
2180 struct dcesrv_socket_context
{
2181 const struct dcesrv_endpoint
*endpoint
;
2182 struct dcesrv_context
*dcesrv_ctx
;
2186 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
);
2188 static void dcesrv_sock_accept(struct stream_connection
*srv_conn
)
2191 struct dcesrv_socket_context
*dcesrv_sock
=
2192 talloc_get_type(srv_conn
->private_data
, struct dcesrv_socket_context
);
2193 enum dcerpc_transport_t transport
=
2194 dcerpc_binding_get_transport(dcesrv_sock
->endpoint
->ep_description
);
2195 struct dcesrv_connection
*dcesrv_conn
= NULL
;
2197 struct tevent_req
*subreq
;
2198 struct loadparm_context
*lp_ctx
= dcesrv_sock
->dcesrv_ctx
->lp_ctx
;
2200 dcesrv_cleanup_broken_connections(dcesrv_sock
->dcesrv_ctx
);
2202 if (!srv_conn
->session_info
) {
2203 status
= auth_anonymous_session_info(srv_conn
,
2205 &srv_conn
->session_info
);
2206 if (!NT_STATUS_IS_OK(status
)) {
2207 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2208 nt_errstr(status
)));
2209 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2214 status
= dcesrv_endpoint_connect(dcesrv_sock
->dcesrv_ctx
,
2216 dcesrv_sock
->endpoint
,
2217 srv_conn
->session_info
,
2218 srv_conn
->event
.ctx
,
2220 srv_conn
->server_id
,
2221 DCESRV_CALL_STATE_FLAG_MAY_ASYNC
,
2223 if (!NT_STATUS_IS_OK(status
)) {
2224 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2225 nt_errstr(status
)));
2226 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2230 dcesrv_conn
->transport
.private_data
= srv_conn
;
2231 dcesrv_conn
->transport
.report_output_data
= dcesrv_sock_report_output_data
;
2233 TALLOC_FREE(srv_conn
->event
.fde
);
2235 dcesrv_conn
->send_queue
= tevent_queue_create(dcesrv_conn
, "dcesrv send queue");
2236 if (!dcesrv_conn
->send_queue
) {
2237 status
= NT_STATUS_NO_MEMORY
;
2238 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2239 nt_errstr(status
)));
2240 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2244 if (transport
== NCACN_NP
) {
2245 dcesrv_conn
->auth_state
.session_key
= dcesrv_inherited_session_key
;
2246 dcesrv_conn
->stream
= talloc_move(dcesrv_conn
,
2247 &srv_conn
->tstream
);
2249 ret
= tstream_bsd_existing_socket(dcesrv_conn
,
2250 socket_get_fd(srv_conn
->socket
),
2251 &dcesrv_conn
->stream
);
2253 status
= map_nt_error_from_unix_common(errno
);
2254 DEBUG(0, ("dcesrv_sock_accept: "
2255 "failed to setup tstream: %s\n",
2256 nt_errstr(status
)));
2257 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2260 socket_set_flags(srv_conn
->socket
, SOCKET_FLAG_NOCLOSE
);
2263 dcesrv_conn
->local_address
= srv_conn
->local_address
;
2264 dcesrv_conn
->remote_address
= srv_conn
->remote_address
;
2266 if (transport
== NCALRPC
) {
2271 sock_fd
= socket_get_fd(srv_conn
->socket
);
2272 if (sock_fd
== -1) {
2273 stream_terminate_connection(
2274 srv_conn
, "socket_get_fd failed\n");
2278 ret
= getpeereid(sock_fd
, &uid
, &gid
);
2280 status
= map_nt_error_from_unix_common(errno
);
2281 DEBUG(0, ("dcesrv_sock_accept: "
2282 "getpeereid() failed for NCALRPC: %s\n",
2283 nt_errstr(status
)));
2284 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2287 if (uid
== dcesrv_conn
->dce_ctx
->initial_euid
) {
2288 struct tsocket_address
*r
= NULL
;
2290 ret
= tsocket_address_unix_from_path(dcesrv_conn
,
2291 "/root/ncalrpc_as_system",
2294 status
= map_nt_error_from_unix_common(errno
);
2295 DEBUG(0, ("dcesrv_sock_accept: "
2296 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2297 nt_errstr(status
)));
2298 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2301 dcesrv_conn
->remote_address
= r
;
2305 srv_conn
->private_data
= dcesrv_conn
;
2307 irpc_add_name(srv_conn
->msg_ctx
, "rpc_server");
2309 subreq
= dcerpc_read_ncacn_packet_send(dcesrv_conn
,
2310 dcesrv_conn
->event_ctx
,
2311 dcesrv_conn
->stream
);
2313 status
= NT_STATUS_NO_MEMORY
;
2314 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2315 nt_errstr(status
)));
2316 stream_terminate_connection(srv_conn
, nt_errstr(status
));
2319 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dcesrv_conn
);
2324 static void dcesrv_read_fragment_done(struct tevent_req
*subreq
)
2326 struct dcesrv_connection
*dce_conn
= tevent_req_callback_data(subreq
,
2327 struct dcesrv_connection
);
2328 struct dcesrv_context
*dce_ctx
= dce_conn
->dce_ctx
;
2329 struct ncacn_packet
*pkt
;
2333 if (dce_conn
->terminate
) {
2335 * if the current connection is broken
2336 * we need to clean it up before any other connection
2338 dcesrv_terminate_connection(dce_conn
, dce_conn
->terminate
);
2339 dcesrv_cleanup_broken_connections(dce_ctx
);
2343 dcesrv_cleanup_broken_connections(dce_ctx
);
2345 status
= dcerpc_read_ncacn_packet_recv(subreq
, dce_conn
,
2347 TALLOC_FREE(subreq
);
2348 if (!NT_STATUS_IS_OK(status
)) {
2349 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2353 status
= dcesrv_process_ncacn_packet(dce_conn
, pkt
, buffer
);
2354 if (!NT_STATUS_IS_OK(status
)) {
2355 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2359 subreq
= dcerpc_read_ncacn_packet_send(dce_conn
,
2360 dce_conn
->event_ctx
,
2363 status
= NT_STATUS_NO_MEMORY
;
2364 dcesrv_terminate_connection(dce_conn
, nt_errstr(status
));
2367 tevent_req_set_callback(subreq
, dcesrv_read_fragment_done
, dce_conn
);
2370 static void dcesrv_sock_recv(struct stream_connection
*conn
, uint16_t flags
)
2372 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
2373 struct dcesrv_connection
);
2374 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_recv triggered");
2377 static void dcesrv_sock_send(struct stream_connection
*conn
, uint16_t flags
)
2379 struct dcesrv_connection
*dce_conn
= talloc_get_type(conn
->private_data
,
2380 struct dcesrv_connection
);
2381 dcesrv_terminate_connection(dce_conn
, "dcesrv_sock_send triggered");
2385 static const struct stream_server_ops dcesrv_stream_ops
= {
2387 .accept_connection
= dcesrv_sock_accept
,
2388 .recv_handler
= dcesrv_sock_recv
,
2389 .send_handler
= dcesrv_sock_send
,
2392 static NTSTATUS
dcesrv_add_ep_unix(struct dcesrv_context
*dce_ctx
,
2393 struct loadparm_context
*lp_ctx
,
2394 struct dcesrv_endpoint
*e
,
2395 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
2397 struct dcesrv_socket_context
*dcesrv_sock
;
2400 const char *endpoint
;
2402 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
2403 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
2405 /* remember the endpoint of this socket */
2406 dcesrv_sock
->endpoint
= e
;
2407 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
2409 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
2411 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, lp_ctx
,
2412 model_ops
, &dcesrv_stream_ops
,
2413 "unix", endpoint
, &port
,
2414 lpcfg_socket_options(lp_ctx
),
2416 if (!NT_STATUS_IS_OK(status
)) {
2417 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2418 endpoint
, nt_errstr(status
)));
2424 static NTSTATUS
dcesrv_add_ep_ncalrpc(struct dcesrv_context
*dce_ctx
,
2425 struct loadparm_context
*lp_ctx
,
2426 struct dcesrv_endpoint
*e
,
2427 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
2429 struct dcesrv_socket_context
*dcesrv_sock
;
2433 const char *endpoint
;
2435 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
2437 if (endpoint
== NULL
) {
2439 * No identifier specified: use DEFAULT.
2441 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2442 * no endpoint and let the epmapper worry about it.
2444 endpoint
= "DEFAULT";
2445 status
= dcerpc_binding_set_string_option(e
->ep_description
,
2448 if (!NT_STATUS_IS_OK(status
)) {
2449 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2450 nt_errstr(status
)));
2455 full_path
= talloc_asprintf(dce_ctx
, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx
),
2458 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
2459 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
2461 /* remember the endpoint of this socket */
2462 dcesrv_sock
->endpoint
= e
;
2463 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
2465 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, lp_ctx
,
2466 model_ops
, &dcesrv_stream_ops
,
2467 "unix", full_path
, &port
,
2468 lpcfg_socket_options(lp_ctx
),
2470 if (!NT_STATUS_IS_OK(status
)) {
2471 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2472 endpoint
, full_path
, nt_errstr(status
)));
2477 static NTSTATUS
dcesrv_add_ep_np(struct dcesrv_context
*dce_ctx
,
2478 struct loadparm_context
*lp_ctx
,
2479 struct dcesrv_endpoint
*e
,
2480 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
2482 struct dcesrv_socket_context
*dcesrv_sock
;
2484 const char *endpoint
;
2486 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
2487 if (endpoint
== NULL
) {
2488 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2489 return NT_STATUS_INVALID_PARAMETER
;
2492 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
2493 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
2495 /* remember the endpoint of this socket */
2496 dcesrv_sock
->endpoint
= e
;
2497 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
2499 status
= tstream_setup_named_pipe(dce_ctx
, event_ctx
, lp_ctx
,
2500 model_ops
, &dcesrv_stream_ops
,
2503 if (!NT_STATUS_IS_OK(status
)) {
2504 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2505 endpoint
, nt_errstr(status
)));
2509 return NT_STATUS_OK
;
2513 add a socket address to the list of events, one event per dcerpc endpoint
2515 static NTSTATUS
add_socket_rpc_tcp_iface(struct dcesrv_context
*dce_ctx
, struct dcesrv_endpoint
*e
,
2516 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
,
2517 const char *address
)
2519 struct dcesrv_socket_context
*dcesrv_sock
;
2522 const char *endpoint
;
2525 endpoint
= dcerpc_binding_get_string_option(e
->ep_description
, "endpoint");
2526 if (endpoint
!= NULL
) {
2527 port
= atoi(endpoint
);
2530 dcesrv_sock
= talloc_zero(event_ctx
, struct dcesrv_socket_context
);
2531 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock
);
2533 /* remember the endpoint of this socket */
2534 dcesrv_sock
->endpoint
= e
;
2535 dcesrv_sock
->dcesrv_ctx
= talloc_reference(dcesrv_sock
, dce_ctx
);
2537 status
= stream_setup_socket(dcesrv_sock
, event_ctx
, dce_ctx
->lp_ctx
,
2538 model_ops
, &dcesrv_stream_ops
,
2539 "ip", address
, &port
,
2540 lpcfg_socket_options(dce_ctx
->lp_ctx
),
2542 if (!NT_STATUS_IS_OK(status
)) {
2543 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
2544 address
, port
, nt_errstr(status
)));
2548 snprintf(port_str
, sizeof(port_str
), "%u", port
);
2550 status
= dcerpc_binding_set_string_option(e
->ep_description
,
2551 "endpoint", port_str
);
2552 if (!NT_STATUS_IS_OK(status
)) {
2553 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2554 port_str
, nt_errstr(status
)));
2558 return NT_STATUS_OK
;
2561 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2563 static NTSTATUS
dcesrv_add_ep_tcp(struct dcesrv_context
*dce_ctx
,
2564 struct loadparm_context
*lp_ctx
,
2565 struct dcesrv_endpoint
*e
,
2566 struct tevent_context
*event_ctx
, const struct model_ops
*model_ops
)
2570 /* Add TCP/IP sockets */
2571 if (lpcfg_interfaces(lp_ctx
) && lpcfg_bind_interfaces_only(lp_ctx
)) {
2574 struct interface
*ifaces
;
2576 load_interface_list(dce_ctx
, lp_ctx
, &ifaces
);
2578 num_interfaces
= iface_list_count(ifaces
);
2579 for(i
= 0; i
< num_interfaces
; i
++) {
2580 const char *address
= iface_list_n_ip(ifaces
, i
);
2581 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
, address
);
2582 NT_STATUS_NOT_OK_RETURN(status
);
2588 wcard
= iface_list_wildcard(dce_ctx
);
2589 NT_STATUS_HAVE_NO_MEMORY(wcard
);
2590 for (i
=0; wcard
[i
]; i
++) {
2591 status
= add_socket_rpc_tcp_iface(dce_ctx
, e
, event_ctx
, model_ops
, wcard
[i
]);
2592 if (NT_STATUS_IS_OK(status
)) {
2597 if (num_binds
== 0) {
2598 return NT_STATUS_INVALID_PARAMETER_MIX
;
2602 return NT_STATUS_OK
;
2605 NTSTATUS
dcesrv_add_ep(struct dcesrv_context
*dce_ctx
,
2606 struct loadparm_context
*lp_ctx
,
2607 struct dcesrv_endpoint
*e
,
2608 struct tevent_context
*event_ctx
,
2609 const struct model_ops
*model_ops
)
2611 enum dcerpc_transport_t transport
=
2612 dcerpc_binding_get_transport(e
->ep_description
);
2614 switch (transport
) {
2615 case NCACN_UNIX_STREAM
:
2616 return dcesrv_add_ep_unix(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
2619 return dcesrv_add_ep_ncalrpc(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
2622 return dcesrv_add_ep_tcp(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
2625 return dcesrv_add_ep_np(dce_ctx
, lp_ctx
, e
, event_ctx
, model_ops
);
2628 return NT_STATUS_NOT_SUPPORTED
;
2634 * retrieve credentials from a dce_call
2636 _PUBLIC_
struct cli_credentials
*dcesrv_call_credentials(struct dcesrv_call_state
*dce_call
)
2638 return dce_call
->conn
->auth_state
.session_info
->credentials
;
2642 * returns true if this is an authenticated call
2644 _PUBLIC_
bool dcesrv_call_authenticated(struct dcesrv_call_state
*dce_call
)
2646 enum security_user_level level
;
2647 level
= security_session_user_level(dce_call
->conn
->auth_state
.session_info
, NULL
);
2648 return level
>= SECURITY_USER
;
2652 * retrieve account_name for a dce_call
2654 _PUBLIC_
const char *dcesrv_call_account_name(struct dcesrv_call_state
*dce_call
)
2656 return dce_call
->context
->conn
->auth_state
.session_info
->info
->account_name
;