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;
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));
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;
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(void);
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(static_init);
2128 run_init_functions(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->allow_bind = false;
2164 dce_conn->allow_auth3 = false;
2165 dce_conn->allow_alter = false;
2166 dce_conn->allow_request = false;
2168 if (dce_conn->pending_call_list == NULL) {
2169 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2171 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2172 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2176 if (dce_conn->terminate != NULL) {
2180 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2182 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2183 if (dce_conn->terminate == NULL) {
2184 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2186 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2189 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2191 struct dcesrv_connection *cur, *next;
2193 next = dce_ctx->broken_connections;
2194 while (next != NULL) {
2198 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2199 struct dcesrv_connection_context *context_cur, *context_next;
2201 context_next = cur->contexts;
2202 while (context_next != NULL) {
2203 context_cur = context_next;
2204 context_next = context_cur->next;
2206 dcesrv_connection_context_destructor(context_cur);
2210 dcesrv_terminate_connection(cur, cur->terminate);
2214 /* We need this include to be able to compile on some plateforms
2215 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2217 * It has to be that deep because otherwise we have a conflict on
2218 * const struct dcesrv_interface declaration.
2219 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2220 * which conflict with the bind used before.
2222 #include "system/network.h"
2224 struct dcesrv_sock_reply_state {
2225 struct dcesrv_connection *dce_conn;
2226 struct dcesrv_call_state *call;
2230 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2231 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2233 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2235 struct dcesrv_call_state *call;
2237 call = dce_conn->call_list;
2238 if (!call || !call->replies) {
2242 while (call->replies) {
2243 struct data_blob_list_item *rep = call->replies;
2244 struct dcesrv_sock_reply_state *substate;
2245 struct tevent_req *subreq;
2247 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2249 dcesrv_terminate_connection(dce_conn, "no memory");
2253 substate->dce_conn = dce_conn;
2254 substate->call = NULL;
2256 DLIST_REMOVE(call->replies, rep);
2258 if (call->replies == NULL && call->terminate_reason == NULL) {
2259 substate->call = call;
2262 substate->iov.iov_base = (void *) rep->blob.data;
2263 substate->iov.iov_len = rep->blob.length;
2265 subreq = tstream_writev_queue_send(substate,
2266 dce_conn->event_ctx,
2268 dce_conn->send_queue,
2271 dcesrv_terminate_connection(dce_conn, "no memory");
2274 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2278 if (call->terminate_reason != NULL) {
2279 struct tevent_req *subreq;
2281 subreq = tevent_queue_wait_send(call,
2282 dce_conn->event_ctx,
2283 dce_conn->send_queue);
2285 dcesrv_terminate_connection(dce_conn, __location__);
2288 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2292 DLIST_REMOVE(call->conn->call_list, call);
2293 call->list = DCESRV_LIST_NONE;
2296 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2298 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2299 struct dcesrv_sock_reply_state);
2303 struct dcesrv_call_state *call = substate->call;
2305 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2306 TALLOC_FREE(subreq);
2308 status = map_nt_error_from_unix_common(sys_errno);
2309 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2313 talloc_free(substate);
2319 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2321 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2323 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2324 struct dcesrv_call_state);
2328 /* make sure we stop send queue before removing subreq */
2329 tevent_queue_stop(call->conn->send_queue);
2331 ok = tevent_queue_wait_recv(subreq);
2332 TALLOC_FREE(subreq);
2334 dcesrv_terminate_connection(call->conn, __location__);
2338 /* disconnect after 200 usecs */
2339 tv = timeval_current_ofs_usec(200);
2340 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2341 if (subreq == NULL) {
2342 dcesrv_terminate_connection(call->conn, __location__);
2345 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2349 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2351 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2352 struct dcesrv_call_state);
2355 ok = tevent_wakeup_recv(subreq);
2356 TALLOC_FREE(subreq);
2358 dcesrv_terminate_connection(call->conn, __location__);
2362 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2365 struct dcesrv_socket_context {
2366 const struct dcesrv_endpoint *endpoint;
2367 struct dcesrv_context *dcesrv_ctx;
2371 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2373 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2376 struct dcesrv_socket_context *dcesrv_sock =
2377 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2378 enum dcerpc_transport_t transport =
2379 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2380 struct dcesrv_connection *dcesrv_conn = NULL;
2382 struct tevent_req *subreq;
2383 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2385 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2387 if (!srv_conn->session_info) {
2388 status = auth_anonymous_session_info(srv_conn,
2390 &srv_conn->session_info);
2391 if (!NT_STATUS_IS_OK(status)) {
2392 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2393 nt_errstr(status)));
2394 stream_terminate_connection(srv_conn, nt_errstr(status));
2400 * This fills in dcesrv_conn->endpoint with the endpoint
2401 * associated with the socket. From this point on we know
2402 * which (group of) services we are handling, but not the
2403 * specific interface.
2406 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2408 dcesrv_sock->endpoint,
2409 srv_conn->session_info,
2410 srv_conn->event.ctx,
2412 srv_conn->server_id,
2413 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2415 if (!NT_STATUS_IS_OK(status)) {
2416 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2417 nt_errstr(status)));
2418 stream_terminate_connection(srv_conn, nt_errstr(status));
2422 dcesrv_conn->transport.private_data = srv_conn;
2423 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2425 TALLOC_FREE(srv_conn->event.fde);
2427 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2428 if (!dcesrv_conn->send_queue) {
2429 status = NT_STATUS_NO_MEMORY;
2430 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2431 nt_errstr(status)));
2432 stream_terminate_connection(srv_conn, nt_errstr(status));
2436 if (transport == NCACN_NP) {
2437 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2438 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2439 &srv_conn->tstream);
2441 ret = tstream_bsd_existing_socket(dcesrv_conn,
2442 socket_get_fd(srv_conn->socket),
2443 &dcesrv_conn->stream);
2445 status = map_nt_error_from_unix_common(errno);
2446 DEBUG(0, ("dcesrv_sock_accept: "
2447 "failed to setup tstream: %s\n",
2448 nt_errstr(status)));
2449 stream_terminate_connection(srv_conn, nt_errstr(status));
2452 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2455 dcesrv_conn->local_address = srv_conn->local_address;
2456 dcesrv_conn->remote_address = srv_conn->remote_address;
2458 if (transport == NCALRPC) {
2463 sock_fd = socket_get_fd(srv_conn->socket);
2464 if (sock_fd == -1) {
2465 stream_terminate_connection(
2466 srv_conn, "socket_get_fd failed\n");
2470 ret = getpeereid(sock_fd, &uid, &gid);
2472 status = map_nt_error_from_unix_common(errno);
2473 DEBUG(0, ("dcesrv_sock_accept: "
2474 "getpeereid() failed for NCALRPC: %s\n",
2475 nt_errstr(status)));
2476 stream_terminate_connection(srv_conn, nt_errstr(status));
2479 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2480 struct tsocket_address *r = NULL;
2482 ret = tsocket_address_unix_from_path(dcesrv_conn,
2483 "/root/ncalrpc_as_system",
2486 status = map_nt_error_from_unix_common(errno);
2487 DEBUG(0, ("dcesrv_sock_accept: "
2488 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2489 nt_errstr(status)));
2490 stream_terminate_connection(srv_conn, nt_errstr(status));
2493 dcesrv_conn->remote_address = r;
2497 srv_conn->private_data = dcesrv_conn;
2499 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2501 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2502 dcesrv_conn->event_ctx,
2503 dcesrv_conn->stream);
2505 status = NT_STATUS_NO_MEMORY;
2506 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2507 nt_errstr(status)));
2508 stream_terminate_connection(srv_conn, nt_errstr(status));
2511 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2516 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2518 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2519 struct dcesrv_connection);
2520 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2521 struct ncacn_packet *pkt;
2525 if (dce_conn->terminate) {
2527 * if the current connection is broken
2528 * we need to clean it up before any other connection
2530 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2531 dcesrv_cleanup_broken_connections(dce_ctx);
2535 dcesrv_cleanup_broken_connections(dce_ctx);
2537 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2539 TALLOC_FREE(subreq);
2540 if (!NT_STATUS_IS_OK(status)) {
2541 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2545 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2546 if (!NT_STATUS_IS_OK(status)) {
2547 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2551 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2552 dce_conn->event_ctx,
2555 status = NT_STATUS_NO_MEMORY;
2556 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2559 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2562 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2564 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2565 struct dcesrv_connection);
2566 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2569 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2571 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2572 struct dcesrv_connection);
2573 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2577 static const struct stream_server_ops dcesrv_stream_ops = {
2579 .accept_connection = dcesrv_sock_accept,
2580 .recv_handler = dcesrv_sock_recv,
2581 .send_handler = dcesrv_sock_send,
2584 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2585 struct loadparm_context *lp_ctx,
2586 struct dcesrv_endpoint *e,
2587 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2589 struct dcesrv_socket_context *dcesrv_sock;
2592 const char *endpoint;
2594 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2595 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2597 /* remember the endpoint of this socket */
2598 dcesrv_sock->endpoint = e;
2599 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2601 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2603 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2604 model_ops, &dcesrv_stream_ops,
2605 "unix", endpoint, &port,
2606 lpcfg_socket_options(lp_ctx),
2608 if (!NT_STATUS_IS_OK(status)) {
2609 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2610 endpoint, nt_errstr(status)));
2616 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2617 struct loadparm_context *lp_ctx,
2618 struct dcesrv_endpoint *e,
2619 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2621 struct dcesrv_socket_context *dcesrv_sock;
2625 const char *endpoint;
2627 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2629 if (endpoint == NULL) {
2631 * No identifier specified: use DEFAULT.
2633 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2634 * no endpoint and let the epmapper worry about it.
2636 endpoint = "DEFAULT";
2637 status = dcerpc_binding_set_string_option(e->ep_description,
2640 if (!NT_STATUS_IS_OK(status)) {
2641 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2642 nt_errstr(status)));
2647 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2650 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2651 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2653 /* remember the endpoint of this socket */
2654 dcesrv_sock->endpoint = e;
2655 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2657 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2658 model_ops, &dcesrv_stream_ops,
2659 "unix", full_path, &port,
2660 lpcfg_socket_options(lp_ctx),
2662 if (!NT_STATUS_IS_OK(status)) {
2663 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2664 endpoint, full_path, nt_errstr(status)));
2669 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2670 struct loadparm_context *lp_ctx,
2671 struct dcesrv_endpoint *e,
2672 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2674 struct dcesrv_socket_context *dcesrv_sock;
2676 const char *endpoint;
2678 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2679 if (endpoint == NULL) {
2680 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2681 return NT_STATUS_INVALID_PARAMETER;
2684 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2685 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2687 /* remember the endpoint of this socket */
2688 dcesrv_sock->endpoint = e;
2689 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2691 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2692 model_ops, &dcesrv_stream_ops,
2695 if (!NT_STATUS_IS_OK(status)) {
2696 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2697 endpoint, nt_errstr(status)));
2701 return NT_STATUS_OK;
2705 add a socket address to the list of events, one event per dcerpc endpoint
2707 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2708 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2709 const char *address)
2711 struct dcesrv_socket_context *dcesrv_sock;
2714 const char *endpoint;
2717 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2718 if (endpoint != NULL) {
2719 port = atoi(endpoint);
2722 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2723 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2725 /* remember the endpoint of this socket */
2726 dcesrv_sock->endpoint = e;
2727 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2729 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2730 model_ops, &dcesrv_stream_ops,
2731 "ip", address, &port,
2732 lpcfg_socket_options(dce_ctx->lp_ctx),
2734 if (!NT_STATUS_IS_OK(status)) {
2735 struct dcesrv_if_list *iface;
2736 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2738 for (iface = e->interface_list; iface; iface = iface->next) {
2739 DEBUGADD(0, ("%s ", iface->iface.name));
2741 DEBUGADD(0, ("failed - %s",
2742 nt_errstr(status)));
2746 snprintf(port_str, sizeof(port_str), "%u", port);
2748 status = dcerpc_binding_set_string_option(e->ep_description,
2749 "endpoint", port_str);
2750 if (!NT_STATUS_IS_OK(status)) {
2751 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2752 port_str, nt_errstr(status)));
2755 struct dcesrv_if_list *iface;
2756 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2757 address, port_str));
2758 for (iface = e->interface_list; iface; iface = iface->next) {
2759 DEBUGADD(4, ("%s ", iface->iface.name));
2761 DEBUGADD(4, ("\n"));
2764 return NT_STATUS_OK;
2767 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2769 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2770 struct loadparm_context *lp_ctx,
2771 struct dcesrv_endpoint *e,
2772 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2776 /* Add TCP/IP sockets */
2777 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2780 struct interface *ifaces;
2782 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2784 num_interfaces = iface_list_count(ifaces);
2785 for(i = 0; i < num_interfaces; i++) {
2786 const char *address = iface_list_n_ip(ifaces, i);
2787 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2788 NT_STATUS_NOT_OK_RETURN(status);
2794 wcard = iface_list_wildcard(dce_ctx);
2795 NT_STATUS_HAVE_NO_MEMORY(wcard);
2796 for (i=0; wcard[i]; i++) {
2797 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2798 if (NT_STATUS_IS_OK(status)) {
2803 if (num_binds == 0) {
2804 return NT_STATUS_INVALID_PARAMETER_MIX;
2808 return NT_STATUS_OK;
2811 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2812 struct loadparm_context *lp_ctx,
2813 struct dcesrv_endpoint *e,
2814 struct tevent_context *event_ctx,
2815 const struct model_ops *model_ops)
2817 enum dcerpc_transport_t transport =
2818 dcerpc_binding_get_transport(e->ep_description);
2820 switch (transport) {
2821 case NCACN_UNIX_STREAM:
2822 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2825 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2828 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2831 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2834 return NT_STATUS_NOT_SUPPORTED;
2840 * retrieve credentials from a dce_call
2842 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2844 return dce_call->conn->auth_state.session_info->credentials;
2848 * returns true if this is an authenticated call
2850 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2852 enum security_user_level level;
2853 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2854 return level >= SECURITY_USER;
2858 * retrieve account_name for a dce_call
2860 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2862 return dce_call->context->conn->auth_state.session_info->info->account_name;