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 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
46 const struct dcerpc_bind *b,
47 struct dcerpc_ack_ctx *ack_ctx_list);
50 find an association group given a assoc_group_id
52 static struct dcesrv_assoc_group *dcesrv_assoc_group_find(struct dcesrv_context *dce_ctx,
57 id_ptr = idr_find(dce_ctx->assoc_groups_idr, id);
61 return talloc_get_type_abort(id_ptr, struct dcesrv_assoc_group);
65 take a reference to an existing association group
67 static struct dcesrv_assoc_group *dcesrv_assoc_group_reference(TALLOC_CTX *mem_ctx,
68 struct dcesrv_context *dce_ctx,
71 struct dcesrv_assoc_group *assoc_group;
73 assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
74 if (assoc_group == NULL) {
75 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id));
78 return talloc_reference(mem_ctx, assoc_group);
81 static int dcesrv_assoc_group_destructor(struct dcesrv_assoc_group *assoc_group)
84 ret = idr_remove(assoc_group->dce_ctx->assoc_groups_idr, assoc_group->id);
86 DEBUG(0,(__location__ ": Failed to remove assoc_group 0x%08x\n",
93 allocate a new association group
95 static struct dcesrv_assoc_group *dcesrv_assoc_group_new(TALLOC_CTX *mem_ctx,
96 struct dcesrv_context *dce_ctx)
98 struct dcesrv_assoc_group *assoc_group;
101 assoc_group = talloc_zero(mem_ctx, struct dcesrv_assoc_group);
102 if (assoc_group == NULL) {
106 id = idr_get_new_random(dce_ctx->assoc_groups_idr, assoc_group, UINT16_MAX);
108 talloc_free(assoc_group);
109 DEBUG(0,(__location__ ": Out of association groups!\n"));
113 assoc_group->id = id;
114 assoc_group->dce_ctx = dce_ctx;
116 talloc_set_destructor(assoc_group, dcesrv_assoc_group_destructor);
123 see if two endpoints match
125 static bool endpoints_match(const struct dcerpc_binding *ep1,
126 const struct dcerpc_binding *ep2)
128 enum dcerpc_transport_t t1;
129 enum dcerpc_transport_t t2;
133 t1 = dcerpc_binding_get_transport(ep1);
134 t2 = dcerpc_binding_get_transport(ep2);
136 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
137 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
147 if (strcasecmp(e1, e2) != 0) {
155 find an endpoint in the dcesrv_context
157 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
158 const struct dcerpc_binding *ep_description)
160 struct dcesrv_endpoint *ep;
161 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
162 if (endpoints_match(ep->ep_description, ep_description)) {
170 find a registered context_id from a bind or alter_context
172 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
175 struct dcesrv_connection_context *c;
176 for (c=conn->contexts;c;c=c->next) {
177 if (c->context_id == context_id) return c;
183 see if a uuid and if_version match to an interface
185 static bool interface_match(const struct dcesrv_interface *if1,
186 const struct dcesrv_interface *if2)
188 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
189 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
193 find the interface operations on any endpoint with this binding
195 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
196 struct dcerpc_binding *binding,
197 const struct dcesrv_interface *iface)
199 struct dcesrv_endpoint *ep;
200 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
201 if (endpoints_match(ep->ep_description, binding)) {
202 struct dcesrv_if_list *ifl;
203 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
204 if (interface_match(&(ifl->iface), iface)) {
205 return &(ifl->iface);
214 see if a uuid and if_version match to an interface
216 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
217 const struct GUID *uuid, uint32_t if_version)
219 return (iface->syntax_id.if_version == if_version &&
220 GUID_equal(&iface->syntax_id.uuid, uuid));
224 find the interface operations on an endpoint by uuid
226 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
227 const struct GUID *uuid, uint32_t if_version)
229 struct dcesrv_if_list *ifl;
230 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
231 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
232 return &(ifl->iface);
239 find the earlier parts of a fragmented call awaiting reassembily
241 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
243 struct dcesrv_call_state *c;
244 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
245 if (c->pkt.call_id == call_id) {
253 register an interface on an endpoint
255 An endpoint is one unix domain socket (for ncalrpc), one TCP port
256 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
258 Each endpoint can have many interfaces such as netlogon, lsa or
259 samr. Some have essentially the full set.
261 This is driven from the set of interfaces listed in each IDL file
262 via the PIDL generated *__op_init_server() functions.
264 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
266 const struct dcesrv_interface *iface,
267 const struct security_descriptor *sd)
269 struct dcesrv_endpoint *ep;
270 struct dcesrv_if_list *ifl;
271 struct dcerpc_binding *binding;
274 enum dcerpc_transport_t transport;
275 char *ep_string = NULL;
276 bool use_single_process = true;
278 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
280 if (NT_STATUS_IS_ERR(status)) {
281 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
285 transport = dcerpc_binding_get_transport(binding);
286 if (transport == NCACN_IP_TCP) {
291 * First check if there is already a port specified, eg
292 * for epmapper on ncacn_ip_tcp:[135]
295 = dcerpc_binding_get_string_option(binding,
297 if (endpoint == NULL) {
298 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
299 "rpc server port", iface->name, 0);
302 * For RPC services that are not set to use a single
303 * process, we do not default to using the 'rpc server
304 * port' because that would cause a double-bind on
307 if (port == 0 && !use_single_process) {
308 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
311 snprintf(port_str, sizeof(port_str), "%u", port);
312 status = dcerpc_binding_set_string_option(binding,
315 if (!NT_STATUS_IS_OK(status)) {
322 /* see if the interface is already registered on the endpoint */
323 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
324 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
325 iface->name, ep_name));
326 return NT_STATUS_OBJECT_NAME_COLLISION;
329 /* check if this endpoint exists
331 ep = find_endpoint(dce_ctx, binding);
335 * We want a new port on ncacn_ip_tcp for NETLOGON, so
336 * it can be multi-process. Other processes can also
337 * listen on distinct ports, if they have one forced
338 * in the code above with eg 'rpc server port:drsuapi = 1027'
340 * If we have mulitiple endpoints on port 0, they each
341 * get an epemeral port (currently by walking up from
344 if (!use_single_process && transport == NCACN_IP_TCP) {
349 if (ep == NULL || add_ep) {
350 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
352 return NT_STATUS_NO_MEMORY;
355 ep->ep_description = talloc_move(ep, &binding);
358 /* add mgmt interface */
359 ifl = talloc_zero(ep, struct dcesrv_if_list);
361 return NT_STATUS_NO_MEMORY;
364 ifl->iface = dcesrv_get_mgmt_interface();
366 DLIST_ADD(ep->interface_list, ifl);
370 * By default don't force into a single process, but if any
371 * interface on this endpoint on this service uses handles
372 * (most do), then we must force into single process mode
374 * By overwriting this each time a new interface is added to
375 * this endpoint, we end up with the most restrictive setting.
377 if (use_single_process) {
378 ep->use_single_process = true;
381 /* talloc a new interface list element */
382 ifl = talloc_zero(ep, struct dcesrv_if_list);
384 return NT_STATUS_NO_MEMORY;
387 /* copy the given interface struct to the one on the endpoints interface list */
388 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
390 /* if we have a security descriptor given,
391 * we should see if we can set it up on the endpoint
394 /* if there's currently no security descriptor given on the endpoint
397 if (ep->sd == NULL) {
398 ep->sd = security_descriptor_copy(ep, sd);
401 /* if now there's no security descriptor given on the endpoint
402 * something goes wrong, either we failed to copy the security descriptor
403 * or there was already one on the endpoint
405 if (ep->sd != NULL) {
406 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
407 " on endpoint '%s'\n",
408 iface->name, ep_name));
409 if (add_ep) free(ep);
411 return NT_STATUS_OBJECT_NAME_COLLISION;
415 /* finally add the interface on the endpoint */
416 DLIST_ADD(ep->interface_list, ifl);
418 /* if it's a new endpoint add it to the dcesrv_context */
420 DLIST_ADD(dce_ctx->endpoint_list, ep);
423 /* Re-get the string as we may have set a port */
424 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
426 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
427 iface->name, ep_string));
428 TALLOC_FREE(ep_string);
433 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
434 DATA_BLOB *session_key)
436 if (p->auth_state.session_info->session_key.length) {
437 *session_key = p->auth_state.session_info->session_key;
440 return NT_STATUS_NO_USER_SESSION_KEY;
444 fetch the user session key - may be default (above) or the SMB session key
446 The key is always truncated to 16 bytes
448 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
449 DATA_BLOB *session_key)
451 NTSTATUS status = p->auth_state.session_key(p, session_key);
452 if (!NT_STATUS_IS_OK(status)) {
456 session_key->length = MIN(session_key->length, 16);
462 connect to a dcerpc endpoint
464 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
466 const struct dcesrv_endpoint *ep,
467 struct auth_session_info *session_info,
468 struct tevent_context *event_ctx,
469 struct imessaging_context *msg_ctx,
470 struct server_id server_id,
471 uint32_t state_flags,
472 struct dcesrv_connection **_p)
474 struct dcesrv_connection *p;
477 return NT_STATUS_ACCESS_DENIED;
480 p = talloc_zero(mem_ctx, struct dcesrv_connection);
481 NT_STATUS_HAVE_NO_MEMORY(p);
483 if (!talloc_reference(p, session_info)) {
485 return NT_STATUS_NO_MEMORY;
488 p->dce_ctx = dce_ctx;
490 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
491 p->auth_state.session_info = session_info;
492 p->auth_state.session_key = dcesrv_generic_session_key;
493 p->event_ctx = event_ctx;
494 p->msg_ctx = msg_ctx;
495 p->server_id = server_id;
496 p->state_flags = state_flags;
497 p->allow_bind = true;
498 p->max_recv_frag = 5840;
499 p->max_xmit_frag = 5840;
500 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
503 * For now we only support NDR32.
505 p->preferred_transfer = &ndr_transfer_syntax_ndr;
512 move a call from an existing linked list to the specified list. This
513 prevents bugs where we forget to remove the call from a previous
516 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
517 enum dcesrv_call_list list)
519 switch (call->list) {
520 case DCESRV_LIST_NONE:
522 case DCESRV_LIST_CALL_LIST:
523 DLIST_REMOVE(call->conn->call_list, call);
525 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
526 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
528 case DCESRV_LIST_PENDING_CALL_LIST:
529 DLIST_REMOVE(call->conn->pending_call_list, call);
534 case DCESRV_LIST_NONE:
536 case DCESRV_LIST_CALL_LIST:
537 DLIST_ADD_END(call->conn->call_list, call);
539 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
540 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
542 case DCESRV_LIST_PENDING_CALL_LIST:
543 DLIST_ADD_END(call->conn->pending_call_list, call);
548 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
551 if (call->conn->terminate != NULL) {
555 call->conn->allow_bind = false;
556 call->conn->allow_alter = false;
557 call->conn->allow_auth3 = false;
558 call->conn->allow_request = false;
560 call->terminate_reason = talloc_strdup(call, reason);
561 if (call->terminate_reason == NULL) {
562 call->terminate_reason = __location__;
567 return a dcerpc bind_nak
569 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
571 struct ncacn_packet pkt;
572 struct dcerpc_bind_nak_version version;
573 struct data_blob_list_item *rep;
575 static const uint8_t _pad[3] = { 0, };
578 * We add the call to the pending_call_list
579 * in order to defer the termination.
581 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
583 /* setup a bind_nak */
584 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
586 pkt.call_id = call->pkt.call_id;
587 pkt.ptype = DCERPC_PKT_BIND_NAK;
588 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
589 pkt.u.bind_nak.reject_reason = reason;
590 version.rpc_vers = 5;
591 version.rpc_vers_minor = 0;
592 pkt.u.bind_nak.num_versions = 1;
593 pkt.u.bind_nak.versions = &version;
594 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
596 rep = talloc_zero(call, struct data_blob_list_item);
598 return NT_STATUS_NO_MEMORY;
601 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
602 if (!NT_STATUS_IS_OK(status)) {
606 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
608 DLIST_ADD_END(call->replies, rep);
609 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
611 if (call->conn->call_list && call->conn->call_list->replies) {
612 if (call->conn->transport.report_output_data) {
613 call->conn->transport.report_output_data(call->conn);
620 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
624 * We add the call to the pending_call_list
625 * in order to defer the termination.
627 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
629 return dcesrv_fault_with_flags(call, fault_code,
630 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
633 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
635 DLIST_REMOVE(c->conn->contexts, c);
637 if (c->iface && c->iface->unbind) {
638 c->iface->unbind(c, c->iface);
645 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
647 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
648 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
649 enum dcerpc_transport_t transport =
650 dcerpc_binding_get_transport(endpoint->ep_description);
651 struct dcesrv_connection_context *context = dce_call->context;
652 const struct dcesrv_interface *iface = context->iface;
654 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
656 if (transport == NCALRPC) {
657 context->allow_connect = true;
662 * allow overwrite per interface
663 * allow dcerpc auth level connect:<interface>
665 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
666 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
667 "allow dcerpc auth level connect",
669 context->allow_connect);
672 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
673 const struct dcesrv_interface *iface)
675 if (dce_call->context == NULL) {
676 return NT_STATUS_INTERNAL_ERROR;
680 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
681 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
683 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
687 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
688 const struct dcesrv_interface *iface)
690 if (dce_call->context == NULL) {
691 return NT_STATUS_INTERNAL_ERROR;
694 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
698 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
699 const struct dcesrv_interface *iface)
701 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
702 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
703 enum dcerpc_transport_t transport =
704 dcerpc_binding_get_transport(endpoint->ep_description);
705 struct dcesrv_connection_context *context = dce_call->context;
707 if (context == NULL) {
708 return NT_STATUS_INTERNAL_ERROR;
711 if (transport == NCALRPC) {
712 context->allow_connect = true;
717 * allow overwrite per interface
718 * allow dcerpc auth level connect:<interface>
720 context->allow_connect = false;
721 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
722 "allow dcerpc auth level connect",
724 context->allow_connect);
728 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
729 const struct dcesrv_interface *iface)
731 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
732 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
733 enum dcerpc_transport_t transport =
734 dcerpc_binding_get_transport(endpoint->ep_description);
735 struct dcesrv_connection_context *context = dce_call->context;
737 if (context == NULL) {
738 return NT_STATUS_INTERNAL_ERROR;
741 if (transport == NCALRPC) {
742 context->allow_connect = true;
747 * allow overwrite per interface
748 * allow dcerpc auth level connect:<interface>
750 context->allow_connect = true;
751 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
752 "allow dcerpc auth level connect",
754 context->allow_connect);
759 handle a bind request
761 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
763 struct ncacn_packet pkt;
764 struct data_blob_list_item *rep;
766 uint32_t extra_flags = 0;
767 uint16_t max_req = 0;
768 uint16_t max_rep = 0;
769 const char *ep_prefix = "";
770 const char *endpoint = NULL;
771 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
772 struct dcerpc_ack_ctx *ack_features = NULL;
775 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
777 call->pkt.u.bind.auth_info.length,
778 0, /* required flags */
779 DCERPC_PFC_FLAG_FIRST |
780 DCERPC_PFC_FLAG_LAST |
781 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
782 0x08 | /* this is not defined, but should be ignored */
783 DCERPC_PFC_FLAG_CONC_MPX |
784 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
785 DCERPC_PFC_FLAG_MAYBE |
786 DCERPC_PFC_FLAG_OBJECT_UUID);
787 if (!NT_STATUS_IS_OK(status)) {
788 return dcesrv_bind_nak(call,
789 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
792 /* max_recv_frag and max_xmit_frag result always in the same value! */
793 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
794 call->pkt.u.bind.max_recv_frag);
796 * The values are between 2048 and 5840 tested against Windows 2012R2
797 * via ncacn_ip_tcp on port 135.
799 max_req = MAX(2048, max_req);
800 max_rep = MIN(max_req, call->conn->max_recv_frag);
801 /* They are truncated to an 8 byte boundary. */
804 /* max_recv_frag and max_xmit_frag result always in the same value! */
805 call->conn->max_recv_frag = max_rep;
806 call->conn->max_xmit_frag = max_rep;
809 if provided, check the assoc_group is valid
811 if (call->pkt.u.bind.assoc_group_id != 0) {
812 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
814 call->pkt.u.bind.assoc_group_id);
816 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
817 call->conn->dce_ctx);
821 * The NETLOGON server does not use handles and so
822 * there is no need to support association groups, but
823 * we need to give back a number regardless.
825 * We have to do this when it is not run as a single process,
826 * because then it can't see the other valid association
827 * groups. We handle this genericly for all endpoints not
828 * running in single process mode.
830 * We know which endpoint we are on even before checking the
831 * iface UUID, so for simplicity we enforce the same policy
832 * for all interfaces on the endpoint.
834 * This means that where NETLOGON
835 * shares an endpoint (such as ncalrpc or of 'lsa over
836 * netlogon' is set) we will still check association groups.
840 if (call->conn->assoc_group == NULL &&
841 !call->conn->endpoint->use_single_process) {
842 call->conn->assoc_group
843 = dcesrv_assoc_group_new(call->conn,
844 call->conn->dce_ctx);
846 if (call->conn->assoc_group == NULL) {
847 return dcesrv_bind_nak(call, 0);
850 if (call->pkt.u.bind.num_contexts < 1) {
851 return dcesrv_bind_nak(call, 0);
854 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
855 call->pkt.u.bind.num_contexts);
856 if (ack_ctx_list == NULL) {
857 return dcesrv_bind_nak(call, 0);
861 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
862 * dcesrv_check_or_create_context()) and do some protocol validation
863 * and set sane defaults.
865 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
866 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
867 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
868 bool is_feature = false;
869 uint64_t features = 0;
871 if (c->num_transfer_syntaxes == 0) {
872 return dcesrv_bind_nak(call, 0);
875 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
876 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
879 * It's only treated as bind time feature request, if the first
880 * transfer_syntax matches, all others are ignored.
882 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
888 if (ack_features != NULL) {
890 * Only one bind time feature context is allowed.
892 return dcesrv_bind_nak(call, 0);
896 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
897 a->reason.negotiate = 0;
898 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
899 /* not supported yet */
901 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
902 a->reason.negotiate |=
903 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
906 call->conn->bind_time_features = a->reason.negotiate;
910 * Try to negotiate one new presentation context.
912 * Deep in here we locate the iface (by uuid) that the client
913 * requested, from the list of interfaces on the
914 * call->conn->endpoint, and call iface->bind() on that iface.
916 * call->conn was set up at the accept() of the socket, and
917 * call->conn->endpoint has a list of interfaces restricted to
920 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
921 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
922 return dcesrv_bind_nak(call, 0);
924 if (!NT_STATUS_IS_OK(status)) {
929 * At this point we know which interface (eg netlogon, lsa,
930 * drsuapi) the caller requested. This is available on
931 * call->conntext->iface.
934 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
935 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
936 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
937 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
940 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
941 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
945 * After finding the interface and setting up the NDR
946 * transport negotiation etc, handle any authentication that
947 * is being requested.
949 if (!dcesrv_auth_bind(call)) {
950 struct dcesrv_auth *auth = &call->conn->auth_state;
952 TALLOC_FREE(call->context);
954 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
956 * With DCERPC_AUTH_LEVEL_NONE, we get the
957 * reject_reason in auth->auth_context_id.
959 return dcesrv_bind_nak(call, auth->auth_context_id);
963 * This must a be a temporary failure e.g. talloc or invalid
964 * configuration, e.g. no machine account.
966 return dcesrv_bind_nak(call,
967 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
970 /* setup a bind_ack */
971 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
973 pkt.call_id = call->pkt.call_id;
974 pkt.ptype = DCERPC_PKT_BIND_ACK;
975 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
976 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
977 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
978 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
980 endpoint = dcerpc_binding_get_string_option(
981 call->conn->endpoint->ep_description,
983 if (endpoint == NULL) {
987 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
989 * TODO: check if this is really needed
991 * Or if we should fix this in our idl files.
993 ep_prefix = "\\PIPE\\";
997 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1000 if (pkt.u.bind_ack.secondary_address == NULL) {
1001 TALLOC_FREE(call->context);
1002 return NT_STATUS_NO_MEMORY;
1004 pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1005 pkt.u.bind_ack.ctx_list = ack_ctx_list;
1006 pkt.u.bind_ack.auth_info = data_blob_null;
1008 status = dcesrv_auth_bind_ack(call, &pkt);
1009 if (!NT_STATUS_IS_OK(status)) {
1010 TALLOC_FREE(call->context);
1011 return dcesrv_bind_nak(call, 0);
1014 rep = talloc_zero(call, struct data_blob_list_item);
1016 TALLOC_FREE(call->context);
1017 return NT_STATUS_NO_MEMORY;
1020 status = ncacn_push_auth(&rep->blob, call, &pkt,
1021 call->out_auth_info);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 TALLOC_FREE(call->context);
1027 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1029 DLIST_ADD_END(call->replies, rep);
1030 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1032 if (call->conn->call_list && call->conn->call_list->replies) {
1033 if (call->conn->transport.report_output_data) {
1034 call->conn->transport.report_output_data(call->conn);
1038 return NT_STATUS_OK;
1043 handle a auth3 request
1045 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1049 if (!call->conn->allow_auth3) {
1050 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1053 if (call->conn->auth_state.auth_finished) {
1054 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1057 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1059 call->pkt.u.auth3.auth_info.length,
1060 0, /* required flags */
1061 DCERPC_PFC_FLAG_FIRST |
1062 DCERPC_PFC_FLAG_LAST |
1063 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1064 0x08 | /* this is not defined, but should be ignored */
1065 DCERPC_PFC_FLAG_CONC_MPX |
1066 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1067 DCERPC_PFC_FLAG_MAYBE |
1068 DCERPC_PFC_FLAG_OBJECT_UUID);
1069 if (!NT_STATUS_IS_OK(status)) {
1070 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1073 /* handle the auth3 in the auth code */
1074 if (!dcesrv_auth_auth3(call)) {
1075 call->conn->auth_state.auth_invalid = true;
1076 if (call->fault_code != 0) {
1077 return dcesrv_fault_disconnect(call, call->fault_code);
1083 /* we don't send a reply to a auth3 request, except by a
1085 return NT_STATUS_OK;
1089 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1090 const struct dcerpc_bind *b,
1091 const struct dcerpc_ctx_list *ctx,
1092 struct dcerpc_ack_ctx *ack,
1094 const struct ndr_syntax_id *supported_transfer)
1096 uint32_t if_version;
1097 struct dcesrv_connection_context *context;
1098 const struct dcesrv_interface *iface;
1101 const struct ndr_syntax_id *selected_transfer = NULL;
1106 return NT_STATUS_INTERNAL_ERROR;
1109 return NT_STATUS_INTERNAL_ERROR;
1111 if (ctx->num_transfer_syntaxes < 1) {
1112 return NT_STATUS_INTERNAL_ERROR;
1115 return NT_STATUS_INTERNAL_ERROR;
1117 if (supported_transfer == NULL) {
1118 return NT_STATUS_INTERNAL_ERROR;
1121 switch (ack->result) {
1122 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1123 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1125 * We is already completed.
1127 return NT_STATUS_OK;
1132 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1133 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1135 if_version = ctx->abstract_syntax.if_version;
1136 uuid = ctx->abstract_syntax.uuid;
1138 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1139 if (iface == NULL) {
1140 char *uuid_str = GUID_string(call, &uuid);
1141 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1142 talloc_free(uuid_str);
1144 * We report this only via ack->result
1146 return NT_STATUS_OK;
1149 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1150 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1152 if (validate_only) {
1154 * We report this only via ack->result
1156 return NT_STATUS_OK;
1159 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1161 * we only do NDR encoded dcerpc for now.
1163 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1164 supported_transfer);
1166 selected_transfer = supported_transfer;
1171 context = dcesrv_find_context(call->conn, ctx->context_id);
1172 if (context != NULL) {
1173 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1174 &ctx->abstract_syntax);
1176 return NT_STATUS_RPC_PROTOCOL_ERROR;
1179 if (selected_transfer != NULL) {
1180 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1183 return NT_STATUS_RPC_PROTOCOL_ERROR;
1186 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1187 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1188 ack->syntax = context->transfer_syntax;
1192 * We report this only via ack->result
1194 return NT_STATUS_OK;
1197 if (selected_transfer == NULL) {
1199 * We report this only via ack->result
1201 return NT_STATUS_OK;
1204 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1205 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1207 /* add this context to the list of available context_ids */
1208 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1209 if (context == NULL) {
1210 return NT_STATUS_NO_MEMORY;
1212 context->conn = call->conn;
1213 context->context_id = ctx->context_id;
1214 context->iface = iface;
1215 context->transfer_syntax = *selected_transfer;
1216 context->private_data = NULL;
1217 DLIST_ADD(call->conn->contexts, context);
1218 call->context = context;
1219 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1221 dcesrv_prepare_context_auth(call);
1224 * Multiplex is supported by default
1226 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1228 status = iface->bind(call, iface, if_version);
1229 call->context = NULL;
1230 if (!NT_STATUS_IS_OK(status)) {
1231 /* we don't want to trigger the iface->unbind() hook */
1232 context->iface = NULL;
1233 talloc_free(context);
1235 * We report this only via ack->result
1237 return NT_STATUS_OK;
1240 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1241 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1242 ack->syntax = context->transfer_syntax;
1243 return NT_STATUS_OK;
1246 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1247 const struct dcerpc_bind *b,
1248 struct dcerpc_ack_ctx *ack_ctx_list)
1252 bool validate_only = false;
1253 bool preferred_ndr32;
1256 * Try to negotiate one new presentation context,
1257 * using our preferred transfer syntax.
1259 for (i = 0; i < b->num_contexts; i++) {
1260 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1261 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1263 status = dcesrv_check_or_create_context(call, b, c, a,
1265 call->conn->preferred_transfer);
1266 if (!NT_STATUS_IS_OK(status)) {
1270 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1272 * We managed to negotiate one context.
1276 validate_only = true;
1280 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1281 call->conn->preferred_transfer);
1282 if (preferred_ndr32) {
1286 return NT_STATUS_OK;
1290 * Try to negotiate one new presentation context,
1291 * using NDR 32 as fallback.
1293 for (i = 0; i < b->num_contexts; i++) {
1294 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1295 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1297 status = dcesrv_check_or_create_context(call, b, c, a,
1299 &ndr_transfer_syntax_ndr);
1300 if (!NT_STATUS_IS_OK(status)) {
1304 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1306 * We managed to negotiate one context.
1310 validate_only = true;
1314 return NT_STATUS_OK;
1318 handle a alter context request
1320 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1323 bool auth_ok = false;
1324 struct ncacn_packet pkt;
1325 uint32_t extra_flags = 0;
1326 struct data_blob_list_item *rep = NULL;
1327 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1330 if (!call->conn->allow_alter) {
1331 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1334 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1336 call->pkt.u.alter.auth_info.length,
1337 0, /* required flags */
1338 DCERPC_PFC_FLAG_FIRST |
1339 DCERPC_PFC_FLAG_LAST |
1340 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1341 0x08 | /* this is not defined, but should be ignored */
1342 DCERPC_PFC_FLAG_CONC_MPX |
1343 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1344 DCERPC_PFC_FLAG_MAYBE |
1345 DCERPC_PFC_FLAG_OBJECT_UUID);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1350 auth_ok = dcesrv_auth_alter(call);
1352 if (call->fault_code != 0) {
1353 return dcesrv_fault_disconnect(call, call->fault_code);
1357 if (call->pkt.u.alter.num_contexts < 1) {
1358 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1361 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1362 call->pkt.u.alter.num_contexts);
1363 if (ack_ctx_list == NULL) {
1364 return NT_STATUS_NO_MEMORY;
1368 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1369 * dcesrv_check_or_create_context()) and do some protocol validation
1370 * and set sane defaults.
1372 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1373 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1374 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1376 if (c->num_transfer_syntaxes == 0) {
1377 return dcesrv_fault_disconnect(call,
1378 DCERPC_NCA_S_PROTO_ERROR);
1381 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1382 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1386 * Try to negotiate one new presentation context.
1388 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1389 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1390 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1392 if (!NT_STATUS_IS_OK(status)) {
1396 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1397 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1398 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1399 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1402 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1403 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1406 /* handle any authentication that is being requested */
1408 if (call->in_auth_info.auth_type !=
1409 call->conn->auth_state.auth_type)
1411 return dcesrv_fault_disconnect(call,
1412 DCERPC_FAULT_SEC_PKG_ERROR);
1414 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1417 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1418 pkt.auth_length = 0;
1419 pkt.call_id = call->pkt.call_id;
1420 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1421 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1422 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1423 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1424 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1425 pkt.u.alter_resp.secondary_address = "";
1426 pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1427 pkt.u.alter_resp.ctx_list = ack_ctx_list;
1428 pkt.u.alter_resp.auth_info = data_blob_null;
1430 status = dcesrv_auth_alter_ack(call, &pkt);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1435 rep = talloc_zero(call, struct data_blob_list_item);
1437 return NT_STATUS_NO_MEMORY;
1440 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1441 if (!NT_STATUS_IS_OK(status)) {
1445 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1447 DLIST_ADD_END(call->replies, rep);
1448 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1450 if (call->conn->call_list && call->conn->call_list->replies) {
1451 if (call->conn->transport.report_output_data) {
1452 call->conn->transport.report_output_data(call->conn);
1456 return NT_STATUS_OK;
1460 possibly save the call for inspection with ndrdump
1462 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1466 const char *dump_dir;
1467 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1471 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1473 call->context->iface->name,
1474 call->pkt.u.request.opnum,
1476 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1477 DEBUG(0,("RPC SAVED %s\n", fname));
1483 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1485 TALLOC_CTX *frame = talloc_stackframe();
1486 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1487 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1488 const struct dcerpc_sec_vt_pcontext pcontext = {
1489 .abstract_syntax = call->context->iface->syntax_id,
1490 .transfer_syntax = call->context->transfer_syntax,
1492 const struct dcerpc_sec_vt_header2 header2 =
1493 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1494 enum ndr_err_code ndr_err;
1495 struct dcerpc_sec_verification_trailer *vt = NULL;
1496 NTSTATUS status = NT_STATUS_OK;
1499 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1501 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1503 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1504 status = ndr_map_error2ntstatus(ndr_err);
1508 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1509 &pcontext, &header2);
1511 status = NT_STATUS_ACCESS_DENIED;
1520 handle a dcerpc request packet
1522 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1524 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1525 enum dcerpc_transport_t transport =
1526 dcerpc_binding_get_transport(endpoint->ep_description);
1527 struct ndr_pull *pull;
1530 if (!call->conn->allow_request) {
1531 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1534 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1535 if (call->conn->auth_state.gensec_security &&
1536 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1537 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1540 if (call->context == NULL) {
1541 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1542 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1545 switch (call->conn->auth_state.auth_level) {
1546 case DCERPC_AUTH_LEVEL_NONE:
1547 case DCERPC_AUTH_LEVEL_PACKET:
1548 case DCERPC_AUTH_LEVEL_INTEGRITY:
1549 case DCERPC_AUTH_LEVEL_PRIVACY:
1552 if (!call->context->allow_connect) {
1555 addr = tsocket_address_string(call->conn->remote_address,
1558 DEBUG(2, ("%s: restrict auth_level_connect access "
1559 "to [%s] with auth[type=0x%x,level=0x%x] "
1560 "on [%s] from [%s]\n",
1561 __func__, call->context->iface->name,
1562 call->conn->auth_state.auth_type,
1563 call->conn->auth_state.auth_level,
1564 derpc_transport_string_by_transport(transport),
1566 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1571 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1574 addr = tsocket_address_string(call->conn->remote_address, call);
1576 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1577 "to [%s] with auth[type=0x%x,level=0x%x] "
1578 "on [%s] from [%s]\n",
1580 call->context->min_auth_level,
1581 call->context->iface->name,
1582 call->conn->auth_state.auth_type,
1583 call->conn->auth_state.auth_level,
1584 derpc_transport_string_by_transport(transport),
1586 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1589 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1590 NT_STATUS_HAVE_NO_MEMORY(pull);
1592 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1594 call->ndr_pull = pull;
1596 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1597 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1600 status = dcesrv_check_verification_trailer(call);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 uint32_t faultcode = DCERPC_FAULT_OTHER;
1603 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1604 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1606 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1607 nt_errstr(status)));
1608 return dcesrv_fault(call, faultcode);
1611 /* unravel the NDR for the packet */
1612 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1613 if (!NT_STATUS_IS_OK(status)) {
1614 uint8_t extra_flags = 0;
1615 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1616 /* we got an unknown call */
1617 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1618 call->pkt.u.request.opnum,
1619 call->context->iface->name));
1620 dcesrv_save_call(call, "unknown");
1621 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1623 dcesrv_save_call(call, "pullfail");
1625 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1628 if (pull->offset != pull->data_size) {
1629 dcesrv_save_call(call, "extrabytes");
1630 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1631 pull->data_size - pull->offset));
1634 /* call the dispatch function */
1635 status = call->context->iface->dispatch(call, call, call->r);
1636 if (!NT_STATUS_IS_OK(status)) {
1637 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1638 call->context->iface->name,
1639 call->pkt.u.request.opnum,
1640 dcerpc_errstr(pull, call->fault_code)));
1641 return dcesrv_fault(call, call->fault_code);
1644 /* add the call to the pending list */
1645 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1647 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1648 return NT_STATUS_OK;
1651 return dcesrv_reply(call);
1656 remove the call from the right list when freed
1658 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1660 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1664 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1666 return conn->local_address;
1669 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1671 return conn->remote_address;
1675 process some input to a dcerpc endpoint server.
1677 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1678 struct ncacn_packet *pkt,
1682 struct dcesrv_call_state *call;
1683 struct dcesrv_call_state *existing = NULL;
1685 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1687 data_blob_free(&blob);
1689 return NT_STATUS_NO_MEMORY;
1691 call->conn = dce_conn;
1692 call->event_ctx = dce_conn->event_ctx;
1693 call->msg_ctx = dce_conn->msg_ctx;
1694 call->state_flags = call->conn->state_flags;
1695 call->time = timeval_current();
1696 call->list = DCESRV_LIST_NONE;
1698 talloc_steal(call, pkt);
1699 talloc_steal(call, blob.data);
1702 talloc_set_destructor(call, dcesrv_call_dequeue);
1704 if (call->conn->allow_bind) {
1706 * Only one bind is possible per connection
1708 call->conn->allow_bind = false;
1709 return dcesrv_bind(call);
1712 /* we have to check the signing here, before combining the
1714 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1715 if (!call->conn->allow_request) {
1716 return dcesrv_fault_disconnect(call,
1717 DCERPC_NCA_S_PROTO_ERROR);
1720 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1722 call->pkt.u.request.stub_and_verifier.length,
1723 0, /* required_flags */
1724 DCERPC_PFC_FLAG_FIRST |
1725 DCERPC_PFC_FLAG_LAST |
1726 DCERPC_PFC_FLAG_PENDING_CANCEL |
1727 0x08 | /* this is not defined, but should be ignored */
1728 DCERPC_PFC_FLAG_CONC_MPX |
1729 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1730 DCERPC_PFC_FLAG_MAYBE |
1731 DCERPC_PFC_FLAG_OBJECT_UUID);
1732 if (!NT_STATUS_IS_OK(status)) {
1733 return dcesrv_fault_disconnect(call,
1734 DCERPC_NCA_S_PROTO_ERROR);
1737 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1739 * We don't use dcesrv_fault_disconnect()
1740 * here, because we don't want to set
1741 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1743 * Note that we don't check against the negotiated
1744 * max_recv_frag, but a hard coded value.
1746 dcesrv_call_disconnect_after(call,
1747 "dcesrv_auth_request - frag_length too large");
1748 return dcesrv_fault(call,
1749 DCERPC_NCA_S_PROTO_ERROR);
1752 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1753 if (dce_conn->pending_call_list != NULL) {
1755 * concurrent requests are only allowed
1756 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1758 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1759 dcesrv_call_disconnect_after(call,
1760 "dcesrv_auth_request - "
1761 "existing pending call without CONN_MPX");
1762 return dcesrv_fault(call,
1763 DCERPC_NCA_S_PROTO_ERROR);
1766 /* only one request is possible in the fragmented list */
1767 if (dce_conn->incoming_fragmented_call_list != NULL) {
1768 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1770 * Without DCERPC_PFC_FLAG_CONC_MPX
1771 * we need to return the FAULT on the
1772 * already existing call.
1774 * This is important to get the
1775 * call_id and context_id right.
1778 call = dce_conn->incoming_fragmented_call_list;
1780 dcesrv_call_disconnect_after(call,
1781 "dcesrv_auth_request - "
1782 "existing fragmented call");
1783 return dcesrv_fault(call,
1784 DCERPC_NCA_S_PROTO_ERROR);
1786 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1787 return dcesrv_fault_disconnect(call,
1788 DCERPC_FAULT_NO_CALL_ACTIVE);
1790 call->context = dcesrv_find_context(call->conn,
1791 call->pkt.u.request.context_id);
1792 if (call->context == NULL) {
1793 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1794 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1797 const struct dcerpc_request *nr = &call->pkt.u.request;
1798 const struct dcerpc_request *er = NULL;
1801 existing = dcesrv_find_fragmented_call(dce_conn,
1803 if (existing == NULL) {
1804 dcesrv_call_disconnect_after(call,
1805 "dcesrv_auth_request - "
1806 "no existing fragmented call");
1807 return dcesrv_fault(call,
1808 DCERPC_NCA_S_PROTO_ERROR);
1810 er = &existing->pkt.u.request;
1812 if (call->pkt.ptype != existing->pkt.ptype) {
1813 /* trying to play silly buggers are we? */
1814 return dcesrv_fault_disconnect(existing,
1815 DCERPC_NCA_S_PROTO_ERROR);
1817 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1820 return dcesrv_fault_disconnect(existing,
1821 DCERPC_NCA_S_PROTO_ERROR);
1823 if (nr->context_id != er->context_id) {
1824 return dcesrv_fault_disconnect(existing,
1825 DCERPC_NCA_S_PROTO_ERROR);
1827 if (nr->opnum != er->opnum) {
1828 return dcesrv_fault_disconnect(existing,
1829 DCERPC_NCA_S_PROTO_ERROR);
1834 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1836 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1838 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1839 payload_offset += 16;
1842 ok = dcesrv_auth_pkt_pull(call, &blob,
1843 0, /* required_flags */
1844 DCERPC_PFC_FLAG_FIRST |
1845 DCERPC_PFC_FLAG_LAST |
1846 DCERPC_PFC_FLAG_PENDING_CANCEL |
1847 0x08 | /* this is not defined, but should be ignored */
1848 DCERPC_PFC_FLAG_CONC_MPX |
1849 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1850 DCERPC_PFC_FLAG_MAYBE |
1851 DCERPC_PFC_FLAG_OBJECT_UUID,
1853 &call->pkt.u.request.stub_and_verifier);
1856 * We don't use dcesrv_fault_disconnect()
1857 * here, because we don't want to set
1858 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1860 dcesrv_call_disconnect_after(call,
1861 "dcesrv_auth_request - failed");
1862 if (call->fault_code == 0) {
1863 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1865 return dcesrv_fault(call, call->fault_code);
1869 /* see if this is a continued packet */
1870 if (existing != NULL) {
1871 struct dcerpc_request *er = &existing->pkt.u.request;
1872 const struct dcerpc_request *nr = &call->pkt.u.request;
1878 * Up to 4 MByte are allowed by all fragments
1880 available = dce_conn->max_total_request_size;
1881 if (er->stub_and_verifier.length > available) {
1882 dcesrv_call_disconnect_after(existing,
1883 "dcesrv_auth_request - existing payload too large");
1884 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1886 available -= er->stub_and_verifier.length;
1887 if (nr->alloc_hint > available) {
1888 dcesrv_call_disconnect_after(existing,
1889 "dcesrv_auth_request - alloc hint too large");
1890 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1892 if (nr->stub_and_verifier.length > available) {
1893 dcesrv_call_disconnect_after(existing,
1894 "dcesrv_auth_request - new payload too large");
1895 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1897 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1898 /* allocate at least 1 byte */
1899 alloc_hint = MAX(alloc_hint, 1);
1900 alloc_size = er->stub_and_verifier.length +
1901 nr->stub_and_verifier.length;
1902 alloc_size = MAX(alloc_size, alloc_hint);
1904 er->stub_and_verifier.data =
1905 talloc_realloc(existing,
1906 er->stub_and_verifier.data,
1907 uint8_t, alloc_size);
1908 if (er->stub_and_verifier.data == NULL) {
1910 return dcesrv_fault_with_flags(existing,
1911 DCERPC_FAULT_OUT_OF_RESOURCES,
1912 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1914 memcpy(er->stub_and_verifier.data +
1915 er->stub_and_verifier.length,
1916 nr->stub_and_verifier.data,
1917 nr->stub_and_verifier.length);
1918 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1920 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1926 /* this may not be the last pdu in the chain - if its isn't then
1927 just put it on the incoming_fragmented_call_list and wait for the rest */
1928 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1929 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1931 * Up to 4 MByte are allowed by all fragments
1933 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1934 dcesrv_call_disconnect_after(call,
1935 "dcesrv_auth_request - initial alloc hint too large");
1936 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1938 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1939 return NT_STATUS_OK;
1942 /* This removes any fragments we may have had stashed away */
1943 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1945 switch (call->pkt.ptype) {
1946 case DCERPC_PKT_BIND:
1947 status = dcesrv_bind_nak(call,
1948 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1950 case DCERPC_PKT_AUTH3:
1951 status = dcesrv_auth3(call);
1953 case DCERPC_PKT_ALTER:
1954 status = dcesrv_alter(call);
1956 case DCERPC_PKT_REQUEST:
1957 status = dcesrv_request(call);
1959 case DCERPC_PKT_CO_CANCEL:
1960 case DCERPC_PKT_ORPHANED:
1962 * Window just ignores CO_CANCEL and ORPHANED,
1965 status = NT_STATUS_OK;
1968 case DCERPC_PKT_BIND_ACK:
1969 case DCERPC_PKT_BIND_NAK:
1970 case DCERPC_PKT_ALTER_RESP:
1971 case DCERPC_PKT_RESPONSE:
1972 case DCERPC_PKT_FAULT:
1973 case DCERPC_PKT_SHUTDOWN:
1975 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1979 /* if we are going to be sending a reply then add
1980 it to the list of pending calls. We add it to the end to keep the call
1981 list in the order we will answer */
1982 if (!NT_STATUS_IS_OK(status)) {
1989 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1990 struct loadparm_context *lp_ctx,
1991 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1994 struct dcesrv_context *dce_ctx;
1997 if (!endpoint_servers) {
1998 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1999 return NT_STATUS_INTERNAL_ERROR;
2002 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2003 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2005 if (uid_wrapper_enabled()) {
2006 setenv("UID_WRAPPER_MYUID", "1", 1);
2008 dce_ctx->initial_euid = geteuid();
2009 if (uid_wrapper_enabled()) {
2010 unsetenv("UID_WRAPPER_MYUID");
2013 dce_ctx->endpoint_list = NULL;
2014 dce_ctx->lp_ctx = lp_ctx;
2015 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2016 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2017 dce_ctx->broken_connections = NULL;
2019 for (i=0;endpoint_servers[i];i++) {
2020 const struct dcesrv_endpoint_server *ep_server;
2022 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2024 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2025 return NT_STATUS_INTERNAL_ERROR;
2028 status = ep_server->init_server(dce_ctx, ep_server);
2029 if (!NT_STATUS_IS_OK(status)) {
2030 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2031 nt_errstr(status)));
2036 *_dce_ctx = dce_ctx;
2037 return NT_STATUS_OK;
2040 /* the list of currently registered DCERPC endpoint servers.
2042 static struct ep_server {
2043 struct dcesrv_endpoint_server *ep_server;
2044 } *ep_servers = NULL;
2045 static int num_ep_servers;
2048 register a DCERPC endpoint server.
2050 The 'name' can be later used by other backends to find the operations
2051 structure for this backend.
2054 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2057 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2058 /* its already registered! */
2059 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2061 return NT_STATUS_OBJECT_NAME_COLLISION;
2064 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2066 smb_panic("out of memory in dcerpc_register");
2069 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2070 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2074 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2077 return NT_STATUS_OK;
2081 return the operations structure for a named backend of the specified type
2083 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2087 for (i=0;i<num_ep_servers;i++) {
2088 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2089 return ep_servers[i].ep_server;
2096 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2098 static bool initialized;
2099 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
2100 STATIC_dcerpc_server_MODULES_PROTO;
2101 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2102 init_module_fn *shared_init;
2109 shared_init = load_samba_modules(NULL, "dcerpc_server");
2111 run_init_functions(static_init);
2112 run_init_functions(shared_init);
2114 talloc_free(shared_init);
2118 return the DCERPC module version, and the size of some critical types
2119 This can be used by endpoint server modules to either detect compilation errors, or provide
2120 multiple implementations for different smbd compilation options in one module
2122 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2124 static const struct dcesrv_critical_sizes critical_sizes = {
2125 DCERPC_MODULE_VERSION,
2126 sizeof(struct dcesrv_context),
2127 sizeof(struct dcesrv_endpoint),
2128 sizeof(struct dcesrv_endpoint_server),
2129 sizeof(struct dcesrv_interface),
2130 sizeof(struct dcesrv_if_list),
2131 sizeof(struct dcesrv_connection),
2132 sizeof(struct dcesrv_call_state),
2133 sizeof(struct dcesrv_auth),
2134 sizeof(struct dcesrv_handle)
2137 return &critical_sizes;
2140 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2142 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2143 struct stream_connection *srv_conn;
2144 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2145 struct stream_connection);
2147 dce_conn->allow_bind = false;
2148 dce_conn->allow_auth3 = false;
2149 dce_conn->allow_alter = false;
2150 dce_conn->allow_request = false;
2152 if (dce_conn->pending_call_list == NULL) {
2153 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2155 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2156 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2160 if (dce_conn->terminate != NULL) {
2164 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2166 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2167 if (dce_conn->terminate == NULL) {
2168 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2170 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2173 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2175 struct dcesrv_connection *cur, *next;
2177 next = dce_ctx->broken_connections;
2178 while (next != NULL) {
2182 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2183 struct dcesrv_connection_context *context_cur, *context_next;
2185 context_next = cur->contexts;
2186 while (context_next != NULL) {
2187 context_cur = context_next;
2188 context_next = context_cur->next;
2190 dcesrv_connection_context_destructor(context_cur);
2194 dcesrv_terminate_connection(cur, cur->terminate);
2198 /* We need this include to be able to compile on some plateforms
2199 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2201 * It has to be that deep because otherwise we have a conflict on
2202 * const struct dcesrv_interface declaration.
2203 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2204 * which conflict with the bind used before.
2206 #include "system/network.h"
2208 struct dcesrv_sock_reply_state {
2209 struct dcesrv_connection *dce_conn;
2210 struct dcesrv_call_state *call;
2214 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2215 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2217 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2219 struct dcesrv_call_state *call;
2221 call = dce_conn->call_list;
2222 if (!call || !call->replies) {
2226 while (call->replies) {
2227 struct data_blob_list_item *rep = call->replies;
2228 struct dcesrv_sock_reply_state *substate;
2229 struct tevent_req *subreq;
2231 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2233 dcesrv_terminate_connection(dce_conn, "no memory");
2237 substate->dce_conn = dce_conn;
2238 substate->call = NULL;
2240 DLIST_REMOVE(call->replies, rep);
2242 if (call->replies == NULL && call->terminate_reason == NULL) {
2243 substate->call = call;
2246 substate->iov.iov_base = (void *) rep->blob.data;
2247 substate->iov.iov_len = rep->blob.length;
2249 subreq = tstream_writev_queue_send(substate,
2250 dce_conn->event_ctx,
2252 dce_conn->send_queue,
2255 dcesrv_terminate_connection(dce_conn, "no memory");
2258 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2262 if (call->terminate_reason != NULL) {
2263 struct tevent_req *subreq;
2265 subreq = tevent_queue_wait_send(call,
2266 dce_conn->event_ctx,
2267 dce_conn->send_queue);
2269 dcesrv_terminate_connection(dce_conn, __location__);
2272 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2276 DLIST_REMOVE(call->conn->call_list, call);
2277 call->list = DCESRV_LIST_NONE;
2280 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2282 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2283 struct dcesrv_sock_reply_state);
2287 struct dcesrv_call_state *call = substate->call;
2289 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2290 TALLOC_FREE(subreq);
2292 status = map_nt_error_from_unix_common(sys_errno);
2293 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2297 talloc_free(substate);
2303 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2305 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2307 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2308 struct dcesrv_call_state);
2312 /* make sure we stop send queue before removing subreq */
2313 tevent_queue_stop(call->conn->send_queue);
2315 ok = tevent_queue_wait_recv(subreq);
2316 TALLOC_FREE(subreq);
2318 dcesrv_terminate_connection(call->conn, __location__);
2322 /* disconnect after 200 usecs */
2323 tv = timeval_current_ofs_usec(200);
2324 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2325 if (subreq == NULL) {
2326 dcesrv_terminate_connection(call->conn, __location__);
2329 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2333 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2335 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2336 struct dcesrv_call_state);
2339 ok = tevent_wakeup_recv(subreq);
2340 TALLOC_FREE(subreq);
2342 dcesrv_terminate_connection(call->conn, __location__);
2346 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2349 struct dcesrv_socket_context {
2350 const struct dcesrv_endpoint *endpoint;
2351 struct dcesrv_context *dcesrv_ctx;
2355 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2357 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2360 struct dcesrv_socket_context *dcesrv_sock =
2361 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2362 enum dcerpc_transport_t transport =
2363 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2364 struct dcesrv_connection *dcesrv_conn = NULL;
2366 struct tevent_req *subreq;
2367 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2369 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2371 if (!srv_conn->session_info) {
2372 status = auth_anonymous_session_info(srv_conn,
2374 &srv_conn->session_info);
2375 if (!NT_STATUS_IS_OK(status)) {
2376 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2377 nt_errstr(status)));
2378 stream_terminate_connection(srv_conn, nt_errstr(status));
2384 * This fills in dcesrv_conn->endpoint with the endpoint
2385 * associated with the socket. From this point on we know
2386 * which (group of) services we are handling, but not the
2387 * specific interface.
2390 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2392 dcesrv_sock->endpoint,
2393 srv_conn->session_info,
2394 srv_conn->event.ctx,
2396 srv_conn->server_id,
2397 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2399 if (!NT_STATUS_IS_OK(status)) {
2400 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2401 nt_errstr(status)));
2402 stream_terminate_connection(srv_conn, nt_errstr(status));
2406 dcesrv_conn->transport.private_data = srv_conn;
2407 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2409 TALLOC_FREE(srv_conn->event.fde);
2411 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2412 if (!dcesrv_conn->send_queue) {
2413 status = NT_STATUS_NO_MEMORY;
2414 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2415 nt_errstr(status)));
2416 stream_terminate_connection(srv_conn, nt_errstr(status));
2420 if (transport == NCACN_NP) {
2421 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2422 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2423 &srv_conn->tstream);
2425 ret = tstream_bsd_existing_socket(dcesrv_conn,
2426 socket_get_fd(srv_conn->socket),
2427 &dcesrv_conn->stream);
2429 status = map_nt_error_from_unix_common(errno);
2430 DEBUG(0, ("dcesrv_sock_accept: "
2431 "failed to setup tstream: %s\n",
2432 nt_errstr(status)));
2433 stream_terminate_connection(srv_conn, nt_errstr(status));
2436 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2439 dcesrv_conn->local_address = srv_conn->local_address;
2440 dcesrv_conn->remote_address = srv_conn->remote_address;
2442 if (transport == NCALRPC) {
2447 sock_fd = socket_get_fd(srv_conn->socket);
2448 if (sock_fd == -1) {
2449 stream_terminate_connection(
2450 srv_conn, "socket_get_fd failed\n");
2454 ret = getpeereid(sock_fd, &uid, &gid);
2456 status = map_nt_error_from_unix_common(errno);
2457 DEBUG(0, ("dcesrv_sock_accept: "
2458 "getpeereid() failed for NCALRPC: %s\n",
2459 nt_errstr(status)));
2460 stream_terminate_connection(srv_conn, nt_errstr(status));
2463 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2464 struct tsocket_address *r = NULL;
2466 ret = tsocket_address_unix_from_path(dcesrv_conn,
2467 "/root/ncalrpc_as_system",
2470 status = map_nt_error_from_unix_common(errno);
2471 DEBUG(0, ("dcesrv_sock_accept: "
2472 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2473 nt_errstr(status)));
2474 stream_terminate_connection(srv_conn, nt_errstr(status));
2477 dcesrv_conn->remote_address = r;
2481 srv_conn->private_data = dcesrv_conn;
2483 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2485 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2486 dcesrv_conn->event_ctx,
2487 dcesrv_conn->stream);
2489 status = NT_STATUS_NO_MEMORY;
2490 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2491 nt_errstr(status)));
2492 stream_terminate_connection(srv_conn, nt_errstr(status));
2495 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2500 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2502 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2503 struct dcesrv_connection);
2504 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2505 struct ncacn_packet *pkt;
2509 if (dce_conn->terminate) {
2511 * if the current connection is broken
2512 * we need to clean it up before any other connection
2514 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2515 dcesrv_cleanup_broken_connections(dce_ctx);
2519 dcesrv_cleanup_broken_connections(dce_ctx);
2521 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2523 TALLOC_FREE(subreq);
2524 if (!NT_STATUS_IS_OK(status)) {
2525 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2529 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2530 if (!NT_STATUS_IS_OK(status)) {
2531 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2535 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2536 dce_conn->event_ctx,
2539 status = NT_STATUS_NO_MEMORY;
2540 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2543 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2546 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2548 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2549 struct dcesrv_connection);
2550 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2553 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2555 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2556 struct dcesrv_connection);
2557 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2561 static const struct stream_server_ops dcesrv_stream_ops = {
2563 .accept_connection = dcesrv_sock_accept,
2564 .recv_handler = dcesrv_sock_recv,
2565 .send_handler = dcesrv_sock_send,
2568 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2569 struct loadparm_context *lp_ctx,
2570 struct dcesrv_endpoint *e,
2571 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2573 struct dcesrv_socket_context *dcesrv_sock;
2576 const char *endpoint;
2578 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2579 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2581 /* remember the endpoint of this socket */
2582 dcesrv_sock->endpoint = e;
2583 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2585 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2587 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2588 model_ops, &dcesrv_stream_ops,
2589 "unix", endpoint, &port,
2590 lpcfg_socket_options(lp_ctx),
2592 if (!NT_STATUS_IS_OK(status)) {
2593 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2594 endpoint, nt_errstr(status)));
2600 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2601 struct loadparm_context *lp_ctx,
2602 struct dcesrv_endpoint *e,
2603 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2605 struct dcesrv_socket_context *dcesrv_sock;
2609 const char *endpoint;
2611 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2613 if (endpoint == NULL) {
2615 * No identifier specified: use DEFAULT.
2617 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2618 * no endpoint and let the epmapper worry about it.
2620 endpoint = "DEFAULT";
2621 status = dcerpc_binding_set_string_option(e->ep_description,
2624 if (!NT_STATUS_IS_OK(status)) {
2625 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2626 nt_errstr(status)));
2631 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2634 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2635 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2637 /* remember the endpoint of this socket */
2638 dcesrv_sock->endpoint = e;
2639 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2641 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2642 model_ops, &dcesrv_stream_ops,
2643 "unix", full_path, &port,
2644 lpcfg_socket_options(lp_ctx),
2646 if (!NT_STATUS_IS_OK(status)) {
2647 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2648 endpoint, full_path, nt_errstr(status)));
2653 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2654 struct loadparm_context *lp_ctx,
2655 struct dcesrv_endpoint *e,
2656 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2658 struct dcesrv_socket_context *dcesrv_sock;
2660 const char *endpoint;
2662 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2663 if (endpoint == NULL) {
2664 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2665 return NT_STATUS_INVALID_PARAMETER;
2668 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2669 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2671 /* remember the endpoint of this socket */
2672 dcesrv_sock->endpoint = e;
2673 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2675 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2676 model_ops, &dcesrv_stream_ops,
2679 if (!NT_STATUS_IS_OK(status)) {
2680 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2681 endpoint, nt_errstr(status)));
2685 return NT_STATUS_OK;
2689 add a socket address to the list of events, one event per dcerpc endpoint
2691 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2692 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2693 const char *address)
2695 struct dcesrv_socket_context *dcesrv_sock;
2698 const char *endpoint;
2701 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2702 if (endpoint != NULL) {
2703 port = atoi(endpoint);
2706 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2707 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2709 /* remember the endpoint of this socket */
2710 dcesrv_sock->endpoint = e;
2711 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2713 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2714 model_ops, &dcesrv_stream_ops,
2715 "ip", address, &port,
2716 lpcfg_socket_options(dce_ctx->lp_ctx),
2718 if (!NT_STATUS_IS_OK(status)) {
2719 struct dcesrv_if_list *iface;
2720 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2722 for (iface = e->interface_list; iface; iface = iface->next) {
2723 DEBUGADD(0, ("%s ", iface->iface.name));
2725 DEBUGADD(0, ("failed - %s",
2726 nt_errstr(status)));
2730 snprintf(port_str, sizeof(port_str), "%u", port);
2732 status = dcerpc_binding_set_string_option(e->ep_description,
2733 "endpoint", port_str);
2734 if (!NT_STATUS_IS_OK(status)) {
2735 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2736 port_str, nt_errstr(status)));
2739 struct dcesrv_if_list *iface;
2740 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2741 address, port_str));
2742 for (iface = e->interface_list; iface; iface = iface->next) {
2743 DEBUGADD(4, ("%s ", iface->iface.name));
2745 DEBUGADD(4, ("\n"));
2748 return NT_STATUS_OK;
2751 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2753 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2754 struct loadparm_context *lp_ctx,
2755 struct dcesrv_endpoint *e,
2756 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2760 /* Add TCP/IP sockets */
2761 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2764 struct interface *ifaces;
2766 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2768 num_interfaces = iface_list_count(ifaces);
2769 for(i = 0; i < num_interfaces; i++) {
2770 const char *address = iface_list_n_ip(ifaces, i);
2771 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2772 NT_STATUS_NOT_OK_RETURN(status);
2778 wcard = iface_list_wildcard(dce_ctx);
2779 NT_STATUS_HAVE_NO_MEMORY(wcard);
2780 for (i=0; wcard[i]; i++) {
2781 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2782 if (NT_STATUS_IS_OK(status)) {
2787 if (num_binds == 0) {
2788 return NT_STATUS_INVALID_PARAMETER_MIX;
2792 return NT_STATUS_OK;
2795 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2796 struct loadparm_context *lp_ctx,
2797 struct dcesrv_endpoint *e,
2798 struct tevent_context *event_ctx,
2799 const struct model_ops *model_ops)
2801 enum dcerpc_transport_t transport =
2802 dcerpc_binding_get_transport(e->ep_description);
2804 switch (transport) {
2805 case NCACN_UNIX_STREAM:
2806 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2809 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2812 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2815 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2818 return NT_STATUS_NOT_SUPPORTED;
2824 * retrieve credentials from a dce_call
2826 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2828 return dce_call->conn->auth_state.session_info->credentials;
2832 * returns true if this is an authenticated call
2834 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2836 enum security_user_level level;
2837 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2838 return level >= SECURITY_USER;
2842 * retrieve account_name for a dce_call
2844 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2846 return dce_call->context->conn->auth_state.session_info->info->account_name;