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 know which interface (eg netlogon, lsa,
943 * drsuapi) the caller requested. This is available on
944 * call->conntext->iface.
947 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
948 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
949 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
950 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
953 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
954 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
958 * After finding the interface and setting up the NDR
959 * transport negotiation etc, handle any authentication that
960 * is being requested.
962 if (!dcesrv_auth_bind(call)) {
963 struct dcesrv_auth *auth = &call->conn->auth_state;
965 TALLOC_FREE(call->context);
967 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
969 * With DCERPC_AUTH_LEVEL_NONE, we get the
970 * reject_reason in auth->auth_context_id.
972 return dcesrv_bind_nak(call, auth->auth_context_id);
976 * This must a be a temporary failure e.g. talloc or invalid
977 * configuration, e.g. no machine account.
979 return dcesrv_bind_nak(call,
980 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
983 /* setup a bind_ack */
984 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
986 pkt.call_id = call->pkt.call_id;
987 pkt.ptype = DCERPC_PKT_BIND_ACK;
988 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
989 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
990 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
991 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
993 endpoint = dcerpc_binding_get_string_option(
994 call->conn->endpoint->ep_description,
996 if (endpoint == NULL) {
1000 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) {
1002 * TODO: check if this is really needed
1004 * Or if we should fix this in our idl files.
1006 ep_prefix = "\\PIPE\\";
1010 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s",
1013 if (pkt.u.bind_ack.secondary_address == NULL) {
1014 TALLOC_FREE(call->context);
1015 return NT_STATUS_NO_MEMORY;
1017 pkt.u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1018 pkt.u.bind_ack.ctx_list = ack_ctx_list;
1019 pkt.u.bind_ack.auth_info = data_blob_null;
1021 status = dcesrv_auth_bind_ack(call, &pkt);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 TALLOC_FREE(call->context);
1024 return dcesrv_bind_nak(call, 0);
1027 rep = talloc_zero(call, struct data_blob_list_item);
1029 TALLOC_FREE(call->context);
1030 return NT_STATUS_NO_MEMORY;
1033 status = ncacn_push_auth(&rep->blob, call, &pkt,
1034 call->out_auth_info);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 TALLOC_FREE(call->context);
1040 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1042 DLIST_ADD_END(call->replies, rep);
1043 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1045 if (call->conn->call_list && call->conn->call_list->replies) {
1046 if (call->conn->transport.report_output_data) {
1047 call->conn->transport.report_output_data(call->conn);
1051 return NT_STATUS_OK;
1056 handle a auth3 request
1058 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1062 if (!call->conn->allow_auth3) {
1063 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1066 if (call->conn->auth_state.auth_finished) {
1067 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1070 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1072 call->pkt.u.auth3.auth_info.length,
1073 0, /* required flags */
1074 DCERPC_PFC_FLAG_FIRST |
1075 DCERPC_PFC_FLAG_LAST |
1076 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1077 0x08 | /* this is not defined, but should be ignored */
1078 DCERPC_PFC_FLAG_CONC_MPX |
1079 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1080 DCERPC_PFC_FLAG_MAYBE |
1081 DCERPC_PFC_FLAG_OBJECT_UUID);
1082 if (!NT_STATUS_IS_OK(status)) {
1083 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1086 /* handle the auth3 in the auth code */
1087 if (!dcesrv_auth_auth3(call)) {
1088 call->conn->auth_state.auth_invalid = true;
1089 if (call->fault_code != 0) {
1090 return dcesrv_fault_disconnect(call, call->fault_code);
1096 /* we don't send a reply to a auth3 request, except by a
1098 return NT_STATUS_OK;
1102 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1103 const struct dcerpc_bind *b,
1104 const struct dcerpc_ctx_list *ctx,
1105 struct dcerpc_ack_ctx *ack,
1107 const struct ndr_syntax_id *supported_transfer)
1109 uint32_t if_version;
1110 struct dcesrv_connection_context *context;
1111 const struct dcesrv_interface *iface;
1114 const struct ndr_syntax_id *selected_transfer = NULL;
1119 return NT_STATUS_INTERNAL_ERROR;
1122 return NT_STATUS_INTERNAL_ERROR;
1124 if (ctx->num_transfer_syntaxes < 1) {
1125 return NT_STATUS_INTERNAL_ERROR;
1128 return NT_STATUS_INTERNAL_ERROR;
1130 if (supported_transfer == NULL) {
1131 return NT_STATUS_INTERNAL_ERROR;
1134 switch (ack->result) {
1135 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1136 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1138 * We is already completed.
1140 return NT_STATUS_OK;
1145 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1146 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1148 if_version = ctx->abstract_syntax.if_version;
1149 uuid = ctx->abstract_syntax.uuid;
1151 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1152 if (iface == NULL) {
1153 char *uuid_str = GUID_string(call, &uuid);
1154 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1155 talloc_free(uuid_str);
1157 * We report this only via ack->result
1159 return NT_STATUS_OK;
1162 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1163 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1165 if (validate_only) {
1167 * We report this only via ack->result
1169 return NT_STATUS_OK;
1172 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1174 * we only do NDR encoded dcerpc for now.
1176 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1177 supported_transfer);
1179 selected_transfer = supported_transfer;
1184 context = dcesrv_find_context(call->conn, ctx->context_id);
1185 if (context != NULL) {
1186 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1187 &ctx->abstract_syntax);
1189 return NT_STATUS_RPC_PROTOCOL_ERROR;
1192 if (selected_transfer != NULL) {
1193 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1196 return NT_STATUS_RPC_PROTOCOL_ERROR;
1199 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1200 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1201 ack->syntax = context->transfer_syntax;
1205 * We report this only via ack->result
1207 return NT_STATUS_OK;
1210 if (selected_transfer == NULL) {
1212 * We report this only via ack->result
1214 return NT_STATUS_OK;
1217 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1218 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1220 /* add this context to the list of available context_ids */
1221 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1222 if (context == NULL) {
1223 return NT_STATUS_NO_MEMORY;
1225 context->conn = call->conn;
1226 context->context_id = ctx->context_id;
1227 context->iface = iface;
1228 context->transfer_syntax = *selected_transfer;
1229 context->private_data = NULL;
1230 DLIST_ADD(call->conn->contexts, context);
1231 call->context = context;
1232 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1234 dcesrv_prepare_context_auth(call);
1237 * Multiplex is supported by default
1239 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1241 status = iface->bind(call, iface, if_version);
1242 call->context = NULL;
1243 if (!NT_STATUS_IS_OK(status)) {
1244 /* we don't want to trigger the iface->unbind() hook */
1245 context->iface = NULL;
1246 talloc_free(context);
1248 * We report this only via ack->result
1250 return NT_STATUS_OK;
1253 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1254 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1255 ack->syntax = context->transfer_syntax;
1256 return NT_STATUS_OK;
1259 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1260 const struct dcerpc_bind *b,
1261 struct dcerpc_ack_ctx *ack_ctx_list)
1265 bool validate_only = false;
1266 bool preferred_ndr32;
1269 * Try to negotiate one new presentation context,
1270 * using our preferred transfer syntax.
1272 for (i = 0; i < b->num_contexts; i++) {
1273 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1274 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1276 status = dcesrv_check_or_create_context(call, b, c, a,
1278 call->conn->preferred_transfer);
1279 if (!NT_STATUS_IS_OK(status)) {
1283 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1285 * We managed to negotiate one context.
1289 validate_only = true;
1293 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1294 call->conn->preferred_transfer);
1295 if (preferred_ndr32) {
1299 return NT_STATUS_OK;
1303 * Try to negotiate one new presentation context,
1304 * using NDR 32 as fallback.
1306 for (i = 0; i < b->num_contexts; i++) {
1307 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1308 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1310 status = dcesrv_check_or_create_context(call, b, c, a,
1312 &ndr_transfer_syntax_ndr);
1313 if (!NT_STATUS_IS_OK(status)) {
1317 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1319 * We managed to negotiate one context.
1323 validate_only = true;
1327 return NT_STATUS_OK;
1331 handle a alter context request
1333 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1336 bool auth_ok = false;
1337 struct ncacn_packet pkt;
1338 uint32_t extra_flags = 0;
1339 struct data_blob_list_item *rep = NULL;
1340 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1343 if (!call->conn->allow_alter) {
1344 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1347 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1349 call->pkt.u.alter.auth_info.length,
1350 0, /* required flags */
1351 DCERPC_PFC_FLAG_FIRST |
1352 DCERPC_PFC_FLAG_LAST |
1353 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1354 0x08 | /* this is not defined, but should be ignored */
1355 DCERPC_PFC_FLAG_CONC_MPX |
1356 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1357 DCERPC_PFC_FLAG_MAYBE |
1358 DCERPC_PFC_FLAG_OBJECT_UUID);
1359 if (!NT_STATUS_IS_OK(status)) {
1360 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1363 auth_ok = dcesrv_auth_alter(call);
1365 if (call->fault_code != 0) {
1366 return dcesrv_fault_disconnect(call, call->fault_code);
1370 if (call->pkt.u.alter.num_contexts < 1) {
1371 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1374 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1375 call->pkt.u.alter.num_contexts);
1376 if (ack_ctx_list == NULL) {
1377 return NT_STATUS_NO_MEMORY;
1381 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1382 * dcesrv_check_or_create_context()) and do some protocol validation
1383 * and set sane defaults.
1385 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1386 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1387 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1389 if (c->num_transfer_syntaxes == 0) {
1390 return dcesrv_fault_disconnect(call,
1391 DCERPC_NCA_S_PROTO_ERROR);
1394 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1395 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1399 * Try to negotiate one new presentation context.
1401 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1402 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1403 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1405 if (!NT_STATUS_IS_OK(status)) {
1409 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1410 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1411 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1412 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1415 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1416 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1419 /* handle any authentication that is being requested */
1421 if (call->in_auth_info.auth_type !=
1422 call->conn->auth_state.auth_type)
1424 return dcesrv_fault_disconnect(call,
1425 DCERPC_FAULT_SEC_PKG_ERROR);
1427 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1430 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1431 pkt.auth_length = 0;
1432 pkt.call_id = call->pkt.call_id;
1433 pkt.ptype = DCERPC_PKT_ALTER_RESP;
1434 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1435 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1436 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1437 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1438 pkt.u.alter_resp.secondary_address = "";
1439 pkt.u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1440 pkt.u.alter_resp.ctx_list = ack_ctx_list;
1441 pkt.u.alter_resp.auth_info = data_blob_null;
1443 status = dcesrv_auth_alter_ack(call, &pkt);
1444 if (!NT_STATUS_IS_OK(status)) {
1445 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1448 rep = talloc_zero(call, struct data_blob_list_item);
1450 return NT_STATUS_NO_MEMORY;
1453 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info);
1454 if (!NT_STATUS_IS_OK(status)) {
1458 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1460 DLIST_ADD_END(call->replies, rep);
1461 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1463 if (call->conn->call_list && call->conn->call_list->replies) {
1464 if (call->conn->transport.report_output_data) {
1465 call->conn->transport.report_output_data(call->conn);
1469 return NT_STATUS_OK;
1473 possibly save the call for inspection with ndrdump
1475 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1479 const char *dump_dir;
1480 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1484 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1486 call->context->iface->name,
1487 call->pkt.u.request.opnum,
1489 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1490 DEBUG(0,("RPC SAVED %s\n", fname));
1496 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1498 TALLOC_CTX *frame = talloc_stackframe();
1499 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ?
1500 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1501 const struct dcerpc_sec_vt_pcontext pcontext = {
1502 .abstract_syntax = call->context->iface->syntax_id,
1503 .transfer_syntax = call->context->transfer_syntax,
1505 const struct dcerpc_sec_vt_header2 header2 =
1506 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1507 enum ndr_err_code ndr_err;
1508 struct dcerpc_sec_verification_trailer *vt = NULL;
1509 NTSTATUS status = NT_STATUS_OK;
1512 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1514 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1516 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1517 status = ndr_map_error2ntstatus(ndr_err);
1521 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1522 &pcontext, &header2);
1524 status = NT_STATUS_ACCESS_DENIED;
1533 handle a dcerpc request packet
1535 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1537 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1538 enum dcerpc_transport_t transport =
1539 dcerpc_binding_get_transport(endpoint->ep_description);
1540 struct ndr_pull *pull;
1543 if (!call->conn->allow_request) {
1544 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1547 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1548 if (call->conn->auth_state.gensec_security &&
1549 !gensec_have_feature(call->conn->auth_state.gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1550 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1553 if (call->context == NULL) {
1554 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1555 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1558 switch (call->conn->auth_state.auth_level) {
1559 case DCERPC_AUTH_LEVEL_NONE:
1560 case DCERPC_AUTH_LEVEL_PACKET:
1561 case DCERPC_AUTH_LEVEL_INTEGRITY:
1562 case DCERPC_AUTH_LEVEL_PRIVACY:
1565 if (!call->context->allow_connect) {
1568 addr = tsocket_address_string(call->conn->remote_address,
1571 DEBUG(2, ("%s: restrict auth_level_connect access "
1572 "to [%s] with auth[type=0x%x,level=0x%x] "
1573 "on [%s] from [%s]\n",
1574 __func__, call->context->iface->name,
1575 call->conn->auth_state.auth_type,
1576 call->conn->auth_state.auth_level,
1577 derpc_transport_string_by_transport(transport),
1579 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1584 if (call->conn->auth_state.auth_level < call->context->min_auth_level) {
1587 addr = tsocket_address_string(call->conn->remote_address, call);
1589 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1590 "to [%s] with auth[type=0x%x,level=0x%x] "
1591 "on [%s] from [%s]\n",
1593 call->context->min_auth_level,
1594 call->context->iface->name,
1595 call->conn->auth_state.auth_type,
1596 call->conn->auth_state.auth_level,
1597 derpc_transport_string_by_transport(transport),
1599 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1602 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1603 NT_STATUS_HAVE_NO_MEMORY(pull);
1605 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1607 call->ndr_pull = pull;
1609 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1610 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1613 status = dcesrv_check_verification_trailer(call);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 uint32_t faultcode = DCERPC_FAULT_OTHER;
1616 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1617 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1619 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1620 nt_errstr(status)));
1621 return dcesrv_fault(call, faultcode);
1624 /* unravel the NDR for the packet */
1625 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1626 if (!NT_STATUS_IS_OK(status)) {
1627 uint8_t extra_flags = 0;
1628 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1629 /* we got an unknown call */
1630 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1631 call->pkt.u.request.opnum,
1632 call->context->iface->name));
1633 dcesrv_save_call(call, "unknown");
1634 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1636 dcesrv_save_call(call, "pullfail");
1638 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1641 if (pull->offset != pull->data_size) {
1642 dcesrv_save_call(call, "extrabytes");
1643 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1644 pull->data_size - pull->offset));
1647 /* call the dispatch function */
1648 status = call->context->iface->dispatch(call, call, call->r);
1649 if (!NT_STATUS_IS_OK(status)) {
1650 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1651 call->context->iface->name,
1652 call->pkt.u.request.opnum,
1653 dcerpc_errstr(pull, call->fault_code)));
1654 return dcesrv_fault(call, call->fault_code);
1657 /* add the call to the pending list */
1658 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1660 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1661 return NT_STATUS_OK;
1664 return dcesrv_reply(call);
1669 remove the call from the right list when freed
1671 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1673 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1677 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1679 return conn->local_address;
1682 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1684 return conn->remote_address;
1688 process some input to a dcerpc endpoint server.
1690 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1691 struct ncacn_packet *pkt,
1695 struct dcesrv_call_state *call;
1696 struct dcesrv_call_state *existing = NULL;
1698 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1700 data_blob_free(&blob);
1702 return NT_STATUS_NO_MEMORY;
1704 call->conn = dce_conn;
1705 call->event_ctx = dce_conn->event_ctx;
1706 call->msg_ctx = dce_conn->msg_ctx;
1707 call->state_flags = call->conn->state_flags;
1708 call->time = timeval_current();
1709 call->list = DCESRV_LIST_NONE;
1711 talloc_steal(call, pkt);
1712 talloc_steal(call, blob.data);
1715 talloc_set_destructor(call, dcesrv_call_dequeue);
1717 if (call->conn->allow_bind) {
1719 * Only one bind is possible per connection
1721 call->conn->allow_bind = false;
1722 return dcesrv_bind(call);
1725 /* we have to check the signing here, before combining the
1727 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1728 if (!call->conn->allow_request) {
1729 return dcesrv_fault_disconnect(call,
1730 DCERPC_NCA_S_PROTO_ERROR);
1733 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1735 call->pkt.u.request.stub_and_verifier.length,
1736 0, /* required_flags */
1737 DCERPC_PFC_FLAG_FIRST |
1738 DCERPC_PFC_FLAG_LAST |
1739 DCERPC_PFC_FLAG_PENDING_CANCEL |
1740 0x08 | /* this is not defined, but should be ignored */
1741 DCERPC_PFC_FLAG_CONC_MPX |
1742 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1743 DCERPC_PFC_FLAG_MAYBE |
1744 DCERPC_PFC_FLAG_OBJECT_UUID);
1745 if (!NT_STATUS_IS_OK(status)) {
1746 return dcesrv_fault_disconnect(call,
1747 DCERPC_NCA_S_PROTO_ERROR);
1750 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
1752 * We don't use dcesrv_fault_disconnect()
1753 * here, because we don't want to set
1754 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1756 * Note that we don't check against the negotiated
1757 * max_recv_frag, but a hard coded value.
1759 dcesrv_call_disconnect_after(call,
1760 "dcesrv_auth_request - frag_length too large");
1761 return dcesrv_fault(call,
1762 DCERPC_NCA_S_PROTO_ERROR);
1765 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
1766 if (dce_conn->pending_call_list != NULL) {
1768 * concurrent requests are only allowed
1769 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
1771 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1772 dcesrv_call_disconnect_after(call,
1773 "dcesrv_auth_request - "
1774 "existing pending call without CONN_MPX");
1775 return dcesrv_fault(call,
1776 DCERPC_NCA_S_PROTO_ERROR);
1779 /* only one request is possible in the fragmented list */
1780 if (dce_conn->incoming_fragmented_call_list != NULL) {
1781 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1783 * Without DCERPC_PFC_FLAG_CONC_MPX
1784 * we need to return the FAULT on the
1785 * already existing call.
1787 * This is important to get the
1788 * call_id and context_id right.
1791 call = dce_conn->incoming_fragmented_call_list;
1793 dcesrv_call_disconnect_after(call,
1794 "dcesrv_auth_request - "
1795 "existing fragmented call");
1796 return dcesrv_fault(call,
1797 DCERPC_NCA_S_PROTO_ERROR);
1799 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
1800 return dcesrv_fault_disconnect(call,
1801 DCERPC_FAULT_NO_CALL_ACTIVE);
1803 call->context = dcesrv_find_context(call->conn,
1804 call->pkt.u.request.context_id);
1805 if (call->context == NULL) {
1806 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1807 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1810 const struct dcerpc_request *nr = &call->pkt.u.request;
1811 const struct dcerpc_request *er = NULL;
1814 existing = dcesrv_find_fragmented_call(dce_conn,
1816 if (existing == NULL) {
1817 dcesrv_call_disconnect_after(call,
1818 "dcesrv_auth_request - "
1819 "no existing fragmented call");
1820 return dcesrv_fault(call,
1821 DCERPC_NCA_S_PROTO_ERROR);
1823 er = &existing->pkt.u.request;
1825 if (call->pkt.ptype != existing->pkt.ptype) {
1826 /* trying to play silly buggers are we? */
1827 return dcesrv_fault_disconnect(existing,
1828 DCERPC_NCA_S_PROTO_ERROR);
1830 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
1833 return dcesrv_fault_disconnect(existing,
1834 DCERPC_NCA_S_PROTO_ERROR);
1836 if (nr->context_id != er->context_id) {
1837 return dcesrv_fault_disconnect(existing,
1838 DCERPC_NCA_S_PROTO_ERROR);
1840 if (nr->opnum != er->opnum) {
1841 return dcesrv_fault_disconnect(existing,
1842 DCERPC_NCA_S_PROTO_ERROR);
1847 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1849 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
1851 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
1852 payload_offset += 16;
1855 ok = dcesrv_auth_pkt_pull(call, &blob,
1856 0, /* required_flags */
1857 DCERPC_PFC_FLAG_FIRST |
1858 DCERPC_PFC_FLAG_LAST |
1859 DCERPC_PFC_FLAG_PENDING_CANCEL |
1860 0x08 | /* this is not defined, but should be ignored */
1861 DCERPC_PFC_FLAG_CONC_MPX |
1862 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1863 DCERPC_PFC_FLAG_MAYBE |
1864 DCERPC_PFC_FLAG_OBJECT_UUID,
1866 &call->pkt.u.request.stub_and_verifier);
1869 * We don't use dcesrv_fault_disconnect()
1870 * here, because we don't want to set
1871 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
1873 dcesrv_call_disconnect_after(call,
1874 "dcesrv_auth_request - failed");
1875 if (call->fault_code == 0) {
1876 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
1878 return dcesrv_fault(call, call->fault_code);
1882 /* see if this is a continued packet */
1883 if (existing != NULL) {
1884 struct dcerpc_request *er = &existing->pkt.u.request;
1885 const struct dcerpc_request *nr = &call->pkt.u.request;
1891 * Up to 4 MByte are allowed by all fragments
1893 available = dce_conn->max_total_request_size;
1894 if (er->stub_and_verifier.length > available) {
1895 dcesrv_call_disconnect_after(existing,
1896 "dcesrv_auth_request - existing payload too large");
1897 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1899 available -= er->stub_and_verifier.length;
1900 if (nr->alloc_hint > available) {
1901 dcesrv_call_disconnect_after(existing,
1902 "dcesrv_auth_request - alloc hint too large");
1903 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1905 if (nr->stub_and_verifier.length > available) {
1906 dcesrv_call_disconnect_after(existing,
1907 "dcesrv_auth_request - new payload too large");
1908 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
1910 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
1911 /* allocate at least 1 byte */
1912 alloc_hint = MAX(alloc_hint, 1);
1913 alloc_size = er->stub_and_verifier.length +
1914 nr->stub_and_verifier.length;
1915 alloc_size = MAX(alloc_size, alloc_hint);
1917 er->stub_and_verifier.data =
1918 talloc_realloc(existing,
1919 er->stub_and_verifier.data,
1920 uint8_t, alloc_size);
1921 if (er->stub_and_verifier.data == NULL) {
1923 return dcesrv_fault_with_flags(existing,
1924 DCERPC_FAULT_OUT_OF_RESOURCES,
1925 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1927 memcpy(er->stub_and_verifier.data +
1928 er->stub_and_verifier.length,
1929 nr->stub_and_verifier.data,
1930 nr->stub_and_verifier.length);
1931 er->stub_and_verifier.length += nr->stub_and_verifier.length;
1933 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
1939 /* this may not be the last pdu in the chain - if its isn't then
1940 just put it on the incoming_fragmented_call_list and wait for the rest */
1941 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1942 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
1944 * Up to 4 MByte are allowed by all fragments
1946 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
1947 dcesrv_call_disconnect_after(call,
1948 "dcesrv_auth_request - initial alloc hint too large");
1949 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1951 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
1952 return NT_STATUS_OK;
1955 /* This removes any fragments we may have had stashed away */
1956 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1958 switch (call->pkt.ptype) {
1959 case DCERPC_PKT_BIND:
1960 status = dcesrv_bind_nak(call,
1961 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
1963 case DCERPC_PKT_AUTH3:
1964 status = dcesrv_auth3(call);
1966 case DCERPC_PKT_ALTER:
1967 status = dcesrv_alter(call);
1969 case DCERPC_PKT_REQUEST:
1970 status = dcesrv_request(call);
1972 case DCERPC_PKT_CO_CANCEL:
1973 case DCERPC_PKT_ORPHANED:
1975 * Window just ignores CO_CANCEL and ORPHANED,
1978 status = NT_STATUS_OK;
1981 case DCERPC_PKT_BIND_ACK:
1982 case DCERPC_PKT_BIND_NAK:
1983 case DCERPC_PKT_ALTER_RESP:
1984 case DCERPC_PKT_RESPONSE:
1985 case DCERPC_PKT_FAULT:
1986 case DCERPC_PKT_SHUTDOWN:
1988 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1992 /* if we are going to be sending a reply then add
1993 it to the list of pending calls. We add it to the end to keep the call
1994 list in the order we will answer */
1995 if (!NT_STATUS_IS_OK(status)) {
2002 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2003 struct loadparm_context *lp_ctx,
2004 const char **endpoint_servers, struct dcesrv_context **_dce_ctx)
2007 struct dcesrv_context *dce_ctx;
2010 if (!endpoint_servers) {
2011 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2012 return NT_STATUS_INTERNAL_ERROR;
2015 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2016 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2018 if (uid_wrapper_enabled()) {
2019 setenv("UID_WRAPPER_MYUID", "1", 1);
2021 dce_ctx->initial_euid = geteuid();
2022 if (uid_wrapper_enabled()) {
2023 unsetenv("UID_WRAPPER_MYUID");
2026 dce_ctx->endpoint_list = NULL;
2027 dce_ctx->lp_ctx = lp_ctx;
2028 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2029 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2030 dce_ctx->broken_connections = NULL;
2032 for (i=0;endpoint_servers[i];i++) {
2033 const struct dcesrv_endpoint_server *ep_server;
2035 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2037 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2038 return NT_STATUS_INTERNAL_ERROR;
2041 status = ep_server->init_server(dce_ctx, ep_server);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2044 nt_errstr(status)));
2049 *_dce_ctx = dce_ctx;
2050 return NT_STATUS_OK;
2053 /* the list of currently registered DCERPC endpoint servers.
2055 static struct ep_server {
2056 struct dcesrv_endpoint_server *ep_server;
2057 } *ep_servers = NULL;
2058 static int num_ep_servers;
2061 register a DCERPC endpoint server.
2063 The 'name' can be later used by other backends to find the operations
2064 structure for this backend.
2067 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2070 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2071 /* its already registered! */
2072 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2074 return NT_STATUS_OBJECT_NAME_COLLISION;
2077 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2079 smb_panic("out of memory in dcerpc_register");
2082 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2083 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2087 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2090 return NT_STATUS_OK;
2094 return the operations structure for a named backend of the specified type
2096 const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2100 for (i=0;i<num_ep_servers;i++) {
2101 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2102 return ep_servers[i].ep_server;
2109 void dcerpc_server_init(struct loadparm_context *lp_ctx)
2111 static bool initialized;
2112 #define _MODULE_PROTO(init) extern NTSTATUS init(void);
2113 STATIC_dcerpc_server_MODULES_PROTO;
2114 init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES };
2115 init_module_fn *shared_init;
2122 shared_init = load_samba_modules(NULL, "dcerpc_server");
2124 run_init_functions(static_init);
2125 run_init_functions(shared_init);
2127 talloc_free(shared_init);
2131 return the DCERPC module version, and the size of some critical types
2132 This can be used by endpoint server modules to either detect compilation errors, or provide
2133 multiple implementations for different smbd compilation options in one module
2135 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2137 static const struct dcesrv_critical_sizes critical_sizes = {
2138 DCERPC_MODULE_VERSION,
2139 sizeof(struct dcesrv_context),
2140 sizeof(struct dcesrv_endpoint),
2141 sizeof(struct dcesrv_endpoint_server),
2142 sizeof(struct dcesrv_interface),
2143 sizeof(struct dcesrv_if_list),
2144 sizeof(struct dcesrv_connection),
2145 sizeof(struct dcesrv_call_state),
2146 sizeof(struct dcesrv_auth),
2147 sizeof(struct dcesrv_handle)
2150 return &critical_sizes;
2153 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2155 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2156 struct stream_connection *srv_conn;
2157 srv_conn = talloc_get_type(dce_conn->transport.private_data,
2158 struct stream_connection);
2160 dce_conn->allow_bind = false;
2161 dce_conn->allow_auth3 = false;
2162 dce_conn->allow_alter = false;
2163 dce_conn->allow_request = false;
2165 if (dce_conn->pending_call_list == NULL) {
2166 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2168 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2169 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason);
2173 if (dce_conn->terminate != NULL) {
2177 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n",
2179 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2180 if (dce_conn->terminate == NULL) {
2181 dce_conn->terminate = "dcesrv: defered terminating connection - no memory";
2183 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2186 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2188 struct dcesrv_connection *cur, *next;
2190 next = dce_ctx->broken_connections;
2191 while (next != NULL) {
2195 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2196 struct dcesrv_connection_context *context_cur, *context_next;
2198 context_next = cur->contexts;
2199 while (context_next != NULL) {
2200 context_cur = context_next;
2201 context_next = context_cur->next;
2203 dcesrv_connection_context_destructor(context_cur);
2207 dcesrv_terminate_connection(cur, cur->terminate);
2211 /* We need this include to be able to compile on some plateforms
2212 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2214 * It has to be that deep because otherwise we have a conflict on
2215 * const struct dcesrv_interface declaration.
2216 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2217 * which conflict with the bind used before.
2219 #include "system/network.h"
2221 struct dcesrv_sock_reply_state {
2222 struct dcesrv_connection *dce_conn;
2223 struct dcesrv_call_state *call;
2227 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2228 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2230 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2232 struct dcesrv_call_state *call;
2234 call = dce_conn->call_list;
2235 if (!call || !call->replies) {
2239 while (call->replies) {
2240 struct data_blob_list_item *rep = call->replies;
2241 struct dcesrv_sock_reply_state *substate;
2242 struct tevent_req *subreq;
2244 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2246 dcesrv_terminate_connection(dce_conn, "no memory");
2250 substate->dce_conn = dce_conn;
2251 substate->call = NULL;
2253 DLIST_REMOVE(call->replies, rep);
2255 if (call->replies == NULL && call->terminate_reason == NULL) {
2256 substate->call = call;
2259 substate->iov.iov_base = (void *) rep->blob.data;
2260 substate->iov.iov_len = rep->blob.length;
2262 subreq = tstream_writev_queue_send(substate,
2263 dce_conn->event_ctx,
2265 dce_conn->send_queue,
2268 dcesrv_terminate_connection(dce_conn, "no memory");
2271 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2275 if (call->terminate_reason != NULL) {
2276 struct tevent_req *subreq;
2278 subreq = tevent_queue_wait_send(call,
2279 dce_conn->event_ctx,
2280 dce_conn->send_queue);
2282 dcesrv_terminate_connection(dce_conn, __location__);
2285 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2289 DLIST_REMOVE(call->conn->call_list, call);
2290 call->list = DCESRV_LIST_NONE;
2293 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2295 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2296 struct dcesrv_sock_reply_state);
2300 struct dcesrv_call_state *call = substate->call;
2302 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2303 TALLOC_FREE(subreq);
2305 status = map_nt_error_from_unix_common(sys_errno);
2306 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2310 talloc_free(substate);
2316 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2318 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2320 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2321 struct dcesrv_call_state);
2325 /* make sure we stop send queue before removing subreq */
2326 tevent_queue_stop(call->conn->send_queue);
2328 ok = tevent_queue_wait_recv(subreq);
2329 TALLOC_FREE(subreq);
2331 dcesrv_terminate_connection(call->conn, __location__);
2335 /* disconnect after 200 usecs */
2336 tv = timeval_current_ofs_usec(200);
2337 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2338 if (subreq == NULL) {
2339 dcesrv_terminate_connection(call->conn, __location__);
2342 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2346 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2348 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2349 struct dcesrv_call_state);
2352 ok = tevent_wakeup_recv(subreq);
2353 TALLOC_FREE(subreq);
2355 dcesrv_terminate_connection(call->conn, __location__);
2359 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2362 struct dcesrv_socket_context {
2363 const struct dcesrv_endpoint *endpoint;
2364 struct dcesrv_context *dcesrv_ctx;
2368 static void dcesrv_read_fragment_done(struct tevent_req *subreq);
2370 static void dcesrv_sock_accept(struct stream_connection *srv_conn)
2373 struct dcesrv_socket_context *dcesrv_sock =
2374 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context);
2375 enum dcerpc_transport_t transport =
2376 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description);
2377 struct dcesrv_connection *dcesrv_conn = NULL;
2379 struct tevent_req *subreq;
2380 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
2382 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
2384 if (!srv_conn->session_info) {
2385 status = auth_anonymous_session_info(srv_conn,
2387 &srv_conn->session_info);
2388 if (!NT_STATUS_IS_OK(status)) {
2389 DEBUG(0,("dcesrv_sock_accept: auth_anonymous_session_info failed: %s\n",
2390 nt_errstr(status)));
2391 stream_terminate_connection(srv_conn, nt_errstr(status));
2397 * This fills in dcesrv_conn->endpoint with the endpoint
2398 * associated with the socket. From this point on we know
2399 * which (group of) services we are handling, but not the
2400 * specific interface.
2403 status = dcesrv_endpoint_connect(dcesrv_sock->dcesrv_ctx,
2405 dcesrv_sock->endpoint,
2406 srv_conn->session_info,
2407 srv_conn->event.ctx,
2409 srv_conn->server_id,
2410 DCESRV_CALL_STATE_FLAG_MAY_ASYNC,
2412 if (!NT_STATUS_IS_OK(status)) {
2413 DEBUG(0,("dcesrv_sock_accept: dcesrv_endpoint_connect failed: %s\n",
2414 nt_errstr(status)));
2415 stream_terminate_connection(srv_conn, nt_errstr(status));
2419 dcesrv_conn->transport.private_data = srv_conn;
2420 dcesrv_conn->transport.report_output_data = dcesrv_sock_report_output_data;
2422 TALLOC_FREE(srv_conn->event.fde);
2424 dcesrv_conn->send_queue = tevent_queue_create(dcesrv_conn, "dcesrv send queue");
2425 if (!dcesrv_conn->send_queue) {
2426 status = NT_STATUS_NO_MEMORY;
2427 DEBUG(0,("dcesrv_sock_accept: tevent_queue_create(%s)\n",
2428 nt_errstr(status)));
2429 stream_terminate_connection(srv_conn, nt_errstr(status));
2433 if (transport == NCACN_NP) {
2434 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
2435 dcesrv_conn->stream = talloc_move(dcesrv_conn,
2436 &srv_conn->tstream);
2438 ret = tstream_bsd_existing_socket(dcesrv_conn,
2439 socket_get_fd(srv_conn->socket),
2440 &dcesrv_conn->stream);
2442 status = map_nt_error_from_unix_common(errno);
2443 DEBUG(0, ("dcesrv_sock_accept: "
2444 "failed to setup tstream: %s\n",
2445 nt_errstr(status)));
2446 stream_terminate_connection(srv_conn, nt_errstr(status));
2449 socket_set_flags(srv_conn->socket, SOCKET_FLAG_NOCLOSE);
2452 dcesrv_conn->local_address = srv_conn->local_address;
2453 dcesrv_conn->remote_address = srv_conn->remote_address;
2455 if (transport == NCALRPC) {
2460 sock_fd = socket_get_fd(srv_conn->socket);
2461 if (sock_fd == -1) {
2462 stream_terminate_connection(
2463 srv_conn, "socket_get_fd failed\n");
2467 ret = getpeereid(sock_fd, &uid, &gid);
2469 status = map_nt_error_from_unix_common(errno);
2470 DEBUG(0, ("dcesrv_sock_accept: "
2471 "getpeereid() failed for NCALRPC: %s\n",
2472 nt_errstr(status)));
2473 stream_terminate_connection(srv_conn, nt_errstr(status));
2476 if (uid == dcesrv_conn->dce_ctx->initial_euid) {
2477 struct tsocket_address *r = NULL;
2479 ret = tsocket_address_unix_from_path(dcesrv_conn,
2480 "/root/ncalrpc_as_system",
2483 status = map_nt_error_from_unix_common(errno);
2484 DEBUG(0, ("dcesrv_sock_accept: "
2485 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n",
2486 nt_errstr(status)));
2487 stream_terminate_connection(srv_conn, nt_errstr(status));
2490 dcesrv_conn->remote_address = r;
2494 srv_conn->private_data = dcesrv_conn;
2496 irpc_add_name(srv_conn->msg_ctx, "rpc_server");
2498 subreq = dcerpc_read_ncacn_packet_send(dcesrv_conn,
2499 dcesrv_conn->event_ctx,
2500 dcesrv_conn->stream);
2502 status = NT_STATUS_NO_MEMORY;
2503 DEBUG(0,("dcesrv_sock_accept: dcerpc_read_fragment_buffer_send(%s)\n",
2504 nt_errstr(status)));
2505 stream_terminate_connection(srv_conn, nt_errstr(status));
2508 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dcesrv_conn);
2513 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2515 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2516 struct dcesrv_connection);
2517 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2518 struct ncacn_packet *pkt;
2522 if (dce_conn->terminate) {
2524 * if the current connection is broken
2525 * we need to clean it up before any other connection
2527 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2528 dcesrv_cleanup_broken_connections(dce_ctx);
2532 dcesrv_cleanup_broken_connections(dce_ctx);
2534 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2536 TALLOC_FREE(subreq);
2537 if (!NT_STATUS_IS_OK(status)) {
2538 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2542 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2543 if (!NT_STATUS_IS_OK(status)) {
2544 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2548 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2549 dce_conn->event_ctx,
2552 status = NT_STATUS_NO_MEMORY;
2553 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2556 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2559 static void dcesrv_sock_recv(struct stream_connection *conn, uint16_t flags)
2561 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2562 struct dcesrv_connection);
2563 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_recv triggered");
2566 static void dcesrv_sock_send(struct stream_connection *conn, uint16_t flags)
2568 struct dcesrv_connection *dce_conn = talloc_get_type(conn->private_data,
2569 struct dcesrv_connection);
2570 dcesrv_terminate_connection(dce_conn, "dcesrv_sock_send triggered");
2574 static const struct stream_server_ops dcesrv_stream_ops = {
2576 .accept_connection = dcesrv_sock_accept,
2577 .recv_handler = dcesrv_sock_recv,
2578 .send_handler = dcesrv_sock_send,
2581 static NTSTATUS dcesrv_add_ep_unix(struct dcesrv_context *dce_ctx,
2582 struct loadparm_context *lp_ctx,
2583 struct dcesrv_endpoint *e,
2584 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2586 struct dcesrv_socket_context *dcesrv_sock;
2589 const char *endpoint;
2591 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2592 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2594 /* remember the endpoint of this socket */
2595 dcesrv_sock->endpoint = e;
2596 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2598 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2600 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2601 model_ops, &dcesrv_stream_ops,
2602 "unix", endpoint, &port,
2603 lpcfg_socket_options(lp_ctx),
2605 if (!NT_STATUS_IS_OK(status)) {
2606 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
2607 endpoint, nt_errstr(status)));
2613 static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
2614 struct loadparm_context *lp_ctx,
2615 struct dcesrv_endpoint *e,
2616 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2618 struct dcesrv_socket_context *dcesrv_sock;
2622 const char *endpoint;
2624 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2626 if (endpoint == NULL) {
2628 * No identifier specified: use DEFAULT.
2630 * TODO: DO NOT hardcode this value anywhere else. Rather, specify
2631 * no endpoint and let the epmapper worry about it.
2633 endpoint = "DEFAULT";
2634 status = dcerpc_binding_set_string_option(e->ep_description,
2637 if (!NT_STATUS_IS_OK(status)) {
2638 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n",
2639 nt_errstr(status)));
2644 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx),
2647 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2648 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2650 /* remember the endpoint of this socket */
2651 dcesrv_sock->endpoint = e;
2652 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2654 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
2655 model_ops, &dcesrv_stream_ops,
2656 "unix", full_path, &port,
2657 lpcfg_socket_options(lp_ctx),
2659 if (!NT_STATUS_IS_OK(status)) {
2660 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
2661 endpoint, full_path, nt_errstr(status)));
2666 static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
2667 struct loadparm_context *lp_ctx,
2668 struct dcesrv_endpoint *e,
2669 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2671 struct dcesrv_socket_context *dcesrv_sock;
2673 const char *endpoint;
2675 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2676 if (endpoint == NULL) {
2677 DEBUG(0, ("Endpoint mandatory for named pipes\n"));
2678 return NT_STATUS_INVALID_PARAMETER;
2681 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2682 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2684 /* remember the endpoint of this socket */
2685 dcesrv_sock->endpoint = e;
2686 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2688 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
2689 model_ops, &dcesrv_stream_ops,
2692 if (!NT_STATUS_IS_OK(status)) {
2693 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
2694 endpoint, nt_errstr(status)));
2698 return NT_STATUS_OK;
2702 add a socket address to the list of events, one event per dcerpc endpoint
2704 static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
2705 struct tevent_context *event_ctx, const struct model_ops *model_ops,
2706 const char *address)
2708 struct dcesrv_socket_context *dcesrv_sock;
2711 const char *endpoint;
2714 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
2715 if (endpoint != NULL) {
2716 port = atoi(endpoint);
2719 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
2720 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
2722 /* remember the endpoint of this socket */
2723 dcesrv_sock->endpoint = e;
2724 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
2726 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
2727 model_ops, &dcesrv_stream_ops,
2728 "ip", address, &port,
2729 lpcfg_socket_options(dce_ctx->lp_ctx),
2731 if (!NT_STATUS_IS_OK(status)) {
2732 struct dcesrv_if_list *iface;
2733 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) for ",
2735 for (iface = e->interface_list; iface; iface = iface->next) {
2736 DEBUGADD(0, ("%s ", iface->iface.name));
2738 DEBUGADD(0, ("failed - %s",
2739 nt_errstr(status)));
2743 snprintf(port_str, sizeof(port_str), "%u", port);
2745 status = dcerpc_binding_set_string_option(e->ep_description,
2746 "endpoint", port_str);
2747 if (!NT_STATUS_IS_OK(status)) {
2748 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n",
2749 port_str, nt_errstr(status)));
2752 struct dcesrv_if_list *iface;
2753 DEBUG(4,("Successfully listening on ncacn_ip_tcp endpoint [%s]:[%s] for ",
2754 address, port_str));
2755 for (iface = e->interface_list; iface; iface = iface->next) {
2756 DEBUGADD(4, ("%s ", iface->iface.name));
2758 DEBUGADD(4, ("\n"));
2761 return NT_STATUS_OK;
2764 #include "lib/socket/netif.h" /* Included here to work around the fact that socket_wrapper redefines bind() */
2766 static NTSTATUS dcesrv_add_ep_tcp(struct dcesrv_context *dce_ctx,
2767 struct loadparm_context *lp_ctx,
2768 struct dcesrv_endpoint *e,
2769 struct tevent_context *event_ctx, const struct model_ops *model_ops)
2773 /* Add TCP/IP sockets */
2774 if (lpcfg_interfaces(lp_ctx) && lpcfg_bind_interfaces_only(lp_ctx)) {
2777 struct interface *ifaces;
2779 load_interface_list(dce_ctx, lp_ctx, &ifaces);
2781 num_interfaces = iface_list_count(ifaces);
2782 for(i = 0; i < num_interfaces; i++) {
2783 const char *address = iface_list_n_ip(ifaces, i);
2784 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
2785 NT_STATUS_NOT_OK_RETURN(status);
2791 wcard = iface_list_wildcard(dce_ctx);
2792 NT_STATUS_HAVE_NO_MEMORY(wcard);
2793 for (i=0; wcard[i]; i++) {
2794 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]);
2795 if (NT_STATUS_IS_OK(status)) {
2800 if (num_binds == 0) {
2801 return NT_STATUS_INVALID_PARAMETER_MIX;
2805 return NT_STATUS_OK;
2808 NTSTATUS dcesrv_add_ep(struct dcesrv_context *dce_ctx,
2809 struct loadparm_context *lp_ctx,
2810 struct dcesrv_endpoint *e,
2811 struct tevent_context *event_ctx,
2812 const struct model_ops *model_ops)
2814 enum dcerpc_transport_t transport =
2815 dcerpc_binding_get_transport(e->ep_description);
2817 switch (transport) {
2818 case NCACN_UNIX_STREAM:
2819 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2822 return dcesrv_add_ep_ncalrpc(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2825 return dcesrv_add_ep_tcp(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2828 return dcesrv_add_ep_np(dce_ctx, lp_ctx, e, event_ctx, model_ops);
2831 return NT_STATUS_NOT_SUPPORTED;
2837 * retrieve credentials from a dce_call
2839 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2841 return dce_call->conn->auth_state.session_info->credentials;
2845 * returns true if this is an authenticated call
2847 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2849 enum security_user_level level;
2850 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
2851 return level >= SECURITY_USER;
2855 * retrieve account_name for a dce_call
2857 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2859 return dce_call->context->conn->auth_state.session_info->info->account_name;