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);
771 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
774 handle a bind request
776 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
778 struct ncacn_packet *pkt = &call->ack_pkt;
780 uint32_t extra_flags = 0;
781 uint16_t max_req = 0;
782 uint16_t max_rep = 0;
783 const char *ep_prefix = "";
784 const char *endpoint = NULL;
785 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
786 struct dcerpc_ack_ctx *ack_features = NULL;
789 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
791 call->pkt.u.bind.auth_info.length,
792 0, /* required flags */
793 DCERPC_PFC_FLAG_FIRST |
794 DCERPC_PFC_FLAG_LAST |
795 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
796 0x08 | /* this is not defined, but should be ignored */
797 DCERPC_PFC_FLAG_CONC_MPX |
798 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
799 DCERPC_PFC_FLAG_MAYBE |
800 DCERPC_PFC_FLAG_OBJECT_UUID);
801 if (!NT_STATUS_IS_OK(status)) {
802 return dcesrv_bind_nak(call,
803 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
806 /* max_recv_frag and max_xmit_frag result always in the same value! */
807 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
808 call->pkt.u.bind.max_recv_frag);
810 * The values are between 2048 and 5840 tested against Windows 2012R2
811 * via ncacn_ip_tcp on port 135.
813 max_req = MAX(2048, max_req);
814 max_rep = MIN(max_req, call->conn->max_recv_frag);
815 /* They are truncated to an 8 byte boundary. */
818 /* max_recv_frag and max_xmit_frag result always in the same value! */
819 call->conn->max_recv_frag = max_rep;
820 call->conn->max_xmit_frag = max_rep;
823 if provided, check the assoc_group is valid
825 if (call->pkt.u.bind.assoc_group_id != 0) {
826 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn,
828 call->pkt.u.bind.assoc_group_id);
830 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn,
831 call->conn->dce_ctx);
835 * The NETLOGON server does not use handles and so
836 * there is no need to support association groups, but
837 * we need to give back a number regardless.
839 * We have to do this when it is not run as a single process,
840 * because then it can't see the other valid association
841 * groups. We handle this genericly for all endpoints not
842 * running in single process mode.
844 * We know which endpoint we are on even before checking the
845 * iface UUID, so for simplicity we enforce the same policy
846 * for all interfaces on the endpoint.
848 * This means that where NETLOGON
849 * shares an endpoint (such as ncalrpc or of 'lsa over
850 * netlogon' is set) we will still check association groups.
854 if (call->conn->assoc_group == NULL &&
855 !call->conn->endpoint->use_single_process) {
856 call->conn->assoc_group
857 = dcesrv_assoc_group_new(call->conn,
858 call->conn->dce_ctx);
860 if (call->conn->assoc_group == NULL) {
861 return dcesrv_bind_nak(call, 0);
864 if (call->pkt.u.bind.num_contexts < 1) {
865 return dcesrv_bind_nak(call, 0);
868 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
869 call->pkt.u.bind.num_contexts);
870 if (ack_ctx_list == NULL) {
871 return dcesrv_bind_nak(call, 0);
875 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
876 * dcesrv_check_or_create_context()) and do some protocol validation
877 * and set sane defaults.
879 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
880 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
881 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
882 bool is_feature = false;
883 uint64_t features = 0;
885 if (c->num_transfer_syntaxes == 0) {
886 return dcesrv_bind_nak(call, 0);
889 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
890 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
893 * It's only treated as bind time feature request, if the first
894 * transfer_syntax matches, all others are ignored.
896 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
902 if (ack_features != NULL) {
904 * Only one bind time feature context is allowed.
906 return dcesrv_bind_nak(call, 0);
910 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
911 a->reason.negotiate = 0;
912 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
913 /* not supported yet */
915 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
916 a->reason.negotiate |=
917 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
920 call->conn->bind_time_features = a->reason.negotiate;
924 * Try to negotiate one new presentation context.
926 * Deep in here we locate the iface (by uuid) that the client
927 * requested, from the list of interfaces on the
928 * call->conn->endpoint, and call iface->bind() on that iface.
930 * call->conn was set up at the accept() of the socket, and
931 * call->conn->endpoint has a list of interfaces restricted to
934 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
935 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
936 return dcesrv_bind_nak(call, 0);
938 if (!NT_STATUS_IS_OK(status)) {
943 * At this point we still don't know which interface (eg
944 * netlogon, lsa, drsuapi) the caller requested in this bind!
945 * The most recently added context is available as the first
946 * element in the linked list at call->conn->contexts, that is
947 * call->conn->contexts->iface, but they may not have
948 * requested one at all!
951 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
952 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
953 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
954 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
957 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
958 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
962 * After finding the interface and setting up the NDR
963 * transport negotiation etc, handle any authentication that
964 * is being requested.
966 if (!dcesrv_auth_bind(call)) {
967 struct dcesrv_auth *auth = &call->conn->auth_state;
969 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
971 * With DCERPC_AUTH_LEVEL_NONE, we get the
972 * reject_reason in auth->auth_context_id.
974 return dcesrv_bind_nak(call, auth->auth_context_id);
978 * This must a be a temporary failure e.g. talloc or invalid
979 * configuration, e.g. no machine account.
981 return dcesrv_bind_nak(call,
982 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
985 /* setup a bind_ack */
986 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
987 pkt->auth_length = 0;
988 pkt->call_id = call->pkt.call_id;
989 pkt->ptype = DCERPC_PKT_BIND_ACK;
990 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
991 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
992 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
993 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
995 endpoint = dcerpc_binding_get_string_option(
996 call->conn->endpoint->ep_description,
998 if (endpoint == NULL) {
1002 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1004 * TODO: check if this is really needed
1006 * Or if we should fix this in our idl files.
1008 ep_prefix = "\\PIPE\\";
1012 pkt->u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1015 if (pkt->u.bind_ack.secondary_address == NULL) {
1016 return NT_STATUS_NO_MEMORY;
1018 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1019 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1020 pkt->u.bind_ack.auth_info = data_blob_null;
1022 status = dcesrv_auth_bind_ack(call, pkt);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 return dcesrv_bind_nak(call, 0);
1027 return dcesrv_auth_reply(call);
1030 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1032 struct ncacn_packet *pkt = &call->ack_pkt;
1033 struct data_blob_list_item *rep = NULL;
1036 rep = talloc_zero(call, struct data_blob_list_item);
1038 return NT_STATUS_NO_MEMORY;
1041 status = ncacn_push_auth(&rep->blob, call, pkt,
1042 call->out_auth_info);
1043 if (!NT_STATUS_IS_OK(status)) {
1047 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1049 DLIST_ADD_END(call->replies, rep);
1050 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1052 if (call->conn->call_list && call->conn->call_list->replies) {
1053 if (call->conn->transport.report_output_data) {
1054 call->conn->transport.report_output_data(call->conn);
1058 return NT_STATUS_OK;
1063 handle a auth3 request
1065 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1069 if (!call->conn->allow_auth3) {
1070 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1073 if (call->conn->auth_state.auth_finished) {
1074 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1077 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1079 call->pkt.u.auth3.auth_info.length,
1080 0, /* required flags */
1081 DCERPC_PFC_FLAG_FIRST |
1082 DCERPC_PFC_FLAG_LAST |
1083 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1084 0x08 | /* this is not defined, but should be ignored */
1085 DCERPC_PFC_FLAG_CONC_MPX |
1086 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1087 DCERPC_PFC_FLAG_MAYBE |
1088 DCERPC_PFC_FLAG_OBJECT_UUID);
1089 if (!NT_STATUS_IS_OK(status)) {
1090 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1093 /* handle the auth3 in the auth code */
1094 if (!dcesrv_auth_auth3(call)) {
1095 call->conn->auth_state.auth_invalid = true;
1096 if (call->fault_code != 0) {
1097 return dcesrv_fault_disconnect(call, call->fault_code);
1103 /* we don't send a reply to a auth3 request, except by a
1105 return NT_STATUS_OK;
1109 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1110 const struct dcerpc_bind *b,
1111 const struct dcerpc_ctx_list *ctx,
1112 struct dcerpc_ack_ctx *ack,
1114 const struct ndr_syntax_id *supported_transfer)
1116 uint32_t if_version;
1117 struct dcesrv_connection_context *context;
1118 const struct dcesrv_interface *iface;
1121 const struct ndr_syntax_id *selected_transfer = NULL;
1126 return NT_STATUS_INTERNAL_ERROR;
1129 return NT_STATUS_INTERNAL_ERROR;
1131 if (ctx->num_transfer_syntaxes < 1) {
1132 return NT_STATUS_INTERNAL_ERROR;
1135 return NT_STATUS_INTERNAL_ERROR;
1137 if (supported_transfer == NULL) {
1138 return NT_STATUS_INTERNAL_ERROR;
1141 switch (ack->result) {
1142 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1143 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1145 * We is already completed.
1147 return NT_STATUS_OK;
1152 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1153 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1155 if_version = ctx->abstract_syntax.if_version;
1156 uuid = ctx->abstract_syntax.uuid;
1158 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1159 if (iface == NULL) {
1160 char *uuid_str = GUID_string(call, &uuid);
1161 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1162 talloc_free(uuid_str);
1164 * We report this only via ack->result
1166 return NT_STATUS_OK;
1169 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1170 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1172 if (validate_only) {
1174 * We report this only via ack->result
1176 return NT_STATUS_OK;
1179 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1181 * we only do NDR encoded dcerpc for now.
1183 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1184 supported_transfer);
1186 selected_transfer = supported_transfer;
1191 context = dcesrv_find_context(call->conn, ctx->context_id);
1192 if (context != NULL) {
1193 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1194 &ctx->abstract_syntax);
1196 return NT_STATUS_RPC_PROTOCOL_ERROR;
1199 if (selected_transfer != NULL) {
1200 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1203 return NT_STATUS_RPC_PROTOCOL_ERROR;
1206 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1207 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1208 ack->syntax = context->transfer_syntax;
1212 * We report this only via ack->result
1214 return NT_STATUS_OK;
1217 if (selected_transfer == NULL) {
1219 * We report this only via ack->result
1221 return NT_STATUS_OK;
1224 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1225 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1227 /* add this context to the list of available context_ids */
1228 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1229 if (context == NULL) {
1230 return NT_STATUS_NO_MEMORY;
1232 context->conn = call->conn;
1233 context->context_id = ctx->context_id;
1234 context->iface = iface;
1235 context->transfer_syntax = *selected_transfer;
1236 context->private_data = NULL;
1237 DLIST_ADD(call->conn->contexts, context);
1238 call->context = context;
1239 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1241 dcesrv_prepare_context_auth(call);
1244 * Multiplex is supported by default
1246 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1248 status = iface->bind(call, iface, if_version);
1249 call->context = NULL;
1250 if (!NT_STATUS_IS_OK(status)) {
1251 /* we don't want to trigger the iface->unbind() hook */
1252 context->iface = NULL;
1253 talloc_free(context);
1255 * We report this only via ack->result
1257 return NT_STATUS_OK;
1260 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1261 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1262 ack->syntax = context->transfer_syntax;
1263 return NT_STATUS_OK;
1266 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1267 const struct dcerpc_bind *b,
1268 struct dcerpc_ack_ctx *ack_ctx_list)
1272 bool validate_only = false;
1273 bool preferred_ndr32;
1276 * Try to negotiate one new presentation context,
1277 * using our preferred transfer syntax.
1279 for (i = 0; i < b->num_contexts; i++) {
1280 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1281 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1283 status = dcesrv_check_or_create_context(call, b, c, a,
1285 call->conn->preferred_transfer);
1286 if (!NT_STATUS_IS_OK(status)) {
1290 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1292 * We managed to negotiate one context.
1296 validate_only = true;
1300 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1301 call->conn->preferred_transfer);
1302 if (preferred_ndr32) {
1306 return NT_STATUS_OK;
1310 * Try to negotiate one new presentation context,
1311 * using NDR 32 as fallback.
1313 for (i = 0; i < b->num_contexts; i++) {
1314 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1315 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1317 status = dcesrv_check_or_create_context(call, b, c, a,
1319 &ndr_transfer_syntax_ndr);
1320 if (!NT_STATUS_IS_OK(status)) {
1324 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1326 * We managed to negotiate one context.
1330 validate_only = true;
1334 return NT_STATUS_OK;
1338 handle a alter context request
1340 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1343 bool auth_ok = false;
1344 struct ncacn_packet *pkt = &call->ack_pkt;
1345 uint32_t extra_flags = 0;
1346 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1349 if (!call->conn->allow_alter) {
1350 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1353 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1355 call->pkt.u.alter.auth_info.length,
1356 0, /* required flags */
1357 DCERPC_PFC_FLAG_FIRST |
1358 DCERPC_PFC_FLAG_LAST |
1359 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1360 0x08 | /* this is not defined, but should be ignored */
1361 DCERPC_PFC_FLAG_CONC_MPX |
1362 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1363 DCERPC_PFC_FLAG_MAYBE |
1364 DCERPC_PFC_FLAG_OBJECT_UUID);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1369 auth_ok = dcesrv_auth_alter(call);
1371 if (call->fault_code != 0) {
1372 return dcesrv_fault_disconnect(call, call->fault_code);
1376 if (call->pkt.u.alter.num_contexts < 1) {
1377 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1380 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1381 call->pkt.u.alter.num_contexts);
1382 if (ack_ctx_list == NULL) {
1383 return NT_STATUS_NO_MEMORY;
1387 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1388 * dcesrv_check_or_create_context()) and do some protocol validation
1389 * and set sane defaults.
1391 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1392 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1393 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1395 if (c->num_transfer_syntaxes == 0) {
1396 return dcesrv_fault_disconnect(call,
1397 DCERPC_NCA_S_PROTO_ERROR);
1400 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1401 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1405 * Try to negotiate one new presentation context.
1407 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1408 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1409 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1411 if (!NT_STATUS_IS_OK(status)) {
1415 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1416 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1417 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1418 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1421 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1422 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1425 /* handle any authentication that is being requested */
1427 if (call->in_auth_info.auth_type !=
1428 call->conn->auth_state.auth_type)
1430 return dcesrv_fault_disconnect(call,
1431 DCERPC_FAULT_SEC_PKG_ERROR);
1433 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1436 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1437 pkt->auth_length = 0;
1438 pkt->call_id = call->pkt.call_id;
1439 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1440 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1441 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1442 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1443 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1444 pkt->u.alter_resp.secondary_address = "";
1445 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1446 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1447 pkt->u.alter_resp.auth_info = data_blob_null;
1449 status = dcesrv_auth_alter_ack(call, pkt);
1450 if (!NT_STATUS_IS_OK(status)) {
1451 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1454 return dcesrv_auth_reply(call);
1458 possibly save the call for inspection with ndrdump
1460 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1464 const char *dump_dir;
1465 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1469 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1471 call->context->iface->name,
1472 call->pkt.u.request.opnum,
1474 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1475 DEBUG(0,("RPC SAVED %s\n", fname));
1481 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1483 TALLOC_CTX *frame = talloc_stackframe();
1484 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1485 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1486 const struct dcerpc_sec_vt_pcontext pcontext = {
1487 .abstract_syntax = call->context->iface->syntax_id,
1488 .transfer_syntax = call->context->transfer_syntax,
1490 const struct dcerpc_sec_vt_header2 header2 =
1491 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1492 enum ndr_err_code ndr_err;
1493 struct dcerpc_sec_verification_trailer *vt = NULL;
1494 NTSTATUS status = NT_STATUS_OK;
1497 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1499 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1501 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1502 status = ndr_map_error2ntstatus(ndr_err);
1506 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1507 &pcontext, &header2);
1509 status = NT_STATUS_ACCESS_DENIED;
1518 handle a dcerpc request packet
1520 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1522 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1523 enum dcerpc_transport_t transport =
1524 dcerpc_binding_get_transport(endpoint->ep_description);
1525 struct ndr_pull *pull;
1528 if (!call->conn->allow_request) {
1529 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1532 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1533 if (call->conn->auth_state.gensec_security &&
1534 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1535 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1538 if (call->context == NULL) {
1539 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1540 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1543 switch (call->conn->auth_state.auth_level) {
1544 case DCERPC_AUTH_LEVEL_NONE:
1545 case DCERPC_AUTH_LEVEL_PACKET:
1546 case DCERPC_AUTH_LEVEL_INTEGRITY:
1547 case DCERPC_AUTH_LEVEL_PRIVACY:
1550 if (!call->context->allow_connect) {
1553 addr = tsocket_address_string(call->conn->remote_address,
1556 DEBUG(2, ("%s: restrict auth_level_connect access "
1557 "to [%s] with auth[type=0x%x,level=0x%x] "
1558 "on [%s] from [%s]\n",
1559 __func__, call->context->iface->name,
1560 call->conn->auth_state.auth_type,
1561 call->conn->auth_state.auth_level,
1562 derpc_transport_string_by_transport(transport),
1564 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1569 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1572 addr = tsocket_address_string(call->conn->remote_address, call);
1574 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1575 "to [%s] with auth[type=0x%x,level=0x%x] "
1576 "on [%s] from [%s]\n",
1578 call->context->min_auth_level,
1579 call->context->iface->name,
1580 call->conn->auth_state.auth_type,
1581 call->conn->auth_state.auth_level,
1582 derpc_transport_string_by_transport(transport),
1584 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1587 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1588 NT_STATUS_HAVE_NO_MEMORY(pull);
1590 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1592 call->ndr_pull = pull;
1594 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1595 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1598 status = dcesrv_check_verification_trailer(call);
1599 if (!NT_STATUS_IS_OK(status)) {
1600 uint32_t faultcode = DCERPC_FAULT_OTHER;
1601 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1602 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1604 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1605 nt_errstr(status)));
1606 return dcesrv_fault(call, faultcode);
1609 /* unravel the NDR for the packet */
1610 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1611 if (!NT_STATUS_IS_OK(status)) {
1612 uint8_t extra_flags = 0;
1613 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1614 /* we got an unknown call */
1615 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1616 call->pkt.u.request.opnum,
1617 call->context->iface->name));
1618 dcesrv_save_call(call, "unknown");
1619 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1621 dcesrv_save_call(call, "pullfail");
1623 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1626 if (pull->offset != pull->data_size) {
1627 dcesrv_save_call(call, "extrabytes");
1628 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1629 pull->data_size - pull->offset));
1632 /* call the dispatch function */
1633 status = call->context->iface->dispatch(call, call, call->r);
1634 if (!NT_STATUS_IS_OK(status)) {
1635 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1636 call->context->iface->name,
1637 call->pkt.u.request.opnum,
1638 dcerpc_errstr(pull, call->fault_code)));
1639 return dcesrv_fault(call, call->fault_code);
1642 /* add the call to the pending list */
1643 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1645 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1646 return NT_STATUS_OK;
1649 return dcesrv_reply(call);
1654 remove the call from the right list when freed
1656 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1658 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1662 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1664 return conn->local_address;
1667 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1669 return conn->remote_address;
1673 process some input to a dcerpc endpoint server.
1675 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1676 struct ncacn_packet *pkt,
1680 struct dcesrv_call_state *call;
1681 struct dcesrv_call_state *existing = NULL;
1683 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1685 data_blob_free(&blob);
1687 return NT_STATUS_NO_MEMORY;
1689 call->conn = dce_conn;
1690 call->event_ctx = dce_conn->event_ctx;
1691 call->msg_ctx = dce_conn->msg_ctx;
1692 call->state_flags = call->conn->state_flags;
1693 call->time = timeval_current();
1694 call->list = DCESRV_LIST_NONE;
1696 talloc_steal(call, pkt);
1697 talloc_steal(call, blob.data);
1700 talloc_set_destructor(call, dcesrv_call_dequeue);
1702 if (call->conn->allow_bind) {
1704 * Only one bind is possible per connection
1706 call->conn->allow_bind = false;
1707 return dcesrv_bind(call);
1710 /* we have to check the signing here, before combining the
1712 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1713 if (!call->conn->allow_request) {
1714 return dcesrv_fault_disconnect(call,
1715 DCERPC_NCA_S_PROTO_ERROR);
1718 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1720 call->pkt.u.request.stub_and_verifier.length,
1721 0, /* required_flags */
1722 DCERPC_PFC_FLAG_FIRST |
1723 DCERPC_PFC_FLAG_LAST |
1724 DCERPC_PFC_FLAG_PENDING_CANCEL |
1725 0x08 | /* this is not defined, but should be ignored */
1726 DCERPC_PFC_FLAG_CONC_MPX |
1727 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1728 DCERPC_PFC_FLAG_MAYBE |
1729 DCERPC_PFC_FLAG_OBJECT_UUID);
1730 if (!NT_STATUS_IS_OK(status)) {
1731 return dcesrv_fault_disconnect(call,
1732 DCERPC_NCA_S_PROTO_ERROR);
1735 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1737 * We don't use dcesrv_fault_disconnect()
1738 * here, because we don't want to set
1739 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1741 * Note that we don't check against the negotiated
1742 * max_recv_frag, but a hard coded value.
1744 dcesrv_call_disconnect_after(call,
1745 "dcesrv_auth_request - frag_length too large");
1746 return dcesrv_fault(call,
1747 DCERPC_NCA_S_PROTO_ERROR);
1750 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1751 if (dce_conn->pending_call_list != NULL) {
1753 * concurrent requests are only allowed
1754 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1756 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1757 dcesrv_call_disconnect_after(call,
1758 "dcesrv_auth_request - "
1759 "existing pending call without CONN_MPX");
1760 return dcesrv_fault(call,
1761 DCERPC_NCA_S_PROTO_ERROR);
1764 /* only one request is possible in the fragmented list */
1765 if (dce_conn->incoming_fragmented_call_list != NULL) {
1766 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1768 * Without DCERPC_PFC_FLAG_CONC_MPX
1769 * we need to return the FAULT on the
1770 * already existing call.
1772 * This is important to get the
1773 * call_id and context_id right.
1776 call = dce_conn->incoming_fragmented_call_list;
1778 dcesrv_call_disconnect_after(call,
1779 "dcesrv_auth_request - "
1780 "existing fragmented call");
1781 return dcesrv_fault(call,
1782 DCERPC_NCA_S_PROTO_ERROR);
1784 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1785 return dcesrv_fault_disconnect(call,
1786 DCERPC_FAULT_NO_CALL_ACTIVE);
1788 call->context = dcesrv_find_context(call->conn,
1789 call->pkt.u.request.context_id);
1790 if (call->context == NULL) {
1791 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1792 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1795 const struct dcerpc_request *nr = &call->pkt.u.request;
1796 const struct dcerpc_request *er = NULL;
1799 existing = dcesrv_find_fragmented_call(dce_conn,
1801 if (existing == NULL) {
1802 dcesrv_call_disconnect_after(call,
1803 "dcesrv_auth_request - "
1804 "no existing fragmented call");
1805 return dcesrv_fault(call,
1806 DCERPC_NCA_S_PROTO_ERROR);
1808 er = &existing->pkt.u.request;
1810 if (call->pkt.ptype != existing->pkt.ptype) {
1811 /* trying to play silly buggers are we? */
1812 return dcesrv_fault_disconnect(existing,
1813 DCERPC_NCA_S_PROTO_ERROR);
1815 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1818 return dcesrv_fault_disconnect(existing,
1819 DCERPC_NCA_S_PROTO_ERROR);
1821 if (nr->context_id != er->context_id) {
1822 return dcesrv_fault_disconnect(existing,
1823 DCERPC_NCA_S_PROTO_ERROR);
1825 if (nr->opnum != er->opnum) {
1826 return dcesrv_fault_disconnect(existing,
1827 DCERPC_NCA_S_PROTO_ERROR);
1832 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1834 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1836 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1837 payload_offset += 16;
1840 ok = dcesrv_auth_pkt_pull(call, &blob,
1841 0, /* required_flags */
1842 DCERPC_PFC_FLAG_FIRST |
1843 DCERPC_PFC_FLAG_LAST |
1844 DCERPC_PFC_FLAG_PENDING_CANCEL |
1845 0x08 | /* this is not defined, but should be ignored */
1846 DCERPC_PFC_FLAG_CONC_MPX |
1847 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1848 DCERPC_PFC_FLAG_MAYBE |
1849 DCERPC_PFC_FLAG_OBJECT_UUID,
1851 &call->pkt.u.request.stub_and_verifier);
1854 * We don't use dcesrv_fault_disconnect()
1855 * here, because we don't want to set
1856 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1858 dcesrv_call_disconnect_after(call,
1859 "dcesrv_auth_request - failed");
1860 if (call->fault_code == 0) {
1861 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1863 return dcesrv_fault(call, call->fault_code);
1867 /* see if this is a continued packet */
1868 if (existing != NULL) {
1869 struct dcerpc_request *er = &existing->pkt.u.request;
1870 const struct dcerpc_request *nr = &call->pkt.u.request;
1876 * Up to 4 MByte are allowed by all fragments
1878 available = dce_conn->max_total_request_size;
1879 if (er->stub_and_verifier.length > available) {
1880 dcesrv_call_disconnect_after(existing,
1881 "dcesrv_auth_request - existing payload too large");
1882 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1884 available -= er->stub_and_verifier.length;
1885 if (nr->alloc_hint > available) {
1886 dcesrv_call_disconnect_after(existing,
1887 "dcesrv_auth_request - alloc hint too large");
1888 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1890 if (nr->stub_and_verifier.length > available) {
1891 dcesrv_call_disconnect_after(existing,
1892 "dcesrv_auth_request - new payload too large");
1893 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1895 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1896 /* allocate at least 1 byte */
1897 alloc_hint = MAX(alloc_hint, 1);
1898 alloc_size = er->stub_and_verifier.length +
1899 nr->stub_and_verifier.length;
1900 alloc_size = MAX(alloc_size, alloc_hint);
1902 er->stub_and_verifier.data =
1903 talloc_realloc(existing,
1904 er->stub_and_verifier.data,
1905 uint8_t, alloc_size);
1906 if (er->stub_and_verifier.data == NULL) {
1908 return dcesrv_fault_with_flags(existing,
1909 DCERPC_FAULT_OUT_OF_RESOURCES,
1910 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1912 memcpy(er->stub_and_verifier.data +
1913 er->stub_and_verifier.length,
1914 nr->stub_and_verifier.data,
1915 nr->stub_and_verifier.length);
1916 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1918 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1924 /* this may not be the last pdu in the chain - if its isn't then
1925 just put it on the incoming_fragmented_call_list and wait for the rest */
1926 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1927 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1929 * Up to 4 MByte are allowed by all fragments
1931 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1932 dcesrv_call_disconnect_after(call,
1933 "dcesrv_auth_request - initial alloc hint too large");
1934 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1936 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1937 return NT_STATUS_OK;
1940 /* This removes any fragments we may have had stashed away */
1941 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1943 switch (call->pkt.ptype) {
1944 case DCERPC_PKT_BIND:
1945 status = dcesrv_bind_nak(call,
1946 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1948 case DCERPC_PKT_AUTH3:
1949 status = dcesrv_auth3(call);
1951 case DCERPC_PKT_ALTER:
1952 status = dcesrv_alter(call);
1954 case DCERPC_PKT_REQUEST:
1955 status = dcesrv_request(call);
1957 case DCERPC_PKT_CO_CANCEL:
1958 case DCERPC_PKT_ORPHANED:
1960 * Window just ignores CO_CANCEL and ORPHANED,
1963 status = NT_STATUS_OK;
1966 case DCERPC_PKT_BIND_ACK:
1967 case DCERPC_PKT_BIND_NAK:
1968 case DCERPC_PKT_ALTER_RESP:
1969 case DCERPC_PKT_RESPONSE:
1970 case DCERPC_PKT_FAULT:
1971 case DCERPC_PKT_SHUTDOWN:
1973 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1977 /* if we are going to be sending a reply then add
1978 it to the list of pending calls. We add it to the end to keep the call
1979 list in the order we will answer */
1980 if (!NT_STATUS_IS_OK(status)) {
1987 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
1988 struct loadparm_context *lp_ctx,
1989 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
1992 struct dcesrv_context *dce_ctx;
1995 if (!endpoint_servers) {
1996 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
1997 return NT_STATUS_INTERNAL_ERROR;
2000 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2001 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2003 if (uid_wrapper_enabled()) {
2004 setenv("UID_WRAPPER_MYUID", "1", 1);
2006 dce_ctx->initial_euid = geteuid();
2007 if (uid_wrapper_enabled()) {
2008 unsetenv("UID_WRAPPER_MYUID");
2011 dce_ctx->endpoint_list = NULL;
2012 dce_ctx->lp_ctx = lp_ctx;
2013 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2014 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2015 dce_ctx->broken_connections = NULL;
2017 for (i=0;endpoint_servers[i];i++) {
2018 const struct dcesrv_endpoint_server *ep_server;
2020 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2022 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2023 return NT_STATUS_INTERNAL_ERROR;
2026 status = ep_server->init_server(dce_ctx, ep_server);
2027 if (!NT_STATUS_IS_OK(status)) {
2028 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2029 nt_errstr(status)));
2034 *_dce_ctx = dce_ctx;
2035 return NT_STATUS_OK;
2038 /* the list of currently registered DCERPC endpoint servers.
2040 static struct ep_server {
2041 struct dcesrv_endpoint_server *ep_server;
2042 } *ep_servers = NULL;
2043 static int num_ep_servers;
2046 register a DCERPC endpoint server.
2048 The 'name' can be later used by other backends to find the operations
2049 structure for this backend.
2052 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2055 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2056 /* its already registered! */
2057 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2059 return NT_STATUS_OBJECT_NAME_COLLISION;
2062 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2064 smb_panic("out of memory in dcerpc_register");
2067 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2068 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2072 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2075 return NT_STATUS_OK;
2079 return the operations structure for a named backend of the specified type
2081 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2085 for (i=0;i<num_ep_servers;i++) {
2086 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2087 return ep_servers[i].ep_server;
2094 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2096 static bool initialized;
2097 #define _MODULE_PROTO(init) extern NTSTATUS init(TALLOC_CTX *);
2098 STATIC_dcerpc_server_MODULES_PROTO;
2099 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2100 init_module_fn *shared_init;
2107 shared_init = load_samba_modules(NULL, "dcerpc_server");
2109 run_init_functions(NULL, static_init);
2110 run_init_functions(NULL, shared_init);
2112 talloc_free(shared_init);
2116 return the DCERPC module version, and the size of some critical types
2117 This can be used by endpoint server modules to either detect compilation errors, or provide
2118 multiple implementations for different smbd compilation options in one module
2120 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2122 static const struct dcesrv_critical_sizes critical_sizes = {
2123 DCERPC_MODULE_VERSION,
2124 sizeof(struct dcesrv_context),
2125 sizeof(struct dcesrv_endpoint),
2126 sizeof(struct dcesrv_endpoint_server),
2127 sizeof(struct dcesrv_interface),
2128 sizeof(struct dcesrv_if_list),
2129 sizeof(struct dcesrv_connection),
2130 sizeof(struct dcesrv_call_state),
2131 sizeof(struct dcesrv_auth),
2132 sizeof(struct dcesrv_handle)
2135 return &critical_sizes;
2138 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2140 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2141 struct stream_connection *srv_conn;
2142 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2143 struct stream_connection);
2145 dce_conn->wait_send = NULL;
2146 dce_conn->wait_recv = NULL;
2147 dce_conn->wait_private = NULL;
2149 dce_conn->allow_bind = false;
2150 dce_conn->allow_auth3 = false;
2151 dce_conn->allow_alter = false;
2152 dce_conn->allow_request = false;
2154 if (dce_conn->pending_call_list == NULL) {
2155 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2157 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2158 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2162 if (dce_conn->terminate != NULL) {
2166 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2168 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2169 if (dce_conn->terminate == NULL) {
2170 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2172 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2175 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2177 struct dcesrv_connection *cur, *next;
2179 next = dce_ctx->broken_connections;
2180 while (next != NULL) {
2184 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2185 struct dcesrv_connection_context *context_cur, *context_next;
2187 context_next = cur->contexts;
2188 while (context_next != NULL) {
2189 context_cur = context_next;
2190 context_next = context_cur->next;
2192 dcesrv_connection_context_destructor(context_cur);
2196 dcesrv_terminate_connection(cur, cur->terminate);
2200 /* We need this include to be able to compile on some plateforms
2201 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2203 * It has to be that deep because otherwise we have a conflict on
2204 * const struct dcesrv_interface declaration.
2205 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2206 * which conflict with the bind used before.
2208 #include "system/network.h"
2210 struct dcesrv_sock_reply_state {
2211 struct dcesrv_connection *dce_conn;
2212 struct dcesrv_call_state *call;
2216 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2217 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2219 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2221 struct dcesrv_call_state *call;
2223 call = dce_conn->call_list;
2224 if (!call || !call->replies) {
2228 while (call->replies) {
2229 struct data_blob_list_item *rep = call->replies;
2230 struct dcesrv_sock_reply_state *substate;
2231 struct tevent_req *subreq;
2233 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2235 dcesrv_terminate_connection(dce_conn, "no memory");
2239 substate->dce_conn = dce_conn;
2240 substate->call = NULL;
2242 DLIST_REMOVE(call->replies, rep);
2244 if (call->replies == NULL && call->terminate_reason == NULL) {
2245 substate->call = call;
2248 substate->iov.iov_base = (void *) rep->blob.data;
2249 substate->iov.iov_len = rep->blob.length;
2251 subreq = tstream_writev_queue_send(substate,
2252 dce_conn->event_ctx,
2254 dce_conn->send_queue,
2257 dcesrv_terminate_connection(dce_conn, "no memory");
2260 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2264 if (call->terminate_reason != NULL) {
2265 struct tevent_req *subreq;
2267 subreq = tevent_queue_wait_send(call,
2268 dce_conn->event_ctx,
2269 dce_conn->send_queue);
2271 dcesrv_terminate_connection(dce_conn, __location__);
2274 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2278 DLIST_REMOVE(call->conn->call_list, call);
2279 call->list = DCESRV_LIST_NONE;
2282 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2284 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2285 struct dcesrv_sock_reply_state);
2289 struct dcesrv_call_state *call = substate->call;
2291 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2292 TALLOC_FREE(subreq);
2294 status = map_nt_error_from_unix_common(sys_errno);
2295 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2299 talloc_free(substate);
2305 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2307 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2309 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2310 struct dcesrv_call_state);
2314 /* make sure we stop send queue before removing subreq */
2315 tevent_queue_stop(call->conn->send_queue);
2317 ok = tevent_queue_wait_recv(subreq);
2318 TALLOC_FREE(subreq);
2320 dcesrv_terminate_connection(call->conn, __location__);
2324 /* disconnect after 200 usecs */
2325 tv = timeval_current_ofs_usec(200);
2326 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2327 if (subreq == NULL) {
2328 dcesrv_terminate_connection(call->conn, __location__);
2331 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2335 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2337 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2338 struct dcesrv_call_state);
2341 ok = tevent_wakeup_recv(subreq);
2342 TALLOC_FREE(subreq);
2344 dcesrv_terminate_connection(call->conn, __location__);
2348 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2351 struct dcesrv_socket_context {
2352 const struct dcesrv_endpoint *endpoint;
2353 struct dcesrv_context *dcesrv_ctx;
2357 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2359 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2362 struct dcesrv_socket_context *dcesrv_sock =
2363 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2364 enum dcerpc_transport_t transport =
2365 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2366 struct dcesrv_connection *dcesrv_conn = NULL;
2368 struct tevent_req *subreq;
2369 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2371 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2373 if (!srv_conn->session_info) {
2374 status = auth_anonymous_session_info(srv_conn,
2376 &srv_conn->session_info);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2379 nt_errstr(status)));
2380 stream_terminate_connection(srv_conn, nt_errstr(status));
2386 * This fills in dcesrv_conn->endpoint with the endpoint
2387 * associated with the socket. From this point on we know
2388 * which (group of) services we are handling, but not the
2389 * specific interface.
2392 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2394 dcesrv_sock->endpoint,
2395 srv_conn->session_info,
2396 srv_conn->event.ctx,
2398 srv_conn->server_id,
2399 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2401 if (!NT_STATUS_IS_OK(status)) {
2402 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2403 nt_errstr(status)));
2404 stream_terminate_connection(srv_conn, nt_errstr(status));
2408 dcesrv_conn->transport.private_data = srv_conn;
2409 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2411 TALLOC_FREE(srv_conn->event.fde);
2413 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2414 if (!dcesrv_conn->send_queue) {
2415 status = NT_STATUS_NO_MEMORY;
2416 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2417 nt_errstr(status)));
2418 stream_terminate_connection(srv_conn, nt_errstr(status));
2422 if (transport == NCACN_NP) {
2423 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2424 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2425 &srv_conn->tstream);
2427 ret = tstream_bsd_existing_socket(dcesrv_conn,
2428 socket_get_fd(srv_conn->socket),
2429 &dcesrv_conn->stream);
2431 status = map_nt_error_from_unix_common(errno);
2432 DEBUG(0, ("dcesrv_sock_accept: "
2433 "failed to setup tstream: %s\n",
2434 nt_errstr(status)));
2435 stream_terminate_connection(srv_conn, nt_errstr(status));
2438 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2441 dcesrv_conn->local_address = srv_conn->local_address;
2442 dcesrv_conn->remote_address = srv_conn->remote_address;
2444 if (transport == NCALRPC) {
2449 sock_fd = socket_get_fd(srv_conn->socket);
2450 if (sock_fd == -1) {
2451 stream_terminate_connection(
2452 srv_conn, "socket_get_fd failed\n");
2456 ret = getpeereid(sock_fd, &uid, &gid);
2458 status = map_nt_error_from_unix_common(errno);
2459 DEBUG(0, ("dcesrv_sock_accept: "
2460 "getpeereid() failed for NCALRPC: %s\n",
2461 nt_errstr(status)));
2462 stream_terminate_connection(srv_conn, nt_errstr(status));
2465 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2466 struct tsocket_address *r = NULL;
2468 ret = tsocket_address_unix_from_path(dcesrv_conn,
2469 "/root/ncalrpc_as_system",
2472 status = map_nt_error_from_unix_common(errno);
2473 DEBUG(0, ("dcesrv_sock_accept: "
2474 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2475 nt_errstr(status)));
2476 stream_terminate_connection(srv_conn, nt_errstr(status));
2479 dcesrv_conn->remote_address = r;
2483 srv_conn->private_data = dcesrv_conn;
2485 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2487 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2488 dcesrv_conn->event_ctx,
2489 dcesrv_conn->stream);
2491 status = NT_STATUS_NO_MEMORY;
2492 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2493 nt_errstr(status)));
2494 stream_terminate_connection(srv_conn, nt_errstr(status));
2497 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2502 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2504 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2506 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2507 struct dcesrv_connection);
2508 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2509 struct ncacn_packet *pkt;
2513 if (dce_conn->terminate) {
2515 * if the current connection is broken
2516 * we need to clean it up before any other connection
2518 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2519 dcesrv_cleanup_broken_connections(dce_ctx);
2523 dcesrv_cleanup_broken_connections(dce_ctx);
2525 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2527 TALLOC_FREE(subreq);
2528 if (!NT_STATUS_IS_OK(status)) {
2529 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2533 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2540 * This is used to block the connection during
2541 * pending authentication.
2543 if (dce_conn->wait_send != NULL) {
2544 subreq = dce_conn->wait_send(dce_conn,
2545 dce_conn->event_ctx,
2546 dce_conn->wait_private);
2548 status = NT_STATUS_NO_MEMORY;
2549 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2552 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2556 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2557 dce_conn->event_ctx,
2560 status = NT_STATUS_NO_MEMORY;
2561 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2564 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2567 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2569 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2570 struct dcesrv_connection);
2571 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2574 if (dce_conn->terminate) {
2576 * if the current connection is broken
2577 * we need to clean it up before any other connection
2579 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2580 dcesrv_cleanup_broken_connections(dce_ctx);
2584 dcesrv_cleanup_broken_connections(dce_ctx);
2586 status = dce_conn->wait_recv(subreq);
2587 dce_conn->wait_send = NULL;
2588 dce_conn->wait_recv = NULL;
2589 dce_conn->wait_private = NULL;
2590 TALLOC_FREE(subreq);
2591 if (!NT_STATUS_IS_OK(status)) {
2592 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2596 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2597 dce_conn->event_ctx,
2600 status = NT_STATUS_NO_MEMORY;
2601 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2604 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2607 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2609 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2610 struct dcesrv_connection);
2611 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2614 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2616 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2617 struct dcesrv_connection);
2618 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2622 static const struct stream_server_ops dcesrv_stream_ops = {
2624 .accept_connection = dcesrv_sock_accept,
2625 .recv_handler = dcesrv_sock_recv,
2626 .send_handler = dcesrv_sock_send,
2629 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2630 struct loadparm_context *lp_ctx,
2631 struct dcesrv_endpoint *e,
2632 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2634 struct dcesrv_socket_context *dcesrv_sock;
2637 const char *endpoint;
2639 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2640 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2642 /* remember the endpoint of this socket */
2643 dcesrv_sock->endpoint = e;
2644 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2646 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2648 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2649 model_ops, &dcesrv_stream_ops,
2650 "unix", endpoint, &port,
2651 lpcfg_socket_options(lp_ctx),
2653 if (!NT_STATUS_IS_OK(status)) {
2654 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2655 endpoint, nt_errstr(status)));
2661 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2662 struct loadparm_context *lp_ctx,
2663 struct dcesrv_endpoint *e,
2664 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2666 struct dcesrv_socket_context *dcesrv_sock;
2670 const char *endpoint;
2672 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2674 if (endpoint == NULL) {
2676 * No identifier specified: use DEFAULT.
2678 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2679 * no endpoint and let the epmapper worry about it.
2681 endpoint = "DEFAULT";
2682 status = dcerpc_binding_set_string_option(e->ep_description,
2685 if (!NT_STATUS_IS_OK(status)) {
2686 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2687 nt_errstr(status)));
2692 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2695 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2696 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2698 /* remember the endpoint of this socket */
2699 dcesrv_sock->endpoint = e;
2700 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2702 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2703 model_ops, &dcesrv_stream_ops,
2704 "unix", full_path, &port,
2705 lpcfg_socket_options(lp_ctx),
2707 if (!NT_STATUS_IS_OK(status)) {
2708 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2709 endpoint, full_path, nt_errstr(status)));
2714 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2715 struct loadparm_context *lp_ctx,
2716 struct dcesrv_endpoint *e,
2717 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2719 struct dcesrv_socket_context *dcesrv_sock;
2721 const char *endpoint;
2723 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2724 if (endpoint == NULL) {
2725 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2726 return NT_STATUS_INVALID_PARAMETER;
2729 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2730 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2732 /* remember the endpoint of this socket */
2733 dcesrv_sock->endpoint = e;
2734 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2736 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2737 model_ops, &dcesrv_stream_ops,
2740 if (!NT_STATUS_IS_OK(status)) {
2741 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2742 endpoint, nt_errstr(status)));
2746 return NT_STATUS_OK;
2750 add a socket address to the list of events, one event per dcerpc endpoint
2752 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2753 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2754 const char *address)
2756 struct dcesrv_socket_context *dcesrv_sock;
2759 const char *endpoint;
2762 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2763 if (endpoint != NULL) {
2764 port = atoi(endpoint);
2767 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2768 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2770 /* remember the endpoint of this socket */
2771 dcesrv_sock->endpoint = e;
2772 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2774 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2775 model_ops, &dcesrv_stream_ops,
2776 "ip", address, &port,
2777 lpcfg_socket_options(dce_ctx->lp_ctx),
2779 if (!NT_STATUS_IS_OK(status)) {
2780 struct dcesrv_if_list *iface;
2781 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2783 for (iface = e->interface_list; iface; iface = iface->next) {
2784 DEBUGADD(0, ("%s ", iface->iface.name));
2786 DEBUGADD(0, ("failed - %s",
2787 nt_errstr(status)));
2791 snprintf(port_str, sizeof(port_str), "%u", port);
2793 status = dcerpc_binding_set_string_option(e->ep_description,
2794 "endpoint", port_str);
2795 if (!NT_STATUS_IS_OK(status)) {
2796 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2797 port_str, nt_errstr(status)));
2800 struct dcesrv_if_list *iface;
2801 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2802 address, port_str));
2803 for (iface = e->interface_list; iface; iface = iface->next) {
2804 DEBUGADD(4, ("%s ", iface->iface.name));
2806 DEBUGADD(4, ("\n"));
2809 return NT_STATUS_OK;
2812 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2814 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2815 struct loadparm_context *lp_ctx,
2816 struct dcesrv_endpoint *e,
2817 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2821 /* Add TCP/IP sockets */
2822 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2825 struct interface *ifaces;
2827 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2829 num_interfaces = iface_list_count(ifaces);
2830 for(i = 0; i < num_interfaces; i++) {
2831 const char *address = iface_list_n_ip(ifaces, i);
2832 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2833 NT_STATUS_NOT_OK_RETURN(status);
2839 wcard = iface_list_wildcard(dce_ctx);
2840 NT_STATUS_HAVE_NO_MEMORY(wcard);
2841 for (i=0; wcard[i]; i++) {
2842 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2843 if (NT_STATUS_IS_OK(status)) {
2848 if (num_binds == 0) {
2849 return NT_STATUS_INVALID_PARAMETER_MIX;
2853 return NT_STATUS_OK;
2856 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2857 struct loadparm_context *lp_ctx,
2858 struct dcesrv_endpoint *e,
2859 struct tevent_context *event_ctx,
2860 const struct model_ops *model_ops)
2862 enum dcerpc_transport_t transport =
2863 dcerpc_binding_get_transport(e->ep_description);
2865 switch (transport) {
2866 case NCACN_UNIX_STREAM:
2867 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2870 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2873 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2876 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2879 return NT_STATUS_NOT_SUPPORTED;
2885 * retrieve credentials from a dce_call
2887 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2889 return dce_call->conn->auth_state.session_info->credentials;
2893 * returns true if this is an authenticated call
2895 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2897 enum security_user_level level;
2898 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2899 return level >= SECURITY_USER;
2903 * retrieve account_name for a dce_call
2905 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2907 return dce_call->context->conn->auth_state.session_info->info->account_name;