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;
279 * If we are not using handles, there is no need for force
280 * this service into using a single process.
282 * However, due to the way we listen for RPC packets, we can
283 * only do this if we have a single service per pipe or TCP
284 * port, so we still force a single combined process for
287 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
288 use_single_process = false;
291 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
293 if (NT_STATUS_IS_ERR(status)) {
294 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
298 transport = dcerpc_binding_get_transport(binding);
299 if (transport == NCACN_IP_TCP) {
304 * First check if there is already a port specified, eg
305 * for epmapper on ncacn_ip_tcp:[135]
308 = dcerpc_binding_get_string_option(binding,
310 if (endpoint == NULL) {
311 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
312 "rpc server port", iface->name, 0);
315 * For RPC services that are not set to use a single
316 * process, we do not default to using the 'rpc server
317 * port' because that would cause a double-bind on
320 if (port == 0 && !use_single_process) {
321 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
324 snprintf(port_str, sizeof(port_str), "%u", port);
325 status = dcerpc_binding_set_string_option(binding,
328 if (!NT_STATUS_IS_OK(status)) {
335 /* see if the interface is already registered on the endpoint */
336 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
337 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
338 iface->name, ep_name));
339 return NT_STATUS_OBJECT_NAME_COLLISION;
342 /* check if this endpoint exists
344 ep = find_endpoint(dce_ctx, binding);
348 * We want a new port on ncacn_ip_tcp for NETLOGON, so
349 * it can be multi-process. Other processes can also
350 * listen on distinct ports, if they have one forced
351 * in the code above with eg 'rpc server port:drsuapi = 1027'
353 * If we have mulitiple endpoints on port 0, they each
354 * get an epemeral port (currently by walking up from
357 if (!use_single_process && transport == NCACN_IP_TCP) {
362 if (ep == NULL || add_ep) {
363 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
365 return NT_STATUS_NO_MEMORY;
368 ep->ep_description = talloc_move(ep, &binding);
371 /* add mgmt interface */
372 ifl = talloc_zero(ep, struct dcesrv_if_list);
374 return NT_STATUS_NO_MEMORY;
377 ifl->iface = dcesrv_get_mgmt_interface();
379 DLIST_ADD(ep->interface_list, ifl);
383 * By default don't force into a single process, but if any
384 * interface on this endpoint on this service uses handles
385 * (most do), then we must force into single process mode
387 * By overwriting this each time a new interface is added to
388 * this endpoint, we end up with the most restrictive setting.
390 if (use_single_process) {
391 ep->use_single_process = true;
394 /* talloc a new interface list element */
395 ifl = talloc_zero(ep, struct dcesrv_if_list);
397 return NT_STATUS_NO_MEMORY;
400 /* copy the given interface struct to the one on the endpoints interface list */
401 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
403 /* if we have a security descriptor given,
404 * we should see if we can set it up on the endpoint
407 /* if there's currently no security descriptor given on the endpoint
410 if (ep->sd == NULL) {
411 ep->sd = security_descriptor_copy(ep, sd);
414 /* if now there's no security descriptor given on the endpoint
415 * something goes wrong, either we failed to copy the security descriptor
416 * or there was already one on the endpoint
418 if (ep->sd != NULL) {
419 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
420 " on endpoint '%s'\n",
421 iface->name, ep_name));
422 if (add_ep) free(ep);
424 return NT_STATUS_OBJECT_NAME_COLLISION;
428 /* finally add the interface on the endpoint */
429 DLIST_ADD(ep->interface_list, ifl);
431 /* if it's a new endpoint add it to the dcesrv_context */
433 DLIST_ADD(dce_ctx->endpoint_list, ep);
436 /* Re-get the string as we may have set a port */
437 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
439 DEBUG(4,("dcesrv_interface_register: interface '%s' registered on endpoint '%s'\n",
440 iface->name, ep_string));
441 TALLOC_FREE(ep_string);
446 NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
447 DATA_BLOB *session_key)
449 if (p->auth_state.session_info->session_key.length) {
450 *session_key = p->auth_state.session_info->session_key;
453 return NT_STATUS_NO_USER_SESSION_KEY;
457 fetch the user session key - may be default (above) or the SMB session key
459 The key is always truncated to 16 bytes
461 _PUBLIC_ NTSTATUS dcesrv_fetch_session_key(struct dcesrv_connection *p,
462 DATA_BLOB *session_key)
464 NTSTATUS status = p->auth_state.session_key(p, session_key);
465 if (!NT_STATUS_IS_OK(status)) {
469 session_key->length = MIN(session_key->length, 16);
475 connect to a dcerpc endpoint
477 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
479 const struct dcesrv_endpoint *ep,
480 struct auth_session_info *session_info,
481 struct tevent_context *event_ctx,
482 struct imessaging_context *msg_ctx,
483 struct server_id server_id,
484 uint32_t state_flags,
485 struct dcesrv_connection **_p)
487 struct dcesrv_connection *p;
490 return NT_STATUS_ACCESS_DENIED;
493 p = talloc_zero(mem_ctx, struct dcesrv_connection);
494 NT_STATUS_HAVE_NO_MEMORY(p);
496 if (!talloc_reference(p, session_info)) {
498 return NT_STATUS_NO_MEMORY;
501 p->dce_ctx = dce_ctx;
503 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
504 p->auth_state.session_info = session_info;
505 p->auth_state.session_key = dcesrv_generic_session_key;
506 p->event_ctx = event_ctx;
507 p->msg_ctx = msg_ctx;
508 p->server_id = server_id;
509 p->state_flags = state_flags;
510 p->allow_bind = true;
511 p->max_recv_frag = 5840;
512 p->max_xmit_frag = 5840;
513 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
516 * For now we only support NDR32.
518 p->preferred_transfer = &ndr_transfer_syntax_ndr;
525 move a call from an existing linked list to the specified list. This
526 prevents bugs where we forget to remove the call from a previous
529 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
530 enum dcesrv_call_list list)
532 switch (call->list) {
533 case DCESRV_LIST_NONE:
535 case DCESRV_LIST_CALL_LIST:
536 DLIST_REMOVE(call->conn->call_list, call);
538 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
539 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
541 case DCESRV_LIST_PENDING_CALL_LIST:
542 DLIST_REMOVE(call->conn->pending_call_list, call);
547 case DCESRV_LIST_NONE:
549 case DCESRV_LIST_CALL_LIST:
550 DLIST_ADD_END(call->conn->call_list, call);
552 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
553 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
555 case DCESRV_LIST_PENDING_CALL_LIST:
556 DLIST_ADD_END(call->conn->pending_call_list, call);
561 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
564 if (call->conn->terminate != NULL) {
568 call->conn->allow_bind = false;
569 call->conn->allow_alter = false;
570 call->conn->allow_auth3 = false;
571 call->conn->allow_request = false;
573 call->terminate_reason = talloc_strdup(call, reason);
574 if (call->terminate_reason == NULL) {
575 call->terminate_reason = __location__;
580 return a dcerpc bind_nak
582 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
584 struct ncacn_packet pkt;
585 struct dcerpc_bind_nak_version version;
586 struct data_blob_list_item *rep;
588 static const uint8_t _pad[3] = { 0, };
591 * We add the call to the pending_call_list
592 * in order to defer the termination.
594 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
596 /* setup a bind_nak */
597 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
599 pkt.call_id = call->pkt.call_id;
600 pkt.ptype = DCERPC_PKT_BIND_NAK;
601 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
602 pkt.u.bind_nak.reject_reason = reason;
603 version.rpc_vers = 5;
604 version.rpc_vers_minor = 0;
605 pkt.u.bind_nak.num_versions = 1;
606 pkt.u.bind_nak.versions = &version;
607 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
609 rep = talloc_zero(call, struct data_blob_list_item);
611 return NT_STATUS_NO_MEMORY;
614 status = ncacn_push_auth(&rep->blob, call, &pkt, NULL);
615 if (!NT_STATUS_IS_OK(status)) {
619 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
621 DLIST_ADD_END(call->replies, rep);
622 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
624 if (call->conn->call_list && call->conn->call_list->replies) {
625 if (call->conn->transport.report_output_data) {
626 call->conn->transport.report_output_data(call->conn);
633 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
637 * We add the call to the pending_call_list
638 * in order to defer the termination.
640 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
642 return dcesrv_fault_with_flags(call, fault_code,
643 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
646 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
648 DLIST_REMOVE(c->conn->contexts, c);
650 if (c->iface && c->iface->unbind) {
651 c->iface->unbind(c, c->iface);
658 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
660 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
661 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
662 enum dcerpc_transport_t transport =
663 dcerpc_binding_get_transport(endpoint->ep_description);
664 struct dcesrv_connection_context *context = dce_call->context;
665 const struct dcesrv_interface *iface = context->iface;
667 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
669 if (transport == NCALRPC) {
670 context->allow_connect = true;
675 * allow overwrite per interface
676 * allow dcerpc auth level connect:<interface>
678 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
679 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
680 "allow dcerpc auth level connect",
682 context->allow_connect);
685 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call,
686 const struct dcesrv_interface *iface)
688 if (dce_call->context == NULL) {
689 return NT_STATUS_INTERNAL_ERROR;
693 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
694 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
696 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
700 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call,
701 const struct dcesrv_interface *iface)
703 if (dce_call->context == NULL) {
704 return NT_STATUS_INTERNAL_ERROR;
707 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
711 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call,
712 const struct dcesrv_interface *iface)
714 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
715 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
716 enum dcerpc_transport_t transport =
717 dcerpc_binding_get_transport(endpoint->ep_description);
718 struct dcesrv_connection_context *context = dce_call->context;
720 if (context == NULL) {
721 return NT_STATUS_INTERNAL_ERROR;
724 if (transport == NCALRPC) {
725 context->allow_connect = true;
730 * allow overwrite per interface
731 * allow dcerpc auth level connect:<interface>
733 context->allow_connect = false;
734 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
735 "allow dcerpc auth level connect",
737 context->allow_connect);
741 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call,
742 const struct dcesrv_interface *iface)
744 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
745 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
746 enum dcerpc_transport_t transport =
747 dcerpc_binding_get_transport(endpoint->ep_description);
748 struct dcesrv_connection_context *context = dce_call->context;
750 if (context == NULL) {
751 return NT_STATUS_INTERNAL_ERROR;
754 if (transport == NCALRPC) {
755 context->allow_connect = true;
760 * allow overwrite per interface
761 * allow dcerpc auth level connect:<interface>
763 context->allow_connect = true;
764 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
765 "allow dcerpc auth level connect",
767 context->allow_connect);
772 handle a bind request
774 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
776 struct ncacn_packet *pkt = &call->ack_pkt;
777 struct data_blob_list_item *rep;
779 uint32_t extra_flags = 0;
780 uint16_t max_req = 0;
781 uint16_t max_rep = 0;
782 const char *ep_prefix = "";
783 const char *endpoint = NULL;
784 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
785 struct dcerpc_ack_ctx *ack_features = NULL;
788 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
790 call->pkt.u.bind.auth_info.length,
791 0, /* required flags */
792 DCERPC_PFC_FLAG_FIRST |
793 DCERPC_PFC_FLAG_LAST |
794 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
795 0x08 | /* this is not defined, but should be ignored */
796 DCERPC_PFC_FLAG_CONC_MPX |
797 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
798 DCERPC_PFC_FLAG_MAYBE |
799 DCERPC_PFC_FLAG_OBJECT_UUID);
800 if (!NT_STATUS_IS_OK(status)) {
801 return dcesrv_bind_nak(call,
802 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
805 /* max_recv_frag and max_xmit_frag result always in the same value! */
806 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
807 call->pkt.u.bind.max_recv_frag);
809 * The values are between 2048 and 5840 tested against Windows 2012R2
810 * via ncacn_ip_tcp on port 135.
812 max_req = MAX(2048, max_req);
813 max_rep = MIN(max_req, call->conn->max_recv_frag);
814 /* They are truncated to an 8 byte boundary. */
817 /* max_recv_frag and max_xmit_frag result always in the same value! */
818 call->conn->max_recv_frag = max_rep;
819 call->conn->max_xmit_frag = max_rep;
822 if provided, check the assoc_group is valid
824 if (call->pkt.u.bind.assoc_group_id != 0) {
825 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
827 call->pkt.u.bind.assoc_group_id);
829 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
830 call->conn->dce_ctx);
834 * The NETLOGON server does not use handles and so
835 * there is no need to support association groups, but
836 * we need to give back a number regardless.
838 * We have to do this when it is not run as a single process,
839 * because then it can't see the other valid association
840 * groups. We handle this genericly for all endpoints not
841 * running in single process mode.
843 * We know which endpoint we are on even before checking the
844 * iface UUID, so for simplicity we enforce the same policy
845 * for all interfaces on the endpoint.
847 * This means that where NETLOGON
848 * shares an endpoint (such as ncalrpc or of 'lsa over
849 * netlogon' is set) we will still check association groups.
853 if (call->conn->assoc_group == NULL &&
854 !call->conn->endpoint->use_single_process) {
855 call->conn->assoc_group
856 = dcesrv_assoc_group_new(call->conn,
857 call->conn->dce_ctx);
859 if (call->conn->assoc_group == NULL) {
860 return dcesrv_bind_nak(call, 0);
863 if (call->pkt.u.bind.num_contexts < 1) {
864 return dcesrv_bind_nak(call, 0);
867 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
868 call->pkt.u.bind.num_contexts);
869 if (ack_ctx_list == NULL) {
870 return dcesrv_bind_nak(call, 0);
874 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
875 * dcesrv_check_or_create_context()) and do some protocol validation
876 * and set sane defaults.
878 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
879 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
880 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
881 bool is_feature = false;
882 uint64_t features = 0;
884 if (c->num_transfer_syntaxes == 0) {
885 return dcesrv_bind_nak(call, 0);
888 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
889 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
892 * It's only treated as bind time feature request, if the first
893 * transfer_syntax matches, all others are ignored.
895 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
901 if (ack_features != NULL) {
903 * Only one bind time feature context is allowed.
905 return dcesrv_bind_nak(call, 0);
909 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
910 a->reason.negotiate = 0;
911 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
912 /* not supported yet */
914 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
915 a->reason.negotiate |=
916 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
919 call->conn->bind_time_features = a->reason.negotiate;
923 * Try to negotiate one new presentation context.
925 * Deep in here we locate the iface (by uuid) that the client
926 * requested, from the list of interfaces on the
927 * call->conn->endpoint, and call iface->bind() on that iface.
929 * call->conn was set up at the accept() of the socket, and
930 * call->conn->endpoint has a list of interfaces restricted to
933 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
934 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
935 return dcesrv_bind_nak(call, 0);
937 if (!NT_STATUS_IS_OK(status)) {
942 * At this point we still don't know which interface (eg
943 * netlogon, lsa, drsuapi) the caller requested in this bind!
944 * The most recently added context is available as the first
945 * element in the linked list at call->conn->contexts, that is
946 * call->conn->contexts->iface, but they may not have
947 * requested one at all!
950 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
951 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
952 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
953 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
956 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
957 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
961 * After finding the interface and setting up the NDR
962 * transport negotiation etc, handle any authentication that
963 * is being requested.
965 if (!dcesrv_auth_bind(call)) {
966 struct dcesrv_auth *auth = &call->conn->auth_state;
968 TALLOC_FREE(call->context);
970 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
972 * With DCERPC_AUTH_LEVEL_NONE, we get the
973 * reject_reason in auth->auth_context_id.
975 return dcesrv_bind_nak(call, auth->auth_context_id);
979 * This must a be a temporary failure e.g. talloc or invalid
980 * configuration, e.g. no machine account.
982 return dcesrv_bind_nak(call,
983 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
986 /* setup a bind_ack */
987 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
988 pkt->auth_length = 0;
989 pkt->call_id = call->pkt.call_id;
990 pkt->ptype = DCERPC_PKT_BIND_ACK;
991 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
992 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
993 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
994 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
996 endpoint = dcerpc_binding_get_string_option(
997 call->conn->endpoint->ep_description,
999 if (endpoint == NULL) {
1003 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1005 * TODO: check if this is really needed
1007 * Or if we should fix this in our idl files.
1009 ep_prefix = "\\PIPE\\";
1013 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1016 if (pkt->u.bind_ack.secondary_address == NULL) {
1017 TALLOC_FREE(call->context);
1018 return NT_STATUS_NO_MEMORY;
1020 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1021 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1022 pkt->u.bind_ack.auth_info = data_blob_null;
1024 status = dcesrv_auth_bind_ack(call, pkt);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 TALLOC_FREE(call->context);
1027 return dcesrv_bind_nak(call, 0);
1030 rep = talloc_zero(call, struct data_blob_list_item);
1032 TALLOC_FREE(call->context);
1033 return NT_STATUS_NO_MEMORY;
1036 status = ncacn_push_auth(&rep->blob, call, pkt,
1037 call->out_auth_info);
1038 if (!NT_STATUS_IS_OK(status)) {
1039 TALLOC_FREE(call->context);
1043 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1045 DLIST_ADD_END(call->replies, rep);
1046 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1048 if (call->conn->call_list && call->conn->call_list->replies) {
1049 if (call->conn->transport.report_output_data) {
1050 call->conn->transport.report_output_data(call->conn);
1054 return NT_STATUS_OK;
1059 handle a auth3 request
1061 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1065 if (!call->conn->allow_auth3) {
1066 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1069 if (call->conn->auth_state.auth_finished) {
1070 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1073 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1075 call->pkt.u.auth3.auth_info.length,
1076 0, /* required flags */
1077 DCERPC_PFC_FLAG_FIRST |
1078 DCERPC_PFC_FLAG_LAST |
1079 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1080 0x08 | /* this is not defined, but should be ignored */
1081 DCERPC_PFC_FLAG_CONC_MPX |
1082 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1083 DCERPC_PFC_FLAG_MAYBE |
1084 DCERPC_PFC_FLAG_OBJECT_UUID);
1085 if (!NT_STATUS_IS_OK(status)) {
1086 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1089 /* handle the auth3 in the auth code */
1090 if (!dcesrv_auth_auth3(call)) {
1091 call->conn->auth_state.auth_invalid = true;
1092 if (call->fault_code != 0) {
1093 return dcesrv_fault_disconnect(call, call->fault_code);
1099 /* we don't send a reply to a auth3 request, except by a
1101 return NT_STATUS_OK;
1105 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1106 const struct dcerpc_bind *b,
1107 const struct dcerpc_ctx_list *ctx,
1108 struct dcerpc_ack_ctx *ack,
1110 const struct ndr_syntax_id *supported_transfer)
1112 uint32_t if_version;
1113 struct dcesrv_connection_context *context;
1114 const struct dcesrv_interface *iface;
1117 const struct ndr_syntax_id *selected_transfer = NULL;
1122 return NT_STATUS_INTERNAL_ERROR;
1125 return NT_STATUS_INTERNAL_ERROR;
1127 if (ctx->num_transfer_syntaxes < 1) {
1128 return NT_STATUS_INTERNAL_ERROR;
1131 return NT_STATUS_INTERNAL_ERROR;
1133 if (supported_transfer == NULL) {
1134 return NT_STATUS_INTERNAL_ERROR;
1137 switch (ack->result) {
1138 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1139 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1141 * We is already completed.
1143 return NT_STATUS_OK;
1148 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1149 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1151 if_version = ctx->abstract_syntax.if_version;
1152 uuid = ctx->abstract_syntax.uuid;
1154 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1155 if (iface == NULL) {
1156 char *uuid_str = GUID_string(call, &uuid);
1157 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1158 talloc_free(uuid_str);
1160 * We report this only via ack->result
1162 return NT_STATUS_OK;
1165 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1166 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1168 if (validate_only) {
1170 * We report this only via ack->result
1172 return NT_STATUS_OK;
1175 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1177 * we only do NDR encoded dcerpc for now.
1179 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1180 supported_transfer);
1182 selected_transfer = supported_transfer;
1187 context = dcesrv_find_context(call->conn, ctx->context_id);
1188 if (context != NULL) {
1189 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1190 &ctx->abstract_syntax);
1192 return NT_STATUS_RPC_PROTOCOL_ERROR;
1195 if (selected_transfer != NULL) {
1196 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1199 return NT_STATUS_RPC_PROTOCOL_ERROR;
1202 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1203 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1204 ack->syntax = context->transfer_syntax;
1208 * We report this only via ack->result
1210 return NT_STATUS_OK;
1213 if (selected_transfer == NULL) {
1215 * We report this only via ack->result
1217 return NT_STATUS_OK;
1220 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1221 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1223 /* add this context to the list of available context_ids */
1224 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1225 if (context == NULL) {
1226 return NT_STATUS_NO_MEMORY;
1228 context->conn = call->conn;
1229 context->context_id = ctx->context_id;
1230 context->iface = iface;
1231 context->transfer_syntax = *selected_transfer;
1232 context->private_data = NULL;
1233 DLIST_ADD(call->conn->contexts, context);
1234 call->context = context;
1235 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1237 dcesrv_prepare_context_auth(call);
1240 * Multiplex is supported by default
1242 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1244 status = iface->bind(call, iface, if_version);
1245 call->context = NULL;
1246 if (!NT_STATUS_IS_OK(status)) {
1247 /* we don't want to trigger the iface->unbind() hook */
1248 context->iface = NULL;
1249 talloc_free(context);
1251 * We report this only via ack->result
1253 return NT_STATUS_OK;
1256 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1257 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1258 ack->syntax = context->transfer_syntax;
1259 return NT_STATUS_OK;
1262 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1263 const struct dcerpc_bind *b,
1264 struct dcerpc_ack_ctx *ack_ctx_list)
1268 bool validate_only = false;
1269 bool preferred_ndr32;
1272 * Try to negotiate one new presentation context,
1273 * using our preferred transfer syntax.
1275 for (i = 0; i < b->num_contexts; i++) {
1276 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1277 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1279 status = dcesrv_check_or_create_context(call, b, c, a,
1281 call->conn->preferred_transfer);
1282 if (!NT_STATUS_IS_OK(status)) {
1286 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1288 * We managed to negotiate one context.
1292 validate_only = true;
1296 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1297 call->conn->preferred_transfer);
1298 if (preferred_ndr32) {
1302 return NT_STATUS_OK;
1306 * Try to negotiate one new presentation context,
1307 * using NDR 32 as fallback.
1309 for (i = 0; i < b->num_contexts; i++) {
1310 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1311 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1313 status = dcesrv_check_or_create_context(call, b, c, a,
1315 &ndr_transfer_syntax_ndr);
1316 if (!NT_STATUS_IS_OK(status)) {
1320 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1322 * We managed to negotiate one context.
1326 validate_only = true;
1330 return NT_STATUS_OK;
1334 handle a alter context request
1336 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1339 bool auth_ok = false;
1340 struct ncacn_packet *pkt = &call->ack_pkt;
1341 uint32_t extra_flags = 0;
1342 struct data_blob_list_item *rep = NULL;
1343 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1346 if (!call->conn->allow_alter) {
1347 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1350 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1352 call->pkt.u.alter.auth_info.length,
1353 0, /* required flags */
1354 DCERPC_PFC_FLAG_FIRST |
1355 DCERPC_PFC_FLAG_LAST |
1356 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1357 0x08 | /* this is not defined, but should be ignored */
1358 DCERPC_PFC_FLAG_CONC_MPX |
1359 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1360 DCERPC_PFC_FLAG_MAYBE |
1361 DCERPC_PFC_FLAG_OBJECT_UUID);
1362 if (!NT_STATUS_IS_OK(status)) {
1363 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1366 auth_ok = dcesrv_auth_alter(call);
1368 if (call->fault_code != 0) {
1369 return dcesrv_fault_disconnect(call, call->fault_code);
1373 if (call->pkt.u.alter.num_contexts < 1) {
1374 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1377 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1378 call->pkt.u.alter.num_contexts);
1379 if (ack_ctx_list == NULL) {
1380 return NT_STATUS_NO_MEMORY;
1384 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1385 * dcesrv_check_or_create_context()) and do some protocol validation
1386 * and set sane defaults.
1388 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1389 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1390 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1392 if (c->num_transfer_syntaxes == 0) {
1393 return dcesrv_fault_disconnect(call,
1394 DCERPC_NCA_S_PROTO_ERROR);
1397 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1398 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1402 * Try to negotiate one new presentation context.
1404 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1405 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1406 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1408 if (!NT_STATUS_IS_OK(status)) {
1412 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1413 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1414 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1415 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1418 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1419 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1422 /* handle any authentication that is being requested */
1424 if (call->in_auth_info.auth_type !=
1425 call->conn->auth_state.auth_type)
1427 return dcesrv_fault_disconnect(call,
1428 DCERPC_FAULT_SEC_PKG_ERROR);
1430 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1433 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1434 pkt->auth_length = 0;
1435 pkt->call_id = call->pkt.call_id;
1436 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1437 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1438 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1439 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1440 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1441 pkt->u.alter_resp.secondary_address = "";
1442 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1443 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1444 pkt->u.alter_resp.auth_info = data_blob_null;
1446 status = dcesrv_auth_alter_ack(call, pkt);
1447 if (!NT_STATUS_IS_OK(status)) {
1448 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1451 rep = talloc_zero(call, struct data_blob_list_item);
1453 return NT_STATUS_NO_MEMORY;
1456 status = ncacn_push_auth(&rep->blob, call, pkt, call->out_auth_info);
1457 if (!NT_STATUS_IS_OK(status)) {
1461 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1463 DLIST_ADD_END(call->replies, rep);
1464 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1466 if (call->conn->call_list && call->conn->call_list->replies) {
1467 if (call->conn->transport.report_output_data) {
1468 call->conn->transport.report_output_data(call->conn);
1472 return NT_STATUS_OK;
1476 possibly save the call for inspection with ndrdump
1478 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1482 const char *dump_dir;
1483 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1487 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1489 call->context->iface->name,
1490 call->pkt.u.request.opnum,
1492 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1493 DEBUG(0,("RPC SAVED %s\n", fname));
1499 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1501 TALLOC_CTX *frame = talloc_stackframe();
1502 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1503 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1504 const struct dcerpc_sec_vt_pcontext pcontext = {
1505 .abstract_syntax = call->context->iface->syntax_id,
1506 .transfer_syntax = call->context->transfer_syntax,
1508 const struct dcerpc_sec_vt_header2 header2 =
1509 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1510 enum ndr_err_code ndr_err;
1511 struct dcerpc_sec_verification_trailer *vt = NULL;
1512 NTSTATUS status = NT_STATUS_OK;
1515 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1517 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1519 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1520 status = ndr_map_error2ntstatus(ndr_err);
1524 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1525 &pcontext, &header2);
1527 status = NT_STATUS_ACCESS_DENIED;
1536 handle a dcerpc request packet
1538 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1540 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1541 enum dcerpc_transport_t transport =
1542 dcerpc_binding_get_transport(endpoint->ep_description);
1543 struct ndr_pull *pull;
1546 if (!call->conn->allow_request) {
1547 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1550 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1551 if (call->conn->auth_state.gensec_security &&
1552 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1553 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1556 if (call->context == NULL) {
1557 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1558 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1561 switch (call->conn->auth_state.auth_level) {
1562 case DCERPC_AUTH_LEVEL_NONE:
1563 case DCERPC_AUTH_LEVEL_PACKET:
1564 case DCERPC_AUTH_LEVEL_INTEGRITY:
1565 case DCERPC_AUTH_LEVEL_PRIVACY:
1568 if (!call->context->allow_connect) {
1571 addr = tsocket_address_string(call->conn->remote_address,
1574 DEBUG(2, ("%s: restrict auth_level_connect access "
1575 "to [%s] with auth[type=0x%x,level=0x%x] "
1576 "on [%s] from [%s]\n",
1577 __func__, call->context->iface->name,
1578 call->conn->auth_state.auth_type,
1579 call->conn->auth_state.auth_level,
1580 derpc_transport_string_by_transport(transport),
1582 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1587 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1590 addr = tsocket_address_string(call->conn->remote_address, call);
1592 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1593 "to [%s] with auth[type=0x%x,level=0x%x] "
1594 "on [%s] from [%s]\n",
1596 call->context->min_auth_level,
1597 call->context->iface->name,
1598 call->conn->auth_state.auth_type,
1599 call->conn->auth_state.auth_level,
1600 derpc_transport_string_by_transport(transport),
1602 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1605 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1606 NT_STATUS_HAVE_NO_MEMORY(pull);
1608 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1610 call->ndr_pull = pull;
1612 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1613 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1616 status = dcesrv_check_verification_trailer(call);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 uint32_t faultcode = DCERPC_FAULT_OTHER;
1619 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1620 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1622 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1623 nt_errstr(status)));
1624 return dcesrv_fault(call, faultcode);
1627 /* unravel the NDR for the packet */
1628 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1629 if (!NT_STATUS_IS_OK(status)) {
1630 uint8_t extra_flags = 0;
1631 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1632 /* we got an unknown call */
1633 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1634 call->pkt.u.request.opnum,
1635 call->context->iface->name));
1636 dcesrv_save_call(call, "unknown");
1637 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1639 dcesrv_save_call(call, "pullfail");
1641 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1644 if (pull->offset != pull->data_size) {
1645 dcesrv_save_call(call, "extrabytes");
1646 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1647 pull->data_size - pull->offset));
1650 /* call the dispatch function */
1651 status = call->context->iface->dispatch(call, call, call->r);
1652 if (!NT_STATUS_IS_OK(status)) {
1653 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1654 call->context->iface->name,
1655 call->pkt.u.request.opnum,
1656 dcerpc_errstr(pull, call->fault_code)));
1657 return dcesrv_fault(call, call->fault_code);
1660 /* add the call to the pending list */
1661 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1663 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1664 return NT_STATUS_OK;
1667 return dcesrv_reply(call);
1672 remove the call from the right list when freed
1674 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1676 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1680 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1682 return conn->local_address;
1685 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1687 return conn->remote_address;
1691 process some input to a dcerpc endpoint server.
1693 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1694 struct ncacn_packet *pkt,
1698 struct dcesrv_call_state *call;
1699 struct dcesrv_call_state *existing = NULL;
1701 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1703 data_blob_free(&blob);
1705 return NT_STATUS_NO_MEMORY;
1707 call->conn = dce_conn;
1708 call->event_ctx = dce_conn->event_ctx;
1709 call->msg_ctx = dce_conn->msg_ctx;
1710 call->state_flags = call->conn->state_flags;
1711 call->time = timeval_current();
1712 call->list = DCESRV_LIST_NONE;
1714 talloc_steal(call, pkt);
1715 talloc_steal(call, blob.data);
1718 talloc_set_destructor(call, dcesrv_call_dequeue);
1720 if (call->conn->allow_bind) {
1722 * Only one bind is possible per connection
1724 call->conn->allow_bind = false;
1725 return dcesrv_bind(call);
1728 /* we have to check the signing here, before combining the
1730 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1731 if (!call->conn->allow_request) {
1732 return dcesrv_fault_disconnect(call,
1733 DCERPC_NCA_S_PROTO_ERROR);
1736 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1738 call->pkt.u.request.stub_and_verifier.length,
1739 0, /* required_flags */
1740 DCERPC_PFC_FLAG_FIRST |
1741 DCERPC_PFC_FLAG_LAST |
1742 DCERPC_PFC_FLAG_PENDING_CANCEL |
1743 0x08 | /* this is not defined, but should be ignored */
1744 DCERPC_PFC_FLAG_CONC_MPX |
1745 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1746 DCERPC_PFC_FLAG_MAYBE |
1747 DCERPC_PFC_FLAG_OBJECT_UUID);
1748 if (!NT_STATUS_IS_OK(status)) {
1749 return dcesrv_fault_disconnect(call,
1750 DCERPC_NCA_S_PROTO_ERROR);
1753 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1755 * We don't use dcesrv_fault_disconnect()
1756 * here, because we don't want to set
1757 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1759 * Note that we don't check against the negotiated
1760 * max_recv_frag, but a hard coded value.
1762 dcesrv_call_disconnect_after(call,
1763 "dcesrv_auth_request - frag_length too large");
1764 return dcesrv_fault(call,
1765 DCERPC_NCA_S_PROTO_ERROR);
1768 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1769 if (dce_conn->pending_call_list != NULL) {
1771 * concurrent requests are only allowed
1772 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1774 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1775 dcesrv_call_disconnect_after(call,
1776 "dcesrv_auth_request - "
1777 "existing pending call without CONN_MPX");
1778 return dcesrv_fault(call,
1779 DCERPC_NCA_S_PROTO_ERROR);
1782 /* only one request is possible in the fragmented list */
1783 if (dce_conn->incoming_fragmented_call_list != NULL) {
1784 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1786 * Without DCERPC_PFC_FLAG_CONC_MPX
1787 * we need to return the FAULT on the
1788 * already existing call.
1790 * This is important to get the
1791 * call_id and context_id right.
1794 call = dce_conn->incoming_fragmented_call_list;
1796 dcesrv_call_disconnect_after(call,
1797 "dcesrv_auth_request - "
1798 "existing fragmented call");
1799 return dcesrv_fault(call,
1800 DCERPC_NCA_S_PROTO_ERROR);
1802 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1803 return dcesrv_fault_disconnect(call,
1804 DCERPC_FAULT_NO_CALL_ACTIVE);
1806 call->context = dcesrv_find_context(call->conn,
1807 call->pkt.u.request.context_id);
1808 if (call->context == NULL) {
1809 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1810 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1813 const struct dcerpc_request *nr = &call->pkt.u.request;
1814 const struct dcerpc_request *er = NULL;
1817 existing = dcesrv_find_fragmented_call(dce_conn,
1819 if (existing == NULL) {
1820 dcesrv_call_disconnect_after(call,
1821 "dcesrv_auth_request - "
1822 "no existing fragmented call");
1823 return dcesrv_fault(call,
1824 DCERPC_NCA_S_PROTO_ERROR);
1826 er = &existing->pkt.u.request;
1828 if (call->pkt.ptype != existing->pkt.ptype) {
1829 /* trying to play silly buggers are we? */
1830 return dcesrv_fault_disconnect(existing,
1831 DCERPC_NCA_S_PROTO_ERROR);
1833 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1836 return dcesrv_fault_disconnect(existing,
1837 DCERPC_NCA_S_PROTO_ERROR);
1839 if (nr->context_id != er->context_id) {
1840 return dcesrv_fault_disconnect(existing,
1841 DCERPC_NCA_S_PROTO_ERROR);
1843 if (nr->opnum != er->opnum) {
1844 return dcesrv_fault_disconnect(existing,
1845 DCERPC_NCA_S_PROTO_ERROR);
1850 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1852 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1854 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1855 payload_offset += 16;
1858 ok = dcesrv_auth_pkt_pull(call, &blob,
1859 0, /* required_flags */
1860 DCERPC_PFC_FLAG_FIRST |
1861 DCERPC_PFC_FLAG_LAST |
1862 DCERPC_PFC_FLAG_PENDING_CANCEL |
1863 0x08 | /* this is not defined, but should be ignored */
1864 DCERPC_PFC_FLAG_CONC_MPX |
1865 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1866 DCERPC_PFC_FLAG_MAYBE |
1867 DCERPC_PFC_FLAG_OBJECT_UUID,
1869 &call->pkt.u.request.stub_and_verifier);
1872 * We don't use dcesrv_fault_disconnect()
1873 * here, because we don't want to set
1874 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1876 dcesrv_call_disconnect_after(call,
1877 "dcesrv_auth_request - failed");
1878 if (call->fault_code == 0) {
1879 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1881 return dcesrv_fault(call, call->fault_code);
1885 /* see if this is a continued packet */
1886 if (existing != NULL) {
1887 struct dcerpc_request *er = &existing->pkt.u.request;
1888 const struct dcerpc_request *nr = &call->pkt.u.request;
1894 * Up to 4 MByte are allowed by all fragments
1896 available = dce_conn->max_total_request_size;
1897 if (er->stub_and_verifier.length > available) {
1898 dcesrv_call_disconnect_after(existing,
1899 "dcesrv_auth_request - existing payload too large");
1900 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1902 available -= er->stub_and_verifier.length;
1903 if (nr->alloc_hint > available) {
1904 dcesrv_call_disconnect_after(existing,
1905 "dcesrv_auth_request - alloc hint too large");
1906 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1908 if (nr->stub_and_verifier.length > available) {
1909 dcesrv_call_disconnect_after(existing,
1910 "dcesrv_auth_request - new payload too large");
1911 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1913 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1914 /* allocate at least 1 byte */
1915 alloc_hint = MAX(alloc_hint, 1);
1916 alloc_size = er->stub_and_verifier.length +
1917 nr->stub_and_verifier.length;
1918 alloc_size = MAX(alloc_size, alloc_hint);
1920 er->stub_and_verifier.data =
1921 talloc_realloc(existing,
1922 er->stub_and_verifier.data,
1923 uint8_t, alloc_size);
1924 if (er->stub_and_verifier.data == NULL) {
1926 return dcesrv_fault_with_flags(existing,
1927 DCERPC_FAULT_OUT_OF_RESOURCES,
1928 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1930 memcpy(er->stub_and_verifier.data +
1931 er->stub_and_verifier.length,
1932 nr->stub_and_verifier.data,
1933 nr->stub_and_verifier.length);
1934 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1936 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1942 /* this may not be the last pdu in the chain - if its isn't then
1943 just put it on the incoming_fragmented_call_list and wait for the rest */
1944 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1945 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1947 * Up to 4 MByte are allowed by all fragments
1949 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1950 dcesrv_call_disconnect_after(call,
1951 "dcesrv_auth_request - initial alloc hint too large");
1952 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1954 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1955 return NT_STATUS_OK;
1958 /* This removes any fragments we may have had stashed away */
1959 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1961 switch (call->pkt.ptype) {
1962 case DCERPC_PKT_BIND:
1963 status = dcesrv_bind_nak(call,
1964 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1966 case DCERPC_PKT_AUTH3:
1967 status = dcesrv_auth3(call);
1969 case DCERPC_PKT_ALTER:
1970 status = dcesrv_alter(call);
1972 case DCERPC_PKT_REQUEST:
1973 status = dcesrv_request(call);
1975 case DCERPC_PKT_CO_CANCEL:
1976 case DCERPC_PKT_ORPHANED:
1978 * Window just ignores CO_CANCEL and ORPHANED,
1981 status = NT_STATUS_OK;
1984 case DCERPC_PKT_BIND_ACK:
1985 case DCERPC_PKT_BIND_NAK:
1986 case DCERPC_PKT_ALTER_RESP:
1987 case DCERPC_PKT_RESPONSE:
1988 case DCERPC_PKT_FAULT:
1989 case DCERPC_PKT_SHUTDOWN:
1991 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1995 /* if we are going to be sending a reply then add
1996 it to the list of pending calls. We add it to the end to keep the call
1997 list in the order we will answer */
1998 if (!NT_STATUS_IS_OK(status)) {
2005 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2006 struct loadparm_context *lp_ctx,
2007 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2010 struct dcesrv_context *dce_ctx;
2013 if (!endpoint_servers) {
2014 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2015 return NT_STATUS_INTERNAL_ERROR;
2018 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2019 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2021 if (uid_wrapper_enabled()) {
2022 setenv("UID_WRAPPER_MYUID", "1", 1);
2024 dce_ctx->initial_euid = geteuid();
2025 if (uid_wrapper_enabled()) {
2026 unsetenv("UID_WRAPPER_MYUID");
2029 dce_ctx->endpoint_list = NULL;
2030 dce_ctx->lp_ctx = lp_ctx;
2031 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2032 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2033 dce_ctx->broken_connections = NULL;
2035 for (i=0;endpoint_servers[i];i++) {
2036 const struct dcesrv_endpoint_server *ep_server;
2038 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2040 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2041 return NT_STATUS_INTERNAL_ERROR;
2044 status = ep_server->init_server(dce_ctx, ep_server);
2045 if (!NT_STATUS_IS_OK(status)) {
2046 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2047 nt_errstr(status)));
2052 *_dce_ctx = dce_ctx;
2053 return NT_STATUS_OK;
2056 /* the list of currently registered DCERPC endpoint servers.
2058 static struct ep_server {
2059 struct dcesrv_endpoint_server *ep_server;
2060 } *ep_servers = NULL;
2061 static int num_ep_servers;
2064 register a DCERPC endpoint server.
2066 The 'name' can be later used by other backends to find the operations
2067 structure for this backend.
2070 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2073 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2074 /* its already registered! */
2075 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2077 return NT_STATUS_OBJECT_NAME_COLLISION;
2080 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2082 smb_panic("out of memory in dcerpc_register");
2085 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2086 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2090 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2093 return NT_STATUS_OK;
2097 return the operations structure for a named backend of the specified type
2099 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2103 for (i=0;i<num_ep_servers;i++) {
2104 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2105 return ep_servers[i].ep_server;
2112 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2114 static bool initialized;
2115 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2116 STATIC_dcerpc_server_MODULES_PROTO;
2117 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2118 init_module_fn *shared_init;
2125 shared_init = load_samba_modules(NULL, "dcerpc_server");
2127 run_init_functions(NULL, static_init);
2128 run_init_functions(NULL, shared_init);
2130 talloc_free(shared_init);
2134 return the DCERPC module version, and the size of some critical types
2135 This can be used by endpoint server modules to either detect compilation errors, or provide
2136 multiple implementations for different smbd compilation options in one module
2138 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2140 static const struct dcesrv_critical_sizes critical_sizes = {
2141 DCERPC_MODULE_VERSION,
2142 sizeof(struct dcesrv_context),
2143 sizeof(struct dcesrv_endpoint),
2144 sizeof(struct dcesrv_endpoint_server),
2145 sizeof(struct dcesrv_interface),
2146 sizeof(struct dcesrv_if_list),
2147 sizeof(struct dcesrv_connection),
2148 sizeof(struct dcesrv_call_state),
2149 sizeof(struct dcesrv_auth),
2150 sizeof(struct dcesrv_handle)
2153 return &critical_sizes;
2156 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2158 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2159 struct stream_connection *srv_conn;
2160 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2161 struct stream_connection);
2163 dce_conn->wait_send = NULL;
2164 dce_conn->wait_recv = NULL;
2165 dce_conn->wait_private = NULL;
2167 dce_conn->allow_bind = false;
2168 dce_conn->allow_auth3 = false;
2169 dce_conn->allow_alter = false;
2170 dce_conn->allow_request = false;
2172 if (dce_conn->pending_call_list == NULL) {
2173 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2175 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2176 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2180 if (dce_conn->terminate != NULL) {
2184 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2186 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2187 if (dce_conn->terminate == NULL) {
2188 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2190 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2193 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2195 struct dcesrv_connection *cur, *next;
2197 next = dce_ctx->broken_connections;
2198 while (next != NULL) {
2202 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2203 struct dcesrv_connection_context *context_cur, *context_next;
2205 context_next = cur->contexts;
2206 while (context_next != NULL) {
2207 context_cur = context_next;
2208 context_next = context_cur->next;
2210 dcesrv_connection_context_destructor(context_cur);
2214 dcesrv_terminate_connection(cur, cur->terminate);
2218 /* We need this include to be able to compile on some plateforms
2219 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2221 * It has to be that deep because otherwise we have a conflict on
2222 * const struct dcesrv_interface declaration.
2223 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2224 * which conflict with the bind used before.
2226 #include "system/network.h"
2228 struct dcesrv_sock_reply_state {
2229 struct dcesrv_connection *dce_conn;
2230 struct dcesrv_call_state *call;
2234 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2235 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2237 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2239 struct dcesrv_call_state *call;
2241 call = dce_conn->call_list;
2242 if (!call || !call->replies) {
2246 while (call->replies) {
2247 struct data_blob_list_item *rep = call->replies;
2248 struct dcesrv_sock_reply_state *substate;
2249 struct tevent_req *subreq;
2251 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2253 dcesrv_terminate_connection(dce_conn, "no memory");
2257 substate->dce_conn = dce_conn;
2258 substate->call = NULL;
2260 DLIST_REMOVE(call->replies, rep);
2262 if (call->replies == NULL && call->terminate_reason == NULL) {
2263 substate->call = call;
2266 substate->iov.iov_base = (void *) rep->blob.data;
2267 substate->iov.iov_len = rep->blob.length;
2269 subreq = tstream_writev_queue_send(substate,
2270 dce_conn->event_ctx,
2272 dce_conn->send_queue,
2275 dcesrv_terminate_connection(dce_conn, "no memory");
2278 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2282 if (call->terminate_reason != NULL) {
2283 struct tevent_req *subreq;
2285 subreq = tevent_queue_wait_send(call,
2286 dce_conn->event_ctx,
2287 dce_conn->send_queue);
2289 dcesrv_terminate_connection(dce_conn, __location__);
2292 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2296 DLIST_REMOVE(call->conn->call_list, call);
2297 call->list = DCESRV_LIST_NONE;
2300 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2302 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2303 struct dcesrv_sock_reply_state);
2307 struct dcesrv_call_state *call = substate->call;
2309 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2310 TALLOC_FREE(subreq);
2312 status = map_nt_error_from_unix_common(sys_errno);
2313 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2317 talloc_free(substate);
2323 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2325 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2327 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2328 struct dcesrv_call_state);
2332 /* make sure we stop send queue before removing subreq */
2333 tevent_queue_stop(call->conn->send_queue);
2335 ok = tevent_queue_wait_recv(subreq);
2336 TALLOC_FREE(subreq);
2338 dcesrv_terminate_connection(call->conn, __location__);
2342 /* disconnect after 200 usecs */
2343 tv = timeval_current_ofs_usec(200);
2344 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2345 if (subreq == NULL) {
2346 dcesrv_terminate_connection(call->conn, __location__);
2349 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2353 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2355 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2356 struct dcesrv_call_state);
2359 ok = tevent_wakeup_recv(subreq);
2360 TALLOC_FREE(subreq);
2362 dcesrv_terminate_connection(call->conn, __location__);
2366 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2369 struct dcesrv_socket_context {
2370 const struct dcesrv_endpoint *endpoint;
2371 struct dcesrv_context *dcesrv_ctx;
2375 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2377 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2380 struct dcesrv_socket_context *dcesrv_sock =
2381 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2382 enum dcerpc_transport_t transport =
2383 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2384 struct dcesrv_connection *dcesrv_conn = NULL;
2386 struct tevent_req *subreq;
2387 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2389 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2391 if (!srv_conn->session_info) {
2392 status = auth_anonymous_session_info(srv_conn,
2394 &srv_conn->session_info);
2395 if (!NT_STATUS_IS_OK(status)) {
2396 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2397 nt_errstr(status)));
2398 stream_terminate_connection(srv_conn, nt_errstr(status));
2404 * This fills in dcesrv_conn->endpoint with the endpoint
2405 * associated with the socket. From this point on we know
2406 * which (group of) services we are handling, but not the
2407 * specific interface.
2410 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2412 dcesrv_sock->endpoint,
2413 srv_conn->session_info,
2414 srv_conn->event.ctx,
2416 srv_conn->server_id,
2417 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2419 if (!NT_STATUS_IS_OK(status)) {
2420 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2421 nt_errstr(status)));
2422 stream_terminate_connection(srv_conn, nt_errstr(status));
2426 dcesrv_conn->transport.private_data = srv_conn;
2427 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2429 TALLOC_FREE(srv_conn->event.fde);
2431 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2432 if (!dcesrv_conn->send_queue) {
2433 status = NT_STATUS_NO_MEMORY;
2434 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2435 nt_errstr(status)));
2436 stream_terminate_connection(srv_conn, nt_errstr(status));
2440 if (transport == NCACN_NP) {
2441 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2442 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2443 &srv_conn->tstream);
2445 ret = tstream_bsd_existing_socket(dcesrv_conn,
2446 socket_get_fd(srv_conn->socket),
2447 &dcesrv_conn->stream);
2449 status = map_nt_error_from_unix_common(errno);
2450 DEBUG(0, ("dcesrv_sock_accept: "
2451 "failed to setup tstream: %s\n",
2452 nt_errstr(status)));
2453 stream_terminate_connection(srv_conn, nt_errstr(status));
2456 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2459 dcesrv_conn->local_address = srv_conn->local_address;
2460 dcesrv_conn->remote_address = srv_conn->remote_address;
2462 if (transport == NCALRPC) {
2467 sock_fd = socket_get_fd(srv_conn->socket);
2468 if (sock_fd == -1) {
2469 stream_terminate_connection(
2470 srv_conn, "socket_get_fd failed\n");
2474 ret = getpeereid(sock_fd, &uid, &gid);
2476 status = map_nt_error_from_unix_common(errno);
2477 DEBUG(0, ("dcesrv_sock_accept: "
2478 "getpeereid() failed for NCALRPC: %s\n",
2479 nt_errstr(status)));
2480 stream_terminate_connection(srv_conn, nt_errstr(status));
2483 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2484 struct tsocket_address *r = NULL;
2486 ret = tsocket_address_unix_from_path(dcesrv_conn,
2487 "/root/ncalrpc_as_system",
2490 status = map_nt_error_from_unix_common(errno);
2491 DEBUG(0, ("dcesrv_sock_accept: "
2492 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2493 nt_errstr(status)));
2494 stream_terminate_connection(srv_conn, nt_errstr(status));
2497 dcesrv_conn->remote_address = r;
2501 srv_conn->private_data = dcesrv_conn;
2503 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2505 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2506 dcesrv_conn->event_ctx,
2507 dcesrv_conn->stream);
2509 status = NT_STATUS_NO_MEMORY;
2510 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2511 nt_errstr(status)));
2512 stream_terminate_connection(srv_conn, nt_errstr(status));
2515 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2520 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2522 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2524 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2525 struct dcesrv_connection);
2526 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2527 struct ncacn_packet *pkt;
2531 if (dce_conn->terminate) {
2533 * if the current connection is broken
2534 * we need to clean it up before any other connection
2536 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2537 dcesrv_cleanup_broken_connections(dce_ctx);
2541 dcesrv_cleanup_broken_connections(dce_ctx);
2543 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2545 TALLOC_FREE(subreq);
2546 if (!NT_STATUS_IS_OK(status)) {
2547 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2551 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2552 if (!NT_STATUS_IS_OK(status)) {
2553 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2558 * This is used to block the connection during
2559 * pending authentication.
2561 if (dce_conn->wait_send != NULL) {
2562 subreq = dce_conn->wait_send(dce_conn,
2563 dce_conn->event_ctx,
2564 dce_conn->wait_private);
2566 status = NT_STATUS_NO_MEMORY;
2567 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2570 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2574 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2575 dce_conn->event_ctx,
2578 status = NT_STATUS_NO_MEMORY;
2579 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2582 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2585 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2587 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2588 struct dcesrv_connection);
2589 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2592 if (dce_conn->terminate) {
2594 * if the current connection is broken
2595 * we need to clean it up before any other connection
2597 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2598 dcesrv_cleanup_broken_connections(dce_ctx);
2602 dcesrv_cleanup_broken_connections(dce_ctx);
2604 status = dce_conn->wait_recv(subreq);
2605 dce_conn->wait_send = NULL;
2606 dce_conn->wait_recv = NULL;
2607 dce_conn->wait_private = NULL;
2608 TALLOC_FREE(subreq);
2609 if (!NT_STATUS_IS_OK(status)) {
2610 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2614 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2615 dce_conn->event_ctx,
2618 status = NT_STATUS_NO_MEMORY;
2619 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2622 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2625 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2627 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2628 struct dcesrv_connection);
2629 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2632 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2634 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2635 struct dcesrv_connection);
2636 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2640 static const struct stream_server_ops dcesrv_stream_ops = {
2642 .accept_connection = dcesrv_sock_accept,
2643 .recv_handler = dcesrv_sock_recv,
2644 .send_handler = dcesrv_sock_send,
2647 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2648 struct loadparm_context *lp_ctx,
2649 struct dcesrv_endpoint *e,
2650 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2652 struct dcesrv_socket_context *dcesrv_sock;
2655 const char *endpoint;
2657 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2658 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2660 /* remember the endpoint of this socket */
2661 dcesrv_sock->endpoint = e;
2662 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2664 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2666 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2667 model_ops, &dcesrv_stream_ops,
2668 "unix", endpoint, &port,
2669 lpcfg_socket_options(lp_ctx),
2671 if (!NT_STATUS_IS_OK(status)) {
2672 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2673 endpoint, nt_errstr(status)));
2679 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2680 struct loadparm_context *lp_ctx,
2681 struct dcesrv_endpoint *e,
2682 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2684 struct dcesrv_socket_context *dcesrv_sock;
2688 const char *endpoint;
2690 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2692 if (endpoint == NULL) {
2694 * No identifier specified: use DEFAULT.
2696 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2697 * no endpoint and let the epmapper worry about it.
2699 endpoint = "DEFAULT";
2700 status = dcerpc_binding_set_string_option(e->ep_description,
2703 if (!NT_STATUS_IS_OK(status)) {
2704 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2705 nt_errstr(status)));
2710 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2713 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2714 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2716 /* remember the endpoint of this socket */
2717 dcesrv_sock->endpoint = e;
2718 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2720 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2721 model_ops, &dcesrv_stream_ops,
2722 "unix", full_path, &port,
2723 lpcfg_socket_options(lp_ctx),
2725 if (!NT_STATUS_IS_OK(status)) {
2726 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2727 endpoint, full_path, nt_errstr(status)));
2732 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2733 struct loadparm_context *lp_ctx,
2734 struct dcesrv_endpoint *e,
2735 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2737 struct dcesrv_socket_context *dcesrv_sock;
2739 const char *endpoint;
2741 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2742 if (endpoint == NULL) {
2743 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2744 return NT_STATUS_INVALID_PARAMETER;
2747 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2748 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2750 /* remember the endpoint of this socket */
2751 dcesrv_sock->endpoint = e;
2752 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2754 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2755 model_ops, &dcesrv_stream_ops,
2758 if (!NT_STATUS_IS_OK(status)) {
2759 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2760 endpoint, nt_errstr(status)));
2764 return NT_STATUS_OK;
2768 add a socket address to the list of events, one event per dcerpc endpoint
2770 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2771 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2772 const char *address)
2774 struct dcesrv_socket_context *dcesrv_sock;
2777 const char *endpoint;
2780 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2781 if (endpoint != NULL) {
2782 port = atoi(endpoint);
2785 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2786 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2788 /* remember the endpoint of this socket */
2789 dcesrv_sock->endpoint = e;
2790 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2792 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2793 model_ops, &dcesrv_stream_ops,
2794 "ip", address, &port,
2795 lpcfg_socket_options(dce_ctx->lp_ctx),
2797 if (!NT_STATUS_IS_OK(status)) {
2798 struct dcesrv_if_list *iface;
2799 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2801 for (iface = e->interface_list; iface; iface = iface->next) {
2802 DEBUGADD(0, ("%s ", iface->iface.name));
2804 DEBUGADD(0, ("failed - %s",
2805 nt_errstr(status)));
2809 snprintf(port_str, sizeof(port_str), "%u", port);
2811 status = dcerpc_binding_set_string_option(e->ep_description,
2812 "endpoint", port_str);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2815 port_str, nt_errstr(status)));
2818 struct dcesrv_if_list *iface;
2819 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2820 address, port_str));
2821 for (iface = e->interface_list; iface; iface = iface->next) {
2822 DEBUGADD(4, ("%s ", iface->iface.name));
2824 DEBUGADD(4, ("\n"));
2827 return NT_STATUS_OK;
2830 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2832 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2833 struct loadparm_context *lp_ctx,
2834 struct dcesrv_endpoint *e,
2835 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2839 /* Add TCP/IP sockets */
2840 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2843 struct interface *ifaces;
2845 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2847 num_interfaces = iface_list_count(ifaces);
2848 for(i = 0; i < num_interfaces; i++) {
2849 const char *address = iface_list_n_ip(ifaces, i);
2850 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2851 NT_STATUS_NOT_OK_RETURN(status);
2857 wcard = iface_list_wildcard(dce_ctx);
2858 NT_STATUS_HAVE_NO_MEMORY(wcard);
2859 for (i=0; wcard[i]; i++) {
2860 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2861 if (NT_STATUS_IS_OK(status)) {
2866 if (num_binds == 0) {
2867 return NT_STATUS_INVALID_PARAMETER_MIX;
2871 return NT_STATUS_OK;
2874 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2875 struct loadparm_context *lp_ctx,
2876 struct dcesrv_endpoint *e,
2877 struct tevent_context *event_ctx,
2878 const struct model_ops *model_ops)
2880 enum dcerpc_transport_t transport =
2881 dcerpc_binding_get_transport(e->ep_description);
2883 switch (transport) {
2884 case NCACN_UNIX_STREAM:
2885 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2888 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2891 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2894 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2897 return NT_STATUS_NOT_SUPPORTED;
2903 * retrieve credentials from a dce_call
2905 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2907 return dce_call->conn->auth_state.session_info->credentials;
2911 * returns true if this is an authenticated call
2913 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2915 enum security_user_level level;
2916 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2917 return level >= SECURITY_USER;
2921 * retrieve account_name for a dce_call
2923 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2925 return dce_call->context->conn->auth_state.session_info->info->account_name;