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
8 Copyright (C) Samuel Cabrero <scabrero@samba.org> 2019
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "librpc/rpc/dcesrv_core.h"
26 #include "librpc/rpc/dcesrv_core_proto.h"
27 #include "librpc/gen_ndr/auth.h"
28 #include "auth/gensec/gensec.h"
29 #include "lib/util/dlinklist.h"
30 #include "libcli/security/security.h"
31 #include "param/param.h"
32 #include "lib/tsocket/tsocket.h"
33 #include "librpc/gen_ndr/ndr_dcerpc.h"
34 #include "lib/util/tevent_ntstatus.h"
37 #define DBGC_CLASS DBGC_RPC_SRV
39 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
40 const struct dcerpc_bind *b,
41 struct dcerpc_ack_ctx *ack_ctx_list);
44 see if two endpoints match
46 static bool endpoints_match(const struct dcerpc_binding *ep1,
47 const struct dcerpc_binding *ep2)
49 enum dcerpc_transport_t t1;
50 enum dcerpc_transport_t t2;
54 t1 = dcerpc_binding_get_transport(ep1);
55 t2 = dcerpc_binding_get_transport(ep2);
57 e1 = dcerpc_binding_get_string_option(ep1, "endpoint");
58 e2 = dcerpc_binding_get_string_option(ep2, "endpoint");
68 if (strcasecmp(e1, e2) != 0) {
76 find an endpoint in the dcesrv_context
78 static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
79 const struct dcerpc_binding *ep_description)
81 struct dcesrv_endpoint *ep;
82 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
83 if (endpoints_match(ep->ep_description, ep_description)) {
91 find a registered context_id from a bind or alter_context
93 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
96 struct dcesrv_connection_context *c;
97 for (c=conn->contexts;c;c=c->next) {
98 if (c->context_id == context_id) return c;
104 see if a uuid and if_version match to an interface
106 static bool interface_match(const struct dcesrv_interface *if1,
107 const struct dcesrv_interface *if2)
109 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
110 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
114 find the interface operations on any endpoint with this binding
116 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
117 struct dcerpc_binding *binding,
118 const struct dcesrv_interface *iface)
120 struct dcesrv_endpoint *ep;
121 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
122 if (endpoints_match(ep->ep_description, binding)) {
123 struct dcesrv_if_list *ifl;
124 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
125 if (interface_match(&(ifl->iface), iface)) {
126 return &(ifl->iface);
135 see if a uuid and if_version match to an interface
137 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
138 const struct GUID *uuid, uint32_t if_version)
140 return (iface->syntax_id.if_version == if_version &&
141 GUID_equal(&iface->syntax_id.uuid, uuid));
145 find the interface operations on an endpoint by uuid
147 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
148 const struct GUID *uuid, uint32_t if_version)
150 struct dcesrv_if_list *ifl;
151 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
152 if (interface_match_by_uuid(&(ifl->iface), uuid, if_version)) {
153 return &(ifl->iface);
160 find the earlier parts of a fragmented call awaiting reassembily
162 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
164 struct dcesrv_call_state *c;
165 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
166 if (c->pkt.call_id == call_id) {
174 register an interface on an endpoint
176 An endpoint is one unix domain socket (for ncalrpc), one TCP port
177 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
179 Each endpoint can have many interfaces such as netlogon, lsa or
180 samr. Some have essentially the full set.
182 This is driven from the set of interfaces listed in each IDL file
183 via the PIDL generated *__op_init_server() functions.
185 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
187 const char *ncacn_np_secondary_endpoint,
188 const struct dcesrv_interface *iface,
189 const struct security_descriptor *sd)
191 struct dcesrv_endpoint *ep;
192 struct dcesrv_if_list *ifl;
193 struct dcerpc_binding *binding;
194 struct dcerpc_binding *binding2 = NULL;
197 enum dcerpc_transport_t transport;
198 char *ep_string = NULL;
199 bool use_single_process = true;
200 const char *ep_process_string;
203 * If we are not using handles, there is no need for force
204 * this service into using a single process.
206 * However, due to the way we listen for RPC packets, we can
207 * only do this if we have a single service per pipe or TCP
208 * port, so we still force a single combined process for
211 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
212 use_single_process = false;
215 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
217 if (NT_STATUS_IS_ERR(status)) {
218 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
222 transport = dcerpc_binding_get_transport(binding);
223 if (transport == NCACN_IP_TCP) {
228 * First check if there is already a port specified, eg
229 * for epmapper on ncacn_ip_tcp:[135]
232 = dcerpc_binding_get_string_option(binding,
234 if (endpoint == NULL) {
235 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
236 "rpc server port", iface->name, 0);
239 * For RPC services that are not set to use a single
240 * process, we do not default to using the 'rpc server
241 * port' because that would cause a double-bind on
244 if (port == 0 && !use_single_process) {
245 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
248 snprintf(port_str, sizeof(port_str), "%u", port);
249 status = dcerpc_binding_set_string_option(binding,
252 if (!NT_STATUS_IS_OK(status)) {
259 if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) {
260 enum dcerpc_transport_t transport2;
262 status = dcerpc_parse_binding(dce_ctx,
263 ncacn_np_secondary_endpoint,
265 if (!NT_STATUS_IS_OK(status)) {
266 DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n",
267 ncacn_np_secondary_endpoint));
271 transport2 = dcerpc_binding_get_transport(binding2);
272 SMB_ASSERT(transport2 == transport);
275 /* see if the interface is already registered on the endpoint */
276 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
277 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
278 iface->name, ep_name));
279 return NT_STATUS_OBJECT_NAME_COLLISION;
282 /* check if this endpoint exists
284 ep = find_endpoint(dce_ctx, binding);
288 * We want a new port on ncacn_ip_tcp for NETLOGON, so
289 * it can be multi-process. Other processes can also
290 * listen on distinct ports, if they have one forced
291 * in the code above with eg 'rpc server port:drsuapi = 1027'
293 * If we have mulitiple endpoints on port 0, they each
294 * get an epemeral port (currently by walking up from
297 * Because one endpoint can only have one process
298 * model, we add a new IP_TCP endpoint for each model.
300 * This works in conjunction with the forced overwrite
301 * of ep->use_single_process below.
303 if (ep->use_single_process != use_single_process
304 && transport == NCACN_IP_TCP) {
309 if (ep == NULL || add_ep) {
310 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
312 return NT_STATUS_NO_MEMORY;
315 ep->ep_description = talloc_move(ep, &binding);
316 ep->ep_2nd_description = talloc_move(ep, &binding2);
319 /* add mgmt interface */
320 ifl = talloc_zero(ep, struct dcesrv_if_list);
322 return NT_STATUS_NO_MEMORY;
325 ifl->iface = dcesrv_get_mgmt_interface();
327 DLIST_ADD(ep->interface_list, ifl);
331 * By default don't force into a single process, but if any
332 * interface on this endpoint on this service uses handles
333 * (most do), then we must force into single process mode
335 * By overwriting this each time a new interface is added to
336 * this endpoint, we end up with the most restrictive setting.
338 if (use_single_process) {
339 ep->use_single_process = true;
342 /* talloc a new interface list element */
343 ifl = talloc_zero(ep, struct dcesrv_if_list);
345 return NT_STATUS_NO_MEMORY;
348 /* copy the given interface struct to the one on the endpoints interface list */
349 memcpy(&(ifl->iface),iface, sizeof(struct dcesrv_interface));
351 /* if we have a security descriptor given,
352 * we should see if we can set it up on the endpoint
355 /* if there's currently no security descriptor given on the endpoint
358 if (ep->sd == NULL) {
359 ep->sd = security_descriptor_copy(ep, sd);
362 /* if now there's no security descriptor given on the endpoint
363 * something goes wrong, either we failed to copy the security descriptor
364 * or there was already one on the endpoint
366 if (ep->sd != NULL) {
367 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
368 " on endpoint '%s'\n",
369 iface->name, ep_name));
370 if (add_ep) free(ep);
372 return NT_STATUS_OBJECT_NAME_COLLISION;
376 /* finally add the interface on the endpoint */
377 DLIST_ADD(ep->interface_list, ifl);
379 /* if it's a new endpoint add it to the dcesrv_context */
381 DLIST_ADD(dce_ctx->endpoint_list, ep);
384 /* Re-get the string as we may have set a port */
385 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
387 if (use_single_process) {
388 ep_process_string = "single process required";
390 ep_process_string = "multi process compatible";
393 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
394 iface->name, ep_string, ep_process_string);
395 TALLOC_FREE(ep_string);
400 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
401 DATA_BLOB *session_key)
403 if (auth->session_info == NULL) {
404 return NT_STATUS_NO_USER_SESSION_KEY;
407 if (auth->session_info->session_key.length == 0) {
408 return NT_STATUS_NO_USER_SESSION_KEY;
411 *session_key = auth->session_info->session_key;
415 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
416 DATA_BLOB *session_key)
418 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
419 return NT_STATUS_NO_USER_SESSION_KEY;
422 return dcesrv_session_info_session_key(auth, session_key);
425 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
426 DATA_BLOB *session_key)
428 return dcerpc_generic_session_key(session_key);
432 * Fetch the authentication session key if available.
434 * This is the key generated by a gensec authentication.
437 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
438 DATA_BLOB *session_key)
440 struct dcesrv_auth *auth = call->auth_state;
441 SMB_ASSERT(auth->auth_finished);
442 return dcesrv_session_info_session_key(auth, session_key);
446 * Fetch the transport session key if available.
447 * Typically this is the SMB session key
448 * or a fixed key for local transports.
450 * The key is always truncated to 16 bytes.
452 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
453 DATA_BLOB *session_key)
455 struct dcesrv_auth *auth = call->auth_state;
458 SMB_ASSERT(auth->auth_finished);
460 if (auth->session_key_fn == NULL) {
461 return NT_STATUS_NO_USER_SESSION_KEY;
464 status = auth->session_key_fn(auth, session_key);
465 if (!NT_STATUS_IS_OK(status)) {
469 session_key->length = MIN(session_key->length, 16);
474 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
476 const struct dcesrv_endpoint *ep = conn->endpoint;
477 enum dcerpc_transport_t transport =
478 dcerpc_binding_get_transport(ep->ep_description);
479 struct dcesrv_auth *auth = NULL;
481 auth = talloc_zero(conn, struct dcesrv_auth);
488 auth->session_key_fn = dcesrv_remote_session_key;
491 case NCACN_UNIX_STREAM:
492 auth->session_key_fn = dcesrv_local_fixed_session_key;
496 * All other's get a NULL pointer, which
497 * results in NT_STATUS_NO_USER_SESSION_KEY
506 connect to a dcerpc endpoint
508 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
510 const struct dcesrv_endpoint *ep,
511 struct auth_session_info *session_info,
512 struct tevent_context *event_ctx,
513 uint32_t state_flags,
514 struct dcesrv_connection **_p)
516 struct dcesrv_auth *auth = NULL;
517 struct dcesrv_connection *p;
520 return NT_STATUS_ACCESS_DENIED;
523 p = talloc_zero(mem_ctx, struct dcesrv_connection);
524 NT_STATUS_HAVE_NO_MEMORY(p);
526 p->dce_ctx = dce_ctx;
528 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx);
529 p->event_ctx = event_ctx;
530 p->state_flags = state_flags;
531 p->allow_bind = true;
532 p->max_recv_frag = 5840;
533 p->max_xmit_frag = 5840;
534 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
536 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
541 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
547 auth = dcesrv_auth_create(p);
550 return NT_STATUS_NO_MEMORY;
553 auth->session_info = talloc_reference(auth, session_info);
554 if (auth->session_info == NULL) {
556 return NT_STATUS_NO_MEMORY;
559 p->default_auth_state = auth;
562 * For now we only support NDR32.
564 p->preferred_transfer = &ndr_transfer_syntax_ndr;
571 move a call from an existing linked list to the specified list. This
572 prevents bugs where we forget to remove the call from a previous
575 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
576 enum dcesrv_call_list list)
578 switch (call->list) {
579 case DCESRV_LIST_NONE:
581 case DCESRV_LIST_CALL_LIST:
582 DLIST_REMOVE(call->conn->call_list, call);
584 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
585 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
587 case DCESRV_LIST_PENDING_CALL_LIST:
588 DLIST_REMOVE(call->conn->pending_call_list, call);
593 case DCESRV_LIST_NONE:
595 case DCESRV_LIST_CALL_LIST:
596 DLIST_ADD_END(call->conn->call_list, call);
598 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
599 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
601 case DCESRV_LIST_PENDING_CALL_LIST:
602 DLIST_ADD_END(call->conn->pending_call_list, call);
607 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
610 struct dcesrv_auth *a = NULL;
612 if (call->conn->terminate != NULL) {
616 call->conn->allow_bind = false;
617 call->conn->allow_alter = false;
619 call->conn->default_auth_state->auth_invalid = true;
621 for (a = call->conn->auth_states; a != NULL; a = a->next) {
622 a->auth_invalid = true;
625 call->terminate_reason = talloc_strdup(call, reason);
626 if (call->terminate_reason == NULL) {
627 call->terminate_reason = __location__;
632 return a dcerpc bind_nak
634 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
636 struct ncacn_packet pkt;
637 struct dcerpc_bind_nak_version version;
638 struct data_blob_list_item *rep;
640 static const uint8_t _pad[3] = { 0, };
643 * We add the call to the pending_call_list
644 * in order to defer the termination.
646 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
648 /* setup a bind_nak */
649 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
651 pkt.call_id = call->pkt.call_id;
652 pkt.ptype = DCERPC_PKT_BIND_NAK;
653 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
654 pkt.u.bind_nak.reject_reason = reason;
655 version.rpc_vers = 5;
656 version.rpc_vers_minor = 0;
657 pkt.u.bind_nak.num_versions = 1;
658 pkt.u.bind_nak.versions = &version;
659 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
661 rep = talloc_zero(call, struct data_blob_list_item);
663 return NT_STATUS_NO_MEMORY;
666 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
667 if (!NT_STATUS_IS_OK(status)) {
671 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
673 DLIST_ADD_END(call->replies, rep);
674 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
676 if (call->conn->call_list && call->conn->call_list->replies) {
677 if (call->conn->transport.report_output_data) {
678 call->conn->transport.report_output_data(call->conn);
685 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
689 * We add the call to the pending_call_list
690 * in order to defer the termination.
692 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
694 return dcesrv_fault_with_flags(call, fault_code,
695 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
698 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
700 DLIST_REMOVE(c->conn->contexts, c);
702 if (c->iface && c->iface->unbind) {
703 c->iface->unbind(c, c->iface);
710 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
712 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
713 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
714 enum dcerpc_transport_t transport =
715 dcerpc_binding_get_transport(endpoint->ep_description);
716 struct dcesrv_connection_context *context = dce_call->context;
717 const struct dcesrv_interface *iface = context->iface;
719 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
721 if (transport == NCALRPC) {
722 context->allow_connect = true;
727 * allow overwrite per interface
728 * allow dcerpc auth level connect:<interface>
730 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
731 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
732 "allow dcerpc auth level connect",
734 context->allow_connect);
737 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
738 const struct dcesrv_interface *iface)
741 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
742 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
744 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
748 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
749 const struct dcesrv_interface *iface)
751 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
755 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
756 const struct dcesrv_interface *iface)
758 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
759 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
760 enum dcerpc_transport_t transport =
761 dcerpc_binding_get_transport(endpoint->ep_description);
763 if (transport == NCALRPC) {
764 context->allow_connect = true;
769 * allow overwrite per interface
770 * allow dcerpc auth level connect:<interface>
772 context->allow_connect = false;
773 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
774 "allow dcerpc auth level connect",
776 context->allow_connect);
780 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
781 const struct dcesrv_interface *iface)
783 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
784 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
785 enum dcerpc_transport_t transport =
786 dcerpc_binding_get_transport(endpoint->ep_description);
788 if (transport == NCALRPC) {
789 context->allow_connect = true;
794 * allow overwrite per interface
795 * allow dcerpc auth level connect:<interface>
797 context->allow_connect = true;
798 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
799 "allow dcerpc auth level connect",
801 context->allow_connect);
805 struct dcesrv_conn_auth_wait_context {
806 struct tevent_req *req;
811 struct dcesrv_conn_auth_wait_state {
815 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
816 struct tevent_context *ev,
819 struct dcesrv_conn_auth_wait_context *auth_wait =
820 talloc_get_type_abort(private_data,
821 struct dcesrv_conn_auth_wait_context);
822 struct tevent_req *req = NULL;
823 struct dcesrv_conn_auth_wait_state *state = NULL;
825 req = tevent_req_create(mem_ctx, &state,
826 struct dcesrv_conn_auth_wait_state);
830 auth_wait->req = req;
832 tevent_req_defer_callback(req, ev);
834 if (!auth_wait->done) {
838 if (tevent_req_nterror(req, auth_wait->status)) {
839 return tevent_req_post(req, ev);
842 tevent_req_done(req);
843 return tevent_req_post(req, ev);
846 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
848 return tevent_req_simple_recv_ntstatus(req);
851 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
853 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
855 if (conn->wait_send != NULL) {
856 return NT_STATUS_INTERNAL_ERROR;
859 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
860 if (auth_wait == NULL) {
861 return NT_STATUS_NO_MEMORY;
864 conn->wait_private = auth_wait;
865 conn->wait_send = dcesrv_conn_auth_wait_send;
866 conn->wait_recv = dcesrv_conn_auth_wait_recv;
870 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
873 struct dcesrv_conn_auth_wait_context *auth_wait =
874 talloc_get_type_abort(conn->wait_private,
875 struct dcesrv_conn_auth_wait_context);
877 auth_wait->done = true;
878 auth_wait->status = status;
880 if (auth_wait->req == NULL) {
884 if (tevent_req_nterror(auth_wait->req, status)) {
888 tevent_req_done(auth_wait->req);
891 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
893 static void dcesrv_bind_done(struct tevent_req *subreq);
896 handle a bind request
898 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
900 struct dcesrv_connection *conn = call->conn;
901 struct ncacn_packet *pkt = &call->ack_pkt;
903 uint32_t extra_flags = 0;
904 uint16_t max_req = 0;
905 uint16_t max_rep = 0;
906 struct dcerpc_binding *ep_2nd_description = NULL;
907 const char *endpoint = NULL;
908 struct dcesrv_auth *auth = call->auth_state;
909 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
910 struct dcerpc_ack_ctx *ack_features = NULL;
911 struct tevent_req *subreq = NULL;
914 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
916 call->pkt.u.bind.auth_info.length,
917 0, /* required flags */
918 DCERPC_PFC_FLAG_FIRST |
919 DCERPC_PFC_FLAG_LAST |
920 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
921 0x08 | /* this is not defined, but should be ignored */
922 DCERPC_PFC_FLAG_CONC_MPX |
923 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
924 DCERPC_PFC_FLAG_MAYBE |
925 DCERPC_PFC_FLAG_OBJECT_UUID);
926 if (!NT_STATUS_IS_OK(status)) {
927 return dcesrv_bind_nak(call,
928 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
931 /* max_recv_frag and max_xmit_frag result always in the same value! */
932 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
933 call->pkt.u.bind.max_recv_frag);
935 * The values are between 2048 and 5840 tested against Windows 2012R2
936 * via ncacn_ip_tcp on port 135.
938 max_req = MAX(2048, max_req);
939 max_rep = MIN(max_req, call->conn->max_recv_frag);
940 /* They are truncated to an 8 byte boundary. */
943 /* max_recv_frag and max_xmit_frag result always in the same value! */
944 call->conn->max_recv_frag = max_rep;
945 call->conn->max_xmit_frag = max_rep;
947 status = call->conn->dce_ctx->callbacks.assoc_group.find(call);
948 if (!NT_STATUS_IS_OK(status)) {
949 DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
950 call->pkt.u.bind.assoc_group_id, nt_errstr(status));
951 return dcesrv_bind_nak(call, 0);
954 if (call->pkt.u.bind.num_contexts < 1) {
955 return dcesrv_bind_nak(call, 0);
958 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
959 call->pkt.u.bind.num_contexts);
960 if (ack_ctx_list == NULL) {
961 return dcesrv_bind_nak(call, 0);
965 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
966 * dcesrv_check_or_create_context()) and do some protocol validation
967 * and set sane defaults.
969 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
970 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
971 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
972 bool is_feature = false;
973 uint64_t features = 0;
975 if (c->num_transfer_syntaxes == 0) {
976 return dcesrv_bind_nak(call, 0);
979 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
980 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
983 * It's only treated as bind time feature request, if the first
984 * transfer_syntax matches, all others are ignored.
986 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
992 if (ack_features != NULL) {
994 * Only one bind time feature context is allowed.
996 return dcesrv_bind_nak(call, 0);
1000 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1001 a->reason.negotiate = 0;
1002 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1003 if (call->conn->max_auth_states != 0) {
1004 a->reason.negotiate |=
1005 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1008 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1009 a->reason.negotiate |=
1010 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1013 call->conn->assoc_group->bind_time_features = a->reason.negotiate;
1017 * Try to negotiate one new presentation context.
1019 * Deep in here we locate the iface (by uuid) that the client
1020 * requested, from the list of interfaces on the
1021 * call->conn->endpoint, and call iface->bind() on that iface.
1023 * call->conn was set up at the accept() of the socket, and
1024 * call->conn->endpoint has a list of interfaces restricted to
1025 * this port or pipe.
1027 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1028 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1029 return dcesrv_bind_nak(call, 0);
1031 if (!NT_STATUS_IS_OK(status)) {
1036 * At this point we still don't know which interface (eg
1037 * netlogon, lsa, drsuapi) the caller requested in this bind!
1038 * The most recently added context is available as the first
1039 * element in the linked list at call->conn->contexts, that is
1040 * call->conn->contexts->iface, but they may not have
1041 * requested one at all!
1044 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1045 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1046 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1047 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1050 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1051 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1055 * After finding the interface and setting up the NDR
1056 * transport negotiation etc, handle any authentication that
1057 * is being requested.
1059 if (!dcesrv_auth_bind(call)) {
1061 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1063 * With DCERPC_AUTH_LEVEL_NONE, we get the
1064 * reject_reason in auth->auth_context_id.
1066 return dcesrv_bind_nak(call, auth->auth_context_id);
1070 * This must a be a temporary failure e.g. talloc or invalid
1071 * configuration, e.g. no machine account.
1073 return dcesrv_bind_nak(call,
1074 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1077 /* setup a bind_ack */
1078 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1079 pkt->auth_length = 0;
1080 pkt->call_id = call->pkt.call_id;
1081 pkt->ptype = DCERPC_PKT_BIND_ACK;
1082 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1083 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1084 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1085 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1087 ep_2nd_description = call->conn->endpoint->ep_2nd_description;
1088 if (ep_2nd_description == NULL) {
1089 ep_2nd_description = call->conn->endpoint->ep_description;
1092 endpoint = dcerpc_binding_get_string_option(
1095 if (endpoint == NULL) {
1099 pkt->u.bind_ack.secondary_address = endpoint;
1100 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1101 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1102 pkt->u.bind_ack.auth_info = data_blob_null;
1104 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 return dcesrv_bind_nak(call, 0);
1109 if (auth->auth_finished) {
1110 return dcesrv_auth_reply(call);
1113 subreq = gensec_update_send(call, call->event_ctx,
1114 auth->gensec_security,
1115 call->in_auth_info.credentials);
1116 if (subreq == NULL) {
1117 return NT_STATUS_NO_MEMORY;
1119 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1121 return dcesrv_conn_auth_wait_setup(conn);
1124 static void dcesrv_bind_done(struct tevent_req *subreq)
1126 struct dcesrv_call_state *call =
1127 tevent_req_callback_data(subreq,
1128 struct dcesrv_call_state);
1129 struct dcesrv_connection *conn = call->conn;
1132 status = gensec_update_recv(subreq, call,
1133 &call->out_auth_info->credentials);
1134 TALLOC_FREE(subreq);
1136 status = dcesrv_auth_complete(call, status);
1137 if (!NT_STATUS_IS_OK(status)) {
1138 status = dcesrv_bind_nak(call, 0);
1139 dcesrv_conn_auth_wait_finished(conn, status);
1143 status = dcesrv_auth_reply(call);
1144 dcesrv_conn_auth_wait_finished(conn, status);
1148 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1150 struct ncacn_packet *pkt = &call->ack_pkt;
1151 struct data_blob_list_item *rep = NULL;
1154 rep = talloc_zero(call, struct data_blob_list_item);
1156 return NT_STATUS_NO_MEMORY;
1159 status = dcerpc_ncacn_push_auth(&rep->blob,
1162 call->out_auth_info);
1163 if (!NT_STATUS_IS_OK(status)) {
1167 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1169 DLIST_ADD_END(call->replies, rep);
1170 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1172 if (call->conn->call_list && call->conn->call_list->replies) {
1173 if (call->conn->transport.report_output_data) {
1174 call->conn->transport.report_output_data(call->conn);
1178 return NT_STATUS_OK;
1182 static void dcesrv_auth3_done(struct tevent_req *subreq);
1185 handle a auth3 request
1187 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1189 struct dcesrv_connection *conn = call->conn;
1190 struct dcesrv_auth *auth = call->auth_state;
1191 struct tevent_req *subreq = NULL;
1194 if (!auth->auth_started) {
1195 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1198 if (auth->auth_finished) {
1199 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1202 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1204 call->pkt.u.auth3.auth_info.length,
1205 0, /* required flags */
1206 DCERPC_PFC_FLAG_FIRST |
1207 DCERPC_PFC_FLAG_LAST |
1208 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1209 0x08 | /* this is not defined, but should be ignored */
1210 DCERPC_PFC_FLAG_CONC_MPX |
1211 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1212 DCERPC_PFC_FLAG_MAYBE |
1213 DCERPC_PFC_FLAG_OBJECT_UUID);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1218 /* handle the auth3 in the auth code */
1219 if (!dcesrv_auth_prepare_auth3(call)) {
1221 * we don't send a reply to a auth3 request,
1222 * except by a fault.
1224 * In anycase we mark the connection as
1227 auth->auth_invalid = true;
1228 if (call->fault_code != 0) {
1229 return dcesrv_fault_disconnect(call, call->fault_code);
1232 return NT_STATUS_OK;
1235 subreq = gensec_update_send(call, call->event_ctx,
1236 auth->gensec_security,
1237 call->in_auth_info.credentials);
1238 if (subreq == NULL) {
1239 return NT_STATUS_NO_MEMORY;
1241 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1243 return dcesrv_conn_auth_wait_setup(conn);
1246 static void dcesrv_auth3_done(struct tevent_req *subreq)
1248 struct dcesrv_call_state *call =
1249 tevent_req_callback_data(subreq,
1250 struct dcesrv_call_state);
1251 struct dcesrv_connection *conn = call->conn;
1252 struct dcesrv_auth *auth = call->auth_state;
1255 status = gensec_update_recv(subreq, call,
1256 &call->out_auth_info->credentials);
1257 TALLOC_FREE(subreq);
1259 status = dcesrv_auth_complete(call, status);
1260 if (!NT_STATUS_IS_OK(status)) {
1262 * we don't send a reply to a auth3 request,
1263 * except by a fault.
1265 * In anycase we mark the connection as
1268 auth->auth_invalid = true;
1269 if (call->fault_code != 0) {
1270 status = dcesrv_fault_disconnect(call, call->fault_code);
1271 dcesrv_conn_auth_wait_finished(conn, status);
1275 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1280 * we don't send a reply to a auth3 request.
1283 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1288 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1289 const struct dcerpc_bind *b,
1290 const struct dcerpc_ctx_list *ctx,
1291 struct dcerpc_ack_ctx *ack,
1293 const struct ndr_syntax_id *supported_transfer)
1295 uint32_t if_version;
1296 struct dcesrv_connection_context *context;
1297 const struct dcesrv_interface *iface;
1300 const struct ndr_syntax_id *selected_transfer = NULL;
1305 return NT_STATUS_INTERNAL_ERROR;
1308 return NT_STATUS_INTERNAL_ERROR;
1310 if (ctx->num_transfer_syntaxes < 1) {
1311 return NT_STATUS_INTERNAL_ERROR;
1314 return NT_STATUS_INTERNAL_ERROR;
1316 if (supported_transfer == NULL) {
1317 return NT_STATUS_INTERNAL_ERROR;
1320 switch (ack->result) {
1321 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1322 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1324 * We is already completed.
1326 return NT_STATUS_OK;
1331 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1332 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1334 if_version = ctx->abstract_syntax.if_version;
1335 uuid = ctx->abstract_syntax.uuid;
1337 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1338 if (iface == NULL) {
1339 char *uuid_str = GUID_string(call, &uuid);
1340 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1341 talloc_free(uuid_str);
1343 * We report this only via ack->result
1345 return NT_STATUS_OK;
1348 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1349 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1351 if (validate_only) {
1353 * We report this only via ack->result
1355 return NT_STATUS_OK;
1358 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1360 * we only do NDR encoded dcerpc for now.
1362 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1363 supported_transfer);
1365 selected_transfer = supported_transfer;
1370 context = dcesrv_find_context(call->conn, ctx->context_id);
1371 if (context != NULL) {
1372 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1373 &ctx->abstract_syntax);
1375 return NT_STATUS_RPC_PROTOCOL_ERROR;
1378 if (selected_transfer != NULL) {
1379 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1382 return NT_STATUS_RPC_PROTOCOL_ERROR;
1385 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1386 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1387 ack->syntax = context->transfer_syntax;
1391 * We report this only via ack->result
1393 return NT_STATUS_OK;
1396 if (selected_transfer == NULL) {
1398 * We report this only via ack->result
1400 return NT_STATUS_OK;
1403 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1404 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1406 /* add this context to the list of available context_ids */
1407 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1408 if (context == NULL) {
1409 return NT_STATUS_NO_MEMORY;
1411 context->conn = call->conn;
1412 context->context_id = ctx->context_id;
1413 context->iface = iface;
1414 context->transfer_syntax = *selected_transfer;
1415 DLIST_ADD(call->conn->contexts, context);
1416 call->context = context;
1417 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1419 dcesrv_prepare_context_auth(call);
1422 * Multiplex is supported by default
1424 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1426 status = iface->bind(context, iface);
1427 call->context = NULL;
1428 if (!NT_STATUS_IS_OK(status)) {
1429 /* we don't want to trigger the iface->unbind() hook */
1430 context->iface = NULL;
1431 talloc_free(context);
1433 * We report this only via ack->result
1435 return NT_STATUS_OK;
1438 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1439 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1440 ack->syntax = context->transfer_syntax;
1441 return NT_STATUS_OK;
1444 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1445 const struct dcerpc_bind *b,
1446 struct dcerpc_ack_ctx *ack_ctx_list)
1450 bool validate_only = false;
1451 bool preferred_ndr32;
1454 * Try to negotiate one new presentation context,
1455 * using our preferred transfer syntax.
1457 for (i = 0; i < b->num_contexts; i++) {
1458 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1459 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1461 status = dcesrv_check_or_create_context(call, b, c, a,
1463 call->conn->preferred_transfer);
1464 if (!NT_STATUS_IS_OK(status)) {
1468 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1470 * We managed to negotiate one context.
1474 validate_only = true;
1478 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1479 call->conn->preferred_transfer);
1480 if (preferred_ndr32) {
1484 return NT_STATUS_OK;
1488 * Try to negotiate one new presentation context,
1489 * using NDR 32 as fallback.
1491 for (i = 0; i < b->num_contexts; i++) {
1492 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1493 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1495 status = dcesrv_check_or_create_context(call, b, c, a,
1497 &ndr_transfer_syntax_ndr);
1498 if (!NT_STATUS_IS_OK(status)) {
1502 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1504 * We managed to negotiate one context.
1508 validate_only = true;
1512 return NT_STATUS_OK;
1515 static void dcesrv_alter_done(struct tevent_req *subreq);
1518 handle a alter context request
1520 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1522 struct dcesrv_connection *conn = call->conn;
1524 bool auth_ok = false;
1525 struct ncacn_packet *pkt = &call->ack_pkt;
1526 uint32_t extra_flags = 0;
1527 struct dcesrv_auth *auth = call->auth_state;
1528 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1529 struct tevent_req *subreq = NULL;
1532 if (!call->conn->allow_alter) {
1533 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1536 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1538 call->pkt.u.alter.auth_info.length,
1539 0, /* required flags */
1540 DCERPC_PFC_FLAG_FIRST |
1541 DCERPC_PFC_FLAG_LAST |
1542 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1543 0x08 | /* this is not defined, but should be ignored */
1544 DCERPC_PFC_FLAG_CONC_MPX |
1545 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1546 DCERPC_PFC_FLAG_MAYBE |
1547 DCERPC_PFC_FLAG_OBJECT_UUID);
1548 if (!NT_STATUS_IS_OK(status)) {
1549 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1552 auth_ok = dcesrv_auth_alter(call);
1554 if (call->fault_code != 0) {
1555 return dcesrv_fault_disconnect(call, call->fault_code);
1559 if (call->pkt.u.alter.num_contexts < 1) {
1560 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1563 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1564 call->pkt.u.alter.num_contexts);
1565 if (ack_ctx_list == NULL) {
1566 return NT_STATUS_NO_MEMORY;
1570 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1571 * dcesrv_check_or_create_context()) and do some protocol validation
1572 * and set sane defaults.
1574 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1575 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1576 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1578 if (c->num_transfer_syntaxes == 0) {
1579 return dcesrv_fault_disconnect(call,
1580 DCERPC_NCA_S_PROTO_ERROR);
1583 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1584 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1588 * Try to negotiate one new presentation context.
1590 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1591 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1592 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1594 if (!NT_STATUS_IS_OK(status)) {
1598 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1599 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1600 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1601 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1604 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1605 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1608 /* handle any authentication that is being requested */
1610 if (call->in_auth_info.auth_type != auth->auth_type) {
1611 return dcesrv_fault_disconnect(call,
1612 DCERPC_FAULT_SEC_PKG_ERROR);
1614 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1617 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1618 pkt->auth_length = 0;
1619 pkt->call_id = call->pkt.call_id;
1620 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1621 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1622 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1623 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1624 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1625 pkt->u.alter_resp.secondary_address = "";
1626 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1627 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1628 pkt->u.alter_resp.auth_info = data_blob_null;
1630 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1635 if (auth->auth_finished) {
1636 return dcesrv_auth_reply(call);
1639 subreq = gensec_update_send(call, call->event_ctx,
1640 auth->gensec_security,
1641 call->in_auth_info.credentials);
1642 if (subreq == NULL) {
1643 return NT_STATUS_NO_MEMORY;
1645 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1647 return dcesrv_conn_auth_wait_setup(conn);
1650 static void dcesrv_alter_done(struct tevent_req *subreq)
1652 struct dcesrv_call_state *call =
1653 tevent_req_callback_data(subreq,
1654 struct dcesrv_call_state);
1655 struct dcesrv_connection *conn = call->conn;
1658 status = gensec_update_recv(subreq, call,
1659 &call->out_auth_info->credentials);
1660 TALLOC_FREE(subreq);
1662 status = dcesrv_auth_complete(call, status);
1663 if (!NT_STATUS_IS_OK(status)) {
1664 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1665 dcesrv_conn_auth_wait_finished(conn, status);
1669 status = dcesrv_auth_reply(call);
1670 dcesrv_conn_auth_wait_finished(conn, status);
1675 possibly save the call for inspection with ndrdump
1677 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1681 const char *dump_dir;
1682 dump_dir = lpcfg_parm_string(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv", "stubs directory");
1686 fname = talloc_asprintf(call, "%s/RPC-%s-%u-%s.dat",
1688 call->context->iface->name,
1689 call->pkt.u.request.opnum,
1691 if (file_save(fname, call->pkt.u.request.stub_and_verifier.data, call->pkt.u.request.stub_and_verifier.length)) {
1692 DEBUG(0,("RPC SAVED %s\n", fname));
1698 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1700 TALLOC_CTX *frame = talloc_stackframe();
1701 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1702 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1703 const struct dcerpc_sec_vt_pcontext pcontext = {
1704 .abstract_syntax = call->context->iface->syntax_id,
1705 .transfer_syntax = call->context->transfer_syntax,
1707 const struct dcerpc_sec_vt_header2 header2 =
1708 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1709 enum ndr_err_code ndr_err;
1710 struct dcerpc_sec_verification_trailer *vt = NULL;
1711 NTSTATUS status = NT_STATUS_OK;
1714 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1716 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1718 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1719 status = ndr_map_error2ntstatus(ndr_err);
1723 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1724 &pcontext, &header2);
1726 status = NT_STATUS_ACCESS_DENIED;
1735 handle a dcerpc request packet
1737 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1739 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1740 struct dcesrv_auth *auth = call->auth_state;
1741 enum dcerpc_transport_t transport =
1742 dcerpc_binding_get_transport(endpoint->ep_description);
1743 struct ndr_pull *pull;
1746 if (!auth->auth_finished) {
1747 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1750 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1751 if (auth->gensec_security != NULL &&
1752 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1753 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1756 if (call->context == NULL) {
1757 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1758 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1761 switch (auth->auth_level) {
1762 case DCERPC_AUTH_LEVEL_NONE:
1763 case DCERPC_AUTH_LEVEL_PACKET:
1764 case DCERPC_AUTH_LEVEL_INTEGRITY:
1765 case DCERPC_AUTH_LEVEL_PRIVACY:
1768 if (!call->context->allow_connect) {
1771 addr = tsocket_address_string(call->conn->remote_address,
1774 DEBUG(2, ("%s: restrict auth_level_connect access "
1775 "to [%s] with auth[type=0x%x,level=0x%x] "
1776 "on [%s] from [%s]\n",
1777 __func__, call->context->iface->name,
1780 derpc_transport_string_by_transport(transport),
1782 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1787 if (auth->auth_level < call->context->min_auth_level) {
1790 addr = tsocket_address_string(call->conn->remote_address, call);
1792 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1793 "to [%s] with auth[type=0x%x,level=0x%x] "
1794 "on [%s] from [%s]\n",
1796 call->context->min_auth_level,
1797 call->context->iface->name,
1800 derpc_transport_string_by_transport(transport),
1802 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1805 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1806 NT_STATUS_HAVE_NO_MEMORY(pull);
1808 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1810 call->ndr_pull = pull;
1812 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1813 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1816 status = dcesrv_check_verification_trailer(call);
1817 if (!NT_STATUS_IS_OK(status)) {
1818 uint32_t faultcode = DCERPC_FAULT_OTHER;
1819 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1820 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1822 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1823 nt_errstr(status)));
1824 return dcesrv_fault(call, faultcode);
1827 /* unravel the NDR for the packet */
1828 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1829 if (!NT_STATUS_IS_OK(status)) {
1830 uint8_t extra_flags = 0;
1831 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1832 /* we got an unknown call */
1833 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1834 call->pkt.u.request.opnum,
1835 call->context->iface->name));
1836 dcesrv_save_call(call, "unknown");
1837 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1839 dcesrv_save_call(call, "pullfail");
1841 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1844 if (pull->offset != pull->data_size) {
1845 dcesrv_save_call(call, "extrabytes");
1846 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1847 pull->data_size - pull->offset));
1850 /* call the dispatch function */
1851 status = call->context->iface->dispatch(call, call, call->r);
1852 if (!NT_STATUS_IS_OK(status)) {
1853 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1854 call->context->iface->name,
1855 call->pkt.u.request.opnum,
1856 dcerpc_errstr(pull, call->fault_code)));
1857 return dcesrv_fault(call, call->fault_code);
1860 /* add the call to the pending list */
1861 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1863 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1864 return NT_STATUS_OK;
1867 return dcesrv_reply(call);
1872 remove the call from the right list when freed
1874 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1876 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1880 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1882 return conn->local_address;
1885 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1887 return conn->remote_address;
1891 process some input to a dcerpc endpoint server.
1893 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1894 struct ncacn_packet *pkt,
1898 struct dcesrv_call_state *call;
1899 struct dcesrv_call_state *existing = NULL;
1900 size_t num_auth_ctx = 0;
1901 enum dcerpc_AuthType auth_type = 0;
1902 enum dcerpc_AuthLevel auth_level = 0;
1903 uint32_t auth_context_id = 0;
1905 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1907 data_blob_free(&blob);
1909 return NT_STATUS_NO_MEMORY;
1911 call->conn = dce_conn;
1912 call->event_ctx = dce_conn->event_ctx;
1913 call->state_flags = call->conn->state_flags;
1914 call->time = timeval_current();
1915 call->list = DCESRV_LIST_NONE;
1917 talloc_steal(call, pkt);
1918 talloc_steal(call, blob.data);
1921 if (dce_conn->max_auth_states == 0) {
1922 call->auth_state = dce_conn->default_auth_state;
1923 } else if (call->pkt.auth_length == 0) {
1924 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1925 dce_conn->default_auth_level_connect != NULL)
1927 call->auth_state = dce_conn->default_auth_level_connect;
1929 call->auth_state = dce_conn->default_auth_state;
1933 if (call->auth_state == NULL) {
1934 struct dcesrv_auth *a = NULL;
1936 auth_type = dcerpc_get_auth_type(&blob);
1937 auth_level = dcerpc_get_auth_level(&blob);
1938 auth_context_id = dcerpc_get_auth_context_id(&blob);
1940 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1941 dce_conn->default_auth_level_connect = NULL;
1942 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
1943 dce_conn->got_explicit_auth_level_connect = true;
1947 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
1950 if (a->auth_type != auth_type) {
1953 if (a->auth_finished && a->auth_level != auth_level) {
1956 if (a->auth_context_id != auth_context_id) {
1960 DLIST_PROMOTE(dce_conn->auth_states, a);
1961 call->auth_state = a;
1966 if (call->auth_state == NULL) {
1967 struct dcesrv_auth *a = NULL;
1969 if (num_auth_ctx >= dce_conn->max_auth_states) {
1970 return dcesrv_fault_disconnect(call,
1971 DCERPC_NCA_S_PROTO_ERROR);
1974 a = dcesrv_auth_create(dce_conn);
1977 return NT_STATUS_NO_MEMORY;
1979 DLIST_ADD(dce_conn->auth_states, a);
1980 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1982 * This can never be valid.
1984 a->auth_invalid = true;
1986 call->auth_state = a;
1989 talloc_set_destructor(call, dcesrv_call_dequeue);
1991 if (call->conn->allow_bind) {
1993 * Only one bind is possible per connection
1995 call->conn->allow_bind = false;
1996 return dcesrv_bind(call);
1999 /* we have to check the signing here, before combining the
2001 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2002 dcesrv_default_auth_state_prepare_request(call);
2004 if (call->auth_state->auth_started &&
2005 !call->auth_state->auth_finished) {
2006 return dcesrv_fault_disconnect(call,
2007 DCERPC_NCA_S_PROTO_ERROR);
2010 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2012 call->pkt.u.request.stub_and_verifier.length,
2013 0, /* required_flags */
2014 DCERPC_PFC_FLAG_FIRST |
2015 DCERPC_PFC_FLAG_LAST |
2016 DCERPC_PFC_FLAG_PENDING_CANCEL |
2017 0x08 | /* this is not defined, but should be ignored */
2018 DCERPC_PFC_FLAG_CONC_MPX |
2019 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2020 DCERPC_PFC_FLAG_MAYBE |
2021 DCERPC_PFC_FLAG_OBJECT_UUID);
2022 if (!NT_STATUS_IS_OK(status)) {
2023 return dcesrv_fault_disconnect(call,
2024 DCERPC_NCA_S_PROTO_ERROR);
2027 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2029 * We don't use dcesrv_fault_disconnect()
2030 * here, because we don't want to set
2031 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2033 * Note that we don't check against the negotiated
2034 * max_recv_frag, but a hard coded value.
2036 dcesrv_call_disconnect_after(call,
2037 "dcesrv_auth_request - frag_length too large");
2038 return dcesrv_fault(call,
2039 DCERPC_NCA_S_PROTO_ERROR);
2042 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2043 if (dce_conn->pending_call_list != NULL) {
2045 * concurrent requests are only allowed
2046 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2048 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2049 dcesrv_call_disconnect_after(call,
2050 "dcesrv_auth_request - "
2051 "existing pending call without CONN_MPX");
2052 return dcesrv_fault(call,
2053 DCERPC_NCA_S_PROTO_ERROR);
2056 /* only one request is possible in the fragmented list */
2057 if (dce_conn->incoming_fragmented_call_list != NULL) {
2058 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2060 * Without DCERPC_PFC_FLAG_CONC_MPX
2061 * we need to return the FAULT on the
2062 * already existing call.
2064 * This is important to get the
2065 * call_id and context_id right.
2068 call = dce_conn->incoming_fragmented_call_list;
2070 dcesrv_call_disconnect_after(call,
2071 "dcesrv_auth_request - "
2072 "existing fragmented call");
2073 return dcesrv_fault(call,
2074 DCERPC_NCA_S_PROTO_ERROR);
2076 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2077 return dcesrv_fault_disconnect(call,
2078 DCERPC_FAULT_NO_CALL_ACTIVE);
2080 call->context = dcesrv_find_context(call->conn,
2081 call->pkt.u.request.context_id);
2082 if (call->context == NULL) {
2083 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2084 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2087 const struct dcerpc_request *nr = &call->pkt.u.request;
2088 const struct dcerpc_request *er = NULL;
2091 existing = dcesrv_find_fragmented_call(dce_conn,
2093 if (existing == NULL) {
2094 dcesrv_call_disconnect_after(call,
2095 "dcesrv_auth_request - "
2096 "no existing fragmented call");
2097 return dcesrv_fault(call,
2098 DCERPC_NCA_S_PROTO_ERROR);
2100 er = &existing->pkt.u.request;
2102 if (call->pkt.ptype != existing->pkt.ptype) {
2103 /* trying to play silly buggers are we? */
2104 return dcesrv_fault_disconnect(existing,
2105 DCERPC_NCA_S_PROTO_ERROR);
2107 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2110 return dcesrv_fault_disconnect(existing,
2111 DCERPC_NCA_S_PROTO_ERROR);
2113 if (nr->context_id != er->context_id) {
2114 return dcesrv_fault_disconnect(existing,
2115 DCERPC_NCA_S_PROTO_ERROR);
2117 if (nr->opnum != er->opnum) {
2118 return dcesrv_fault_disconnect(existing,
2119 DCERPC_NCA_S_PROTO_ERROR);
2124 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2126 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2128 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2129 payload_offset += 16;
2132 ok = dcesrv_auth_pkt_pull(call, &blob,
2133 0, /* required_flags */
2134 DCERPC_PFC_FLAG_FIRST |
2135 DCERPC_PFC_FLAG_LAST |
2136 DCERPC_PFC_FLAG_PENDING_CANCEL |
2137 0x08 | /* this is not defined, but should be ignored */
2138 DCERPC_PFC_FLAG_CONC_MPX |
2139 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2140 DCERPC_PFC_FLAG_MAYBE |
2141 DCERPC_PFC_FLAG_OBJECT_UUID,
2143 &call->pkt.u.request.stub_and_verifier);
2146 * We don't use dcesrv_fault_disconnect()
2147 * here, because we don't want to set
2148 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2150 dcesrv_call_disconnect_after(call,
2151 "dcesrv_auth_request - failed");
2152 if (call->fault_code == 0) {
2153 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2155 return dcesrv_fault(call, call->fault_code);
2159 /* see if this is a continued packet */
2160 if (existing != NULL) {
2161 struct dcerpc_request *er = &existing->pkt.u.request;
2162 const struct dcerpc_request *nr = &call->pkt.u.request;
2168 * Up to 4 MByte are allowed by all fragments
2170 available = dce_conn->max_total_request_size;
2171 if (er->stub_and_verifier.length > available) {
2172 dcesrv_call_disconnect_after(existing,
2173 "dcesrv_auth_request - existing payload too large");
2174 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2176 available -= er->stub_and_verifier.length;
2177 if (nr->alloc_hint > available) {
2178 dcesrv_call_disconnect_after(existing,
2179 "dcesrv_auth_request - alloc hint too large");
2180 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2182 if (nr->stub_and_verifier.length > available) {
2183 dcesrv_call_disconnect_after(existing,
2184 "dcesrv_auth_request - new payload too large");
2185 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2187 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2188 /* allocate at least 1 byte */
2189 alloc_hint = MAX(alloc_hint, 1);
2190 alloc_size = er->stub_and_verifier.length +
2191 nr->stub_and_verifier.length;
2192 alloc_size = MAX(alloc_size, alloc_hint);
2194 er->stub_and_verifier.data =
2195 talloc_realloc(existing,
2196 er->stub_and_verifier.data,
2197 uint8_t, alloc_size);
2198 if (er->stub_and_verifier.data == NULL) {
2200 return dcesrv_fault_with_flags(existing,
2201 DCERPC_FAULT_OUT_OF_RESOURCES,
2202 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2204 memcpy(er->stub_and_verifier.data +
2205 er->stub_and_verifier.length,
2206 nr->stub_and_verifier.data,
2207 nr->stub_and_verifier.length);
2208 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2210 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2216 /* this may not be the last pdu in the chain - if its isn't then
2217 just put it on the incoming_fragmented_call_list and wait for the rest */
2218 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2219 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2221 * Up to 4 MByte are allowed by all fragments
2223 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2224 dcesrv_call_disconnect_after(call,
2225 "dcesrv_auth_request - initial alloc hint too large");
2226 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2228 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2229 return NT_STATUS_OK;
2232 /* This removes any fragments we may have had stashed away */
2233 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2235 switch (call->pkt.ptype) {
2236 case DCERPC_PKT_BIND:
2237 status = dcesrv_bind_nak(call,
2238 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2240 case DCERPC_PKT_AUTH3:
2241 status = dcesrv_auth3(call);
2243 case DCERPC_PKT_ALTER:
2244 status = dcesrv_alter(call);
2246 case DCERPC_PKT_REQUEST:
2247 status = dcesrv_request(call);
2249 case DCERPC_PKT_CO_CANCEL:
2250 case DCERPC_PKT_ORPHANED:
2252 * Window just ignores CO_CANCEL and ORPHANED,
2255 status = NT_STATUS_OK;
2258 case DCERPC_PKT_BIND_ACK:
2259 case DCERPC_PKT_BIND_NAK:
2260 case DCERPC_PKT_ALTER_RESP:
2261 case DCERPC_PKT_RESPONSE:
2262 case DCERPC_PKT_FAULT:
2263 case DCERPC_PKT_SHUTDOWN:
2265 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2269 /* if we are going to be sending a reply then add
2270 it to the list of pending calls. We add it to the end to keep the call
2271 list in the order we will answer */
2272 if (!NT_STATUS_IS_OK(status)) {
2279 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2280 struct loadparm_context *lp_ctx,
2281 const char **endpoint_servers,
2282 struct dcesrv_context_callbacks *cb,
2283 struct dcesrv_context **_dce_ctx)
2286 struct dcesrv_context *dce_ctx;
2289 if (!endpoint_servers) {
2290 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2291 return NT_STATUS_INTERNAL_ERROR;
2294 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2295 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2297 if (uid_wrapper_enabled()) {
2298 setenv("UID_WRAPPER_MYUID", "1", 1);
2300 dce_ctx->initial_euid = geteuid();
2301 if (uid_wrapper_enabled()) {
2302 unsetenv("UID_WRAPPER_MYUID");
2305 dce_ctx->endpoint_list = NULL;
2306 dce_ctx->lp_ctx = lp_ctx;
2307 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2308 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2309 dce_ctx->broken_connections = NULL;
2311 dce_ctx->callbacks = *cb;
2314 for (i=0;endpoint_servers[i];i++) {
2315 const struct dcesrv_endpoint_server *ep_server;
2317 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2319 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2320 return NT_STATUS_INTERNAL_ERROR;
2323 status = ep_server->init_server(dce_ctx, ep_server);
2324 if (!NT_STATUS_IS_OK(status)) {
2325 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2326 nt_errstr(status)));
2331 *_dce_ctx = dce_ctx;
2332 return NT_STATUS_OK;
2335 /* the list of currently registered DCERPC endpoint servers.
2337 static struct ep_server {
2338 struct dcesrv_endpoint_server *ep_server;
2339 } *ep_servers = NULL;
2340 static int num_ep_servers;
2343 register a DCERPC endpoint server.
2345 The 'name' can be later used by other backends to find the operations
2346 structure for this backend.
2349 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2352 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2353 /* its already registered! */
2354 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2356 return NT_STATUS_OBJECT_NAME_COLLISION;
2359 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2361 smb_panic("out of memory in dcerpc_register");
2364 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2365 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2369 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2372 return NT_STATUS_OK;
2376 return the operations structure for a named backend of the specified type
2378 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2382 for (i=0;i<num_ep_servers;i++) {
2383 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2384 return ep_servers[i].ep_server;
2392 return the DCERPC module version, and the size of some critical types
2393 This can be used by endpoint server modules to either detect compilation errors, or provide
2394 multiple implementations for different smbd compilation options in one module
2396 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2398 static const struct dcesrv_critical_sizes critical_sizes = {
2399 DCERPC_MODULE_VERSION,
2400 sizeof(struct dcesrv_context),
2401 sizeof(struct dcesrv_endpoint),
2402 sizeof(struct dcesrv_endpoint_server),
2403 sizeof(struct dcesrv_interface),
2404 sizeof(struct dcesrv_if_list),
2405 sizeof(struct dcesrv_connection),
2406 sizeof(struct dcesrv_call_state),
2407 sizeof(struct dcesrv_auth),
2408 sizeof(struct dcesrv_handle)
2411 return &critical_sizes;
2414 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2416 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2417 struct dcesrv_auth *a = NULL;
2419 dce_conn->wait_send = NULL;
2420 dce_conn->wait_recv = NULL;
2421 dce_conn->wait_private = NULL;
2423 dce_conn->allow_bind = false;
2424 dce_conn->allow_alter = false;
2426 dce_conn->default_auth_state->auth_invalid = true;
2428 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2429 a->auth_invalid = true;
2432 if (dce_conn->pending_call_list == NULL) {
2433 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2435 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2436 dce_conn->transport.terminate_connection(dce_conn,
2437 full_reason ? full_reason : reason);
2441 if (dce_conn->terminate != NULL) {
2445 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2447 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2448 if (dce_conn->terminate == NULL) {
2449 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2451 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2454 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2456 struct dcesrv_connection *cur, *next;
2458 next = dce_ctx->broken_connections;
2459 while (next != NULL) {
2463 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2464 struct dcesrv_connection_context *context_cur, *context_next;
2466 context_next = cur->contexts;
2467 while (context_next != NULL) {
2468 context_cur = context_next;
2469 context_next = context_cur->next;
2471 dcesrv_connection_context_destructor(context_cur);
2475 dcesrv_terminate_connection(cur, cur->terminate);
2479 /* We need this include to be able to compile on some plateforms
2480 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2482 * It has to be that deep because otherwise we have a conflict on
2483 * const struct dcesrv_interface declaration.
2484 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2485 * which conflict with the bind used before.
2487 #include "system/network.h"
2489 struct dcesrv_sock_reply_state {
2490 struct dcesrv_connection *dce_conn;
2491 struct dcesrv_call_state *call;
2495 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2496 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2498 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2500 struct dcesrv_call_state *call;
2502 call = dce_conn->call_list;
2503 if (!call || !call->replies) {
2507 while (call->replies) {
2508 struct data_blob_list_item *rep = call->replies;
2509 struct dcesrv_sock_reply_state *substate;
2510 struct tevent_req *subreq;
2512 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2514 dcesrv_terminate_connection(dce_conn, "no memory");
2518 substate->dce_conn = dce_conn;
2519 substate->call = NULL;
2521 DLIST_REMOVE(call->replies, rep);
2523 if (call->replies == NULL && call->terminate_reason == NULL) {
2524 substate->call = call;
2527 substate->iov.iov_base = (void *) rep->blob.data;
2528 substate->iov.iov_len = rep->blob.length;
2530 subreq = tstream_writev_queue_send(substate,
2531 dce_conn->event_ctx,
2533 dce_conn->send_queue,
2536 dcesrv_terminate_connection(dce_conn, "no memory");
2539 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2543 if (call->terminate_reason != NULL) {
2544 struct tevent_req *subreq;
2546 subreq = tevent_queue_wait_send(call,
2547 dce_conn->event_ctx,
2548 dce_conn->send_queue);
2550 dcesrv_terminate_connection(dce_conn, __location__);
2553 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2557 DLIST_REMOVE(call->conn->call_list, call);
2558 call->list = DCESRV_LIST_NONE;
2561 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2563 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2564 struct dcesrv_sock_reply_state);
2568 struct dcesrv_call_state *call = substate->call;
2570 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2571 TALLOC_FREE(subreq);
2573 status = map_nt_error_from_unix_common(sys_errno);
2574 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2578 talloc_free(substate);
2584 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2586 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2588 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2589 struct dcesrv_call_state);
2593 /* make sure we stop send queue before removing subreq */
2594 tevent_queue_stop(call->conn->send_queue);
2596 ok = tevent_queue_wait_recv(subreq);
2597 TALLOC_FREE(subreq);
2599 dcesrv_terminate_connection(call->conn, __location__);
2603 /* disconnect after 200 usecs */
2604 tv = timeval_current_ofs_usec(200);
2605 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2606 if (subreq == NULL) {
2607 dcesrv_terminate_connection(call->conn, __location__);
2610 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2614 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2616 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2617 struct dcesrv_call_state);
2620 ok = tevent_wakeup_recv(subreq);
2621 TALLOC_FREE(subreq);
2623 dcesrv_terminate_connection(call->conn, __location__);
2627 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2630 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2632 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2634 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2635 struct dcesrv_connection);
2636 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2637 struct ncacn_packet *pkt;
2641 if (dce_conn->terminate) {
2643 * if the current connection is broken
2644 * we need to clean it up before any other connection
2646 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2647 dcesrv_cleanup_broken_connections(dce_ctx);
2651 dcesrv_cleanup_broken_connections(dce_ctx);
2653 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2655 TALLOC_FREE(subreq);
2656 if (!NT_STATUS_IS_OK(status)) {
2657 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2661 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2662 if (!NT_STATUS_IS_OK(status)) {
2663 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2668 * This is used to block the connection during
2669 * pending authentication.
2671 if (dce_conn->wait_send != NULL) {
2672 subreq = dce_conn->wait_send(dce_conn,
2673 dce_conn->event_ctx,
2674 dce_conn->wait_private);
2676 status = NT_STATUS_NO_MEMORY;
2677 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2680 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2684 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2685 dce_conn->event_ctx,
2688 status = NT_STATUS_NO_MEMORY;
2689 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2692 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2695 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2697 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2698 struct dcesrv_connection);
2699 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2702 if (dce_conn->terminate) {
2704 * if the current connection is broken
2705 * we need to clean it up before any other connection
2707 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2708 dcesrv_cleanup_broken_connections(dce_ctx);
2712 dcesrv_cleanup_broken_connections(dce_ctx);
2714 status = dce_conn->wait_recv(subreq);
2715 dce_conn->wait_send = NULL;
2716 dce_conn->wait_recv = NULL;
2717 dce_conn->wait_private = NULL;
2718 TALLOC_FREE(subreq);
2719 if (!NT_STATUS_IS_OK(status)) {
2720 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2724 status = dcesrv_connection_loop_start(dce_conn);
2725 if (!NT_STATUS_IS_OK(status)) {
2726 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2732 * retrieve credentials from a dce_call
2734 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2736 struct dcesrv_auth *auth = dce_call->auth_state;
2737 SMB_ASSERT(auth->auth_finished);
2738 return auth->session_info->credentials;
2742 * returns true if this is an authenticated call
2744 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2746 struct dcesrv_auth *auth = dce_call->auth_state;
2747 enum security_user_level level;
2748 SMB_ASSERT(auth->auth_finished);
2749 level = security_session_user_level(auth->session_info, NULL);
2750 return level >= SECURITY_USER;
2754 * retrieve account_name for a dce_call
2756 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call)
2758 struct dcesrv_auth *auth = dce_call->auth_state;
2759 SMB_ASSERT(auth->auth_finished);
2760 return auth->session_info->info->account_name;
2764 * retrieve session_info from a dce_call
2766 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
2768 struct dcesrv_auth *auth = dce_call->auth_state;
2769 SMB_ASSERT(auth->auth_finished);
2770 return auth->session_info;
2774 * retrieve auth type/level from a dce_call
2776 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
2777 enum dcerpc_AuthType *auth_type,
2778 enum dcerpc_AuthLevel *auth_level)
2780 struct dcesrv_auth *auth = dce_call->auth_state;
2782 SMB_ASSERT(auth->auth_finished);
2784 if (auth_type != NULL) {
2785 *auth_type = auth->auth_type;
2787 if (auth_level != NULL) {
2788 *auth_level = auth->auth_level;
2792 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
2794 struct tevent_req *subreq;
2796 subreq = dcerpc_read_ncacn_packet_send(conn,
2799 if (subreq == NULL) {
2800 return NT_STATUS_NO_MEMORY;
2802 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
2804 return NT_STATUS_OK;