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 _PUBLIC_ NTSTATUS dcesrv_find_endpoint(struct dcesrv_context *dce_ctx,
79 const struct dcerpc_binding *ep_description,
80 struct dcesrv_endpoint **_out)
82 struct dcesrv_endpoint *ep = NULL;
83 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
84 if (endpoints_match(ep->ep_description, ep_description)) {
89 return NT_STATUS_NOT_FOUND;
93 find a registered context_id from a bind or alter_context
95 static struct dcesrv_connection_context *dcesrv_find_context(struct dcesrv_connection *conn,
98 struct dcesrv_connection_context *c;
99 for (c=conn->contexts;c;c=c->next) {
100 if (c->context_id == context_id) return c;
106 see if a uuid and if_version match to an interface
108 static bool interface_match(const struct dcesrv_interface *if1,
109 const struct dcesrv_interface *if2)
111 return (if1->syntax_id.if_version == if2->syntax_id.if_version &&
112 GUID_equal(&if1->syntax_id.uuid, &if2->syntax_id.uuid));
116 find the interface operations on any endpoint with this binding
118 static const struct dcesrv_interface *find_interface_by_binding(struct dcesrv_context *dce_ctx,
119 struct dcerpc_binding *binding,
120 const struct dcesrv_interface *iface)
122 struct dcesrv_endpoint *ep;
123 for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
124 if (endpoints_match(ep->ep_description, binding)) {
125 struct dcesrv_if_list *ifl;
126 for (ifl=ep->interface_list; ifl; ifl=ifl->next) {
127 if (interface_match(ifl->iface, iface)) {
137 see if a uuid and if_version match to an interface
139 static bool interface_match_by_uuid(const struct dcesrv_interface *iface,
140 const struct GUID *uuid, uint32_t if_version)
142 return (iface->syntax_id.if_version == if_version &&
143 GUID_equal(&iface->syntax_id.uuid, uuid));
147 find the interface operations on an endpoint by uuid
149 const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv_endpoint *endpoint,
150 const struct GUID *uuid, uint32_t if_version)
152 struct dcesrv_if_list *ifl;
153 for (ifl=endpoint->interface_list; ifl; ifl=ifl->next) {
154 if (interface_match_by_uuid(ifl->iface, uuid, if_version)) {
162 find the earlier parts of a fragmented call awaiting reassembily
164 static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint32_t call_id)
166 struct dcesrv_call_state *c;
167 for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
168 if (c->pkt.call_id == call_id) {
176 register an interface on an endpoint
178 An endpoint is one unix domain socket (for ncalrpc), one TCP port
179 (for ncacn_ip_tcp) or one (forwarded) named pipe (for ncacn_np).
181 Each endpoint can have many interfaces such as netlogon, lsa or
182 samr. Some have essentially the full set.
184 This is driven from the set of interfaces listed in each IDL file
185 via the PIDL generated *__op_init_server() functions.
187 _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
189 const char *ncacn_np_secondary_endpoint,
190 const struct dcesrv_interface *iface,
191 const struct security_descriptor *sd)
193 struct dcesrv_endpoint *ep;
194 struct dcesrv_if_list *ifl;
195 struct dcerpc_binding *binding;
196 struct dcerpc_binding *binding2 = NULL;
199 enum dcerpc_transport_t transport;
200 char *ep_string = NULL;
201 bool use_single_process = true;
202 const char *ep_process_string;
205 * If we are not using handles, there is no need for force
206 * this service into using a single process.
208 * However, due to the way we listen for RPC packets, we can
209 * only do this if we have a single service per pipe or TCP
210 * port, so we still force a single combined process for
213 if (iface->flags & DCESRV_INTERFACE_FLAGS_HANDLES_NOT_USED) {
214 use_single_process = false;
217 status = dcerpc_parse_binding(dce_ctx, ep_name, &binding);
219 if (NT_STATUS_IS_ERR(status)) {
220 DEBUG(0, ("Trouble parsing binding string '%s'\n", ep_name));
224 transport = dcerpc_binding_get_transport(binding);
225 if (transport == NCACN_IP_TCP) {
230 * First check if there is already a port specified, eg
231 * for epmapper on ncacn_ip_tcp:[135]
234 = dcerpc_binding_get_string_option(binding,
236 if (endpoint == NULL) {
237 port = lpcfg_parm_int(dce_ctx->lp_ctx, NULL,
238 "rpc server port", iface->name, 0);
241 * For RPC services that are not set to use a single
242 * process, we do not default to using the 'rpc server
243 * port' because that would cause a double-bind on
246 if (port == 0 && !use_single_process) {
247 port = lpcfg_rpc_server_port(dce_ctx->lp_ctx);
250 snprintf(port_str, sizeof(port_str), "%u", port);
251 status = dcerpc_binding_set_string_option(binding,
254 if (!NT_STATUS_IS_OK(status)) {
261 if (transport == NCACN_NP && ncacn_np_secondary_endpoint != NULL) {
262 enum dcerpc_transport_t transport2;
264 status = dcerpc_parse_binding(dce_ctx,
265 ncacn_np_secondary_endpoint,
267 if (!NT_STATUS_IS_OK(status)) {
268 DEBUG(0, ("Trouble parsing 2nd binding string '%s'\n",
269 ncacn_np_secondary_endpoint));
273 transport2 = dcerpc_binding_get_transport(binding2);
274 SMB_ASSERT(transport2 == transport);
277 /* see if the interface is already registered on the endpoint */
278 if (find_interface_by_binding(dce_ctx, binding, iface)!=NULL) {
279 DEBUG(0,("dcesrv_interface_register: interface '%s' already registered on endpoint '%s'\n",
280 iface->name, ep_name));
281 return NT_STATUS_OBJECT_NAME_COLLISION;
284 /* check if this endpoint exists
286 status = dcesrv_find_endpoint(dce_ctx, binding, &ep);
287 if (NT_STATUS_IS_OK(status)) {
289 * We want a new port on ncacn_ip_tcp for NETLOGON, so
290 * it can be multi-process. Other processes can also
291 * listen on distinct ports, if they have one forced
292 * in the code above with eg 'rpc server port:drsuapi = 1027'
294 * If we have mulitiple endpoints on port 0, they each
295 * get an epemeral port (currently by walking up from
298 * Because one endpoint can only have one process
299 * model, we add a new IP_TCP endpoint for each model.
301 * This works in conjunction with the forced overwrite
302 * of ep->use_single_process below.
304 if (ep->use_single_process != use_single_process
305 && transport == NCACN_IP_TCP) {
310 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) || add_ep) {
311 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint);
313 return NT_STATUS_NO_MEMORY;
316 ep->ep_description = talloc_move(ep, &binding);
317 ep->ep_2nd_description = talloc_move(ep, &binding2);
320 /* add mgmt interface */
321 ifl = talloc_zero(ep, struct dcesrv_if_list);
323 return NT_STATUS_NO_MEMORY;
326 ifl->iface = talloc_memdup(ifl,
327 dcesrv_get_mgmt_interface(),
328 sizeof(struct dcesrv_interface));
329 if (ifl->iface == NULL) {
331 return NT_STATUS_NO_MEMORY;
334 DLIST_ADD(ep->interface_list, ifl);
335 } else if (!NT_STATUS_IS_OK(status)) {
336 DBG_NOTICE("Failed to find endpoint: %s\n", nt_errstr(status));
341 * By default don't force into a single process, but if any
342 * interface on this endpoint on this service uses handles
343 * (most do), then we must force into single process mode
345 * By overwriting this each time a new interface is added to
346 * this endpoint, we end up with the most restrictive setting.
348 if (use_single_process) {
349 ep->use_single_process = true;
352 /* talloc a new interface list element */
353 ifl = talloc_zero(ep, struct dcesrv_if_list);
355 return NT_STATUS_NO_MEMORY;
358 /* copy the given interface struct to the one on the endpoints interface list */
359 ifl->iface = talloc_memdup(ifl,
361 sizeof(struct dcesrv_interface));
362 if (ifl->iface == NULL) {
364 return NT_STATUS_NO_MEMORY;
367 /* if we have a security descriptor given,
368 * we should see if we can set it up on the endpoint
371 /* if there's currently no security descriptor given on the endpoint
374 if (ep->sd == NULL) {
375 ep->sd = security_descriptor_copy(ep, sd);
378 /* if now there's no security descriptor given on the endpoint
379 * something goes wrong, either we failed to copy the security descriptor
380 * or there was already one on the endpoint
382 if (ep->sd != NULL) {
383 DEBUG(0,("dcesrv_interface_register: interface '%s' failed to setup a security descriptor\n"
384 " on endpoint '%s'\n",
385 iface->name, ep_name));
386 if (add_ep) free(ep);
388 return NT_STATUS_OBJECT_NAME_COLLISION;
392 /* finally add the interface on the endpoint */
393 DLIST_ADD(ep->interface_list, ifl);
395 /* if it's a new endpoint add it to the dcesrv_context */
397 DLIST_ADD(dce_ctx->endpoint_list, ep);
400 /* Re-get the string as we may have set a port */
401 ep_string = dcerpc_binding_string(dce_ctx, ep->ep_description);
403 if (use_single_process) {
404 ep_process_string = "single process required";
406 ep_process_string = "multi process compatible";
409 DBG_INFO("Interface '%s' registered on endpoint '%s' (%s)\n",
410 iface->name, ep_string, ep_process_string);
411 TALLOC_FREE(ep_string);
416 static NTSTATUS dcesrv_session_info_session_key(struct dcesrv_auth *auth,
417 DATA_BLOB *session_key)
419 if (auth->session_info == NULL) {
420 return NT_STATUS_NO_USER_SESSION_KEY;
423 if (auth->session_info->session_key.length == 0) {
424 return NT_STATUS_NO_USER_SESSION_KEY;
427 *session_key = auth->session_info->session_key;
431 static NTSTATUS dcesrv_remote_session_key(struct dcesrv_auth *auth,
432 DATA_BLOB *session_key)
434 if (auth->auth_type != DCERPC_AUTH_TYPE_NONE) {
435 return NT_STATUS_NO_USER_SESSION_KEY;
438 return dcesrv_session_info_session_key(auth, session_key);
441 static NTSTATUS dcesrv_local_fixed_session_key(struct dcesrv_auth *auth,
442 DATA_BLOB *session_key)
444 return dcerpc_generic_session_key(session_key);
448 * Fetch the authentication session key if available.
450 * This is the key generated by a gensec authentication.
453 _PUBLIC_ NTSTATUS dcesrv_auth_session_key(struct dcesrv_call_state *call,
454 DATA_BLOB *session_key)
456 struct dcesrv_auth *auth = call->auth_state;
457 SMB_ASSERT(auth->auth_finished);
458 return dcesrv_session_info_session_key(auth, session_key);
462 * Fetch the transport session key if available.
463 * Typically this is the SMB session key
464 * or a fixed key for local transports.
466 * The key is always truncated to 16 bytes.
468 _PUBLIC_ NTSTATUS dcesrv_transport_session_key(struct dcesrv_call_state *call,
469 DATA_BLOB *session_key)
471 struct dcesrv_auth *auth = call->auth_state;
474 SMB_ASSERT(auth->auth_finished);
476 if (auth->session_key_fn == NULL) {
477 return NT_STATUS_NO_USER_SESSION_KEY;
480 status = auth->session_key_fn(auth, session_key);
481 if (!NT_STATUS_IS_OK(status)) {
485 session_key->length = MIN(session_key->length, 16);
490 static struct dcesrv_auth *dcesrv_auth_create(struct dcesrv_connection *conn)
492 const struct dcesrv_endpoint *ep = conn->endpoint;
493 enum dcerpc_transport_t transport =
494 dcerpc_binding_get_transport(ep->ep_description);
495 struct dcesrv_auth *auth = NULL;
497 auth = talloc_zero(conn, struct dcesrv_auth);
504 auth->session_key_fn = dcesrv_remote_session_key;
507 case NCACN_UNIX_STREAM:
508 auth->session_key_fn = dcesrv_local_fixed_session_key;
512 * All other's get a NULL pointer, which
513 * results in NT_STATUS_NO_USER_SESSION_KEY
522 connect to a dcerpc endpoint
524 _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx,
526 const struct dcesrv_endpoint *ep,
527 struct auth_session_info *session_info,
528 struct tevent_context *event_ctx,
529 uint32_t state_flags,
530 struct dcesrv_connection **_p)
532 struct dcesrv_auth *auth = NULL;
533 struct dcesrv_connection *p;
536 return NT_STATUS_ACCESS_DENIED;
539 p = talloc_zero(mem_ctx, struct dcesrv_connection);
540 NT_STATUS_HAVE_NO_MEMORY(p);
542 p->dce_ctx = dce_ctx;
544 p->packet_log_dir = lpcfg_parm_string(dce_ctx->lp_ctx,
548 p->event_ctx = event_ctx;
549 p->state_flags = state_flags;
550 p->allow_bind = true;
551 p->max_recv_frag = 5840;
552 p->max_xmit_frag = 5840;
553 p->max_total_request_size = DCERPC_NCACN_REQUEST_DEFAULT_MAX_SIZE;
555 p->support_hdr_signing = lpcfg_parm_bool(dce_ctx->lp_ctx,
560 p->max_auth_states = lpcfg_parm_ulong(dce_ctx->lp_ctx,
566 auth = dcesrv_auth_create(p);
569 return NT_STATUS_NO_MEMORY;
572 auth->session_info = talloc_reference(auth, session_info);
573 if (auth->session_info == NULL) {
575 return NT_STATUS_NO_MEMORY;
578 p->default_auth_state = auth;
581 * For now we only support NDR32.
583 p->preferred_transfer = &ndr_transfer_syntax_ndr;
590 move a call from an existing linked list to the specified list. This
591 prevents bugs where we forget to remove the call from a previous
594 static void dcesrv_call_set_list(struct dcesrv_call_state *call,
595 enum dcesrv_call_list list)
597 switch (call->list) {
598 case DCESRV_LIST_NONE:
600 case DCESRV_LIST_CALL_LIST:
601 DLIST_REMOVE(call->conn->call_list, call);
603 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
604 DLIST_REMOVE(call->conn->incoming_fragmented_call_list, call);
606 case DCESRV_LIST_PENDING_CALL_LIST:
607 DLIST_REMOVE(call->conn->pending_call_list, call);
612 case DCESRV_LIST_NONE:
614 case DCESRV_LIST_CALL_LIST:
615 DLIST_ADD_END(call->conn->call_list, call);
617 case DCESRV_LIST_FRAGMENTED_CALL_LIST:
618 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call);
620 case DCESRV_LIST_PENDING_CALL_LIST:
621 DLIST_ADD_END(call->conn->pending_call_list, call);
626 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call,
629 struct dcesrv_auth *a = NULL;
631 if (call->conn->terminate != NULL) {
635 call->conn->allow_bind = false;
636 call->conn->allow_alter = false;
638 call->conn->default_auth_state->auth_invalid = true;
640 for (a = call->conn->auth_states; a != NULL; a = a->next) {
641 a->auth_invalid = true;
644 call->terminate_reason = talloc_strdup(call, reason);
645 if (call->terminate_reason == NULL) {
646 call->terminate_reason = __location__;
651 return a dcerpc bind_nak
653 static NTSTATUS dcesrv_bind_nak(struct dcesrv_call_state *call, uint32_t reason)
655 struct ncacn_packet pkt;
656 struct dcerpc_bind_nak_version version;
657 struct data_blob_list_item *rep;
659 static const uint8_t _pad[3] = { 0, };
662 * We add the call to the pending_call_list
663 * in order to defer the termination.
665 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak");
667 /* setup a bind_nak */
668 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
670 pkt.call_id = call->pkt.call_id;
671 pkt.ptype = DCERPC_PKT_BIND_NAK;
672 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
673 pkt.u.bind_nak.reject_reason = reason;
674 version.rpc_vers = 5;
675 version.rpc_vers_minor = 0;
676 pkt.u.bind_nak.num_versions = 1;
677 pkt.u.bind_nak.versions = &version;
678 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad));
680 rep = talloc_zero(call, struct data_blob_list_item);
682 return NT_STATUS_NO_MEMORY;
685 status = dcerpc_ncacn_push_auth(&rep->blob, call, &pkt, NULL);
686 if (!NT_STATUS_IS_OK(status)) {
690 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
692 DLIST_ADD_END(call->replies, rep);
693 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
695 if (call->conn->call_list && call->conn->call_list->replies) {
696 if (call->conn->transport.report_output_data) {
697 call->conn->transport.report_output_data(call->conn);
704 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call,
708 * We add the call to the pending_call_list
709 * in order to defer the termination.
711 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect");
713 return dcesrv_fault_with_flags(call, fault_code,
714 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
717 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
719 DLIST_REMOVE(c->conn->contexts, c);
721 if (c->iface && c->iface->unbind) {
722 c->iface->unbind(c, c->iface);
729 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call)
731 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
732 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint;
733 enum dcerpc_transport_t transport =
734 dcerpc_binding_get_transport(endpoint->ep_description);
735 struct dcesrv_connection_context *context = dce_call->context;
736 const struct dcesrv_interface *iface = context->iface;
738 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE;
740 if (transport == NCALRPC) {
741 context->allow_connect = true;
746 * allow overwrite per interface
747 * allow dcerpc auth level connect:<interface>
749 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx);
750 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
751 "allow dcerpc auth level connect",
753 context->allow_connect);
756 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_connection_context *context,
757 const struct dcesrv_interface *iface)
760 * For connection oriented DCERPC DCERPC_AUTH_LEVEL_PACKET (4)
761 * has the same behavior as DCERPC_AUTH_LEVEL_INTEGRITY (5).
763 context->min_auth_level = DCERPC_AUTH_LEVEL_PACKET;
767 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_connection_context *context,
768 const struct dcesrv_interface *iface)
770 context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
774 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_connection_context *context,
775 const struct dcesrv_interface *iface)
777 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
778 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
779 enum dcerpc_transport_t transport =
780 dcerpc_binding_get_transport(endpoint->ep_description);
782 if (transport == NCALRPC) {
783 context->allow_connect = true;
788 * allow overwrite per interface
789 * allow dcerpc auth level connect:<interface>
791 context->allow_connect = false;
792 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
793 "allow dcerpc auth level connect",
795 context->allow_connect);
799 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_connection_context *context,
800 const struct dcesrv_interface *iface)
802 struct loadparm_context *lp_ctx = context->conn->dce_ctx->lp_ctx;
803 const struct dcesrv_endpoint *endpoint = context->conn->endpoint;
804 enum dcerpc_transport_t transport =
805 dcerpc_binding_get_transport(endpoint->ep_description);
807 if (transport == NCALRPC) {
808 context->allow_connect = true;
813 * allow overwrite per interface
814 * allow dcerpc auth level connect:<interface>
816 context->allow_connect = true;
817 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL,
818 "allow dcerpc auth level connect",
820 context->allow_connect);
824 struct dcesrv_conn_auth_wait_context {
825 struct tevent_req *req;
830 struct dcesrv_conn_auth_wait_state {
834 static struct tevent_req *dcesrv_conn_auth_wait_send(TALLOC_CTX *mem_ctx,
835 struct tevent_context *ev,
838 struct dcesrv_conn_auth_wait_context *auth_wait =
839 talloc_get_type_abort(private_data,
840 struct dcesrv_conn_auth_wait_context);
841 struct tevent_req *req = NULL;
842 struct dcesrv_conn_auth_wait_state *state = NULL;
844 req = tevent_req_create(mem_ctx, &state,
845 struct dcesrv_conn_auth_wait_state);
849 auth_wait->req = req;
851 tevent_req_defer_callback(req, ev);
853 if (!auth_wait->done) {
857 if (tevent_req_nterror(req, auth_wait->status)) {
858 return tevent_req_post(req, ev);
861 tevent_req_done(req);
862 return tevent_req_post(req, ev);
865 static NTSTATUS dcesrv_conn_auth_wait_recv(struct tevent_req *req)
867 return tevent_req_simple_recv_ntstatus(req);
870 static NTSTATUS dcesrv_conn_auth_wait_setup(struct dcesrv_connection *conn)
872 struct dcesrv_conn_auth_wait_context *auth_wait = NULL;
874 if (conn->wait_send != NULL) {
875 return NT_STATUS_INTERNAL_ERROR;
878 auth_wait = talloc_zero(conn, struct dcesrv_conn_auth_wait_context);
879 if (auth_wait == NULL) {
880 return NT_STATUS_NO_MEMORY;
883 conn->wait_private = auth_wait;
884 conn->wait_send = dcesrv_conn_auth_wait_send;
885 conn->wait_recv = dcesrv_conn_auth_wait_recv;
889 static void dcesrv_conn_auth_wait_finished(struct dcesrv_connection *conn,
892 struct dcesrv_conn_auth_wait_context *auth_wait =
893 talloc_get_type_abort(conn->wait_private,
894 struct dcesrv_conn_auth_wait_context);
896 auth_wait->done = true;
897 auth_wait->status = status;
899 if (auth_wait->req == NULL) {
903 if (tevent_req_nterror(auth_wait->req, status)) {
907 tevent_req_done(auth_wait->req);
910 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call);
912 static void dcesrv_bind_done(struct tevent_req *subreq);
915 handle a bind request
917 static NTSTATUS dcesrv_bind(struct dcesrv_call_state *call)
919 struct dcesrv_connection *conn = call->conn;
920 struct ncacn_packet *pkt = &call->ack_pkt;
922 uint32_t extra_flags = 0;
923 uint16_t max_req = 0;
924 uint16_t max_rep = 0;
925 struct dcerpc_binding *ep_2nd_description = NULL;
926 const char *endpoint = NULL;
927 struct dcesrv_auth *auth = call->auth_state;
928 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
929 struct dcerpc_ack_ctx *ack_features = NULL;
930 struct tevent_req *subreq = NULL;
933 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
935 call->pkt.u.bind.auth_info.length,
936 0, /* required flags */
937 DCERPC_PFC_FLAG_FIRST |
938 DCERPC_PFC_FLAG_LAST |
939 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
940 0x08 | /* this is not defined, but should be ignored */
941 DCERPC_PFC_FLAG_CONC_MPX |
942 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
943 DCERPC_PFC_FLAG_MAYBE |
944 DCERPC_PFC_FLAG_OBJECT_UUID);
945 if (!NT_STATUS_IS_OK(status)) {
946 return dcesrv_bind_nak(call,
947 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED);
950 /* max_recv_frag and max_xmit_frag result always in the same value! */
951 max_req = MIN(call->pkt.u.bind.max_xmit_frag,
952 call->pkt.u.bind.max_recv_frag);
954 * The values are between 2048 and 5840 tested against Windows 2012R2
955 * via ncacn_ip_tcp on port 135.
957 max_req = MAX(2048, max_req);
958 max_rep = MIN(max_req, call->conn->max_recv_frag);
959 /* They are truncated to an 8 byte boundary. */
962 /* max_recv_frag and max_xmit_frag result always in the same value! */
963 call->conn->max_recv_frag = max_rep;
964 call->conn->max_xmit_frag = max_rep;
966 status = call->conn->dce_ctx->callbacks.assoc_group.find(call);
967 if (!NT_STATUS_IS_OK(status)) {
968 DBG_NOTICE("Failed to find assoc_group 0x%08x: %s\n",
969 call->pkt.u.bind.assoc_group_id, nt_errstr(status));
970 return dcesrv_bind_nak(call, 0);
973 if (call->pkt.u.bind.num_contexts < 1) {
974 return dcesrv_bind_nak(call, 0);
977 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
978 call->pkt.u.bind.num_contexts);
979 if (ack_ctx_list == NULL) {
980 return dcesrv_bind_nak(call, 0);
984 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
985 * dcesrv_check_or_create_context()) and do some protocol validation
986 * and set sane defaults.
988 for (i = 0; i < call->pkt.u.bind.num_contexts; i++) {
989 const struct dcerpc_ctx_list *c = &call->pkt.u.bind.ctx_list[i];
990 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
991 bool is_feature = false;
992 uint64_t features = 0;
994 if (c->num_transfer_syntaxes == 0) {
995 return dcesrv_bind_nak(call, 0);
998 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
999 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1002 * It's only treated as bind time feature request, if the first
1003 * transfer_syntax matches, all others are ignored.
1005 is_feature = dcerpc_extract_bind_time_features(c->transfer_syntaxes[0],
1011 if (ack_features != NULL) {
1013 * Only one bind time feature context is allowed.
1015 return dcesrv_bind_nak(call, 0);
1019 a->result = DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK;
1020 a->reason.negotiate = 0;
1021 if (features & DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING) {
1022 if (call->conn->max_auth_states != 0) {
1023 a->reason.negotiate |=
1024 DCERPC_BIND_TIME_SECURITY_CONTEXT_MULTIPLEXING;
1027 if (features & DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
1028 a->reason.negotiate |=
1029 DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN;
1032 call->conn->assoc_group->bind_time_features = a->reason.negotiate;
1036 * Try to negotiate one new presentation context.
1038 * Deep in here we locate the iface (by uuid) that the client
1039 * requested, from the list of interfaces on the
1040 * call->conn->endpoint, and call iface->bind() on that iface.
1042 * call->conn was set up at the accept() of the socket, and
1043 * call->conn->endpoint has a list of interfaces restricted to
1044 * this port or pipe.
1046 status = dcesrv_negotiate_contexts(call, &call->pkt.u.bind, ack_ctx_list);
1047 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1048 return dcesrv_bind_nak(call, 0);
1050 if (!NT_STATUS_IS_OK(status)) {
1055 * At this point we still don't know which interface (eg
1056 * netlogon, lsa, drsuapi) the caller requested in this bind!
1057 * The most recently added context is available as the first
1058 * element in the linked list at call->conn->contexts, that is
1059 * call->conn->contexts->iface, but they may not have
1060 * requested one at all!
1063 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1064 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1065 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1066 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1069 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1070 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1074 * After finding the interface and setting up the NDR
1075 * transport negotiation etc, handle any authentication that
1076 * is being requested.
1078 if (!dcesrv_auth_bind(call)) {
1080 if (auth->auth_level == DCERPC_AUTH_LEVEL_NONE) {
1082 * With DCERPC_AUTH_LEVEL_NONE, we get the
1083 * reject_reason in auth->auth_context_id.
1085 return dcesrv_bind_nak(call, auth->auth_context_id);
1089 * This must a be a temporary failure e.g. talloc or invalid
1090 * configuration, e.g. no machine account.
1092 return dcesrv_bind_nak(call,
1093 DCERPC_BIND_NAK_REASON_TEMPORARY_CONGESTION);
1096 /* setup a bind_ack */
1097 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1098 pkt->auth_length = 0;
1099 pkt->call_id = call->pkt.call_id;
1100 pkt->ptype = DCERPC_PKT_BIND_ACK;
1101 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1102 pkt->u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag;
1103 pkt->u.bind_ack.max_recv_frag = call->conn->max_recv_frag;
1104 pkt->u.bind_ack.assoc_group_id = call->conn->assoc_group->id;
1106 ep_2nd_description = call->conn->endpoint->ep_2nd_description;
1107 if (ep_2nd_description == NULL) {
1108 ep_2nd_description = call->conn->endpoint->ep_description;
1111 endpoint = dcerpc_binding_get_string_option(
1114 if (endpoint == NULL) {
1118 pkt->u.bind_ack.secondary_address = endpoint;
1119 pkt->u.bind_ack.num_results = call->pkt.u.bind.num_contexts;
1120 pkt->u.bind_ack.ctx_list = ack_ctx_list;
1121 pkt->u.bind_ack.auth_info = data_blob_null;
1123 status = dcesrv_auth_prepare_bind_ack(call, pkt);
1124 if (!NT_STATUS_IS_OK(status)) {
1125 return dcesrv_bind_nak(call, 0);
1128 if (auth->auth_finished) {
1129 return dcesrv_auth_reply(call);
1132 subreq = gensec_update_send(call, call->event_ctx,
1133 auth->gensec_security,
1134 call->in_auth_info.credentials);
1135 if (subreq == NULL) {
1136 return NT_STATUS_NO_MEMORY;
1138 tevent_req_set_callback(subreq, dcesrv_bind_done, call);
1140 return dcesrv_conn_auth_wait_setup(conn);
1143 static void dcesrv_bind_done(struct tevent_req *subreq)
1145 struct dcesrv_call_state *call =
1146 tevent_req_callback_data(subreq,
1147 struct dcesrv_call_state);
1148 struct dcesrv_connection *conn = call->conn;
1151 status = gensec_update_recv(subreq, call,
1152 &call->out_auth_info->credentials);
1153 TALLOC_FREE(subreq);
1155 status = dcesrv_auth_complete(call, status);
1156 if (!NT_STATUS_IS_OK(status)) {
1157 status = dcesrv_bind_nak(call, 0);
1158 dcesrv_conn_auth_wait_finished(conn, status);
1162 status = dcesrv_auth_reply(call);
1163 dcesrv_conn_auth_wait_finished(conn, status);
1167 static NTSTATUS dcesrv_auth_reply(struct dcesrv_call_state *call)
1169 struct ncacn_packet *pkt = &call->ack_pkt;
1170 struct data_blob_list_item *rep = NULL;
1173 rep = talloc_zero(call, struct data_blob_list_item);
1175 return NT_STATUS_NO_MEMORY;
1178 status = dcerpc_ncacn_push_auth(&rep->blob,
1181 call->out_auth_info);
1182 if (!NT_STATUS_IS_OK(status)) {
1186 dcerpc_set_frag_length(&rep->blob, rep->blob.length);
1188 DLIST_ADD_END(call->replies, rep);
1189 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
1191 if (call->conn->call_list && call->conn->call_list->replies) {
1192 if (call->conn->transport.report_output_data) {
1193 call->conn->transport.report_output_data(call->conn);
1197 return NT_STATUS_OK;
1201 static void dcesrv_auth3_done(struct tevent_req *subreq);
1204 handle a auth3 request
1206 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
1208 struct dcesrv_connection *conn = call->conn;
1209 struct dcesrv_auth *auth = call->auth_state;
1210 struct tevent_req *subreq = NULL;
1213 if (!auth->auth_started) {
1214 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1217 if (auth->auth_finished) {
1218 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1221 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1223 call->pkt.u.auth3.auth_info.length,
1224 0, /* required flags */
1225 DCERPC_PFC_FLAG_FIRST |
1226 DCERPC_PFC_FLAG_LAST |
1227 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1228 0x08 | /* this is not defined, but should be ignored */
1229 DCERPC_PFC_FLAG_CONC_MPX |
1230 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1231 DCERPC_PFC_FLAG_MAYBE |
1232 DCERPC_PFC_FLAG_OBJECT_UUID);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1237 /* handle the auth3 in the auth code */
1238 if (!dcesrv_auth_prepare_auth3(call)) {
1240 * we don't send a reply to a auth3 request,
1241 * except by a fault.
1243 * In anycase we mark the connection as
1246 auth->auth_invalid = true;
1247 if (call->fault_code != 0) {
1248 return dcesrv_fault_disconnect(call, call->fault_code);
1251 return NT_STATUS_OK;
1254 subreq = gensec_update_send(call, call->event_ctx,
1255 auth->gensec_security,
1256 call->in_auth_info.credentials);
1257 if (subreq == NULL) {
1258 return NT_STATUS_NO_MEMORY;
1260 tevent_req_set_callback(subreq, dcesrv_auth3_done, call);
1262 return dcesrv_conn_auth_wait_setup(conn);
1265 static void dcesrv_auth3_done(struct tevent_req *subreq)
1267 struct dcesrv_call_state *call =
1268 tevent_req_callback_data(subreq,
1269 struct dcesrv_call_state);
1270 struct dcesrv_connection *conn = call->conn;
1271 struct dcesrv_auth *auth = call->auth_state;
1274 status = gensec_update_recv(subreq, call,
1275 &call->out_auth_info->credentials);
1276 TALLOC_FREE(subreq);
1278 status = dcesrv_auth_complete(call, status);
1279 if (!NT_STATUS_IS_OK(status)) {
1281 * we don't send a reply to a auth3 request,
1282 * except by a fault.
1284 * In anycase we mark the connection as
1287 auth->auth_invalid = true;
1288 if (call->fault_code != 0) {
1289 status = dcesrv_fault_disconnect(call, call->fault_code);
1290 dcesrv_conn_auth_wait_finished(conn, status);
1294 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1299 * we don't send a reply to a auth3 request.
1302 dcesrv_conn_auth_wait_finished(conn, NT_STATUS_OK);
1307 static NTSTATUS dcesrv_check_or_create_context(struct dcesrv_call_state *call,
1308 const struct dcerpc_bind *b,
1309 const struct dcerpc_ctx_list *ctx,
1310 struct dcerpc_ack_ctx *ack,
1312 const struct ndr_syntax_id *supported_transfer)
1314 uint32_t if_version;
1315 struct dcesrv_connection_context *context;
1316 const struct dcesrv_interface *iface;
1319 const struct ndr_syntax_id *selected_transfer = NULL;
1324 return NT_STATUS_INTERNAL_ERROR;
1327 return NT_STATUS_INTERNAL_ERROR;
1329 if (ctx->num_transfer_syntaxes < 1) {
1330 return NT_STATUS_INTERNAL_ERROR;
1333 return NT_STATUS_INTERNAL_ERROR;
1335 if (supported_transfer == NULL) {
1336 return NT_STATUS_INTERNAL_ERROR;
1339 switch (ack->result) {
1340 case DCERPC_BIND_ACK_RESULT_ACCEPTANCE:
1341 case DCERPC_BIND_ACK_RESULT_NEGOTIATE_ACK:
1343 * We is already completed.
1345 return NT_STATUS_OK;
1350 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1351 ack->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1353 if_version = ctx->abstract_syntax.if_version;
1354 uuid = ctx->abstract_syntax.uuid;
1356 iface = find_interface_by_uuid(call->conn->endpoint, &uuid, if_version);
1357 if (iface == NULL) {
1358 char *uuid_str = GUID_string(call, &uuid);
1359 DEBUG(2,("Request for unknown dcerpc interface %s/%d\n", uuid_str, if_version));
1360 talloc_free(uuid_str);
1362 * We report this only via ack->result
1364 return NT_STATUS_OK;
1367 ack->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1368 ack->reason.value = DCERPC_BIND_ACK_REASON_TRANSFER_SYNTAXES_NOT_SUPPORTED;
1370 if (validate_only) {
1372 * We report this only via ack->result
1374 return NT_STATUS_OK;
1377 for (i = 0; i < ctx->num_transfer_syntaxes; i++) {
1379 * we only do NDR encoded dcerpc for now.
1381 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[i],
1382 supported_transfer);
1384 selected_transfer = supported_transfer;
1389 context = dcesrv_find_context(call->conn, ctx->context_id);
1390 if (context != NULL) {
1391 ok = ndr_syntax_id_equal(&context->iface->syntax_id,
1392 &ctx->abstract_syntax);
1394 return NT_STATUS_RPC_PROTOCOL_ERROR;
1397 if (selected_transfer != NULL) {
1398 ok = ndr_syntax_id_equal(&context->transfer_syntax,
1401 return NT_STATUS_RPC_PROTOCOL_ERROR;
1404 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1405 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1406 ack->syntax = context->transfer_syntax;
1410 * We report this only via ack->result
1412 return NT_STATUS_OK;
1415 if (selected_transfer == NULL) {
1417 * We report this only via ack->result
1419 return NT_STATUS_OK;
1422 ack->result = DCERPC_BIND_ACK_RESULT_USER_REJECTION;
1423 ack->reason.value = DCERPC_BIND_ACK_REASON_LOCAL_LIMIT_EXCEEDED;
1425 /* add this context to the list of available context_ids */
1426 context = talloc_zero(call->conn, struct dcesrv_connection_context);
1427 if (context == NULL) {
1428 return NT_STATUS_NO_MEMORY;
1430 context->conn = call->conn;
1431 context->context_id = ctx->context_id;
1432 context->iface = iface;
1433 context->transfer_syntax = *selected_transfer;
1434 DLIST_ADD(call->conn->contexts, context);
1435 call->context = context;
1436 talloc_set_destructor(context, dcesrv_connection_context_destructor);
1438 dcesrv_prepare_context_auth(call);
1441 * Multiplex is supported by default
1443 call->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1445 status = iface->bind(context, iface);
1446 call->context = NULL;
1447 if (!NT_STATUS_IS_OK(status)) {
1448 /* we don't want to trigger the iface->unbind() hook */
1449 context->iface = NULL;
1450 talloc_free(context);
1452 * We report this only via ack->result
1454 return NT_STATUS_OK;
1457 ack->result = DCERPC_BIND_ACK_RESULT_ACCEPTANCE;
1458 ack->reason.value = DCERPC_BIND_ACK_REASON_NOT_SPECIFIED;
1459 ack->syntax = context->transfer_syntax;
1460 return NT_STATUS_OK;
1463 static NTSTATUS dcesrv_negotiate_contexts(struct dcesrv_call_state *call,
1464 const struct dcerpc_bind *b,
1465 struct dcerpc_ack_ctx *ack_ctx_list)
1469 bool validate_only = false;
1470 bool preferred_ndr32;
1473 * Try to negotiate one new presentation context,
1474 * using our preferred transfer syntax.
1476 for (i = 0; i < b->num_contexts; i++) {
1477 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1478 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1480 status = dcesrv_check_or_create_context(call, b, c, a,
1482 call->conn->preferred_transfer);
1483 if (!NT_STATUS_IS_OK(status)) {
1487 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1489 * We managed to negotiate one context.
1493 validate_only = true;
1497 preferred_ndr32 = ndr_syntax_id_equal(&ndr_transfer_syntax_ndr,
1498 call->conn->preferred_transfer);
1499 if (preferred_ndr32) {
1503 return NT_STATUS_OK;
1507 * Try to negotiate one new presentation context,
1508 * using NDR 32 as fallback.
1510 for (i = 0; i < b->num_contexts; i++) {
1511 const struct dcerpc_ctx_list *c = &b->ctx_list[i];
1512 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1514 status = dcesrv_check_or_create_context(call, b, c, a,
1516 &ndr_transfer_syntax_ndr);
1517 if (!NT_STATUS_IS_OK(status)) {
1521 if (a->result == DCERPC_BIND_ACK_RESULT_ACCEPTANCE) {
1523 * We managed to negotiate one context.
1527 validate_only = true;
1531 return NT_STATUS_OK;
1534 static void dcesrv_alter_done(struct tevent_req *subreq);
1537 handle a alter context request
1539 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call)
1541 struct dcesrv_connection *conn = call->conn;
1543 bool auth_ok = false;
1544 struct ncacn_packet *pkt = &call->ack_pkt;
1545 uint32_t extra_flags = 0;
1546 struct dcesrv_auth *auth = call->auth_state;
1547 struct dcerpc_ack_ctx *ack_ctx_list = NULL;
1548 struct tevent_req *subreq = NULL;
1551 if (!call->conn->allow_alter) {
1552 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1555 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
1557 call->pkt.u.alter.auth_info.length,
1558 0, /* required flags */
1559 DCERPC_PFC_FLAG_FIRST |
1560 DCERPC_PFC_FLAG_LAST |
1561 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN |
1562 0x08 | /* this is not defined, but should be ignored */
1563 DCERPC_PFC_FLAG_CONC_MPX |
1564 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
1565 DCERPC_PFC_FLAG_MAYBE |
1566 DCERPC_PFC_FLAG_OBJECT_UUID);
1567 if (!NT_STATUS_IS_OK(status)) {
1568 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1571 auth_ok = dcesrv_auth_alter(call);
1573 if (call->fault_code != 0) {
1574 return dcesrv_fault_disconnect(call, call->fault_code);
1578 if (call->pkt.u.alter.num_contexts < 1) {
1579 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1582 ack_ctx_list = talloc_zero_array(call, struct dcerpc_ack_ctx,
1583 call->pkt.u.alter.num_contexts);
1584 if (ack_ctx_list == NULL) {
1585 return NT_STATUS_NO_MEMORY;
1589 * Set some sane defaults (required by dcesrv_negotiate_contexts()/
1590 * dcesrv_check_or_create_context()) and do some protocol validation
1591 * and set sane defaults.
1593 for (i = 0; i < call->pkt.u.alter.num_contexts; i++) {
1594 const struct dcerpc_ctx_list *c = &call->pkt.u.alter.ctx_list[i];
1595 struct dcerpc_ack_ctx *a = &ack_ctx_list[i];
1597 if (c->num_transfer_syntaxes == 0) {
1598 return dcesrv_fault_disconnect(call,
1599 DCERPC_NCA_S_PROTO_ERROR);
1602 a->result = DCERPC_BIND_ACK_RESULT_PROVIDER_REJECTION;
1603 a->reason.value = DCERPC_BIND_ACK_REASON_ABSTRACT_SYNTAX_NOT_SUPPORTED;
1607 * Try to negotiate one new presentation context.
1609 status = dcesrv_negotiate_contexts(call, &call->pkt.u.alter, ack_ctx_list);
1610 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROTOCOL_ERROR)) {
1611 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1613 if (!NT_STATUS_IS_OK(status)) {
1617 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) &&
1618 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
1619 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED;
1620 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX;
1623 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
1624 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL;
1627 /* handle any authentication that is being requested */
1629 if (call->in_auth_info.auth_type != auth->auth_type) {
1630 return dcesrv_fault_disconnect(call,
1631 DCERPC_FAULT_SEC_PKG_ERROR);
1633 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED);
1636 dcesrv_init_hdr(pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
1637 pkt->auth_length = 0;
1638 pkt->call_id = call->pkt.call_id;
1639 pkt->ptype = DCERPC_PKT_ALTER_RESP;
1640 pkt->pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags;
1641 pkt->u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag;
1642 pkt->u.alter_resp.max_recv_frag = call->conn->max_recv_frag;
1643 pkt->u.alter_resp.assoc_group_id = call->conn->assoc_group->id;
1644 pkt->u.alter_resp.secondary_address = "";
1645 pkt->u.alter_resp.num_results = call->pkt.u.alter.num_contexts;
1646 pkt->u.alter_resp.ctx_list = ack_ctx_list;
1647 pkt->u.alter_resp.auth_info = data_blob_null;
1649 status = dcesrv_auth_prepare_alter_ack(call, pkt);
1650 if (!NT_STATUS_IS_OK(status)) {
1651 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1654 if (auth->auth_finished) {
1655 return dcesrv_auth_reply(call);
1658 subreq = gensec_update_send(call, call->event_ctx,
1659 auth->gensec_security,
1660 call->in_auth_info.credentials);
1661 if (subreq == NULL) {
1662 return NT_STATUS_NO_MEMORY;
1664 tevent_req_set_callback(subreq, dcesrv_alter_done, call);
1666 return dcesrv_conn_auth_wait_setup(conn);
1669 static void dcesrv_alter_done(struct tevent_req *subreq)
1671 struct dcesrv_call_state *call =
1672 tevent_req_callback_data(subreq,
1673 struct dcesrv_call_state);
1674 struct dcesrv_connection *conn = call->conn;
1677 status = gensec_update_recv(subreq, call,
1678 &call->out_auth_info->credentials);
1679 TALLOC_FREE(subreq);
1681 status = dcesrv_auth_complete(call, status);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 status = dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR);
1684 dcesrv_conn_auth_wait_finished(conn, status);
1688 status = dcesrv_auth_reply(call);
1689 dcesrv_conn_auth_wait_finished(conn, status);
1694 possibly save the call for inspection with ndrdump
1696 static void dcesrv_save_call(struct dcesrv_call_state *call, const char *why)
1699 dcerpc_log_packet(call->conn->packet_log_dir,
1700 call->context->iface->name,
1701 call->pkt.u.request.opnum,
1703 &call->pkt.u.request.stub_and_verifier,
1708 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call)
1710 TALLOC_CTX *frame = talloc_stackframe();
1711 const uint32_t bitmask1 = call->conn->client_hdr_signing ?
1712 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0;
1713 const struct dcerpc_sec_vt_pcontext pcontext = {
1714 .abstract_syntax = call->context->iface->syntax_id,
1715 .transfer_syntax = call->context->transfer_syntax,
1717 const struct dcerpc_sec_vt_header2 header2 =
1718 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt);
1719 enum ndr_err_code ndr_err;
1720 struct dcerpc_sec_verification_trailer *vt = NULL;
1721 NTSTATUS status = NT_STATUS_OK;
1724 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST);
1726 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull,
1728 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1729 status = ndr_map_error2ntstatus(ndr_err);
1733 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1,
1734 &pcontext, &header2);
1736 status = NT_STATUS_ACCESS_DENIED;
1745 handle a dcerpc request packet
1747 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
1749 const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
1750 struct dcesrv_auth *auth = call->auth_state;
1751 enum dcerpc_transport_t transport =
1752 dcerpc_binding_get_transport(endpoint->ep_description);
1753 struct ndr_pull *pull;
1756 if (!auth->auth_finished) {
1757 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
1760 /* if authenticated, and the mech we use can't do async replies, don't use them... */
1761 if (auth->gensec_security != NULL &&
1762 !gensec_have_feature(auth->gensec_security, GENSEC_FEATURE_ASYNC_REPLIES)) {
1763 call->state_flags &= ~DCESRV_CALL_STATE_FLAG_MAY_ASYNC;
1766 if (call->context == NULL) {
1767 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
1768 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
1771 switch (auth->auth_level) {
1772 case DCERPC_AUTH_LEVEL_NONE:
1773 case DCERPC_AUTH_LEVEL_PACKET:
1774 case DCERPC_AUTH_LEVEL_INTEGRITY:
1775 case DCERPC_AUTH_LEVEL_PRIVACY:
1778 if (!call->context->allow_connect) {
1781 addr = tsocket_address_string(call->conn->remote_address,
1784 DEBUG(2, ("%s: restrict auth_level_connect access "
1785 "to [%s] with auth[type=0x%x,level=0x%x] "
1786 "on [%s] from [%s]\n",
1787 __func__, call->context->iface->name,
1790 derpc_transport_string_by_transport(transport),
1792 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1797 if (auth->auth_level < call->context->min_auth_level) {
1800 addr = tsocket_address_string(call->conn->remote_address, call);
1802 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] "
1803 "to [%s] with auth[type=0x%x,level=0x%x] "
1804 "on [%s] from [%s]\n",
1806 call->context->min_auth_level,
1807 call->context->iface->name,
1810 derpc_transport_string_by_transport(transport),
1812 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
1815 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
1816 NT_STATUS_HAVE_NO_MEMORY(pull);
1818 pull->flags |= LIBNDR_FLAG_REF_ALLOC;
1820 call->ndr_pull = pull;
1822 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
1823 pull->flags |= LIBNDR_FLAG_BIGENDIAN;
1826 status = dcesrv_check_verification_trailer(call);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 uint32_t faultcode = DCERPC_FAULT_OTHER;
1829 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
1830 faultcode = DCERPC_FAULT_ACCESS_DENIED;
1832 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n",
1833 nt_errstr(status)));
1834 return dcesrv_fault(call, faultcode);
1837 /* unravel the NDR for the packet */
1838 status = call->context->iface->ndr_pull(call, call, pull, &call->r);
1839 if (!NT_STATUS_IS_OK(status)) {
1840 uint8_t extra_flags = 0;
1841 if (call->fault_code == DCERPC_FAULT_OP_RNG_ERROR) {
1842 /* we got an unknown call */
1843 DEBUG(3,(__location__ ": Unknown RPC call %u on %s\n",
1844 call->pkt.u.request.opnum,
1845 call->context->iface->name));
1846 dcesrv_save_call(call, "unknown");
1847 extra_flags |= DCERPC_PFC_FLAG_DID_NOT_EXECUTE;
1849 dcesrv_save_call(call, "pullfail");
1851 return dcesrv_fault_with_flags(call, call->fault_code, extra_flags);
1854 if (pull->offset != pull->data_size) {
1855 dcesrv_save_call(call, "extrabytes");
1856 DEBUG(3,("Warning: %d extra bytes in incoming RPC request\n",
1857 pull->data_size - pull->offset));
1860 /* call the dispatch function */
1861 status = call->context->iface->dispatch(call, call, call->r);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 DEBUG(5,("dcerpc fault in call %s:%02x - %s\n",
1864 call->context->iface->name,
1865 call->pkt.u.request.opnum,
1866 dcerpc_errstr(pull, call->fault_code)));
1867 return dcesrv_fault(call, call->fault_code);
1870 /* add the call to the pending list */
1871 dcesrv_call_set_list(call, DCESRV_LIST_PENDING_CALL_LIST);
1873 if (call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
1874 return NT_STATUS_OK;
1877 return dcesrv_reply(call);
1882 remove the call from the right list when freed
1884 static int dcesrv_call_dequeue(struct dcesrv_call_state *call)
1886 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
1890 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_local_address(struct dcesrv_connection *conn)
1892 return conn->local_address;
1895 _PUBLIC_ const struct tsocket_address *dcesrv_connection_get_remote_address(struct dcesrv_connection *conn)
1897 return conn->remote_address;
1901 process some input to a dcerpc endpoint server.
1903 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
1904 struct ncacn_packet *pkt,
1908 struct dcesrv_call_state *call;
1909 struct dcesrv_call_state *existing = NULL;
1910 size_t num_auth_ctx = 0;
1911 enum dcerpc_AuthType auth_type = 0;
1912 enum dcerpc_AuthLevel auth_level = 0;
1913 uint32_t auth_context_id = 0;
1915 call = talloc_zero(dce_conn, struct dcesrv_call_state);
1917 data_blob_free(&blob);
1919 return NT_STATUS_NO_MEMORY;
1921 call->conn = dce_conn;
1922 call->event_ctx = dce_conn->event_ctx;
1923 call->state_flags = call->conn->state_flags;
1924 call->time = timeval_current();
1925 call->list = DCESRV_LIST_NONE;
1927 talloc_steal(call, pkt);
1928 talloc_steal(call, blob.data);
1931 if (dce_conn->max_auth_states == 0) {
1932 call->auth_state = dce_conn->default_auth_state;
1933 } else if (call->pkt.auth_length == 0) {
1934 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
1935 dce_conn->default_auth_level_connect != NULL)
1937 call->auth_state = dce_conn->default_auth_level_connect;
1939 call->auth_state = dce_conn->default_auth_state;
1943 if (call->auth_state == NULL) {
1944 struct dcesrv_auth *a = NULL;
1946 auth_type = dcerpc_get_auth_type(&blob);
1947 auth_level = dcerpc_get_auth_level(&blob);
1948 auth_context_id = dcerpc_get_auth_context_id(&blob);
1950 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1951 dce_conn->default_auth_level_connect = NULL;
1952 if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) {
1953 dce_conn->got_explicit_auth_level_connect = true;
1957 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
1960 if (a->auth_type != auth_type) {
1963 if (a->auth_finished && a->auth_level != auth_level) {
1966 if (a->auth_context_id != auth_context_id) {
1970 DLIST_PROMOTE(dce_conn->auth_states, a);
1971 call->auth_state = a;
1976 if (call->auth_state == NULL) {
1977 struct dcesrv_auth *a = NULL;
1979 if (num_auth_ctx >= dce_conn->max_auth_states) {
1980 return dcesrv_fault_disconnect(call,
1981 DCERPC_NCA_S_PROTO_ERROR);
1984 a = dcesrv_auth_create(dce_conn);
1987 return NT_STATUS_NO_MEMORY;
1989 DLIST_ADD(dce_conn->auth_states, a);
1990 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
1992 * This can never be valid.
1994 a->auth_invalid = true;
1996 call->auth_state = a;
1999 talloc_set_destructor(call, dcesrv_call_dequeue);
2001 if (call->conn->allow_bind) {
2003 * Only one bind is possible per connection
2005 call->conn->allow_bind = false;
2006 return dcesrv_bind(call);
2009 /* we have to check the signing here, before combining the
2011 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2012 dcesrv_default_auth_state_prepare_request(call);
2014 if (call->auth_state->auth_started &&
2015 !call->auth_state->auth_finished) {
2016 return dcesrv_fault_disconnect(call,
2017 DCERPC_NCA_S_PROTO_ERROR);
2020 status = dcerpc_verify_ncacn_packet_header(&call->pkt,
2022 call->pkt.u.request.stub_and_verifier.length,
2023 0, /* required_flags */
2024 DCERPC_PFC_FLAG_FIRST |
2025 DCERPC_PFC_FLAG_LAST |
2026 DCERPC_PFC_FLAG_PENDING_CANCEL |
2027 0x08 | /* this is not defined, but should be ignored */
2028 DCERPC_PFC_FLAG_CONC_MPX |
2029 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2030 DCERPC_PFC_FLAG_MAYBE |
2031 DCERPC_PFC_FLAG_OBJECT_UUID);
2032 if (!NT_STATUS_IS_OK(status)) {
2033 return dcesrv_fault_disconnect(call,
2034 DCERPC_NCA_S_PROTO_ERROR);
2037 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) {
2039 * We don't use dcesrv_fault_disconnect()
2040 * here, because we don't want to set
2041 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2043 * Note that we don't check against the negotiated
2044 * max_recv_frag, but a hard coded value.
2046 dcesrv_call_disconnect_after(call,
2047 "dcesrv_auth_request - frag_length too large");
2048 return dcesrv_fault(call,
2049 DCERPC_NCA_S_PROTO_ERROR);
2052 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) {
2053 if (dce_conn->pending_call_list != NULL) {
2055 * concurrent requests are only allowed
2056 * if DCERPC_PFC_FLAG_CONC_MPX was negotiated.
2058 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2059 dcesrv_call_disconnect_after(call,
2060 "dcesrv_auth_request - "
2061 "existing pending call without CONN_MPX");
2062 return dcesrv_fault(call,
2063 DCERPC_NCA_S_PROTO_ERROR);
2066 /* only one request is possible in the fragmented list */
2067 if (dce_conn->incoming_fragmented_call_list != NULL) {
2068 if (!(dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) {
2070 * Without DCERPC_PFC_FLAG_CONC_MPX
2071 * we need to return the FAULT on the
2072 * already existing call.
2074 * This is important to get the
2075 * call_id and context_id right.
2078 call = dce_conn->incoming_fragmented_call_list;
2080 dcesrv_call_disconnect_after(call,
2081 "dcesrv_auth_request - "
2082 "existing fragmented call");
2083 return dcesrv_fault(call,
2084 DCERPC_NCA_S_PROTO_ERROR);
2086 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) {
2087 return dcesrv_fault_disconnect(call,
2088 DCERPC_FAULT_NO_CALL_ACTIVE);
2090 call->context = dcesrv_find_context(call->conn,
2091 call->pkt.u.request.context_id);
2092 if (call->context == NULL) {
2093 return dcesrv_fault_with_flags(call, DCERPC_NCA_S_UNKNOWN_IF,
2094 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2097 const struct dcerpc_request *nr = &call->pkt.u.request;
2098 const struct dcerpc_request *er = NULL;
2101 existing = dcesrv_find_fragmented_call(dce_conn,
2103 if (existing == NULL) {
2104 dcesrv_call_disconnect_after(call,
2105 "dcesrv_auth_request - "
2106 "no existing fragmented call");
2107 return dcesrv_fault(call,
2108 DCERPC_NCA_S_PROTO_ERROR);
2110 er = &existing->pkt.u.request;
2112 if (call->pkt.ptype != existing->pkt.ptype) {
2113 /* trying to play silly buggers are we? */
2114 return dcesrv_fault_disconnect(existing,
2115 DCERPC_NCA_S_PROTO_ERROR);
2117 cmp = memcmp(call->pkt.drep, existing->pkt.drep,
2120 return dcesrv_fault_disconnect(existing,
2121 DCERPC_NCA_S_PROTO_ERROR);
2123 if (nr->context_id != er->context_id) {
2124 return dcesrv_fault_disconnect(existing,
2125 DCERPC_NCA_S_PROTO_ERROR);
2127 if (nr->opnum != er->opnum) {
2128 return dcesrv_fault_disconnect(existing,
2129 DCERPC_NCA_S_PROTO_ERROR);
2134 if (call->pkt.ptype == DCERPC_PKT_REQUEST) {
2136 uint8_t payload_offset = DCERPC_REQUEST_LENGTH;
2138 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_OBJECT_UUID) {
2139 payload_offset += 16;
2142 ok = dcesrv_auth_pkt_pull(call, &blob,
2143 0, /* required_flags */
2144 DCERPC_PFC_FLAG_FIRST |
2145 DCERPC_PFC_FLAG_LAST |
2146 DCERPC_PFC_FLAG_PENDING_CANCEL |
2147 0x08 | /* this is not defined, but should be ignored */
2148 DCERPC_PFC_FLAG_CONC_MPX |
2149 DCERPC_PFC_FLAG_DID_NOT_EXECUTE |
2150 DCERPC_PFC_FLAG_MAYBE |
2151 DCERPC_PFC_FLAG_OBJECT_UUID,
2153 &call->pkt.u.request.stub_and_verifier);
2156 * We don't use dcesrv_fault_disconnect()
2157 * here, because we don't want to set
2158 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE
2160 dcesrv_call_disconnect_after(call,
2161 "dcesrv_auth_request - failed");
2162 if (call->fault_code == 0) {
2163 call->fault_code = DCERPC_FAULT_ACCESS_DENIED;
2165 return dcesrv_fault(call, call->fault_code);
2169 /* see if this is a continued packet */
2170 if (existing != NULL) {
2171 struct dcerpc_request *er = &existing->pkt.u.request;
2172 const struct dcerpc_request *nr = &call->pkt.u.request;
2178 * Up to 4 MByte are allowed by all fragments
2180 available = dce_conn->max_total_request_size;
2181 if (er->stub_and_verifier.length > available) {
2182 dcesrv_call_disconnect_after(existing,
2183 "dcesrv_auth_request - existing payload too large");
2184 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2186 available -= er->stub_and_verifier.length;
2187 if (nr->alloc_hint > available) {
2188 dcesrv_call_disconnect_after(existing,
2189 "dcesrv_auth_request - alloc hint too large");
2190 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2192 if (nr->stub_and_verifier.length > available) {
2193 dcesrv_call_disconnect_after(existing,
2194 "dcesrv_auth_request - new payload too large");
2195 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED);
2197 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint;
2198 /* allocate at least 1 byte */
2199 alloc_hint = MAX(alloc_hint, 1);
2200 alloc_size = er->stub_and_verifier.length +
2201 nr->stub_and_verifier.length;
2202 alloc_size = MAX(alloc_size, alloc_hint);
2204 er->stub_and_verifier.data =
2205 talloc_realloc(existing,
2206 er->stub_and_verifier.data,
2207 uint8_t, alloc_size);
2208 if (er->stub_and_verifier.data == NULL) {
2210 return dcesrv_fault_with_flags(existing,
2211 DCERPC_FAULT_OUT_OF_RESOURCES,
2212 DCERPC_PFC_FLAG_DID_NOT_EXECUTE);
2214 memcpy(er->stub_and_verifier.data +
2215 er->stub_and_verifier.length,
2216 nr->stub_and_verifier.data,
2217 nr->stub_and_verifier.length);
2218 er->stub_and_verifier.length += nr->stub_and_verifier.length;
2220 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST);
2226 /* this may not be the last pdu in the chain - if its isn't then
2227 just put it on the incoming_fragmented_call_list and wait for the rest */
2228 if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
2229 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
2231 * Up to 4 MByte are allowed by all fragments
2233 if (call->pkt.u.request.alloc_hint > dce_conn->max_total_request_size) {
2234 dcesrv_call_disconnect_after(call,
2235 "dcesrv_auth_request - initial alloc hint too large");
2236 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED);
2238 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
2239 return NT_STATUS_OK;
2242 /* This removes any fragments we may have had stashed away */
2243 dcesrv_call_set_list(call, DCESRV_LIST_NONE);
2245 switch (call->pkt.ptype) {
2246 case DCERPC_PKT_BIND:
2247 status = dcesrv_bind_nak(call,
2248 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
2250 case DCERPC_PKT_AUTH3:
2251 status = dcesrv_auth3(call);
2253 case DCERPC_PKT_ALTER:
2254 status = dcesrv_alter(call);
2256 case DCERPC_PKT_REQUEST:
2257 status = dcesrv_request(call);
2259 case DCERPC_PKT_CO_CANCEL:
2260 case DCERPC_PKT_ORPHANED:
2262 * Window just ignores CO_CANCEL and ORPHANED,
2265 status = NT_STATUS_OK;
2268 case DCERPC_PKT_BIND_ACK:
2269 case DCERPC_PKT_BIND_NAK:
2270 case DCERPC_PKT_ALTER_RESP:
2271 case DCERPC_PKT_RESPONSE:
2272 case DCERPC_PKT_FAULT:
2273 case DCERPC_PKT_SHUTDOWN:
2275 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
2279 /* if we are going to be sending a reply then add
2280 it to the list of pending calls. We add it to the end to keep the call
2281 list in the order we will answer */
2282 if (!NT_STATUS_IS_OK(status)) {
2289 _PUBLIC_ NTSTATUS dcesrv_init_context(TALLOC_CTX *mem_ctx,
2290 struct loadparm_context *lp_ctx,
2291 const char **endpoint_servers,
2292 struct dcesrv_context_callbacks *cb,
2293 struct dcesrv_context **_dce_ctx)
2296 struct dcesrv_context *dce_ctx;
2299 if (!endpoint_servers) {
2300 DEBUG(0,("dcesrv_init_context: no endpoint servers configured\n"));
2301 return NT_STATUS_INTERNAL_ERROR;
2304 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
2305 NT_STATUS_HAVE_NO_MEMORY(dce_ctx);
2307 if (uid_wrapper_enabled()) {
2308 setenv("UID_WRAPPER_MYUID", "1", 1);
2310 dce_ctx->initial_euid = geteuid();
2311 if (uid_wrapper_enabled()) {
2312 unsetenv("UID_WRAPPER_MYUID");
2315 dce_ctx->endpoint_list = NULL;
2316 dce_ctx->lp_ctx = lp_ctx;
2317 dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
2318 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
2319 dce_ctx->broken_connections = NULL;
2321 dce_ctx->callbacks = *cb;
2324 for (i=0;endpoint_servers[i];i++) {
2325 const struct dcesrv_endpoint_server *ep_server;
2327 ep_server = dcesrv_ep_server_byname(endpoint_servers[i]);
2329 DEBUG(0,("dcesrv_init_context: failed to find endpoint server = '%s'\n", endpoint_servers[i]));
2330 return NT_STATUS_INTERNAL_ERROR;
2333 status = ep_server->init_server(dce_ctx, ep_server);
2334 if (!NT_STATUS_IS_OK(status)) {
2335 DEBUG(0,("dcesrv_init_context: failed to init endpoint server = '%s': %s\n", endpoint_servers[i],
2336 nt_errstr(status)));
2341 *_dce_ctx = dce_ctx;
2342 return NT_STATUS_OK;
2345 /* the list of currently registered DCERPC endpoint servers.
2347 static struct ep_server {
2348 struct dcesrv_endpoint_server *ep_server;
2349 } *ep_servers = NULL;
2350 static int num_ep_servers = 0;
2353 register a DCERPC endpoint server.
2355 The 'name' can be later used by other backends to find the operations
2356 structure for this backend.
2359 _PUBLIC_ NTSTATUS dcerpc_register_ep_server(const struct dcesrv_endpoint_server *ep_server)
2362 if (dcesrv_ep_server_byname(ep_server->name) != NULL) {
2363 /* its already registered! */
2364 DEBUG(0,("DCERPC endpoint server '%s' already registered\n",
2366 return NT_STATUS_OBJECT_NAME_COLLISION;
2369 ep_servers = realloc_p(ep_servers, struct ep_server, num_ep_servers+1);
2371 smb_panic("out of memory in dcerpc_register");
2374 ep_servers[num_ep_servers].ep_server = smb_xmemdup(ep_server, sizeof(*ep_server));
2375 ep_servers[num_ep_servers].ep_server->name = smb_xstrdup(ep_server->name);
2379 DEBUG(3,("DCERPC endpoint server '%s' registered\n",
2382 return NT_STATUS_OK;
2386 return the operations structure for a named backend of the specified type
2388 _PUBLIC_ const struct dcesrv_endpoint_server *dcesrv_ep_server_byname(const char *name)
2392 for (i=0;i<num_ep_servers;i++) {
2393 if (strcmp(ep_servers[i].ep_server->name, name) == 0) {
2394 return ep_servers[i].ep_server;
2402 return the DCERPC module version, and the size of some critical types
2403 This can be used by endpoint server modules to either detect compilation errors, or provide
2404 multiple implementations for different smbd compilation options in one module
2406 const struct dcesrv_critical_sizes *dcerpc_module_version(void)
2408 static const struct dcesrv_critical_sizes critical_sizes = {
2409 DCERPC_MODULE_VERSION,
2410 sizeof(struct dcesrv_context),
2411 sizeof(struct dcesrv_endpoint),
2412 sizeof(struct dcesrv_endpoint_server),
2413 sizeof(struct dcesrv_interface),
2414 sizeof(struct dcesrv_if_list),
2415 sizeof(struct dcesrv_connection),
2416 sizeof(struct dcesrv_call_state),
2417 sizeof(struct dcesrv_auth),
2418 sizeof(struct dcesrv_handle)
2421 return &critical_sizes;
2424 _PUBLIC_ void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
2426 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2427 struct dcesrv_auth *a = NULL;
2429 dce_conn->wait_send = NULL;
2430 dce_conn->wait_recv = NULL;
2431 dce_conn->wait_private = NULL;
2433 dce_conn->allow_bind = false;
2434 dce_conn->allow_alter = false;
2436 dce_conn->default_auth_state->auth_invalid = true;
2438 for (a = dce_conn->auth_states; a != NULL; a = a->next) {
2439 a->auth_invalid = true;
2442 if (dce_conn->pending_call_list == NULL) {
2443 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason);
2445 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn);
2446 dce_conn->transport.terminate_connection(dce_conn,
2447 full_reason ? full_reason : reason);
2451 if (dce_conn->terminate != NULL) {
2455 DEBUG(3,("dcesrv: terminating connection due to '%s' deferred due to pending calls\n",
2457 dce_conn->terminate = talloc_strdup(dce_conn, reason);
2458 if (dce_conn->terminate == NULL) {
2459 dce_conn->terminate = "dcesrv: deferred terminating connection - no memory";
2461 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn);
2464 _PUBLIC_ void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx)
2466 struct dcesrv_connection *cur, *next;
2468 next = dce_ctx->broken_connections;
2469 while (next != NULL) {
2473 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) {
2474 struct dcesrv_connection_context *context_cur, *context_next;
2476 context_next = cur->contexts;
2477 while (context_next != NULL) {
2478 context_cur = context_next;
2479 context_next = context_cur->next;
2481 dcesrv_connection_context_destructor(context_cur);
2485 dcesrv_terminate_connection(cur, cur->terminate);
2489 /* We need this include to be able to compile on some plateforms
2490 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
2492 * It has to be that deep because otherwise we have a conflict on
2493 * const struct dcesrv_interface declaration.
2494 * This is mostly due to socket_wrapper defining #define bind swrap_bind
2495 * which conflict with the bind used before.
2497 #include "system/network.h"
2499 struct dcesrv_sock_reply_state {
2500 struct dcesrv_connection *dce_conn;
2501 struct dcesrv_call_state *call;
2505 static void dcesrv_sock_reply_done(struct tevent_req *subreq);
2506 static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
2508 _PUBLIC_ void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
2510 struct dcesrv_call_state *call;
2512 call = dce_conn->call_list;
2513 if (!call || !call->replies) {
2517 while (call->replies) {
2518 struct data_blob_list_item *rep = call->replies;
2519 struct dcesrv_sock_reply_state *substate;
2520 struct tevent_req *subreq;
2522 substate = talloc_zero(call, struct dcesrv_sock_reply_state);
2524 dcesrv_terminate_connection(dce_conn, "no memory");
2528 substate->dce_conn = dce_conn;
2529 substate->call = NULL;
2531 DLIST_REMOVE(call->replies, rep);
2533 if (call->replies == NULL && call->terminate_reason == NULL) {
2534 substate->call = call;
2537 substate->iov.iov_base = (void *) rep->blob.data;
2538 substate->iov.iov_len = rep->blob.length;
2540 subreq = tstream_writev_queue_send(substate,
2541 dce_conn->event_ctx,
2543 dce_conn->send_queue,
2546 dcesrv_terminate_connection(dce_conn, "no memory");
2549 tevent_req_set_callback(subreq, dcesrv_sock_reply_done,
2553 if (call->terminate_reason != NULL) {
2554 struct tevent_req *subreq;
2556 subreq = tevent_queue_wait_send(call,
2557 dce_conn->event_ctx,
2558 dce_conn->send_queue);
2560 dcesrv_terminate_connection(dce_conn, __location__);
2563 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1,
2567 DLIST_REMOVE(call->conn->call_list, call);
2568 call->list = DCESRV_LIST_NONE;
2571 static void dcesrv_sock_reply_done(struct tevent_req *subreq)
2573 struct dcesrv_sock_reply_state *substate = tevent_req_callback_data(subreq,
2574 struct dcesrv_sock_reply_state);
2578 struct dcesrv_call_state *call = substate->call;
2580 ret = tstream_writev_queue_recv(subreq, &sys_errno);
2581 TALLOC_FREE(subreq);
2583 status = map_nt_error_from_unix_common(sys_errno);
2584 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
2588 talloc_free(substate);
2594 static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
2596 static void dcesrv_call_terminate_step1(struct tevent_req *subreq)
2598 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2599 struct dcesrv_call_state);
2603 /* make sure we stop send queue before removing subreq */
2604 tevent_queue_stop(call->conn->send_queue);
2606 ok = tevent_queue_wait_recv(subreq);
2607 TALLOC_FREE(subreq);
2609 dcesrv_terminate_connection(call->conn, __location__);
2613 /* disconnect after 200 usecs */
2614 tv = timeval_current_ofs_usec(200);
2615 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv);
2616 if (subreq == NULL) {
2617 dcesrv_terminate_connection(call->conn, __location__);
2620 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2,
2624 static void dcesrv_call_terminate_step2(struct tevent_req *subreq)
2626 struct dcesrv_call_state *call = tevent_req_callback_data(subreq,
2627 struct dcesrv_call_state);
2630 ok = tevent_wakeup_recv(subreq);
2631 TALLOC_FREE(subreq);
2633 dcesrv_terminate_connection(call->conn, __location__);
2637 dcesrv_terminate_connection(call->conn, call->terminate_reason);
2640 static void dcesrv_conn_wait_done(struct tevent_req *subreq);
2642 static void dcesrv_read_fragment_done(struct tevent_req *subreq)
2644 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2645 struct dcesrv_connection);
2646 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2647 struct ncacn_packet *pkt;
2651 if (dce_conn->terminate) {
2653 * if the current connection is broken
2654 * we need to clean it up before any other connection
2656 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2657 dcesrv_cleanup_broken_connections(dce_ctx);
2661 dcesrv_cleanup_broken_connections(dce_ctx);
2663 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
2665 TALLOC_FREE(subreq);
2666 if (!NT_STATUS_IS_OK(status)) {
2667 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2671 status = dcesrv_process_ncacn_packet(dce_conn, pkt, buffer);
2672 if (!NT_STATUS_IS_OK(status)) {
2673 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2678 * This is used to block the connection during
2679 * pending authentication.
2681 if (dce_conn->wait_send != NULL) {
2682 subreq = dce_conn->wait_send(dce_conn,
2683 dce_conn->event_ctx,
2684 dce_conn->wait_private);
2686 status = NT_STATUS_NO_MEMORY;
2687 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2690 tevent_req_set_callback(subreq, dcesrv_conn_wait_done, dce_conn);
2694 subreq = dcerpc_read_ncacn_packet_send(dce_conn,
2695 dce_conn->event_ctx,
2698 status = NT_STATUS_NO_MEMORY;
2699 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2702 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, dce_conn);
2705 static void dcesrv_conn_wait_done(struct tevent_req *subreq)
2707 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
2708 struct dcesrv_connection);
2709 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
2712 if (dce_conn->terminate) {
2714 * if the current connection is broken
2715 * we need to clean it up before any other connection
2717 dcesrv_terminate_connection(dce_conn, dce_conn->terminate);
2718 dcesrv_cleanup_broken_connections(dce_ctx);
2722 dcesrv_cleanup_broken_connections(dce_ctx);
2724 status = dce_conn->wait_recv(subreq);
2725 dce_conn->wait_send = NULL;
2726 dce_conn->wait_recv = NULL;
2727 dce_conn->wait_private = NULL;
2728 TALLOC_FREE(subreq);
2729 if (!NT_STATUS_IS_OK(status)) {
2730 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2734 status = dcesrv_connection_loop_start(dce_conn);
2735 if (!NT_STATUS_IS_OK(status)) {
2736 dcesrv_terminate_connection(dce_conn, nt_errstr(status));
2742 * retrieve credentials from a dce_call
2744 _PUBLIC_ struct cli_credentials *dcesrv_call_credentials(struct dcesrv_call_state *dce_call)
2746 struct dcesrv_auth *auth = dce_call->auth_state;
2747 SMB_ASSERT(auth->auth_finished);
2748 return auth->session_info->credentials;
2752 * returns true if this is an authenticated call
2754 _PUBLIC_ bool dcesrv_call_authenticated(struct dcesrv_call_state *dce_call)
2756 struct dcesrv_auth *auth = dce_call->auth_state;
2757 enum security_user_level level;
2758 SMB_ASSERT(auth->auth_finished);
2759 level = security_session_user_level(auth->session_info, NULL);
2760 return level >= SECURITY_USER;
2764 * retrieve account_name for a dce_call
2766 _PUBLIC_ const char *dcesrv_call_account_name(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->info->account_name;
2774 * retrieve session_info from a dce_call
2776 _PUBLIC_ struct auth_session_info *dcesrv_call_session_info(struct dcesrv_call_state *dce_call)
2778 struct dcesrv_auth *auth = dce_call->auth_state;
2779 SMB_ASSERT(auth->auth_finished);
2780 return auth->session_info;
2784 * retrieve auth type/level from a dce_call
2786 _PUBLIC_ void dcesrv_call_auth_info(struct dcesrv_call_state *dce_call,
2787 enum dcerpc_AuthType *auth_type,
2788 enum dcerpc_AuthLevel *auth_level)
2790 struct dcesrv_auth *auth = dce_call->auth_state;
2792 SMB_ASSERT(auth->auth_finished);
2794 if (auth_type != NULL) {
2795 *auth_type = auth->auth_type;
2797 if (auth_level != NULL) {
2798 *auth_level = auth->auth_level;
2802 _PUBLIC_ NTSTATUS dcesrv_connection_loop_start(struct dcesrv_connection *conn)
2804 struct tevent_req *subreq;
2806 subreq = dcerpc_read_ncacn_packet_send(conn,
2809 if (subreq == NULL) {
2810 return NT_STATUS_NO_MEMORY;
2812 tevent_req_set_callback(subreq, dcesrv_read_fragment_done, conn);
2814 return NT_STATUS_OK;